From 0b8c4b6a27838e89ff49e1ab66bf2ed4378ec7da Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 14 Jul 2023 21:37:52 +0100 Subject: Compile if expression with single conditional branch --- .../org/shedlang/compiler/ast/typed/Typed.java | 28 +++++++++++++ .../compiler/stackir/StackCompilerIfTests.java | 46 ++++++++++++++++++++++ .../stackir/instructions/InstructionMatchers.java | 11 ++++++ 3 files changed, 85 insertions(+) create mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java (limited to 'src/test/java') 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 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 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 isIfInstruction( + Matcher> trueBody, + Matcher> falseBody + ) { + return instanceOf( + IfInstruction.class, + has("trueBody", x -> x.trueBody(), trueBody), + has("falseBody", x -> x.falseBody(), falseBody) + ); + } + public static Matcher isIntAddInstruction() { return instanceOf(IntAddInstruction.class); } -- cgit v1.2.3