aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-10 15:11:49 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-10 15:11:49 +0100
commitd4e6e270b038e721f7eba92d8dbcfe95ab1b31dd (patch)
tree20776839ac50d54c44c94f009a21236838050866 /src/main/java
parent3352299423098fa32275345f46beec19892f6e99 (diff)
Check type of type-level value
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java17
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetMetaType.java20
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetTypeLevelValue.java12
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSets.java2
-rw-r--r--src/main/java/org/shedlang/compiler/types/Types.java4
5 files changed, 38 insertions, 17 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index 8bb6ca23..f03de967 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -4,6 +4,7 @@ import org.shedlang.compiler.ast.typed.*;
import org.shedlang.compiler.ast.untyped.*;
import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.typechecker.errors.*;
+import org.shedlang.compiler.typechecker.typesets.TypeSetTypeLevelValue;
import org.shedlang.compiler.typechecker.typesets.TypeSets;
import org.shedlang.compiler.types.FunctionType;
import org.shedlang.compiler.types.Type;
@@ -167,7 +168,7 @@ public class TypeChecker {
UntypedFunctionDefinitionNode untyped,
TypeCheckerContext context
) {
- var typedReturnType = typeCheckTypeLevelExpression(Type.class, untyped.returnType(), context);
+ var typedReturnType = typeCheckTypeLevelExpression(TypeSets.META_TYPE, untyped.returnType(), context);
return new TypedFunctionDefinitionNode(
untyped.name(),
@@ -231,32 +232,34 @@ public class TypeChecker {
}
static <T extends TypeLevelValue> TypedTypeLevelExpressionNode<T> typeCheckTypeLevelExpression(
- Class<T> valueClass,
+ TypeSetTypeLevelValue<T> valueType,
UntypedTypeLevelExpressionNode untyped,
TypeCheckerContext context
) {
return switch (untyped) {
case UntypedTypeLevelReferenceNode reference ->
- typeCheckTypeLevelReference(valueClass, reference, context);
+ typeCheckTypeLevelReference(valueType, reference, context);
};
}
private static <T extends TypeLevelValue> TypedTypeLevelExpressionNode<T> typeCheckTypeLevelReference(
- Class<T> valueClass,
+ TypeSetTypeLevelValue<T> valueType,
UntypedTypeLevelReferenceNode untyped,
TypeCheckerContext context
) {
var type = lookupVariable(untyped.name(), untyped.source(), context);
if (!(type instanceof TypeLevelValueType typeLevelValueType)) {
- throw new UnexpectedTypeError(TypeSets.TYPE_LEVEL_VALUE, type, untyped.source());
+ throw new UnexpectedTypeError(valueType, type, untyped.source());
}
- // TODO: check instance and raise proper error
+ if (!valueType.valueClass().isInstance(typeLevelValueType.value())) {
+ throw new UnexpectedTypeError(valueType, type, untyped.source());
+ }
return new TypedTypeLevelReferenceNode<>(
untyped.name(),
- (T)typeLevelValueType.value(),
+ valueType.valueClass().cast(typeLevelValueType.value()),
untyped.source()
);
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetMetaType.java b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetMetaType.java
new file mode 100644
index 00000000..095c5c82
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetMetaType.java
@@ -0,0 +1,20 @@
+package org.shedlang.compiler.typechecker.typesets;
+
+import org.shedlang.compiler.types.Type;
+
+public final class TypeSetMetaType implements TypeSetTypeLevelValue<Type> {
+ private TypeSetMetaType() {
+ }
+
+ static final TypeSetMetaType INSTANCE = new TypeSetMetaType();
+
+ @Override
+ public String describe() {
+ return "metatype";
+ }
+
+ @Override
+ public Class<Type> valueClass() {
+ return Type.class;
+ }
+}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetTypeLevelValue.java b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetTypeLevelValue.java
index 791ec37a..c4389aee 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetTypeLevelValue.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSetTypeLevelValue.java
@@ -1,13 +1,7 @@
package org.shedlang.compiler.typechecker.typesets;
-public final class TypeSetTypeLevelValue implements TypeSet {
- private TypeSetTypeLevelValue() {
- }
+import org.shedlang.compiler.types.TypeLevelValue;
- static final TypeSetTypeLevelValue INSTANCE = new TypeSetTypeLevelValue();
-
- @Override
- public String describe() {
- return "type-level value";
- }
+public sealed interface TypeSetTypeLevelValue<T extends TypeLevelValue> extends TypeSet permits TypeSetMetaType {
+ Class<T> valueClass();
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSets.java b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSets.java
index 6bb13f7a..633bff86 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSets.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/typesets/TypeSets.java
@@ -7,7 +7,7 @@ public class TypeSets {
}
public static final TypeSet FUNCTION = TypeSetFunction.INSTANCE;
- public static final TypeSet TYPE_LEVEL_VALUE = TypeSetTypeLevelValue.INSTANCE;
+ public static final TypeSetMetaType META_TYPE = TypeSetMetaType.INSTANCE;
public static TypeSet type(Type type) {
return new TypeSetType(type);
diff --git a/src/main/java/org/shedlang/compiler/types/Types.java b/src/main/java/org/shedlang/compiler/types/Types.java
index cb734272..ad9d0547 100644
--- a/src/main/java/org/shedlang/compiler/types/Types.java
+++ b/src/main/java/org/shedlang/compiler/types/Types.java
@@ -12,4 +12,8 @@ public class Types {
public static Type metaType(Type type) {
return new TypeLevelValueType(type);
}
+
+ public static Type effectType(Effect effect) {
+ return new TypeLevelValueType(effect);
+ }
}