aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-28 22:18:28 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-28 22:18:28 +0100
commitf3da8bbffe9cdf80ba3f422ec2d8ff7ce13ea2ae (patch)
treeae663ed62d128b7df8887395cf7e1eb2d48ee864 /src/test/java
parente4772ab0d4466f3844091ad603938b24c442e75b (diff)
Type check var statements
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java11
-rw-r--r--src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java7
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerVarTests.java79
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);
+ }
+}