diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-04-25 10:56:55 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-04-25 10:56:55 +0100 |
| commit | 72c84ea17a7e4b27cf9428ef23f713e32f5339d3 (patch) | |
| tree | 05f6d962ef88e92f292c834adb1225086824d749 /src/main/java/org | |
| parent | 39ef07c887e33aff56c087388980a92e750b547c (diff) | |
Type check struct fields
Diffstat (limited to 'src/main/java/org')
5 files changed, 57 insertions, 10 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java index 4f56fb1..d9f7d21 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java @@ -4,6 +4,7 @@ import org.zwobble.hobgoblin.compiler.parser.Parser; import org.zwobble.hobgoblin.compiler.typechecker.TypeChecker; import org.zwobble.hobgoblin.compiler.typechecker.TypeCheckerGlobalContext; import org.zwobble.hobgoblin.compiler.types.NamespaceName; +import org.zwobble.hobgoblin.compiler.types.ScalarType; import org.zwobble.sourcetext.SourceText; import java.io.IOException; @@ -29,6 +30,8 @@ public class HobgoblinCompiler { var untypedNamespaceNode = Parser.parseNamespace(sourceText, namespaceName); var typeCheckerContext = TypeCheckerGlobalContext.initial(); + typeCheckerContext.addBuiltinScalarType(new ScalarType("Int32")); + var typedNamespaceNode = TypeChecker.typeCheckNamespace(untypedNamespaceNode, typeCheckerContext); } } 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 b8bdd7f..d9a37e2 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -2,13 +2,9 @@ package org.zwobble.hobgoblin.compiler.typechecker; import org.zwobble.hobgoblin.compiler.ast.typed.*; import org.zwobble.hobgoblin.compiler.ast.untyped.*; -import org.zwobble.hobgoblin.compiler.types.StructType; -import org.zwobble.hobgoblin.compiler.types.TypeLevelValue; -import org.zwobble.hobgoblin.compiler.types.TypeLevelValueType; -import org.zwobble.hobgoblin.compiler.types.TypeSet; +import org.zwobble.hobgoblin.compiler.types.*; import java.util.ArrayList; -import java.util.List; public class TypeChecker { private TypeChecker() { @@ -49,13 +45,36 @@ public class TypeChecker { ) { var structType = new StructType(context.namespaceName(), untyped.name()); + var typedFields = new ArrayList<TypedStructFieldDefinitionNode>(); + for (var untypedField : untyped.fields()) { + var typedField = new TypedStructFieldDefinitionNode( + untypedField.name(), + typeCheckMetaType(untypedField.type(), context), + untyped.source() + ); + typedFields.add(typedField); + } + return new TypedStructDefinitionNode( structType, - List.of(), + typedFields, untyped.source() ); } + private static TypedTypeLevelExpressionNode<Type> typeCheckMetaType( + UntypedTypeLevelExpressionNode untyped, + TypeCheckerNamespaceContext context + ) { + var typed = typeCheckTypeLevelExpression(untyped, context); + if (typed.value() instanceof Type) { + return (TypedTypeLevelExpressionNode<Type>) typed; + } else { + // TODO: better error + throw new RuntimeException("not a metatype"); + } + } + static TypedTypeLevelExpressionNode<? extends TypeLevelValue> typeCheckTypeLevelExpression( UntypedTypeLevelExpressionNode untyped, TypeCheckerNamespaceContext context 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 3915767..849da2f 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java @@ -1,8 +1,16 @@ package org.zwobble.hobgoblin.compiler.typechecker; import org.zwobble.hobgoblin.compiler.types.NamespaceName; +import org.zwobble.hobgoblin.compiler.types.ScalarType; +import org.zwobble.hobgoblin.compiler.types.Type; +import org.zwobble.hobgoblin.compiler.types.TypeLevelValueType; + +import java.util.HashMap; +import java.util.Map; public class TypeCheckerGlobalContext { + private final Map<String, Type> builtins = new HashMap<>(); + public static TypeCheckerGlobalContext initial() { return new TypeCheckerGlobalContext(); } @@ -10,7 +18,11 @@ public class TypeCheckerGlobalContext { private TypeCheckerGlobalContext() { } + public void addBuiltinScalarType(ScalarType type) { + this.builtins.put(type.name(), new TypeLevelValueType(type)); + } + public TypeCheckerNamespaceContext enterNamespace(NamespaceName namespaceName) { - return TypeCheckerNamespaceContext.initial(namespaceName); + return TypeCheckerNamespaceContext.initial(namespaceName, this.builtins); } } 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 c1a23fd..353209b 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java @@ -3,13 +3,22 @@ package org.zwobble.hobgoblin.compiler.typechecker; import org.zwobble.hobgoblin.compiler.types.NamespaceName; import org.zwobble.hobgoblin.compiler.types.Type; -import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; public class TypeCheckerNamespaceContext { - public static TypeCheckerNamespaceContext initial(NamespaceName namespaceName) { - return new TypeCheckerNamespaceContext(namespaceName, new HashMap<>()); + public static TypeCheckerNamespaceContext initial( + NamespaceName namespaceName, + Map<String, Type> builtins + ) { + var variables = builtins.entrySet().stream() + .collect(Collectors.toMap( + entry -> entry.getKey(), + entry -> Variable.defined(entry.getValue()) + )); + + return new TypeCheckerNamespaceContext(namespaceName, variables); } private final NamespaceName namespaceName; diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/Variable.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/Variable.java index 1d3a4b6..e80283f 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/Variable.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/Variable.java @@ -3,6 +3,10 @@ package org.zwobble.hobgoblin.compiler.typechecker; import org.zwobble.hobgoblin.compiler.types.Type; public sealed interface Variable { + public static Variable defined(Type type) { + return new Defined(type); + } + record Declared() implements Variable { } |
