From c08dc7894a1b78a59fdd0372f3090c46b20b5b7d Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 3 Jul 2023 12:40:22 +0100 Subject: Extract EnvironmentBuilder --- .../compiler/ast/typed/TypedParamsNode.java | 6 +++-- .../compiler/typechecker/EnvironmentBuilder.java | 27 ++++++++++++++++++++++ .../shedlang/compiler/typechecker/TypeChecker.java | 26 ++++++++++----------- 3 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/ast/typed/TypedParamsNode.java b/src/main/java/org/shedlang/compiler/ast/typed/TypedParamsNode.java index f2601644..f7273497 100644 --- a/src/main/java/org/shedlang/compiler/ast/typed/TypedParamsNode.java +++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedParamsNode.java @@ -3,6 +3,7 @@ package org.shedlang.compiler.ast.typed; import org.shedlang.compiler.sources.Source; import java.util.List; +import java.util.stream.Collectors; import java.util.stream.Stream; public record TypedParamsNode( @@ -10,7 +11,8 @@ public record TypedParamsNode( List named, Source source ) implements TypedNode { - public Stream all() { - return Stream.concat(positional.stream(), named.stream()); + public Iterable all() { + return Stream.concat(positional.stream(), named.stream()) + .collect(Collectors.toList()); } } diff --git a/src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java b/src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java new file mode 100644 index 00000000..4ac46d2a --- /dev/null +++ b/src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java @@ -0,0 +1,27 @@ +package org.shedlang.compiler.typechecker; + +import org.pcollections.Empty; +import org.pcollections.PMap; +import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.typechecker.errors.DuplicateVariableName; + +public class EnvironmentBuilder { + public static final EnvironmentBuilder EMPTY = new EnvironmentBuilder(Empty.map()); + + private PMap environment; + + private EnvironmentBuilder(PMap environment) { + this.environment = environment; + } + + public EnvironmentBuilder add(String name, TypeCheckerContext.Variable variable, Source source) { + if (environment.containsKey(name)) { + throw new DuplicateVariableName(name, source); + } + return new EnvironmentBuilder(environment.plus(name, variable)); + } + + public PMap build() { + return environment; + } +} diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java index bf09b84b..e7688898 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java @@ -259,30 +259,28 @@ public class TypeChecker { var typedReturnType = typeCheckTypeLevelExpression(TypeSets.META_TYPE, untyped.returnType(), context); + var bodyEnvironment = EnvironmentBuilder.EMPTY; // TODO: check for duplicate param names - var bodyEnvironment = typedParams.all() - .map(param -> Map.entry( + + for (var param : typedParams.all()) { + bodyEnvironment = bodyEnvironment.add( param.name(), - TypeCheckerContext.defined(param.type().value()) - )) - .collect(PCollectors.toMap()); + TypeCheckerContext.defined(param.type().value()), + param.source() + ); + } for (var statement : untyped.body()) { for (var targetVariable : targetVariables(statement)) { - if (bodyEnvironment.containsKey(targetVariable.name())) { - throw new DuplicateVariableName( - targetVariable.name(), - targetVariable.source() - ); - } - bodyEnvironment = bodyEnvironment.plus( + bodyEnvironment = bodyEnvironment.add( targetVariable.name(), - TypeCheckerContext.undefined() + TypeCheckerContext.undefined(), + targetVariable.source() ); } } - var bodyContext = context.enterFunction(bodyEnvironment, typedEffect.map(e -> e.value()).orElse(Effects.NONE)); + var bodyContext = context.enterFunction(bodyEnvironment.build(), typedEffect.map(e -> e.value()).orElse(Effects.NONE)); var bodyResult = bodyContext.mapWithContext( untyped.body(), -- cgit v1.2.3