summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedNativeTypeDefinitionNode.java5
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java26
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/TypeConstructor.java4
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/TypeOrConstructor.java20
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNativeTypeDefinitionTests.java7
5 files changed, 54 insertions, 8 deletions
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<SimpleNativeType> 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<T extends ConstructibleType> 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<T extends ConstructibleType> {
+ record Type<T extends ConstructibleType>(T value) implements TypeOrConstructor<T> {
+ @Override
+ public String name() {
+ return this.value.name();
+ }
+ }
+
+ record Constructor<T extends ConstructibleType>(TypeConstructor<T> value) implements TypeOrConstructor<T> {
+ @Override
+ public String name() {
+ return this.value.name();
+ }
+ }
+
+ String name();
+ TypeLevelValue value();
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNativeTypeDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNativeTypeDefinitionTests.java
index c0a329a..1777506 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNativeTypeDefinitionTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNativeTypeDefinitionTests.java
@@ -5,6 +5,7 @@ import org.zwobble.hobgoblin.compiler.ast.typed.TypedNativeTypeDefinitionNode;
import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNativeTypeDefinitionNode;
import org.zwobble.hobgoblin.compiler.types.NamespaceName;
import org.zwobble.hobgoblin.compiler.types.SimpleNativeType;
+import org.zwobble.hobgoblin.compiler.types.TypeOrConstructor;
import static org.zwobble.hobgoblin.compiler.typechecker.TypeCheckerTesting.typeCheckNamespaceStatement;
import static org.zwobble.precisely.AssertThat.assertThat;
@@ -23,9 +24,9 @@ public class TypeCheckerNativeTypeDefinitionTests {
assertThat(typed, instanceOf(
TypedNativeTypeDefinitionNode.class,
has(
- "type",
- TypedNativeTypeDefinitionNode::type,
- equalTo(new SimpleNativeType(NamespaceName.of("a", "b"), "X"))
+ "typeOrConstructor",
+ TypedNativeTypeDefinitionNode::typeOrConstructor,
+ equalTo(new TypeOrConstructor.Type<>(new SimpleNativeType(NamespaceName.of("a", "b"), "X")))
)
));
}