Better container access formatting

This commit is contained in:
aNNiMON 2023-10-06 23:16:40 +03:00 committed by Victor Melnik
parent ae94a1dc8a
commit 22622b3013

View File

@ -3,6 +3,7 @@ package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.TypeException;
import com.annimon.ownlang.lib.*;
import java.util.List;
import java.util.regex.Pattern;
/**
*
@ -10,9 +11,12 @@ import java.util.List;
*/
public final class ContainerAccessExpression implements Expression, Accessible {
private static final Pattern PATTERN_SIMPLE_INDEX = Pattern.compile("^\"[a-zA-Z$_]\\w*\"");
public final Expression root;
public final List<Expression> indices;
private boolean rootIsVariable;
private final boolean[] simpleIndices;
private final boolean rootIsVariable;
public ContainerAccessExpression(String variable, List<Expression> indices) {
this(new VariableExpression(variable), indices);
@ -22,6 +26,7 @@ public final class ContainerAccessExpression implements Expression, Accessible {
rootIsVariable = root instanceof VariableExpression;
this.root = root;
this.indices = indices;
simpleIndices = precomputeSimpleIndices();
}
public boolean rootIsVariable() {
@ -55,21 +60,12 @@ public final class ContainerAccessExpression implements Expression, Accessible {
final Value container = getContainer();
final Value lastIndex = lastIndex();
switch (container.type()) {
case Types.ARRAY:
((ArrayValue) container).set(lastIndex.asInt(), value);
return value;
case Types.MAP:
((MapValue) container).set(lastIndex, value);
return value;
case Types.CLASS:
((ClassInstanceValue) container).set(lastIndex, value);
return value;
default:
throw new TypeException("Array or map expected. Got " + container.type());
case Types.ARRAY -> ((ArrayValue) container).set(lastIndex.asInt(), value);
case Types.MAP -> ((MapValue) container).set(lastIndex, value);
case Types.CLASS -> ((ClassInstanceValue) container).set(lastIndex, value);
default -> throw new TypeException("Array or map expected. Got " + container.type());
}
return value;
}
public Value getContainer() {
@ -111,8 +107,30 @@ public final class ContainerAccessExpression implements Expression, Accessible {
return visitor.visit(this, t);
}
private boolean[] precomputeSimpleIndices() {
final boolean[] result = new boolean[indices.size()];
int i = 0;
for (Expression index : indices) {
String indexStr = index.toString();
result[i] = PATTERN_SIMPLE_INDEX.matcher(indexStr).matches();
i++;
}
return result;
}
@Override
public String toString() {
return root.toString() + indices;
final var sb = new StringBuilder(root.toString());
int i = 0;
for (Expression index : indices) {
String indexStr = index.toString();
if (simpleIndices[i]) {
sb.append('.').append(indexStr, 1, indexStr.length() - 1);
} else {
sb.append('[').append(indexStr).append(']');
}
i++;
}
return sb.toString();
}
}