From ecbe7b4a85c23ba0520d5ff6e2682efd889848e9 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 16 Jul 2023 18:01:21 +0100 Subject: Check that the variable is not already defined --- .../compiler/typechecker/TypeCheckerContext.java | 33 ++++++++++++++-------- .../errors/VariableIsAlreadyDefinedError.java | 17 +++++++++++ 2 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/typechecker/errors/VariableIsAlreadyDefinedError.java (limited to 'src/main/java') 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; + } +} -- cgit v1.2.3