diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-28 22:18:28 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-28 22:18:28 +0100 |
| commit | f3da8bbffe9cdf80ba3f422ec2d8ff7ce13ea2ae (patch) | |
| tree | ae663ed62d128b7df8887395cf7e1eb2d48ee864 /src/test/java | |
| parent | e4772ab0d4466f3844091ad603938b24c442e75b (diff) | |
Type check var statements
Diffstat (limited to 'src/test/java')
3 files changed, 97 insertions, 0 deletions
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 3a46fa54..ef2e4686 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java @@ -237,4 +237,15 @@ public class TypedNodeMatchers { has("expression", x -> x.expression(), expression) ); } + + public static Matcher<TypedNode> isTypedVarNode( + Matcher<? super TypedTargetNode> target, + Matcher<? super TypedExpressionNode> expression + ) { + return instanceOf( + TypedVarNode.class, + has("target", x -> x.target(), target), + has("expression", x -> x.expression(), expression) + ); + } } diff --git a/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java b/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java index 8dddfa58..141212cc 100644 --- a/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java +++ b/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java @@ -157,4 +157,11 @@ public class Untyped { ) { return new UntypedValNode(target, expression, Sources.NULL); } + + public static UntypedVarNode var( + UntypedTargetNode target, + UntypedExpressionNode expression + ) { + return new UntypedVarNode(target, expression, Sources.NULL); + } } diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerVarTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerVarTests.java new file mode 100644 index 00000000..244ddc98 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerVarTests.java @@ -0,0 +1,79 @@ +package org.shedlang.compiler.typechecker; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.TypedFunctionStatementNode; +import org.shedlang.compiler.ast.typed.TypedNamespaceStatementNode; +import org.shedlang.compiler.ast.untyped.Untyped; +import org.shedlang.compiler.ast.untyped.UntypedFunctionDefinitionNode; +import org.shedlang.compiler.ast.untyped.UntypedFunctionStatementNode; +import org.shedlang.compiler.ast.untyped.UntypedNamespaceStatementNode; +import org.shedlang.compiler.types.Types; +import org.shedlang.compiler.util.P; + +import java.util.Map; + +import static org.shedlang.compiler.ast.typed.TypedNodeMatchers.*; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.anything; +import static org.zwobble.precisely.Matchers.isSequence; + +public class TypeCheckerVarTests { + @Test + public void canTypeCheckAsFunctionStatement() { + var untyped = Untyped.var(Untyped.targetVariable("x"), Untyped.stringLiteral("hello")); + + var typed = typeCheckFunctionStatement(untyped, TypeCheckerContext.EMPTY); + + assertThat(typed.value(), isTypedVarNode( + isTypedTargetVariable("x"), + isTypedStringLiteralNode("hello") + )); + } + + @Test + public void varCanBeReferencedAfterDefinitionInFunction() { + var untyped = UntypedFunctionDefinitionNode.builder() + .addStatement(Untyped.var(Untyped.targetVariable("x"), Untyped.stringLiteral("hello"))) + .addStatement(Untyped.expressionStatement(Untyped.reference("x"))) + .build(); + var context = TypeCheckerContext.EMPTY + .enterNamespaceWithDefinedVariables(P.map( + Map.entry("Unit", Types.metaType(Types.UNIT)) + )); + + var typed = typeCheckNamespaceStatement(untyped, context); + + assertThat( + typed.value(), + isTypedFunctionDefinitionNode() + .withBody(isTypedBlockNode(isSequence( + isTypedVarNode(anything(), anything()), + isTypedExpressionStatementNode(isTypedReferenceNode("x", Types.STRING)) + ))) + ); + } + + private static TypeCheckerResult<? extends TypedFunctionStatementNode> typeCheckFunctionStatement( + UntypedFunctionStatementNode untyped, + TypeCheckerContext context + ) { + var declaredVariables = DeclaredVariables.forFunctionStatement(untyped, P.vector()); + var environment = EnvironmentBuilder.EMPTY.addUndefined(declaredVariables); + + context = context.enterNamespace(environment.build()); + + return TypeChecker.typeCheckFunctionStatement(untyped, context); + } + + private static TypeCheckerResult<? extends TypedNamespaceStatementNode> typeCheckNamespaceStatement( + UntypedNamespaceStatementNode untyped, + TypeCheckerContext context + ) { + var declaredVariables = DeclaredVariables.forNamespaceStatement(untyped, P.vector()); + var environment = EnvironmentBuilder.EMPTY.addUndefined(declaredVariables); + + context = context.enterNamespace(environment.build()); + + return TypeChecker.typeCheckNamespaceStatement(untyped).typeCheckAllPhases(context); + } +} |
