diff options
Diffstat (limited to 'src')
5 files changed, 63 insertions, 11 deletions
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 012fd2b..6fd902b 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -111,14 +111,20 @@ public class TypeChecker { var sumType = (SumType) lookupMetaType(untyped.name(), untyped.source(), context); var typedVariants = new ArrayList<TypedSumVariantDefinitionNode>(); + // TODO: should be StructType? + var variantTypes = new ArrayList<Type>(); for (var untypedVariant : untyped.variants()) { + var variantType = typeCheckMetaType(untypedVariant.type(), context); var typedVariant = new TypedSumVariantDefinitionNode( - typeCheckMetaType(untypedVariant.type(), context), + variantType, untyped.source() ); typedVariants.add(typedVariant); + variantTypes.add(variantType.value()); } + context.defineSumType(sumType, variantTypes); + return new TypedSumDefinitionNode( sumType, typedVariants, diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java index 82a7e96..d3d4c43 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java @@ -3,10 +3,12 @@ package org.zwobble.hobgoblin.compiler.typechecker; import org.zwobble.hobgoblin.compiler.types.*; import java.util.HashMap; +import java.util.List; import java.util.Map; public class TypeCheckerGlobalContext { private final Map<String, Type> nativeTypes = new HashMap<>(); + private final Map<Type, List<SumType>> variantOf = new HashMap<>(); public static TypeCheckerGlobalContext initial() { return new TypeCheckerGlobalContext(); @@ -15,6 +17,10 @@ public class TypeCheckerGlobalContext { private TypeCheckerGlobalContext() { } + public TypesInfo toTypesInfo() { + return new TypesInfo(this.variantOf); + } + public void addNativeType(SimpleNativeType type) { this.nativeTypes.put(type.name(), new TypeLevelValueType(type)); } @@ -24,6 +30,6 @@ public class TypeCheckerGlobalContext { } public TypeCheckerNamespaceContext enterNamespace(NamespaceName namespaceName) { - return TypeCheckerNamespaceContext.initial(namespaceName, this.nativeTypes); + return TypeCheckerNamespaceContext.initial(namespaceName, this.nativeTypes, this.variantOf); } } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java index b18267b..795bd6a 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java @@ -1,8 +1,11 @@ package org.zwobble.hobgoblin.compiler.typechecker; import org.zwobble.hobgoblin.compiler.types.NamespaceName; +import org.zwobble.hobgoblin.compiler.types.SumType; import org.zwobble.hobgoblin.compiler.types.Type; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -10,7 +13,8 @@ import java.util.stream.Collectors; public class TypeCheckerNamespaceContext { public static TypeCheckerNamespaceContext initial( NamespaceName namespaceName, - Map<String, Type> nativeTypes + Map<String, Type> nativeTypes, + Map<Type, List<SumType>> variantOf ) { var variables = nativeTypes.entrySet().stream() .collect(Collectors.toMap( @@ -18,18 +22,21 @@ public class TypeCheckerNamespaceContext { entry -> Variable.defined(entry.getValue()) )); - return new TypeCheckerNamespaceContext(namespaceName, variables); + return new TypeCheckerNamespaceContext(namespaceName, variables, variantOf); } private final NamespaceName namespaceName; private final Map<String, Variable> variables; + private final Map<Type, List<SumType>> variantOf; private TypeCheckerNamespaceContext( NamespaceName namespaceName, - Map<String, Variable> variables + Map<String, Variable> variables, + Map<Type, List<SumType>> variantOf ) { this.namespaceName = namespaceName; this.variables = variables; + this.variantOf = variantOf; } public NamespaceName namespaceName() { @@ -49,4 +56,11 @@ public class TypeCheckerNamespaceContext { public Optional<Variable> lookup(String name) { return Optional.ofNullable(this.variables.get(name)); } + + public void defineSumType(SumType sumType, ArrayList<Type> variantTypes) { + for (var variantType : variantTypes) { + this.variantOf.putIfAbsent(variantType, new ArrayList<>()); + this.variantOf.get(variantType).add(sumType); + } + } } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java new file mode 100644 index 0000000..1c15553 --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java @@ -0,0 +1,20 @@ +package org.zwobble.hobgoblin.compiler.typechecker; + +import org.zwobble.hobgoblin.compiler.types.StructType; +import org.zwobble.hobgoblin.compiler.types.SumType; +import org.zwobble.hobgoblin.compiler.types.Type; + +import java.util.List; +import java.util.Map; + +public class TypesInfo { + private final Map<Type, List<SumType>> variantOf; + + public TypesInfo(Map<Type, List<SumType>> variantOf) { + this.variantOf = variantOf; + } + + public List<SumType> variantOf(StructType variantType) { + return this.variantOf.getOrDefault(variantType, List.of()); + } +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java index 1d968d6..fdf88ee 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java @@ -49,13 +49,15 @@ public class TypeCheckerSumDefinitionTests { DocComment.EMPTY, NullSource.INSTANCE ); - var context = TypeCheckerContextArb.namespaceContext(NamespaceName.of("a", "b")); - context.declare(rectangleType.name()); - context.define(rectangleType.name(), new TypeLevelValueType(rectangleType)); - context.declare(triangleType.name()); - context.define(triangleType.name(), new TypeLevelValueType(triangleType)); + var globalContext = TypeCheckerGlobalContext.initial(); + var namespaceContext = globalContext + .enterNamespace(NamespaceName.of("a", "b")); + namespaceContext.declare(rectangleType.name()); + namespaceContext.define(rectangleType.name(), new TypeLevelValueType(rectangleType)); + namespaceContext.declare(triangleType.name()); + namespaceContext.define(triangleType.name(), new TypeLevelValueType(triangleType)); - var typed = typeCheckNamespaceStatement(untyped, context); + var typed = typeCheckNamespaceStatement(untyped, namespaceContext); assertThat(typed, instanceOf( TypedSumDefinitionNode.class, @@ -76,5 +78,9 @@ public class TypeCheckerSumDefinitionTests { ) ) )); + var sumType = new SumType(NamespaceName.of("a", "b"), "X"); + var typesInfo = globalContext.toTypesInfo(); + assertThat(typesInfo.variantOf(rectangleType), isSequence(equalTo(sumType))); + assertThat(typesInfo.variantOf(triangleType), isSequence(equalTo(sumType))); } } |
