From 829ff6db80143208fd6f1a09f831aa1da72fd2d7 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 30 Jul 2023 18:06:05 +0100 Subject: Support vars in stack compiler --- .../org/shedlang/compiler/ast/typed/Typed.java | 14 +++++++++++ .../compiler/stackir/StackCompilerAssignTests.java | 28 ++++++++++++++++++++++ .../stackir/StackCompilerReferenceTests.java | 21 +++++++++++++++- .../compiler/stackir/StackCompilerVarTests.java | 27 +++++++++++++++++++++ .../stackir/instructions/InstructionMatchers.java | 14 +++++++++++ 5 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerAssignTests.java create mode 100644 src/test/java/org/shedlang/compiler/stackir/StackCompilerVarTests.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 75a67f13..c73e77a0 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,13 @@ public class Typed { private Typed() { } + public static TypedAssignNode assign( + TypedTargetNode target, + TypedExpressionNode expression + ) { + return new TypedAssignNode(target, expression, Sources.NULL); + } + public static TypedBlockNode block(List statements) { return new TypedBlockNode(statements, List.of(), Sources.NULL); } @@ -195,4 +202,11 @@ public class Typed { ) { return new TypedValNode(target, expression, Sources.NULL); } + + public static TypedVarNode var( + TypedTargetNode target, + TypedExpressionNode expression + ) { + return new TypedVarNode(target, expression, Sources.NULL); + } } diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerAssignTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerAssignTests.java new file mode 100644 index 00000000..5b138e7d --- /dev/null +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerAssignTests.java @@ -0,0 +1,28 @@ +package org.shedlang.compiler.stackir; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isPushStringInstruction; +import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isVarStoreInstruction; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class StackCompilerAssignTests { + @Test + public void expressionIsEvaluatedAndStoredAsVar() { + var node = Typed.assign( + Typed.targetVariable("x"), + Typed.stringLiteral("hello") + ); + var context = StackCompiler.Context.EMPTY + .addShedVariable("x"); + + var result = StackCompiler.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello"), + isVarStoreInstruction("x__0") + )); + } +} diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java index 96907222..1e98c35e 100644 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java @@ -3,7 +3,7 @@ package org.shedlang.compiler.stackir; import org.junit.jupiter.api.Test; import org.shedlang.compiler.ast.typed.Typed; -import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.isLocalLoadInstruction; +import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; import static org.zwobble.precisely.AssertThat.assertThat; import static org.zwobble.precisely.Matchers.isSequence; @@ -20,4 +20,23 @@ public class StackCompilerReferenceTests { isLocalLoadInstruction("x__0") )); } + + @Test + public void whenLocalIsVarThenReferenceIsCompiledToVarLoad() { + var node = Typed.reference("x"); + var context = StackCompiler.Context.EMPTY + .addShedVariable("x"); + context = StackCompiler.compileFunctionStatement( + Typed.var(Typed.targetVariable("x"), Typed.intLiteral(0)), + context + ); + + var result = StackCompiler.compileExpression(node, context); + + assertThat(result.instructions(), isSequence( + isPushIntInstruction(0), + isVarStoreInstruction("x__0"), + isVarLoadInstruction("x__0") + )); + } } diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerVarTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerVarTests.java new file mode 100644 index 00000000..414f20d9 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerVarTests.java @@ -0,0 +1,27 @@ +package org.shedlang.compiler.stackir; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.Typed; + +import static org.shedlang.compiler.stackir.instructions.InstructionMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.isSequence; + +public class StackCompilerVarTests { + @Test + public void expressionIsEvaluatedAndStoredAsVar() { + var node = Typed.var( + Typed.targetVariable("x"), + Typed.stringLiteral("hello") + ); + var context = StackCompiler.Context.EMPTY + .addShedVariable("x"); + + var result = StackCompiler.compileFunctionStatement(node, context); + + assertThat(result.instructions(), isSequence( + isPushStringInstruction("hello"), + isVarStoreInstruction("x__0") + )); + } +} 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 4be747b7..a95680d0 100644 --- a/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java +++ b/src/test/java/org/shedlang/compiler/stackir/instructions/InstructionMatchers.java @@ -118,4 +118,18 @@ public class InstructionMatchers { public static Matcher isStringAddInstruction() { return instanceOf(StringAddInstruction.class); } + + public static Matcher isVarLoadInstruction(String name) { + return instanceOf( + VarLoadInstruction.class, + has("name", x -> x.name(), equalTo(name)) + ); + } + + public static Matcher isVarStoreInstruction(String name) { + return instanceOf( + VarStoreInstruction.class, + has("name", x -> x.name(), equalTo(name)) + ); + } } -- cgit v1.2.3