diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-28 19:34:53 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-28 19:35:09 +0100 |
| commit | 4c2c032761adf833dd24f3b833491d4ab08206cb (patch) | |
| tree | 22e3f50e6b564db8eb7dc2ab1052cf06c7966337 /src/test/java | |
| parent | 8349f31ec76c330c12ebdd7e5fb1d036175030a7 (diff) | |
Handle shadowing of variables in function
Diffstat (limited to 'src/test/java')
7 files changed, 110 insertions, 27 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 7ce49957..75a67f13 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/Typed.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/Typed.java @@ -17,6 +17,13 @@ public class Typed { return new TypedBlockNode(statements, List.of(), Sources.NULL); } + public static TypedBlockNode block( + List<TypedFunctionStatementNode> statements, + List<String> boundVariableNames + ) { + return new TypedBlockNode(statements, boundVariableNames, Sources.NULL); + } + public static TypedBlockReturnNode blockReturn(TypedExpressionNode expression) { return new TypedBlockReturnNode(expression, Sources.NULL); } @@ -135,15 +142,16 @@ public class Typed { NamespaceName namespaceName, List<TypedNamespaceStatementNode> body ) { - return namespace(namespaceName, body, List.of()); + return namespace(namespaceName, body, List.of(), List.of()); } public static TypedNamespaceNode namespace( NamespaceName namespaceName, List<TypedNamespaceStatementNode> body, + List<String> boundVariableNames, List<String> fieldNames ) { - return new TypedNamespaceNode(namespaceName, body, fieldNames, Sources.NULL); + return new TypedNamespaceNode(namespaceName, body, boundVariableNames, fieldNames, Sources.NULL); } public static TypedStringLiteralNode stringLiteral(String value) { diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerCallTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerCallTests.java index be2dda99..0d496ccb 100644 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerCallTests.java +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerCallTests.java @@ -24,12 +24,13 @@ public class StackCompilerCallTests { Typed.namedArg("x1", Typed.stringLiteral("n1")) ) ); - var context = StackCompiler.Context.EMPTY; + var context = StackCompiler.Context.EMPTY + .addShedVariable("f"); var result = StackCompiler.compileExpression(node, context); assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("f"), + isLocalLoadInstruction("f__0"), isPushStringInstruction("p1"), isPushStringInstruction("p2"), isPushStringInstruction("n2"), diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionDefinitionTests.java index 44e1118e..34656948 100644 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerFunctionDefinitionTests.java @@ -20,7 +20,9 @@ public class StackCompilerFunctionDefinitionTests { .addFreeVariable("z") .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello"))) .build(); - var context = StackCompiler.Context.EMPTY; + var context = StackCompiler.Context.EMPTY + .addShedVariable("f") + .addShedVariable("z"); var result = StackCompiler.compileNamespaceStatement(node, context); @@ -29,13 +31,13 @@ public class StackCompilerFunctionDefinitionTests { DefineFunctionInstruction.class, has("name", x -> x.name(), equalTo("f")), has("positionalParams", x -> x.positionalParams(), isSequence( - isDefineFunctionInstructionParam("x") + isDefineFunctionInstructionParam("x__0") )), has("namedParams", x -> x.namedParams(), isSequence( - isDefineFunctionInstructionParam("y") + isDefineFunctionInstructionParam("y__0") )), has("freeVariables", x -> x.freeVariables(), containsExactly( - has("name", x -> x.name(), equalTo("z")) + has("name", x -> x.name(), equalTo("z__0")) )), has("body", x -> x.body(), isSequence( isPushStringInstruction("hello"), @@ -44,7 +46,7 @@ public class StackCompilerFunctionDefinitionTests { isReturnInstruction() )) ), - isLocalStoreInstruction("f") + isLocalStoreInstruction("f__0") )); } @@ -52,12 +54,10 @@ public class StackCompilerFunctionDefinitionTests { public void whenLastStatementIsBlockReturnThenThatValueIsReturned() { var node = TypedFunctionDefinitionNode.builder() .withName("f") - .addPositionalParam("x", Typed.typeLevelReference("String", Types.STRING)) - .addNamedParam("y", Typed.typeLevelReference("Int", Types.INT)) - .addFreeVariable("z") .addStatement(Typed.blockReturn(Typed.stringLiteral("hello"))) .build(); - var context = StackCompiler.Context.EMPTY; + var context = StackCompiler.Context.EMPTY + .addShedVariable("f"); var result = StackCompiler.compileNamespaceStatement(node, context); @@ -69,7 +69,7 @@ public class StackCompilerFunctionDefinitionTests { isReturnInstruction() )) ), - isLocalStoreInstruction("f") + isLocalStoreInstruction("f__0") )); } } diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java index ecc55608..d9d63f4f 100644 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerIfTests.java @@ -27,12 +27,13 @@ public class StackCompilerIfTests { )), Types.INT ); - var context = StackCompiler.Context.EMPTY; + var context = StackCompiler.Context.EMPTY + .addShedVariable("c"); var result = StackCompiler.compileExpression(node, context); assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("c"), + isLocalLoadInstruction("c__0"), isIfInstruction( isSequence( isPushIntInstruction(42) @@ -67,18 +68,20 @@ public class StackCompilerIfTests { )), Types.INT ); - var context = StackCompiler.Context.EMPTY; + var context = StackCompiler.Context.EMPTY + .addShedVariable("c") + .addShedVariable("d"); var result = StackCompiler.compileExpression(node, context); assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("c"), + isLocalLoadInstruction("c__0"), isIfInstruction( isSequence( isPushIntInstruction(42) ), isSequence( - isLocalLoadInstruction("d"), + isLocalLoadInstruction("d__0"), isIfInstruction( isSequence( isPushIntInstruction(1) diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerNamespaceTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerNamespaceTests.java index 298611db..b4524e90 100644 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerNamespaceTests.java +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerNamespaceTests.java @@ -31,6 +31,7 @@ public class StackCompilerNamespaceTests { .addStatement(Typed.expressionStatement(Typed.stringLiteral("hello"))) .build() ), + List.of("f"), List.of("f") ); @@ -46,8 +47,8 @@ public class StackCompilerNamespaceTests { DefineFunctionInstruction.class, has("name", x -> x.name(), equalTo("f")) ), - isLocalStoreInstruction("f"), - isLocalLoadInstruction("f"), + isLocalStoreInstruction("f__0"), + isLocalLoadInstruction("f__0"), isNamespaceFieldStore(namespaceName, "f") )); } diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java index 269326aa..96907222 100644 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerReferenceTests.java @@ -11,12 +11,13 @@ public class StackCompilerReferenceTests { @Test public void referenceIsCompiledToLocalLoad() { var node = Typed.reference("x"); - var context = StackCompiler.Context.EMPTY; + var context = StackCompiler.Context.EMPTY + .addShedVariable("x"); var result = StackCompiler.compileExpression(node, context); assertThat(result.instructions(), isSequence( - isLocalLoadInstruction("x") + isLocalLoadInstruction("x__0") )); } } diff --git a/src/test/java/org/shedlang/compiler/stackir/StackCompilerValTests.java b/src/test/java/org/shedlang/compiler/stackir/StackCompilerValTests.java index 144b0461..6424f649 100644 --- a/src/test/java/org/shedlang/compiler/stackir/StackCompilerValTests.java +++ b/src/test/java/org/shedlang/compiler/stackir/StackCompilerValTests.java @@ -2,6 +2,9 @@ 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; @@ -14,13 +17,14 @@ public class StackCompilerValTests { Typed.targetVariable("x"), Typed.stringLiteral("hello") ); - var context = StackCompiler.Context.EMPTY; + var context = StackCompiler.Context.EMPTY + .addShedVariable("x"); var result = StackCompiler.compileFunctionStatement(node, context); assertThat(result.instructions(), isSequence( isPushStringInstruction("hello"), - isLocalStoreInstruction("x") + isLocalStoreInstruction("x__0") )); } @@ -30,13 +34,78 @@ public class StackCompilerValTests { Typed.targetVariable("x"), Typed.stringLiteral("hello") ); - var context = StackCompiler.Context.EMPTY; + var context = StackCompiler.Context.EMPTY + .addShedVariable("x"); var result = StackCompiler.compileNamespaceStatement(node, context); assertThat(result.instructions(), isSequence( isPushStringInstruction("hello"), - isLocalStoreInstruction("x") + isLocalStoreInstruction("x__0") + )); + } + + @Test + public void valsInDifferentBlocksAssignToDifferentLocals() { + var nodes = List.of( + Typed.val(Typed.targetVariable("x"), Typed.intLiteral(10)), + Typed.expressionStatement(Typed.reference("x")), + Typed.expressionStatement(Typed.if_( + List.of( + Typed.conditionalBranch( + Typed.boolLiteral(true), + Typed.block( + List.of( + Typed.val(Typed.targetVariable("x"), Typed.intLiteral(11)), + Typed.expressionStatement(Typed.reference("x")) + ), + List.of("x") + ) + ) + ), + Typed.block( + List.of( + Typed.val(Typed.targetVariable("x"), Typed.intLiteral(12)), + Typed.expressionStatement(Typed.reference("x")) + ), + List.of("x") + ), + Types.INT + )), + Typed.expressionStatement(Typed.reference("x")) + ); + var context = StackCompiler.Context.EMPTY + .addShedVariable("x"); + + for (var node : nodes) { + context = StackCompiler.compileFunctionStatement(node, context); + } + + assertThat(context.instructions(), isSequence( + isPushIntInstruction(10), + isLocalStoreInstruction("x__0"), + isLocalLoadInstruction("x__0"), + isDiscardInstruction(), + isPushBoolInstruction(true), + isIfInstruction( + isSequence( + isPushIntInstruction(11), + isLocalStoreInstruction("x__1"), + isLocalLoadInstruction("x__1"), + isDiscardInstruction(), + isPushUnitInstruction() + ), + isSequence( + isPushIntInstruction(12), + isLocalStoreInstruction("x__2"), + isLocalLoadInstruction("x__2"), + isDiscardInstruction(), + isPushUnitInstruction() + ) + ), + isDiscardInstruction(), + isLocalLoadInstruction("x__0"), + isDiscardInstruction() )); } } |
