diff options
Diffstat (limited to 'src')
6 files changed, 55 insertions, 16 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 6fd902b..da09714 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -8,6 +8,7 @@ import org.zwobble.hobgoblin.compiler.types.*; import java.util.ArrayList; public class TypeChecker { + private TypeChecker() { } @@ -77,15 +78,20 @@ public class TypeChecker { var structType = (StructType) lookupMetaType(untyped.name(), untyped.source(), context); var typedFields = new ArrayList<TypedStructFieldDefinitionNode>(); + var fields = new ArrayList<Field>(); for (var untypedField : untyped.fields()) { + var fieldType = typeCheckMetaType(untypedField.type(), context); var typedField = new TypedStructFieldDefinitionNode( untypedField.name(), - typeCheckMetaType(untypedField.type(), context), + fieldType, untyped.source() ); typedFields.add(typedField); + fields.add(new Field(untypedField.name(), fieldType.value())); } + context.defineStructType(structType, fields); + return new TypedStructDefinitionNode( structType, typedFields, 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 d3d4c43..e653321 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java @@ -8,6 +8,7 @@ import java.util.Map; public class TypeCheckerGlobalContext { private final Map<String, Type> nativeTypes = new HashMap<>(); + private final Map<StructType, List<Field>> fieldsOf = new HashMap<>(); private final Map<Type, List<SumType>> variantOf = new HashMap<>(); public static TypeCheckerGlobalContext initial() { @@ -18,7 +19,7 @@ public class TypeCheckerGlobalContext { } public TypesInfo toTypesInfo() { - return new TypesInfo(this.variantOf); + return new TypesInfo(this.fieldsOf, this.variantOf); } public void addNativeType(SimpleNativeType type) { @@ -30,6 +31,11 @@ public class TypeCheckerGlobalContext { } public TypeCheckerNamespaceContext enterNamespace(NamespaceName namespaceName) { - return TypeCheckerNamespaceContext.initial(namespaceName, this.nativeTypes, this.variantOf); + return TypeCheckerNamespaceContext.initial( + namespaceName, + this.nativeTypes, + this.fieldsOf, + 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 795bd6a..5685a6e 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,6 @@ 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 org.zwobble.hobgoblin.compiler.types.*; import java.util.ArrayList; import java.util.List; @@ -14,6 +12,7 @@ public class TypeCheckerNamespaceContext { public static TypeCheckerNamespaceContext initial( NamespaceName namespaceName, Map<String, Type> nativeTypes, + Map<StructType, List<Field>> fieldsOf, Map<Type, List<SumType>> variantOf ) { var variables = nativeTypes.entrySet().stream() @@ -22,20 +21,23 @@ public class TypeCheckerNamespaceContext { entry -> Variable.defined(entry.getValue()) )); - return new TypeCheckerNamespaceContext(namespaceName, variables, variantOf); + return new TypeCheckerNamespaceContext(namespaceName, variables, fieldsOf, variantOf); } private final NamespaceName namespaceName; private final Map<String, Variable> variables; + private final Map<StructType, List<Field>> fieldsOf; private final Map<Type, List<SumType>> variantOf; private TypeCheckerNamespaceContext( NamespaceName namespaceName, Map<String, Variable> variables, + Map<StructType, List<Field>> fieldsOf, Map<Type, List<SumType>> variantOf ) { this.namespaceName = namespaceName; this.variables = variables; + this.fieldsOf = fieldsOf; this.variantOf = variantOf; } @@ -57,7 +59,11 @@ public class TypeCheckerNamespaceContext { return Optional.ofNullable(this.variables.get(name)); } - public void defineSumType(SumType sumType, ArrayList<Type> variantTypes) { + public void defineStructType(StructType structType, List<Field> fields) { + this.fieldsOf.put(structType, fields); + } + + public void defineSumType(SumType sumType, List<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 index 1c15553..b174be8 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypesInfo.java @@ -1,19 +1,28 @@ package org.zwobble.hobgoblin.compiler.typechecker; +import org.zwobble.hobgoblin.compiler.types.Field; 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; +import java.util.Optional; public class TypesInfo { + private final Map<StructType, List<Field>> fieldsOf; private final Map<Type, List<SumType>> variantOf; - public TypesInfo(Map<Type, List<SumType>> variantOf) { + public TypesInfo(Map<StructType, List<Field>> fieldsOf, Map<Type, List<SumType>> variantOf) { + this.fieldsOf = fieldsOf; this.variantOf = variantOf; } + public List<Field> fieldsOf(StructType structType) { + // TODO: handle error better + return Optional.ofNullable(this.fieldsOf.get(structType)).orElseThrow(); + } + public List<SumType> variantOf(StructType variantType) { return this.variantOf.getOrDefault(variantType, List.of()); } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/Field.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/Field.java new file mode 100644 index 0000000..e806c11 --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/Field.java @@ -0,0 +1,4 @@ +package org.zwobble.hobgoblin.compiler.types; + +public record Field(String name, Type type) { +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java index 336c496..8967601 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerStructDefinitionTests.java @@ -11,10 +11,10 @@ import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceNode; import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStructDefinitionNode; import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStructFieldDefinitionNode; import org.zwobble.hobgoblin.compiler.sources.NullSource; +import org.zwobble.hobgoblin.compiler.types.Field; import org.zwobble.hobgoblin.compiler.types.NamespaceName; import org.zwobble.hobgoblin.compiler.types.SimpleNativeType; import org.zwobble.hobgoblin.compiler.types.StructType; -import org.zwobble.hobgoblin.compiler.types.TypeLevelValueType; import java.util.List; @@ -58,13 +58,13 @@ public class TypeCheckerStructDefinitionTests { DocComment.EMPTY, NullSource.INSTANCE ); - var context = TypeCheckerContextArb.namespaceContext(NamespaceName.of("a", "b")); - context.declare(int32Type.name()); - context.define(int32Type.name(), new TypeLevelValueType(int32Type)); - context.declare(int64Type.name()); - context.define(int64Type.name(), new TypeLevelValueType(int64Type)); + var globalContext = TypeCheckerGlobalContext.initial(); + globalContext.addNativeType(int32Type); + globalContext.addNativeType(int64Type); + var namespaceName = NamespaceName.of("a", "b"); + var namespaceContext = globalContext.enterNamespace(namespaceName); - var typed = typeCheckNamespaceStatement(untyped, context); + var typed = typeCheckNamespaceStatement(untyped, namespaceContext); assertThat(typed, instanceOf( TypedStructDefinitionNode.class, @@ -91,6 +91,14 @@ public class TypeCheckerStructDefinitionTests { ) ) )); + var typesInfo = globalContext.toTypesInfo(); + assertThat( + typesInfo.fieldsOf(new StructType(namespaceName, "X")), + isSequence( + equalTo(new Field("a", int32Type)), + equalTo(new Field("b", int64Type)) + ) + ); } @Test |
