aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-12 20:23:23 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-12 20:23:23 +0100
commit5b999386f081b1f7e5259e26ffd33ea85e3e7a2b (patch)
treeb0bac012a2fcd9dae29295f0fe2dad3968b0bafb /src/test/java
parent84807c9365168b8b5c0ce277a341d78a222cef33 (diff)
Add incomplete type-checking for if expressions
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java18
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIfTests.java57
2 files changed, 75 insertions, 0 deletions
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 24ca7f87..8dddfa58 100644
--- a/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
+++ b/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
@@ -22,6 +22,10 @@ public class Untyped {
);
}
+ public static UntypedBlockNode block(List<UntypedFunctionStatementNode> statements) {
+ return new UntypedBlockNode(statements, Sources.NULL);
+ }
+
public static UntypedBlockReturnNode blockReturn(UntypedExpressionNode expression) {
return new UntypedBlockReturnNode(expression, Sources.NULL);
}
@@ -50,6 +54,13 @@ public class Untyped {
);
}
+ public static UntypedConditionalBranchNode conditionalBranch(
+ UntypedExpressionNode condition,
+ UntypedBlockNode body
+ ) {
+ return new UntypedConditionalBranchNode(condition, body, Sources.NULL);
+ }
+
public static UntypedBinaryOperationNode equals(
UntypedExpressionNode left,
UntypedExpressionNode right
@@ -70,6 +81,13 @@ public class Untyped {
return new UntypedFunctionReturnNode(expression, Sources.NULL);
}
+ public static UntypedIfNode if_(
+ List<UntypedConditionalBranchNode> conditionalBranches,
+ UntypedBlockNode elseBody
+ ) {
+ return new UntypedIfNode(conditionalBranches, elseBody, Sources.NULL);
+ }
+
public static UntypedIntLiteralNode intLiteral(int value) {
return new UntypedIntLiteralNode(BigInteger.valueOf(value), Sources.NULL);
}
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIfTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIfTests.java
new file mode 100644
index 00000000..796dd7c9
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIfTests.java
@@ -0,0 +1,57 @@
+package org.shedlang.compiler.typechecker;
+
+import org.junit.jupiter.api.Test;
+import org.shedlang.compiler.ast.untyped.Untyped;
+import org.shedlang.compiler.typechecker.errors.UnexpectedTypeError;
+import org.shedlang.compiler.typechecker.typesets.TypeSets;
+import org.shedlang.compiler.types.Types;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.zwobble.precisely.AssertThat.assertThat;
+import static org.zwobble.precisely.Matchers.equalTo;
+
+public class TypeCheckerIfTests {
+ @Test
+ public void canTypeCheckIfWithAllBranchesGivingTheSameType() {
+ var untyped = Untyped.if_(
+ List.of(
+ Untyped.conditionalBranch(
+ Untyped.boolLiteral(true),
+ Untyped.block(List.of(
+ Untyped.blockReturn(Untyped.stringLiteral("a"))
+ ))
+ )
+ ),
+ Untyped.block(List.of(
+ Untyped.blockReturn(Untyped.stringLiteral("b"))
+ ))
+ );
+
+ var result = TypeChecker.typeCheckExpression(untyped, TypeCheckerContext.EMPTY);
+
+ assertThat(result.value().type(), equalTo(Types.STRING));
+ }
+
+ @Test
+ public void whenConditionIsNotBoolThenErrorIsThrown() {
+ var untyped = Untyped.if_(
+ List.of(
+ Untyped.conditionalBranch(
+ Untyped.intLiteral(0),
+ Untyped.block(List.of())
+ )
+ ),
+ Untyped.block(List.of())
+ );
+
+ var error = assertThrows(
+ UnexpectedTypeError.class,
+ () -> TypeChecker.typeCheckExpression(untyped, TypeCheckerContext.EMPTY)
+ );
+
+ assertThat(error.expected(), equalTo(TypeSets.type(Types.BOOL)));
+ assertThat(error.actual(), equalTo(Types.INT));
+ }
+}