diff options
| author | Elizabeth Hunt <me@liz.coffee> | 2026-02-15 10:08:30 -0800 |
|---|---|---|
| committer | Elizabeth Hunt <me@liz.coffee> | 2026-02-15 10:12:08 -0800 |
| commit | d6a294e14604aecd9046cbc19dc1837ca694fbb0 (patch) | |
| tree | 616e87e59f9ee95253acce05aa26405523a9acd7 /core/src/test/java/coffee/liz/lambda | |
| parent | 347564c592325007cb81dbdf1a07831c2ae003c3 (diff) | |
| download | the-abstraction-engine-java-d6a294e14604aecd9046cbc19dc1837ca694fbb0.tar.gz the-abstraction-engine-java-d6a294e14604aecd9046cbc19dc1837ca694fbb0.zip | |
feat: Adding ValueEmitter, LambdaEvaluatorSystem
Diffstat (limited to 'core/src/test/java/coffee/liz/lambda')
| -rw-r--r-- | core/src/test/java/coffee/liz/lambda/format/ValueEmitterTest.java | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/core/src/test/java/coffee/liz/lambda/format/ValueEmitterTest.java b/core/src/test/java/coffee/liz/lambda/format/ValueEmitterTest.java new file mode 100644 index 0000000..c1ab704 --- /dev/null +++ b/core/src/test/java/coffee/liz/lambda/format/ValueEmitterTest.java @@ -0,0 +1,60 @@ +package coffee.liz.lambda.format; + +import coffee.liz.lambda.LambdaDriver; +import coffee.liz.lambda.ast.SourceCode; +import coffee.liz.lambda.eval.Value; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ValueEmitterTest { + @Test + void emitsFreeInBothSyntaxes() { + final Value value = LambdaDriver.interpret(SourceCode.ofArrow("z")); + + final SourceCode arrow = ValueEmitter.emit(value, SourceCode.Syntax.ARROW); + final SourceCode lambda = ValueEmitter.emit(value, SourceCode.Syntax.LAMBDA); + + assertEquals("z", assertInstanceOf(SourceCode.Arrow.class, arrow).source()); + assertEquals("z", assertInstanceOf(SourceCode.Lambda.class, lambda).source()); + } + + @Test + void emitsApplicationInBothSyntaxes() { + final Value value = LambdaDriver.interpret(SourceCode.ofArrow("f(x)")); + + final SourceCode arrow = ValueEmitter.emit(value, SourceCode.Syntax.ARROW); + final SourceCode lambda = ValueEmitter.emit(value, SourceCode.Syntax.LAMBDA); + + assertEquals("f(x)", assertInstanceOf(SourceCode.Arrow.class, arrow).source()); + assertEquals("f x", assertInstanceOf(SourceCode.Lambda.class, lambda).source()); + } + + @Test + void emitsClosureWithCaptureMacros() { + 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")); + + // Validate emitted program is parsable and evaluates. + final Value roundTrip = LambdaDriver.interpret(emitted); + assertInstanceOf(Value.Closure.class, roundTrip); + } + + @Test + void emitsHygienicCapturesWhenNamesShadow() { + 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 =")); + } +} |
