summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-06-19 17:30:18 +0100
committerMichael Williamson <mike@zwobble.org>2026-06-19 17:30:18 +0100
commita31c0145beb998c9f83d61770ba03f9230610c87 (patch)
tree657e7445437098ad5d6b68999690227c8da14ced /src
parentb281c5757b38cd0ce6144b3d42feba49b94d1ee7 (diff)
Merge variable declaration and definition
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java24
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java30
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/Variable.java15
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java6
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java6
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java20
6 files changed, 23 insertions, 78 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 98b29a9..abc4bec 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
@@ -30,7 +30,7 @@ public class TypeChecker {
var importedNamespaceFields = context.namespaceFields(importedNamespace);
for (var importedName : untypedImport.importedNames()) {
- namespaceContext.define(importedName, importedNamespaceFields.get(importedName));
+ namespaceContext.declare(importedName, importedNamespaceFields.get(importedName));
}
}
@@ -92,10 +92,8 @@ public class TypeChecker {
TypeCheckerNamespaceContext context
) {
var nativeType = new SimpleNativeType(context.namespaceName(), untyped.name());
- // TODO: tidy up declare vs define
- context.declare(untyped.name());
var metaType = new TypeLevelValueType(nativeType);
- context.define(untyped.name(), metaType);
+ context.declare(untyped.name(), metaType);
return metaType;
}
@@ -117,10 +115,8 @@ public class TypeChecker {
TypeCheckerNamespaceContext context
) {
var structType = new StructType(context.namespaceName(), untyped.name());
- // TODO: tidy up declare vs define
- context.declare(untyped.name());
var metaType = new TypeLevelValueType(structType);
- context.define(untyped.name(), metaType);
+ context.declare(untyped.name(), metaType);
return metaType;
}
@@ -173,10 +169,8 @@ public class TypeChecker {
TypeCheckerNamespaceContext context
) {
var sumType = new SumType(context.namespaceName(), untyped.name());
- // TODO: tidy up declare vs define
- context.declare(untyped.name());
var metaType = new TypeLevelValueType(sumType);
- context.define(untyped.name(), metaType);
+ context.declare(untyped.name(), metaType);
return metaType;
}
@@ -284,17 +278,9 @@ public class TypeChecker {
Source source,
TypeCheckerNamespaceContext context
) {
- var variable = context.lookup(name)
+ var type = context.lookupType(name)
.orElseThrow(() -> new UndeclaredVariableError(name, source));
- var type = switch (variable) {
- case Variable.Declared declared ->
- throw new UndefinedVariableError(name, source);
-
- case Variable.Defined defined ->
- defined.type();
- };
-
// TODO: handle not a type-level value
if (!(type instanceof TypeLevelValueType(TypeLevelValue value))) {
throw new UnexpectedTypeError(new TypeSet.MetaType(), type, source);
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 6366a12..69827a8 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
@@ -3,10 +3,10 @@ package org.zwobble.hobgoblin.compiler.typechecker;
import org.zwobble.hobgoblin.compiler.types.*;
import org.zwobble.hobgoblin.compiler.util.ManyToMany;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.stream.Collectors;
public class TypeCheckerNamespaceContext {
public static TypeCheckerNamespaceContext initial(
@@ -15,23 +15,22 @@ public class TypeCheckerNamespaceContext {
Map<StructType, List<Field>> fieldsOf,
ManyToMany<SumType, Type> variants
) {
- var variables = nativeTypes.entrySet().stream()
- .collect(Collectors.toMap(
- entry -> entry.getKey(),
- entry -> Variable.defined(entry.getValue())
- ));
-
- return new TypeCheckerNamespaceContext(namespaceName, variables, fieldsOf, variants);
+ return new TypeCheckerNamespaceContext(
+ namespaceName,
+ new HashMap<>(nativeTypes),
+ fieldsOf,
+ variants
+ );
}
private final NamespaceName namespaceName;
- private final Map<String, Variable> variables;
+ private final Map<String, Type> variables;
private final Map<StructType, List<Field>> fieldsOf;
private final ManyToMany<SumType, Type> variants;
private TypeCheckerNamespaceContext(
NamespaceName namespaceName,
- Map<String, Variable> variables,
+ Map<String, Type> variables,
Map<StructType, List<Field>> fieldsOf,
ManyToMany<SumType, Type> variants
) {
@@ -45,17 +44,12 @@ public class TypeCheckerNamespaceContext {
return this.namespaceName;
}
- public void declare(String name) {
+ public void declare(String name, Type type) {
// TODO: Check variable is not already declared.
- this.variables.put(name, new Variable.Declared());
- }
-
- public void define(String name, Type type) {
- // TODO: Check variable is not already defined.
- this.variables.put(name, new Variable.Defined(type));
+ this.variables.put(name, type);
}
- public Optional<Variable> lookup(String name) {
+ public Optional<Type> lookupType(String name) {
return Optional.ofNullable(this.variables.get(name));
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/Variable.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/Variable.java
deleted file mode 100644
index e80283f..0000000
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/Variable.java
+++ /dev/null
@@ -1,15 +0,0 @@
-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 {
- }
-
- record Defined(Type type) implements Variable {
- }
-}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java
index 1f3e5ff..ef55465 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java
@@ -18,13 +18,11 @@ public class TypeCheckerConstructedTypeTests {
List.of(UntypedArb.typeLevelReference("Int32"))
);
var context = TypeCheckerContextArb.namespaceContext();
- context.declare("List");
var listType = SimpleNativeType.builtin("List");
var listTypeConstructor = new TypeConstructor<>(List.of(new TypeParam("T")), listType);
- context.define("List", new TypeLevelValueType(listTypeConstructor));
- context.declare("Int32");
+ context.declare("List", new TypeLevelValueType(listTypeConstructor));
var int32Type = SimpleNativeType.builtin("Int32");
- context.define("Int32", new TypeLevelValueType(int32Type));
+ context.declare("Int32", new TypeLevelValueType(int32Type));
var typed = TypeChecker.typeCheckTypeLevelExpression(untyped, context);
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 c93868b..60c2b9a 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerSumDefinitionTests.java
@@ -48,10 +48,8 @@ public class TypeCheckerSumDefinitionTests {
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));
+ namespaceContext.declare(rectangleType.name(), new TypeLevelValueType(rectangleType));
+ namespaceContext.declare(triangleType.name(), new TypeLevelValueType(triangleType));
var typed = typeCheckNamespaceStatement(untyped, namespaceContext);
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java
index ef90d3e..e633c94 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java
@@ -26,26 +26,11 @@ public class TypeCheckerTypeLevelReferenceTests {
}
@Test
- public void whenNameIsUndefinedThenErrorIsThrown() {
- var untyped = UntypedArb.typeLevelReference("X");
- var context = TypeCheckerContextArb.namespaceContext();
- context.declare("X");
-
- var error = assertThrows(
- UndefinedVariableError.class,
- () -> TypeChecker.typeCheckTypeLevelExpression(untyped, context)
- );
-
- assertThat(error.variableName(), equalTo("X"));
- }
-
- @Test
public void whenVariableIsNotTypeLevelValueThenErrorIsThrown() {
var untyped = UntypedArb.typeLevelReference("X");
var context = TypeCheckerContextArb.namespaceContext();
- context.declare("X");
var nativeType = SimpleNativeType.builtin("Int");
- context.define("X", nativeType);
+ context.declare("X", nativeType);
var error = assertThrows(
UnexpectedTypeError.class,
@@ -60,9 +45,8 @@ public class TypeCheckerTypeLevelReferenceTests {
public void whenNameIsMetaTypeThenValueIsType() {
var untyped = UntypedArb.typeLevelReference("X");
var context = TypeCheckerContextArb.namespaceContext();
- context.declare("X");
var nativeType = SimpleNativeType.builtin("Int");
- context.define("X", new TypeLevelValueType(nativeType));
+ context.declare("X", new TypeLevelValueType(nativeType));
var typed = TypeChecker.typeCheckTypeLevelExpression(untyped, context);