From 8349f31ec76c330c12ebdd7e5fb1d036175030a7 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 28 Jul 2023 19:11:15 +0100 Subject: Store bound variable names in typed block node --- .../org/shedlang/compiler/ast/typed/Typed.java | 2 +- .../compiler/ast/typed/TypedNodeMatchers.java | 8 +++- .../TypeCheckerFunctionDefinitionTests.java | 45 +++++++++++++++++++++ .../compiler/typechecker/TypeCheckerIfTests.java | 46 +++++++++++++++++++++- 4 files changed, 97 insertions(+), 4 deletions(-) (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 160950b6..7ce49957 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/Typed.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/Typed.java @@ -14,7 +14,7 @@ public class Typed { } public static TypedBlockNode block(List statements) { - return new TypedBlockNode(statements, Sources.NULL); + return new TypedBlockNode(statements, List.of(), Sources.NULL); } public static TypedBlockReturnNode blockReturn(TypedExpressionNode expression) { diff --git a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java index 8ce4b168..3a46fa54 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java @@ -35,6 +35,12 @@ public class TypedNodeMatchers { return has("statements", x -> x.statements(), statements); } + public static Matcher isTypedBlockNodeWithBoundVariableNames( + Matcher> boundVariableNames + ) { + return has("boundVariableNames", x -> x.boundVariableNames(), boundVariableNames); + } + public static Matcher isTypedBlockReturnNode( Matcher expression ) { @@ -56,7 +62,7 @@ public class TypedNodeMatchers { } public static Matcher isTypedConditionalBranchNode( - Matcher condition, + Matcher condition, Matcher body ) { return allOf( diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java index ab213695..6e77563f 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java @@ -348,6 +348,51 @@ public class TypeCheckerFunctionDefinitionTests { ); } + @Test + public void boundVariablesAreSet() { + var untyped = UntypedFunctionDefinitionNode.builder() + .addPositionalParam("argPositional", Untyped.typeLevelReference("Unit")) + .addNamedParam("argNamed", Untyped.typeLevelReference("Unit")) + .withReturnType(Untyped.typeLevelReference("Unit")) + .addStatement(Untyped.val( + Untyped.targetVariable("local1"), + Untyped.intLiteral(1) + )) + .addStatement(Untyped.expressionStatement(Untyped.reference("y"))) + .addStatement(Untyped.expressionStatement(Untyped.if_( + List.of( + Untyped.conditionalBranch( + Untyped.boolLiteral(true), + Untyped.block(List.of( + Untyped.val( + Untyped.targetVariable("local2"), + Untyped.intLiteral(2) + ) + )) + ) + ), + Untyped.block(List.of()) + ))) + .build(); + var context = TypeCheckerContext.EMPTY + .enterNamespaceWithDefinedVariables(P.map( + Map.entry("Unit", Types.metaType(Types.UNIT)), + Map.entry("y", Types.STRING) + )); + + var typed = typeCheckNamespaceStatement(untyped, context); + + assertThat( + typed.value(), + isTypedFunctionDefinitionNode() + .withBody(isTypedBlockNodeWithBoundVariableNames(containsExactly( + equalTo("argPositional"), + equalTo("argNamed"), + equalTo("local1") + ))) + ); + } + private static TypeCheckerResult typeCheckNamespaceStatement( UntypedFunctionDefinitionNode untyped, TypeCheckerContext context diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIfTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIfTests.java index 0aaf3d5e..a52fdfac 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIfTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIfTests.java @@ -13,8 +13,7 @@ import java.util.Map; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.shedlang.compiler.ast.typed.TypedNodeMatchers.*; import static org.zwobble.precisely.AssertThat.assertThat; -import static org.zwobble.precisely.Matchers.equalTo; -import static org.zwobble.precisely.Matchers.isSequence; +import static org.zwobble.precisely.Matchers.*; public class TypeCheckerIfTests { @Test @@ -149,4 +148,47 @@ public class TypeCheckerIfTests { )) )); } + + @Test + public void boundVariablesAreSet() { + var untyped = Untyped.if_( + List.of( + Untyped.conditionalBranch( + Untyped.boolLiteral(true), + Untyped.block(List.of( + Untyped.val( + Untyped.targetVariable("local1"), + Untyped.intLiteral(1) + ) + )) + ) + ), + Untyped.block(List.of( + Untyped.val( + Untyped.targetVariable("local2"), + Untyped.intLiteral(2) + ) + )) + ); + var context = TypeCheckerContext.EMPTY; + + var result = TypeChecker.typeCheckExpression(untyped, context); + + assertThat( + result.value(), + isTypedIfNode( + isSequence( + isTypedConditionalBranchNode( + anything(), + isTypedBlockNodeWithBoundVariableNames(containsExactly( + equalTo("local1") + )) + ) + ), + isTypedBlockNodeWithBoundVariableNames(containsExactly( + equalTo("local2") + )) + ) + ); + } } -- cgit v1.2.3