From 8455bb19b7d4235e667cab9112aa276557969dcc Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 5 Aug 2026 18:44:26 +0100 Subject: Type check generic native types --- .../ast/typed/TypedNativeTypeDefinitionNode.java | 5 +++-- .../compiler/typechecker/TypeChecker.java | 26 +++++++++++++++++++--- .../hobgoblin/compiler/types/TypeConstructor.java | 4 ++++ .../compiler/types/TypeOrConstructor.java | 20 +++++++++++++++++ 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/types/TypeOrConstructor.java (limited to 'src/main') diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNativeTypeDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNativeTypeDefinitionNode.java index e81705b..487a80b 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNativeTypeDefinitionNode.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNativeTypeDefinitionNode.java @@ -3,13 +3,14 @@ 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.SimpleNativeType; +import org.zwobble.hobgoblin.compiler.types.TypeOrConstructor; public record TypedNativeTypeDefinitionNode( - SimpleNativeType type, + TypeOrConstructor typeOrConstructor, DocComment docComment, Source source ) implements TypedNamespaceStatementNode { public String name() { - return this.type.name(); + return this.typeOrConstructor.name(); } } 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 eb47870..e403f5b 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -165,7 +165,17 @@ public class TypeChecker { TypeCheckerNamespaceContext context ) { var nativeType = new SimpleNativeType(context.namespaceName(), untyped.name()); - var metaType = new TypeLevelValueType(nativeType); + + var nativeTypeOrConstructor = untyped.typeParams().isEmpty() + ? new TypeOrConstructor.Type<>(nativeType) + : new TypeOrConstructor.Constructor<>(new NativeTypeConstructor( + untyped.typeParams().stream() + .map(typeParam -> new TypeParam(typeParam.name())) + .toList(), + nativeType + )); + + var metaType = new TypeLevelValueType(nativeTypeOrConstructor.value()); context.declare(untyped.name(), metaType, untyped.source()); return metaType; } @@ -174,10 +184,20 @@ public class TypeChecker { UntypedNativeTypeDefinitionNode untyped, TypeCheckerNamespaceContext context ) { - var nativeType = (SimpleNativeType) lookupMetaType(untyped.name(), untyped.source(), context); + var nativeMetaType = lookupTypeLevelValue(untyped.name(), untyped.source(), context); + var nativeTypeOrConstructor = switch (nativeMetaType) { + case SimpleNativeType type -> + new TypeOrConstructor.Type<>(type); + + case NativeTypeConstructor typeConstructor -> + new TypeOrConstructor.Constructor<>(typeConstructor); + + default -> + throw new UnsupportedOperationException("TODO"); + }; return new TypedNativeTypeDefinitionNode( - nativeType, + nativeTypeOrConstructor, untyped.docComment(), untyped.source() ); diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeConstructor.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeConstructor.java index e2726fb..2c779d2 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeConstructor.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeConstructor.java @@ -9,4 +9,8 @@ public sealed interface TypeConstructor extends Typ default String describe() { return genericType().describe(); } + + default String name() { + return genericType().name(); + } } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeOrConstructor.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeOrConstructor.java new file mode 100644 index 0000000..8844669 --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeOrConstructor.java @@ -0,0 +1,20 @@ +package org.zwobble.hobgoblin.compiler.types; + +public sealed interface TypeOrConstructor { + record Type(T value) implements TypeOrConstructor { + @Override + public String name() { + return this.value.name(); + } + } + + record Constructor(TypeConstructor value) implements TypeOrConstructor { + @Override + public String name() { + return this.value.name(); + } + } + + String name(); + TypeLevelValue value(); +} -- cgit v1.2.3