summaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-07-24 20:14:19 +0100
committerMichael Williamson <mike@zwobble.org>2026-07-24 20:14:19 +0100
commitfeb676e39415b89578a7095775f8770f71972f59 (patch)
tree47b9130d2d55f1d27b1e21b5fe0ee6a3984f270e /src/main/java/org
parent2409a40985dad843fe25611c9cd14afdac6d67bf (diff)
Throw error on duplicate variable name
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/DuplicateVariableNameError.java17
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java8
3 files changed, 28 insertions, 7 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/DuplicateVariableNameError.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/DuplicateVariableNameError.java
new file mode 100644
index 0000000..1fc79bf
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/DuplicateVariableNameError.java
@@ -0,0 +1,17 @@
+package org.zwobble.hobgoblin.compiler.typechecker;
+
+import org.zwobble.hobgoblin.compiler.errors.SourceError;
+import org.zwobble.hobgoblin.compiler.sources.Source;
+
+public class DuplicateVariableNameError extends SourceError {
+ private final String name;
+
+ public DuplicateVariableNameError(String name, Source source) {
+ super("A variable with the name " + name + " has already been declared", source);
+ this.name = name;
+ }
+
+ public String name() {
+ return name;
+ }
+}
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 f313333..793e1f6 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
@@ -40,7 +40,7 @@ public class TypeChecker {
importedNamespace,
untypedImport.source()
));
- namespaceContext.declare(importedName, fieldType);
+ namespaceContext.declare(importedName, fieldType, untypedImport.source());
}
}
@@ -109,7 +109,7 @@ public class TypeChecker {
) {
var nativeType = new EnumType(context.namespaceName(), untyped.name());
var metaType = new TypeLevelValueType(nativeType);
- context.declare(untyped.name(), metaType);
+ context.declare(untyped.name(), metaType, untyped.source());
return metaType;
}
@@ -146,7 +146,7 @@ public class TypeChecker {
) {
var nativeType = new SimpleNativeType(context.namespaceName(), untyped.name());
var metaType = new TypeLevelValueType(nativeType);
- context.declare(untyped.name(), metaType);
+ context.declare(untyped.name(), metaType, untyped.source());
return metaType;
}
@@ -169,7 +169,7 @@ public class TypeChecker {
) {
var structType = new StructType(context.namespaceName(), untyped.name());
var metaType = new TypeLevelValueType(structType);
- context.declare(untyped.name(), metaType);
+ context.declare(untyped.name(), metaType, untyped.source());
return metaType;
}
@@ -233,7 +233,7 @@ public class TypeChecker {
) {
var sumType = new SumType(context.namespaceName(), untyped.name());
var metaType = new TypeLevelValueType(sumType);
- context.declare(untyped.name(), metaType);
+ context.declare(untyped.name(), metaType, untyped.source());
return metaType;
}
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 82c8273..51e11d6 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
@@ -1,5 +1,6 @@
package org.zwobble.hobgoblin.compiler.typechecker;
+import org.zwobble.hobgoblin.compiler.sources.Source;
import org.zwobble.hobgoblin.compiler.types.*;
import java.util.HashMap;
@@ -43,8 +44,11 @@ public class TypeCheckerNamespaceContext {
return this.namespaceName;
}
- public void declare(String name, Type type) {
- // TODO: Check variable is not already declared.
+ public void declare(String name, Type type, Source source) {
+ if (this.variables.containsKey(name)) {
+ throw new DuplicateVariableNameError(name, source);
+ }
+
this.variables.put(name, type);
}