aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-10 19:41:09 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-10 19:41:09 +0100
commit4089116972049123f447d72d1bd5cb5d7389c25e (patch)
treeecfcc11caa0516a606ed2064982efcc6800b46be /src/main/java
parente6d39d97d6415ebdaf990d44198ce29472f9cd1e (diff)
Add params to environment in function
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/TypedParamsNode.java4
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java13
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java21
-rw-r--r--src/main/java/org/shedlang/compiler/util/PCollectors.java38
4 files changed, 69 insertions, 7 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 2c864f90..f2601644 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/TypedParamsNode.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/TypedParamsNode.java
@@ -3,10 +3,14 @@ package org.shedlang.compiler.ast.typed;
import org.shedlang.compiler.sources.Source;
import java.util.List;
+import java.util.stream.Stream;
public record TypedParamsNode(
List<TypedParamNode> positional,
List<TypedParamNode> named,
Source source
) implements TypedNode {
+ public Stream<TypedParamNode> all() {
+ return Stream.concat(positional.stream(), named.stream());
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index b6bfb399..aa7ad39b 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -7,8 +7,10 @@ import org.shedlang.compiler.typechecker.errors.*;
import org.shedlang.compiler.typechecker.typesets.TypeSetTypeLevelValue;
import org.shedlang.compiler.typechecker.typesets.TypeSets;
import org.shedlang.compiler.types.*;
+import org.shedlang.compiler.util.PCollectors;
import java.util.HashSet;
+import java.util.Map;
import java.util.Optional;
public class TypeChecker {
@@ -204,19 +206,24 @@ public class TypeChecker {
var typedReturnType = typeCheckTypeLevelExpression(TypeSets.META_TYPE, untyped.returnType(), context);
- var bodyResult = context.mapWithContext(
+ var bodyEnvironment = typedParams.all()
+ .map(param -> Map.entry(param.name(), param.type().value()))
+ .collect(PCollectors.toMap());
+ var bodyContext = context.enter(bodyEnvironment);
+
+ var bodyResult = bodyContext.mapWithContext(
untyped.body(),
TypeChecker::typeCheckFunctionStatement
);
var typedBody = bodyResult.value();
- context = bodyResult.context();
+ bodyContext = bodyResult.context();
return new TypedFunctionDefinitionNode(
untyped.name(),
typedParams,
typedEffect,
typedReturnType,
- context.freeVariables(),
+ bodyContext.freeVariables(),
typedBody,
untyped.source()
);
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
index 91d1daac..da51b959 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java
@@ -14,24 +14,37 @@ import java.util.function.BiFunction;
public class TypeCheckerContext {
public static final TypeCheckerContext EMPTY = new TypeCheckerContext(
Empty.map(),
+ Set.of(),
Empty.orderedSet()
);
private final PMap<String, Type> environment;
+ private final Set<String> boundVariables;
private final POrderedSet<String> freeVariables;
- public TypeCheckerContext(PMap<String, Type> environment, POrderedSet<String> freeVariables) {
+ public TypeCheckerContext(
+ PMap<String, Type> environment,
+ Set<String> boundVariables,
+ POrderedSet<String> freeVariables
+ ) {
this.environment = environment;
+ this.boundVariables = boundVariables;
this.freeVariables = freeVariables;
}
public TypeCheckerContext enter(PMap<String, Type> environment) {
- return new TypeCheckerContext(this.environment.plusAll(environment), Empty.orderedSet());
+ return new TypeCheckerContext(
+ this.environment.plusAll(environment),
+ environment.keySet(),
+ Empty.orderedSet()
+ );
}
public TypeCheckerResult<Optional<Type>> runtimeLookup(String name) {
var type = Optional.ofNullable(environment.get(name));
- return withFreeVariable(name).toResult(type);
+
+ var context = boundVariables.contains(name) ? this : withFreeVariable(name);
+ return context.toResult(type);
}
public Optional<Type> compileTimeLookup(String name) {
@@ -39,7 +52,7 @@ public class TypeCheckerContext {
}
private TypeCheckerContext withFreeVariable(String name) {
- return new TypeCheckerContext(environment, freeVariables.plus(name));
+ return new TypeCheckerContext(environment, boundVariables, freeVariables.plus(name));
}
public <T> TypeCheckerResult<T> toResult(T value) {
diff --git a/src/main/java/org/shedlang/compiler/util/PCollectors.java b/src/main/java/org/shedlang/compiler/util/PCollectors.java
new file mode 100644
index 00000000..6c2d8208
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/util/PCollectors.java
@@ -0,0 +1,38 @@
+package org.shedlang.compiler.util;
+
+import org.pcollections.Empty;
+import org.pcollections.PMap;
+
+import java.util.Map;
+import java.util.stream.Collector;
+
+public class PCollectors {
+ private PCollectors() {
+ }
+
+ public static <K, V> Collector<Map.Entry<K, V>, PMapCollector<K, V>, PMap<K, V>> toMap() {
+ return Collector.of(
+ PMapCollector::new,
+ PMapCollector::add,
+ PMapCollector::addAll,
+ PMapCollector::toMap
+ );
+ }
+
+ private static class PMapCollector<K, V> {
+ private PMap<K, V> map = Empty.map();
+
+ void add(Map.Entry<K, V> entry) {
+ map = map.plus(entry.getKey(), entry.getValue());
+ }
+
+ PMapCollector<K, V> addAll(PMapCollector<K, V> other) {
+ map = map.plusAll(other.map);
+ return this;
+ }
+
+ PMap<K, V> toMap() {
+ return map;
+ }
+ }
+}