aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-16 18:01:21 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-16 18:01:21 +0100
commitecbe7b4a85c23ba0520d5ff6e2682efd889848e9 (patch)
tree196c391a69c402e9632385f2057bb1efe1d2ec67 /src/main/java
parent1fe69b87b1c409c3a4b7a27a165a8e0b71c62fa7 (diff)
Check that the variable is not already defined
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java33
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/errors/VariableIsAlreadyDefinedError.java17
2 files changed, 38 insertions, 12 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
index 8e9aa206..6f626725 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
@@ -5,6 +5,7 @@ import org.pcollections.PMap;
import org.shedlang.compiler.ast.typed.FreeVariables;
import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.typechecker.errors.UnknownVariableError;
+import org.shedlang.compiler.typechecker.errors.VariableIsAlreadyDefinedError;
import org.shedlang.compiler.types.*;
import org.shedlang.compiler.util.PCollectors;
import org.shedlang.compiler.util.POrderedMap;
@@ -130,20 +131,28 @@ public class TypeCheckerContext {
Type type,
Source source
) {
- if (!this.environment.containsKey(name)) {
+ var variable = this.environment.get(name);
+
+ if (variable == null) {
throw new UnknownVariableError(name, source);
}
- // TODO: check if already defined
- // TODO: check is not defined
- // TODO: check is defined in this scope
- return new TypeCheckerContext(
- this.environment.plus(name, new Variable.Defined(type)),
- this.effect,
- this.returnType,
- this.boundVariables,
- this.freeVariables,
- this.namespaceTypeInfo
- );
+
+ switch (variable) {
+ case Variable.Defined defined -> {
+ throw new VariableIsAlreadyDefinedError(name, source);
+ }
+ case Variable.Undefined undefined -> {
+ // TODO: check is declared in this scope
+ return new TypeCheckerContext(
+ this.environment.plus(name, new Variable.Defined(type)),
+ this.effect,
+ this.returnType,
+ this.boundVariables,
+ this.freeVariables,
+ this.namespaceTypeInfo
+ );
+ }
+ }
}
public Effect effect() {
diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/VariableIsAlreadyDefinedError.java b/src/main/java/org/shedlang/compiler/typechecker/errors/VariableIsAlreadyDefinedError.java
new file mode 100644
index 00000000..e781d398
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/errors/VariableIsAlreadyDefinedError.java
@@ -0,0 +1,17 @@
+package org.shedlang.compiler.typechecker.errors;
+
+import org.shedlang.compiler.errors.SourceError;
+import org.shedlang.compiler.sources.Source;
+
+public class VariableIsAlreadyDefinedError extends SourceError {
+ private final String variableName;
+
+ public VariableIsAlreadyDefinedError(String variableName, Source source) {
+ super("Variable is already defined: " + variableName, source);
+ this.variableName = variableName;
+ }
+
+ public String variableName() {
+ return variableName;
+ }
+}