From 6230f7d84bcb3e6c9850ddba810c02bbbe07c32a Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 19 Jun 2026 18:08:56 +0100 Subject: Type check enums --- .../ast/typed/TypedEnumDefinitionNode.java | 15 ++++++++++ .../ast/typed/TypedEnumVariantDefinitionNode.java | 6 ++++ .../ast/typed/TypedNamespaceStatementNode.java | 2 +- .../output/generators/java/JavaGenerator.java | 3 ++ .../JavaPreciselyMatchersGenerator.java | 8 ++--- .../generators/javatypes/JavaTypesGenerator.java | 11 +++++++ .../compiler/typechecker/TypeChecker.java | 35 ++++++++++++++++++++-- .../zwobble/hobgoblin/compiler/types/EnumType.java | 8 +++++ .../org/zwobble/hobgoblin/compiler/types/Type.java | 2 +- 9 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedEnumDefinitionNode.java create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedEnumVariantDefinitionNode.java create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/types/EnumType.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedEnumDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedEnumDefinitionNode.java new file mode 100644 index 0000000..9d62a64 --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedEnumDefinitionNode.java @@ -0,0 +1,15 @@ +package org.zwobble.hobgoblin.compiler.ast.typed; + +import org.zwobble.hobgoblin.compiler.ast.DocComment; +import org.zwobble.hobgoblin.compiler.sources.Source; +import org.zwobble.hobgoblin.compiler.types.EnumType; + +import java.util.List; + +public record TypedEnumDefinitionNode( + EnumType type, + List variants, + DocComment docComment, + Source source +) implements TypedNamespaceStatementNode { +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedEnumVariantDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedEnumVariantDefinitionNode.java new file mode 100644 index 0000000..7036136 --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedEnumVariantDefinitionNode.java @@ -0,0 +1,6 @@ +package org.zwobble.hobgoblin.compiler.ast.typed; + +import org.zwobble.hobgoblin.compiler.sources.Source; + +public record TypedEnumVariantDefinitionNode(String name, Source source) { +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNamespaceStatementNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNamespaceStatementNode.java index 7e96716..fdd45b7 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNamespaceStatementNode.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNamespaceStatementNode.java @@ -1,4 +1,4 @@ package org.zwobble.hobgoblin.compiler.ast.typed; -public sealed interface TypedNamespaceStatementNode extends TypedNode permits TypedNativeTypeDefinitionNode, TypedStructDefinitionNode, TypedSumDefinitionNode { +public sealed interface TypedNamespaceStatementNode extends TypedNode permits TypedEnumDefinitionNode, TypedNativeTypeDefinitionNode, TypedStructDefinitionNode, TypedSumDefinitionNode { } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java index e56a8d5..617d438 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/java/JavaGenerator.java @@ -67,6 +67,9 @@ public class JavaGenerator { yield JavaTypeRef.generic(innerTypeRef.packageName(), innerTypeRef.typeNames(), javaArgs); } + case EnumType enumType -> + JavaTypeRef.topLevel(namespaceToJavaPackageParts(enumType.namespaceName()), enumType.name()); + case SimpleNativeType simpleNativeType -> { var nativeTypeConfig = this.config.nativeTypeConfig(simpleNativeType); if (nativeTypeConfig.isPresent()) { diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java index e1a9e38..bc29ab9 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javapreciselymatchers/JavaPreciselyMatchersGenerator.java @@ -1,10 +1,7 @@ package org.zwobble.hobgoblin.compiler.output.generators.javapreciselymatchers; import org.zwobble.hobgoblin.compiler.ast.DocComment; -import org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceNode; -import org.zwobble.hobgoblin.compiler.ast.typed.TypedNativeTypeDefinitionNode; -import org.zwobble.hobgoblin.compiler.ast.typed.TypedStructDefinitionNode; -import org.zwobble.hobgoblin.compiler.ast.typed.TypedSumDefinitionNode; +import org.zwobble.hobgoblin.compiler.ast.typed.*; import org.zwobble.hobgoblin.compiler.config.OutputConfig; import org.zwobble.hobgoblin.compiler.output.generators.Generator; import org.zwobble.hobgoblin.compiler.output.generators.java.JavaGenerator; @@ -61,6 +58,9 @@ public class JavaPreciselyMatchersGenerator implements Generator { for (var statement : namespace.body()) { switch (statement) { + case TypedEnumDefinitionNode enumDefinitionNode -> { + } + case TypedNativeTypeDefinitionNode nativeTypeDefinition -> { } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java index 3187b27..a0f92ce 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/javatypes/JavaTypesGenerator.java @@ -65,6 +65,10 @@ public class JavaTypesGenerator implements Generator { for (var statement : namespace.body()) { switch (statement) { + case TypedEnumDefinitionNode enumDefinitionNode -> { + throw new UnsupportedOperationException("TODO"); + } + case TypedNativeTypeDefinitionNode nativeTypeDefinition -> { } @@ -322,6 +326,10 @@ public class JavaTypesGenerator implements Generator { yield arbitraryValue(constructedNativeType.constructor().genericType(), context); } + case EnumType enumType -> { + throw new UnsupportedOperationException("TODO"); + } + case SimpleNativeType simpleNativeType -> { yield nativeTypeConfig(simpleNativeType) .flatMap(nativeTypeConfig -> nativeTypeConfig.arbitraryValue()) @@ -374,6 +382,9 @@ public class JavaTypesGenerator implements Generator { case ConstructedNativeType constructedNativeType -> true; + case EnumType enumType -> + true; + case SimpleNativeType simpleNativeType -> true; diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java index f8fe696..ed4ad54 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -70,7 +70,7 @@ public class TypeChecker { ) { return switch (untyped) { case UntypedEnumDefinitionNode untypedEnumDefinitionNode -> - throw new UnsupportedOperationException("TODO"); + declareEnumDefinitionNode(untyped, context); case UntypedNativeTypeDefinitionNode untypedNativeTypeDefinition -> declareNativeTypeDefinition(untypedNativeTypeDefinition, context); @@ -89,7 +89,7 @@ public class TypeChecker { ) { return switch (untyped) { case UntypedEnumDefinitionNode untypedEnumDefinitionNode -> - throw new UnsupportedOperationException("TODO"); + defineEnumDefinition(untypedEnumDefinitionNode, context); case UntypedNativeTypeDefinitionNode untypedNativeTypeDefinition -> defineNativeTypeDefinition(untypedNativeTypeDefinition, context); @@ -102,6 +102,37 @@ public class TypeChecker { }; } + private static Type declareEnumDefinitionNode( + UntypedNamespaceStatementNode untyped, + TypeCheckerNamespaceContext context + ) { + var nativeType = new EnumType(context.namespaceName(), untyped.name()); + var metaType = new TypeLevelValueType(nativeType); + context.declare(untyped.name(), metaType); + return metaType; + } + + private static TypedEnumDefinitionNode defineEnumDefinition( + UntypedEnumDefinitionNode untyped, + TypeCheckerNamespaceContext context + ) { + var enumType = (EnumType) lookupMetaType(untyped.name(), untyped.source(), context); + + var typedVariantNodes = untyped.variants().stream() + .map(untypedVariantNode -> new TypedEnumVariantDefinitionNode( + untypedVariantNode.name(), + untypedVariantNode.source() + )) + .toList(); + + return new TypedEnumDefinitionNode( + enumType, + typedVariantNodes, + untyped.docComment(), + untyped.source() + ); + } + private static Type declareNativeTypeDefinition( UntypedNativeTypeDefinitionNode untyped, TypeCheckerNamespaceContext context diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/EnumType.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/EnumType.java new file mode 100644 index 0000000..bd50d2b --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/EnumType.java @@ -0,0 +1,8 @@ +package org.zwobble.hobgoblin.compiler.types; + +public record EnumType(NamespaceName namespaceName, String name) implements Type { + @Override + public String describe() { + return namespaceName.toString() + "." + name; + } +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java index 6bb1642..4989821 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java @@ -1,4 +1,4 @@ package org.zwobble.hobgoblin.compiler.types; -public sealed interface Type extends TypeLevelValue permits ConstructedNativeType, ConstructibleType, SimpleNativeType, StructType, SumType, TypeLevelValueType, TypeParam { +public sealed interface Type extends TypeLevelValue permits ConstructedNativeType, ConstructibleType, EnumType, SimpleNativeType, StructType, SumType, TypeLevelValueType, TypeParam { } -- cgit v1.2.3