aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-03 12:40:22 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-03 12:40:22 +0100
commitc08dc7894a1b78a59fdd0372f3090c46b20b5b7d (patch)
treeb2c6e1983c8c385398458ee6e65b6ac135ad8793 /src/main/java
parent28b744b0039e381e197f46cea0e5e87ac4b8bab2 (diff)
Extract EnvironmentBuilder
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedParamsNode.java6
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/EnvironmentBuilder.java27
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java26
3 files changed, 43 insertions, 16 deletions
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<TypedParamNode> named,
Source source
) implements TypedNode {
- public Stream<TypedParamNode> all() {
- return Stream.concat(positional.stream(), named.stream());
+ public Iterable<TypedParamNode> 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<String, TypeCheckerContext.Variable> environment;
+
+ private EnvironmentBuilder(PMap<String, TypeCheckerContext.Variable> 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<String, TypeCheckerContext.Variable> 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(),