aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-10-28 23:59:56 +0100
committerMichael Williamson <mike@zwobble.org>2023-10-28 23:59:56 +0100
commit186407bd0ecf485f7197027afd04c8c12e5920ce (patch)
tree010a68a4ea8c7672643924d63c3a9fd1d6b83e3e /src/test/java
parentba87d647e68a52f92dc859008f0ed20fe72659a0 (diff)
Compile expressions to stack IR
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionExpressionTests.java71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionExpressionTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionExpressionTests.java
new file mode 100644
index 00000000..b0ab21cc
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionExpressionTests.java
@@ -0,0 +1,71 @@
+package org.shedlang.compiler.stackir;
+
+import org.junit.jupiter.api.Test;
+import org.shedlang.compiler.ast.typed.Typed;
+import org.shedlang.compiler.ast.typed.TypedFunctionExpressionNode;
+import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction;
+import org.shedlang.compiler.types.Types;
+
+import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*;
+import static org.zwobble.precisely.AssertThat.assertThat;
+import static org.zwobble.precisely.Matchers.*;
+
+public class StackCompilerFunctionExpressionTests {
+ @Test
+ public void functionIsCompiledToDefineFunctionInstruction() {
+ var node = TypedFunctionExpressionNode.builder()
+ .addPositionalParam("x", Typed.typeLevelReference("String", Types.STRING))
+ .addNamedParam("y", Typed.typeLevelReference("Int", Types.INT))
+ .addFreeVariable("z")
+ .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello")))
+ .build();
+ var context = StackCompiler.Context.EMPTY
+ .addShedVariable("f")
+ .addShedVariable("z");
+
+ var result = StackCompiler.compileExpression(node, context);
+
+ assertThat(result.instructions(), isSequence(
+ instanceOf(
+ DefineFunctionInstruction.class,
+ has("name", x -> x.name(), equalTo("anonymous")),
+ has("positionalParams", x -> x.positionalParams(), isSequence(
+ isDefineFunctionInstructionParam("x__0")
+ )),
+ has("namedParams", x -> x.namedParams(), isSequence(
+ isDefineFunctionInstructionParam("y__0")
+ )),
+ has("freeVariables", x -> x.freeVariables(), containsExactly(
+ has("name", x -> x.name(), equalTo("z__0"))
+ )),
+ has("body", x -> x.body(), isSequence(
+ isPushStringInstruction("hello"),
+ isDiscardInstruction(),
+ isPushUnitInstruction(),
+ isReturnInstruction()
+ ))
+ )
+ ));
+ }
+
+ @Test
+ public void whenLastStatementIsBlockReturnThenThatValueIsReturned() {
+ var node = TypedFunctionExpressionNode.builder()
+ .addStatement(Typed.blockReturn(Typed.stringLiteral("hello")))
+ .build();
+ var context = StackCompiler.Context.EMPTY
+ .addShedVariable("f");
+
+ var result = StackCompiler.compileExpression(node, context);
+
+ assertThat(result.instructions(), isSequence(
+ instanceOf(
+ DefineFunctionInstruction.class,
+ has("body", x -> x.body(), isSequence(
+ isPushStringInstruction("hello"),
+ isReturnInstruction()
+ ))
+ )
+ ));
+ }
+}