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 --- .../ast/typed/TypedNamespaceStatementNode.java | 2 +- .../ast/typed/TypedSumTypeDefinitionNode.java | 9 ++++++++ .../ast/untyped/UntypedSumTypeDefinitionNode.java | 18 ++++++++++++++++ .../shedlang/compiler/typechecker/TypeChecker.java | 25 +++++++++++++++++++++- .../CannotDefineSumTypeOutsideOfNamespace.java | 10 +++++++++ .../java/org/shedlang/compiler/types/Types.java | 4 ++++ 6 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/ast/typed/TypedSumTypeDefinitionNode.java create mode 100644 src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineSumTypeOutsideOfNamespace.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java index 9a5e766a..654e073d 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedNamespaceStatementNode.java @@ -1,4 +1,4 @@ package org.shedlang.compiler.ast.typed; -public sealed interface TypedNamespaceStatementNode extends TypedNode permits TypedAssignNode, TypedFunctionDefinitionNode, TypedStructDefinitionNode { +public sealed interface TypedNamespaceStatementNode extends TypedNode permits TypedAssignNode, TypedFunctionDefinitionNode, TypedStructDefinitionNode, TypedSumTypeDefinitionNode { } diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedSumTypeDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedSumTypeDefinitionNode.java new file mode 100644 index 00000000..851e64e8 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedSumTypeDefinitionNode.java @@ -0,0 +1,9 @@ +package org.shedlang.compiler.ast.typed; + +import org.shedlang.compiler.sources.Source; + +public record TypedSumTypeDefinitionNode( + String name, + Source source +) implements TypedNamespaceStatementNode { +} diff --git a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedSumTypeDefinitionNode.java b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedSumTypeDefinitionNode.java index 681c4506..84f46711 100644 --- a/src/main/java/org/shedlang/compiler/ast/untyped/UntypedSumTypeDefinitionNode.java +++ b/src/main/java/org/shedlang/compiler/ast/untyped/UntypedSumTypeDefinitionNode.java @@ -1,6 +1,7 @@ package org.shedlang.compiler.ast.untyped; import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.sources.Sources; import java.util.List; @@ -9,4 +10,21 @@ public record UntypedSumTypeDefinitionNode( List variants, Source source ) implements UntypedNamespaceStatementNode { + public static Builder builder() { + return new Builder("DefaultSumTypeName"); + } + + public record Builder(String name) { + public UntypedSumTypeDefinitionNode build() { + return new UntypedSumTypeDefinitionNode( + name, + List.of(), + Sources.NULL + ); + } + + public Builder withName(String name) { + return new Builder(name); + } + } } diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index c630b9dc..539b9a9d 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -799,7 +799,7 @@ public class TypeChecker { typeCheckStepsStructDefinition(structDefinition); case UntypedSumTypeDefinitionNode sumTypeDefinition -> - throw new UnsupportedOperationException("TODO"); + typeCheckStepsSumTypeDefinition(sumTypeDefinition); }; } @@ -907,6 +907,29 @@ public class TypeChecker { }; } + private static TypeCheckSteps typeCheckStepsSumTypeDefinition( + UntypedSumTypeDefinitionNode untyped + ) { + return new TypeCheckSteps() { + @Override + public TypeCheckerContext declareTypes(TypeCheckerContext context) { + var namespaceName = context.namespaceName() + .orElseThrow(() -> new CannotDefineSumTypeOutsideOfNamespace(untyped.source())); + + var type = new SumType(namespaceName, untyped.name()); + + context = context.addLexicalState(untyped.name(), type); + + return context.define(untyped.name(), Types.metaType(type), untyped.source()); + } + + @Override + public TypeCheckerResult finish(TypeCheckerContext context) { + return context.toResult(null); + } + }; + } + @SuppressWarnings("unchecked") static TypedTypeLevelExpressionNode typeCheckTypeLevelExpression( TypeSetTypeLevelValue valueType, diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineSumTypeOutsideOfNamespace.java b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineSumTypeOutsideOfNamespace.java new file mode 100644 index 00000000..d3f9c48c --- /dev/null +++ b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotDefineSumTypeOutsideOfNamespace.java @@ -0,0 +1,10 @@ +package org.shedlang.compiler.typechecker.errors; + +import org.shedlang.compiler.errors.InternalCompilerError; +import org.shedlang.compiler.sources.Source; + +public class CannotDefineSumTypeOutsideOfNamespace extends InternalCompilerError { + public CannotDefineSumTypeOutsideOfNamespace(Source source) { + super("Cannot define sum type outside of namespace", source); + } +} diff --git a/src/main/java/org/shedlang/compiler/types/Types.java b/src/main/java/org/shedlang/compiler/types/Types.java index 5600d1d9..3e5e1b39 100644 --- a/src/main/java/org/shedlang/compiler/types/Types.java +++ b/src/main/java/org/shedlang/compiler/types/Types.java @@ -18,6 +18,10 @@ public class Types { return new StructType(namespaceName, name); } + public static SumType sum(NamespaceName namespaceName, String name) { + return new SumType(namespaceName, name); + } + public static TupleType tuple(List elements) { return new TupleType(elements); } -- cgit v1.2.3