diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-10-01 22:19:50 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-10-01 22:19:50 +0100 |
| commit | 1952180c719d657b10db6451d7d555366a9f3233 (patch) | |
| tree | ca4c54f6ee0ac40c49a7af7b0922e9f40d8aade8 /src/test/java | |
| parent | e402dc37b14873900b19361c5f64bea745204dd9 (diff) | |
Generate stack IR for when expressions
Diffstat (limited to 'src/test/java')
3 files changed, 96 insertions, 0 deletions
diff --git a/src/test/java/org/shedlang/compiler/ast/typed/Typed.java b/src/test/java/org/shedlang/compiler/ast/typed/Typed.java index 06c481ba..7c5aa0fc 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/Typed.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/Typed.java @@ -252,6 +252,21 @@ public class Typed { return new TypedAssignNode(targetVar(targetName), expression, Sources.NULL); } + public static TypedWhenNode when( + TypedExpressionNode expression, + List<TypedWhenCaseNode> cases, + Type type + ) { + return new TypedWhenNode(expression, cases, type, Sources.NULL); + } + + public static TypedWhenCaseNode whenCase( + TypedTypeLevelExpressionNode<StructType> caseType, + TypedBlockNode body + ) { + return new TypedWhenCaseNode(caseType, body, Sources.NULL); + } + public static TypedWhileNode while_( TypedReferenceNode condition, TypedBlockNode body diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerWhenTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerWhenTests.java new file mode 100644 index 00000000..0f85d48c --- /dev/null +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerWhenTests.java @@ -0,0 +1,62 @@ +package org.shedlang.compiler.stackir; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; + +import java.util.List; + +import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class StackCompilerWhenTests { + private final static NamespaceName NAMESPACE_NAME = NamespaceName.of("Example", "Project"); + + @Test + public void whenIsCompiledToSwitchInstruction() { + var node = Typed.when( + Typed.reference("x"), + List.of( + Typed.whenCase( + Typed.typeLevelReference("A", Types.struct(NAMESPACE_NAME, "A")), + Typed.block(List.of( + Typed.blockReturn(Typed.stringLiteral("a")) + )) + ), + Typed.whenCase( + Typed.typeLevelReference("B", Types.struct(NAMESPACE_NAME, "B")), + Typed.block(List.of( + Typed.blockReturn(Typed.stringLiteral("b")) + )) + ) + ), + Types.STRING + ); + var context = StackCompiler.Context.EMPTY + .addShedVariable("x"); + + var result = StackCompiler.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isLocalLoadInstruction("x__0"), + isSwitchInstruction( + isSequence( + isSwitchInstructionCase( + Types.struct(NAMESPACE_NAME, "A"), + isSequence( + isPushStringInstruction("a") + ) + ), + isSwitchInstructionCase( + Types.struct(NAMESPACE_NAME, "B"), + isSequence( + isPushStringInstruction("b") + ) + ) + ) + ) + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java b/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java index 3d1689e1..10a9cb95 100644 --- a/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java +++ b/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java @@ -162,6 +162,25 @@ public class InstructionMatchers { return instanceOf(StringAddInstruction.class); } + public static Matcher<Instruction> isSwitchInstruction( + Matcher<Iterable<? extends SwitchInstruction.Case>> cases + ) { + return instanceOf( + SwitchInstruction.class, + has("cases", x -> x.cases(), cases) + ); + } + + public static Matcher<SwitchInstruction.Case> isSwitchInstructionCase( + StructType caseType, + Matcher<Iterable<? extends Instruction>> body + ) { + return allOf( + has("caseType", x -> x.caseType(), equalTo(caseType)), + has("body", x -> x.body(), body) + ); + } + public static Matcher<Instruction> isTupleCreateInstruction(int elementCount) { return instanceOf( TupleCreateInstruction.class, |
