From 0dbefb05318c3e1abf94f752b4c59b94859f322a Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 30 Sep 2023 17:23:52 +0100 Subject: Declare sum types --- .../TypeCheckerStructDefinitionTests.java | 22 ++++---- .../TypeCheckerSumTypeDefinitionTests.java | 63 ++++++++++++++++++++++ 2 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 src/test/java/org/shedlang/compiler/typechecker/TypeCheckerSumTypeDefinitionTests.java (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java index 0e27584a..5d53301d 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java @@ -35,7 +35,7 @@ public class TypeCheckerStructDefinitionTests { } @Test - public void canTypeCheckStructDefinitionWithNoFields() { + public void typeIsAddedToEnvironment() { var untyped = UntypedStructDefinitionNode.builder() .withName("ExampleStruct") .build(); @@ -44,15 +44,16 @@ public class TypeCheckerStructDefinitionTests { var typed = typeCheckNamespaceStatement(untyped, context); assertThat( - typed.value(), - isTypedStructDefinitionNode() - .withType(isStructType(NAMESPACE_NAME, "ExampleStruct")) - .withFields(isSequence()) + typed.context().compileTimeLookup("ExampleStruct"), + isOptionalOf(equalTo(Variable.defined( + Types.metaType(Types.struct(NAMESPACE_NAME, "ExampleStruct")), + VariableType.CONSTANT + ))) ); } @Test - public void typeIsAddedToEnvironment() { + public void canTypeCheckStructDefinitionWithNoFields() { var untyped = UntypedStructDefinitionNode.builder() .withName("ExampleStruct") .build(); @@ -61,11 +62,10 @@ public class TypeCheckerStructDefinitionTests { var typed = typeCheckNamespaceStatement(untyped, context); assertThat( - typed.context().compileTimeLookup("ExampleStruct"), - isOptionalOf(equalTo(Variable.defined( - Types.metaType(Types.struct(NAMESPACE_NAME, "ExampleStruct")), - VariableType.CONSTANT - ))) + typed.value(), + isTypedStructDefinitionNode() + .withType(isStructType(NAMESPACE_NAME, "ExampleStruct")) + .withFields(isSequence()) ); } diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerSumTypeDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerSumTypeDefinitionTests.java new file mode 100644 index 00000000..167a2477 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerSumTypeDefinitionTests.java @@ -0,0 +1,63 @@ +package org.shedlang.compiler.typechecker; + +import org.junit.jupiter.api.Test; +import org.shedlang.compiler.ast.typed.TypedNamespaceStatementNode; +import org.shedlang.compiler.ast.untyped.UntypedNamespaceStatementNode; +import org.shedlang.compiler.ast.untyped.UntypedSumTypeDefinitionNode; +import org.shedlang.compiler.typechecker.errors.CannotDefineSumTypeOutsideOfNamespace; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.types.Types; +import org.shedlang.compiler.util.P; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.zwobble.precisely.AssertThat.assertThat; +import static org.zwobble.precisely.Matchers.equalTo; +import static org.zwobble.precisely.Matchers.isOptionalOf; + +public class TypeCheckerSumTypeDefinitionTests { + private static final NamespaceName NAMESPACE_NAME = NamespaceName.of("Example"); + + @Test + public void whenOutsideOfNamespaceThenErrorIsThrown() { + var untyped = UntypedSumTypeDefinitionNode.builder() + .withName("ExampleSumType") + .build(); + var context = TypeCheckerContext.EMPTY; + + assertThrows( + CannotDefineSumTypeOutsideOfNamespace.class, + () -> TypeChecker.typeCheckNamespaceStatement(untyped).typeCheckAllPhases(context) + ); + } + + @Test + public void typeIsAddedToEnvironment() { + var untyped = UntypedSumTypeDefinitionNode.builder() + .withName("ExampleSumType") + .build(); + var context = TypeCheckerContext.EMPTY; + + var typed = typeCheckNamespaceStatement(untyped, context); + + assertThat( + typed.context().compileTimeLookup("ExampleSumType"), + isOptionalOf(equalTo(Variable.defined( + Types.metaType(Types.sum(NAMESPACE_NAME, "ExampleSumType")), + VariableType.CONSTANT + ))) + ); + } + + private static TypeCheckerResult typeCheckNamespaceStatement( + UntypedNamespaceStatementNode untyped, + TypeCheckerContext context + ) { + // TODO: remove duplication of this method + var declaredVariables = DeclaredVariables.forNamespaceStatement(untyped, P.vector()); + var environment = EnvironmentBuilder.EMPTY.addUndefined(declaredVariables); + + context = context.enterNamespace(NAMESPACE_NAME, environment.build()); + + return TypeChecker.typeCheckNamespaceStatement(untyped).typeCheckAllPhases(context); + } +} -- cgit v1.2.3