Skip to content

Commit

Permalink
feat(interpreter): support array access expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
yusshu committed Dec 27, 2023
1 parent 5893f92 commit 8a8b1c2
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,19 @@ public T entity() {
return val;
}

@Override
public @NotNull Value visitArrayAccess(final @NotNull ArrayAccessExpression expression) {
final Value array = expression.array().visit(this);
final Value index = expression.index().visit(this);
if (!(array instanceof ArrayValue)) {
return Value.nil();
} else {
final Value[] values = ((ArrayValue) array).values();
final int validIndex = Math.max(0, (int) index.getAsNumber()) % values.length;
return values[validIndex];
}
}

@Override
public @NotNull Value visitAccess(final @NotNull AccessExpression expression) {
final Value objectValue = expression.object().visit(this);
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/team/unnamed/mocha/MochaAssertions.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.util.Arrays;
import java.util.List;
import java.util.function.UnaryOperator;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -56,4 +57,15 @@ public static void assertParseError(final @NotNull String expr, final int column
assertEquals(column, e.cursor().column(), "Expected parse error at column " + column + " for expression: '" + expr + "'");
}
}

public static void assertEvaluates(final double expected, final @NotNull String expr, final @NotNull UnaryOperator<MochaEngine<?>> configurer) {
MochaEngine<?> engine = MochaEngine.createStandard();
engine = configurer.apply(engine);
final double result = engine.eval(expr);
assertEquals(expected, result, 0.0001, () -> "Expression: '" + expr + "' evaluated to " + result + ", expected " + expected);
}

public static void assertEvaluates(final double expected, final @NotNull String expr) {
assertEvaluates(expected, expr, engine -> engine);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package team.unnamed.mocha.runtime;

import org.junit.jupiter.api.Test;
import team.unnamed.mocha.MochaEngine;
import team.unnamed.mocha.runtime.value.ArrayValue;
import team.unnamed.mocha.runtime.value.NumberValue;

import java.util.function.UnaryOperator;

import static team.unnamed.mocha.MochaAssertions.assertEvaluates;

class ArrayAccessRuntimeTest {
@Test
void test() {
final UnaryOperator<MochaEngine<?>> configurer = engine -> {
engine.scope().query().set("values", ArrayValue.of(
NumberValue.of(5D),
NumberValue.of(10D),
NumberValue.of(100D)
));
return engine;
};

assertEvaluates(5D, "query.values[0]", configurer);
assertEvaluates(10D, "query.values[1]", configurer);
assertEvaluates(100D, "query.values[2]", configurer);
assertEvaluates(100D, "q.values[20 + 3]", configurer);
assertEvaluates(5D, "query.values[-1]", configurer);
assertEvaluates(5D, "q.values[-1000]", configurer);
assertEvaluates(5D, "q.values[0.5]", configurer);
assertEvaluates(10D, "q.values[0.5 + 0.5]", configurer);
assertEvaluates(100D, "q.values[math.pi - 1]", configurer);
}
}

0 comments on commit 8a8b1c2

Please sign in to comment.