From 28b744b0039e381e197f46cea0e5e87ac4b8bab2 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 3 Jul 2023 12:35:23 +0100 Subject: Check for duplicate variable names --- .../shedlang/compiler/typechecker/TypeChecker.java | 22 ++++++++++++++++------ .../typechecker/errors/DuplicateVariableName.java | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/typechecker/errors/DuplicateVariableName.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index feafa5f4..bf09b84b 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -69,20 +69,20 @@ public class TypeChecker { }); } - private static List definedVariableNames(UntypedFunctionStatementNode statement) { + private static List targetVariables(UntypedFunctionStatementNode statement) { return switch (statement) { case UntypedExpressionStatementNode expressionStatement -> List.of(); case UntypedValNode val -> - definedVariableNames(val.target()); + targetVariables(val.target()); }; } - private static List definedVariableNames(UntypedTargetNode target) { + private static List targetVariables(UntypedTargetNode target) { return switch (target) { case UntypedTargetNode.Variable variable -> - List.of(variable.name()); + List.of(variable); }; } @@ -259,6 +259,7 @@ public class TypeChecker { var typedReturnType = typeCheckTypeLevelExpression(TypeSets.META_TYPE, untyped.returnType(), context); + // TODO: check for duplicate param names var bodyEnvironment = typedParams.all() .map(param -> Map.entry( param.name(), @@ -267,8 +268,17 @@ public class TypeChecker { .collect(PCollectors.toMap()); for (var statement : untyped.body()) { - for (var definedVariableName : definedVariableNames(statement)) { - bodyEnvironment = bodyEnvironment.plus(definedVariableName, TypeCheckerContext.undefined()); + for (var targetVariable : targetVariables(statement)) { + if (bodyEnvironment.containsKey(targetVariable.name())) { + throw new DuplicateVariableName( + targetVariable.name(), + targetVariable.source() + ); + } + bodyEnvironment = bodyEnvironment.plus( + targetVariable.name(), + TypeCheckerContext.undefined() + ); } } diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/DuplicateVariableName.java b/src/main/java/org/shedlang/compiler/typechecker/errors/DuplicateVariableName.java new file mode 100644 index 00000000..21771987 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/typechecker/errors/DuplicateVariableName.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 DuplicateVariableName extends SourceError { + private final String variableName; + + public DuplicateVariableName(String variableName, Source source) { + super("Duplicate variable name: " + variableName, source); + this.variableName = variableName; + } + + public String variableName() { + return variableName; + } +} -- cgit v1.2.3