aboutsummaryrefslogtreecommitdiff
path: root/core/src/test/java/coffee/liz
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2026-02-21 12:29:54 -0800
committerElizabeth Hunt <me@liz.coffee>2026-02-21 12:29:54 -0800
commit170f5c496054c9c5c2df9b8a1c5c8df7643ea004 (patch)
tree1ed217130939a04234761d54ba2ec607866f51ad /core/src/test/java/coffee/liz
parentd6a294e14604aecd9046cbc19dc1837ca694fbb0 (diff)
downloadthe-abstraction-engine-java-main.tar.gz
the-abstraction-engine-java-main.zip
Diffstat (limited to 'core/src/test/java/coffee/liz')
-rw-r--r--core/src/test/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystemTest.java43
-rw-r--r--core/src/test/java/coffee/liz/lambda/format/ValueEmitterTest.java34
2 files changed, 57 insertions, 20 deletions
diff --git a/core/src/test/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystemTest.java b/core/src/test/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystemTest.java
index 6829417..b70f669 100644
--- a/core/src/test/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystemTest.java
+++ b/core/src/test/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystemTest.java
@@ -15,6 +15,7 @@ import coffee.liz.lambda.ast.SourceCode;
import org.junit.jupiter.api.Test;
import java.time.Duration;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -23,7 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertInstanceOf;
public class LambdaEvaluatorSystemTest {
private static final Vec2<Integer> GRID_DIMENSIONS = Vec2i.builder().x(3).y(3).build();
- private static final SourceCode IDENTITY = SourceCode.ofArrow("(x -> x)(y)");
+ private static final SourceCode IDENTITY_FUNCTION = SourceCode.ofArrow("x -> x");
private static final SourceCode FREE = SourceCode.ofArrow("z");
@Test
@@ -31,8 +32,8 @@ public class LambdaEvaluatorSystemTest {
final World<GridInputState> world = new DAGWorld<>(new GridIndexSystem(GRID_DIMENSIONS),
new LambdaEvaluatorSystem(SourceCode.Syntax.ARROW));
- world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY))
- .add(new Substitution(Vec2i.EAST, Map.of("y", Vec2i.builder().x(0).y(0).build())));
+ world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY_FUNCTION))
+ .add(new Substitution(Vec2i.EAST, List.of(Vec2i.builder().x(0).y(0).build())));
world.createEntity().add(new GridPosition(Vec2i.builder().x(0).y(0).build())).add(new LambdaTerm(FREE));
world.update(GridInputState.builder().build(), Duration.ZERO);
@@ -50,8 +51,8 @@ public class LambdaEvaluatorSystemTest {
final World<GridInputState> world = new DAGWorld<>(new GridIndexSystem(GRID_DIMENSIONS),
new LambdaEvaluatorSystem(SourceCode.Syntax.LAMBDA));
- world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY))
- .add(new Substitution(Vec2i.EAST, Map.of("y", Vec2i.builder().x(0).y(0).build())));
+ world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY_FUNCTION))
+ .add(new Substitution(Vec2i.EAST, List.of(Vec2i.builder().x(0).y(0).build())));
world.createEntity().add(new GridPosition(Vec2i.builder().x(0).y(0).build())).add(new LambdaTerm(FREE));
world.update(GridInputState.builder().build(), Duration.ZERO);
@@ -68,8 +69,8 @@ public class LambdaEvaluatorSystemTest {
final World<GridInputState> world = new DAGWorld<>(new GridIndexSystem(GRID_DIMENSIONS),
new LambdaEvaluatorSystem(SourceCode.Syntax.ARROW));
- world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY))
- .add(new Substitution(Vec2i.EAST, Map.of("y", Vec2i.builder().x(0).y(0).build())));
+ world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY_FUNCTION))
+ .add(new Substitution(Vec2i.EAST, List.of(Vec2i.builder().x(0).y(0).build())));
world.update(GridInputState.builder().build(), Duration.ZERO);
@@ -79,12 +80,12 @@ public class LambdaEvaluatorSystemTest {
@Test
public void testSpawnsInSubstitutionDirection() {
- final Vec2<Integer> spawnMomentum = Vec2i.builder().x(0).y(-1).build();
+ final Vec2<Integer> spawnMomentum = Vec2i.SOUTH;
final World<GridInputState> world = new DAGWorld<>(new GridIndexSystem(GRID_DIMENSIONS),
new LambdaEvaluatorSystem(SourceCode.Syntax.ARROW));
- world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY))
- .add(new Substitution(spawnMomentum, Map.of("y", Vec2i.builder().x(0).y(0).build())));
+ world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY_FUNCTION))
+ .add(new Substitution(spawnMomentum, List.of(Vec2i.builder().x(0).y(0).build())));
world.createEntity().add(new GridPosition(Vec2i.builder().x(0).y(0).build())).add(new LambdaTerm(FREE));
world.update(GridInputState.builder().build(), Duration.ZERO);
@@ -94,4 +95,26 @@ public class LambdaEvaluatorSystemTest {
final GridMomentum momentum = emittedTerms.iterator().next().get(GridMomentum.class);
assertEquals(new GridMomentum(spawnMomentum), momentum);
}
+
+ @Test
+ public void testDependenciesAppliedInNumericOrder() {
+ final Vec2<Integer> firstDependencyPos = Vec2i.builder().x(0).y(0).build();
+ final Vec2<Integer> secondDependencyPos = Vec2i.builder().x(2).y(0).build();
+ final World<GridInputState> world = new DAGWorld<>(new GridIndexSystem(GRID_DIMENSIONS),
+ new LambdaEvaluatorSystem(SourceCode.Syntax.ARROW));
+
+ world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build()))
+ .add(new LambdaTerm(SourceCode.ofArrow("f -> g -> f")))
+ .add(new Substitution(Vec2i.EAST, List.of(firstDependencyPos, secondDependencyPos)));
+ world.createEntity().add(new GridPosition(firstDependencyPos)).add(new LambdaTerm(SourceCode.ofArrow("one")));
+ world.createEntity().add(new GridPosition(secondDependencyPos)).add(new LambdaTerm(SourceCode.ofArrow("two")));
+
+ world.update(GridInputState.builder().build(), Duration.ZERO);
+
+ final Set<Entity> emittedTerms = world.resolve(Query.allOf(GridMomentum.class, LambdaTerm.class));
+ assertEquals(1, emittedTerms.size());
+ final SourceCode emitted = emittedTerms.iterator().next().get(LambdaTerm.class).getTerm();
+ final SourceCode.Arrow arrow = assertInstanceOf(SourceCode.Arrow.class, emitted);
+ assertEquals("one", arrow.source());
+ }
}
diff --git a/core/src/test/java/coffee/liz/lambda/format/ValueEmitterTest.java b/core/src/test/java/coffee/liz/lambda/format/ValueEmitterTest.java
index c1ab704..959f45d 100644
--- a/core/src/test/java/coffee/liz/lambda/format/ValueEmitterTest.java
+++ b/core/src/test/java/coffee/liz/lambda/format/ValueEmitterTest.java
@@ -12,7 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
class ValueEmitterTest {
@Test
- void emitsFreeInBothSyntaxes() {
+ public void testEmitsFreeInBothSyntaxes() {
final Value value = LambdaDriver.interpret(SourceCode.ofArrow("z"));
final SourceCode arrow = ValueEmitter.emit(value, SourceCode.Syntax.ARROW);
@@ -23,7 +23,7 @@ class ValueEmitterTest {
}
@Test
- void emitsApplicationInBothSyntaxes() {
+ public void testEmitsApplicationInBothSyntaxes() {
final Value value = LambdaDriver.interpret(SourceCode.ofArrow("f(x)"));
final SourceCode arrow = ValueEmitter.emit(value, SourceCode.Syntax.ARROW);
@@ -34,27 +34,41 @@ class ValueEmitterTest {
}
@Test
- void emitsClosureWithCaptureMacros() {
+ public void testEmitsClosureWithCaptureMacros() {
final Value value = LambdaDriver.interpret(SourceCode.ofArrow("(x -> y -> x)(z)"));
final SourceCode emitted = ValueEmitter.emit(value, SourceCode.Syntax.ARROW);
final String source = assertInstanceOf(SourceCode.Arrow.class, emitted).source();
- assertTrue(source.contains("let _cap"));
- assertTrue(source.contains("y -> _cap"));
+ assertEquals("""
+ let x = z;
+
+ y -> x""", source);
- // Validate emitted program is parsable and evaluates.
final Value roundTrip = LambdaDriver.interpret(emitted);
assertInstanceOf(Value.Closure.class, roundTrip);
}
@Test
- void emitsHygienicCapturesWhenNamesShadow() {
+ public void testEmitsHygienicCapturesWhenNamesShadow() {
final Value value = LambdaDriver.interpret(SourceCode.ofArrow("(x -> y -> x)(y)"));
final SourceCode emitted = ValueEmitter.emit(value, SourceCode.Syntax.ARROW);
final String source = assertInstanceOf(SourceCode.Arrow.class, emitted).source();
- assertTrue(source.contains("let _cap"));
- assertTrue(source.contains("y -> _cap"));
- assertFalse(source.contains("let y ="));
+ assertEquals("""
+ let x = y;
+
+ y -> x""", source);
+ }
+
+ @Test
+ public void testPrunesUnusedEnvironmentCaptures() {
+ final Value value = LambdaDriver.interpret(SourceCode.ofArrow("(x -> w -> y -> x)(z)(q)"));
+ final SourceCode emitted = ValueEmitter.emit(value, SourceCode.Syntax.ARROW);
+ final String source = assertInstanceOf(SourceCode.Arrow.class, emitted).source();
+
+ assertEquals("""
+ let x = z;
+
+ y -> x""", source);
}
}