diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-14 21:37:52 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-14 21:37:52 +0100 |
| commit | 0b8c4b6a27838e89ff49e1ab66bf2ed4378ec7da (patch) | |
| tree | a3ae6fac6167191e9d76a2ecb9528951ddbe3e7a /src/test/java | |
| parent | 76fc235449f03fd76ab9a5bd96d9e8f2aec025c3 (diff) | |
Compile if expression with single conditional branch
Diffstat (limited to 'src/test/java')
3 files changed, 85 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 d52f67a5..160950b6 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/Typed.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/Typed.java @@ -13,6 +13,10 @@ public class Typed { private Typed() { } + public static TypedBlockNode block(List<TypedFunctionStatementNode> statements) { + return new TypedBlockNode(statements, Sources.NULL); + } + public static TypedBlockReturnNode blockReturn(TypedExpressionNode expression) { return new TypedBlockReturnNode(expression, Sources.NULL); } @@ -35,6 +39,17 @@ public class Typed { ); } + public static TypedConditionalBranchNode conditionalBranch( + TypedExpressionNode condition, + TypedBlockNode body + ) { + return new TypedConditionalBranchNode( + condition, + body, + Sources.NULL + ); + } + public static TypedExpressionStatementNode expressionStatement(TypedExpressionNode expression) { return new TypedExpressionStatementNode(expression, Sources.NULL); } @@ -43,6 +58,19 @@ public class Typed { return new TypedFunctionReturnNode(expression, Sources.NULL); } + public static TypedIfNode if_( + List<TypedConditionalBranchNode> conditionalBranches, + TypedBlockNode elseBody, + Type type + ) { + return new TypedIfNode( + conditionalBranches, + elseBody, + type, + Sources.NULL + ); + } + public static TypedBinaryOperationNode intAdd( TypedExpressionNode left, TypedExpressionNode right diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java new file mode 100644 index 00000000..49c47208 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java @@ -0,0 +1,46 @@ +package org.shedlang.compiler.stackir; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; +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 StackCompilerIfTests { + @Test + public void ifWithSingleConditionalBranchIsCompiledToSingleIfInstruction() { + var node = Typed.if_( + List.of( + Typed.conditionalBranch( + Typed.reference("c"), + Typed.block(List.of( + Typed.blockReturn(Typed.intLiteral(42)) + )) + ) + ), + Typed.block(List.of( + Typed.functionReturn(Typed.stringLiteral("x")) + )), + Types.INT + ); + + var instructions = StackCompiler.compileExpression(node); + + assertThat(instructions, isSequence( + isLocalLoadInstruction("c"), + isIfInstruction( + isSequence( + isPushIntInstruction(42) + ), + isSequence( + isPushStringInstruction("x"), + isReturnInstruction() + ) + ) + )); + } +} 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 8b2661f7..4be747b7 100644 --- a/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java +++ b/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java @@ -33,6 +33,17 @@ public class InstructionMatchers { ); } + public static Matcher<Instruction> isIfInstruction( + Matcher<Iterable<? extends Instruction>> trueBody, + Matcher<Iterable<? extends Instruction>> falseBody + ) { + return instanceOf( + IfInstruction.class, + has("trueBody", x -> x.trueBody(), trueBody), + has("falseBody", x -> x.falseBody(), falseBody) + ); + } + public static Matcher<Instruction> isIntAddInstruction() { return instanceOf(IntAddInstruction.class); } |
