From 0d3b69afbda09e5140b05b8bb57100338da6c6c0 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 18 May 2026 23:41:24 +0100 Subject: Track struct field types --- .../hobgoblin/compiler/typechecker/TypeChecker.java | 8 +++++++- .../compiler/typechecker/TypeCheckerGlobalContext.java | 10 ++++++++-- .../typechecker/TypeCheckerNamespaceContext.java | 16 +++++++++++----- .../hobgoblin/compiler/typechecker/TypesInfo.java | 11 ++++++++++- .../java/org/zwobble/hobgoblin/compiler/types/Field.java | 4 ++++ 5 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/types/Field.java (limited to 'src/main') 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(); + var fields = new ArrayList(); 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 nativeTypes = new HashMap<>(); + private final Map> fieldsOf = new HashMap<>(); private final Map> 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 nativeTypes, + Map> fieldsOf, Map> 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 variables; + private final Map> fieldsOf; private final Map> variantOf; private TypeCheckerNamespaceContext( NamespaceName namespaceName, Map variables, + Map> fieldsOf, Map> 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 variantTypes) { + public void defineStructType(StructType structType, List fields) { + this.fieldsOf.put(structType, fields); + } + + public void defineSumType(SumType sumType, List 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> fieldsOf; private final Map> variantOf; - public TypesInfo(Map> variantOf) { + public TypesInfo(Map> fieldsOf, Map> variantOf) { + this.fieldsOf = fieldsOf; this.variantOf = variantOf; } + public List fieldsOf(StructType structType) { + // TODO: handle error better + return Optional.ofNullable(this.fieldsOf.get(structType)).orElseThrow(); + } + public List 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) { +} -- cgit v1.2.3