From 4089116972049123f447d72d1bd5cb5d7389c25e Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 10 Jun 2023 19:41:09 +0100 Subject: Add params to environment in function --- .../compiler/ast/typed/TypedParamsNode.java | 4 +++ .../shedlang/compiler/typechecker/TypeChecker.java | 13 ++++++-- .../compiler/typechecker/TypeCheckerContext.java | 21 +++++++++--- .../org/shedlang/compiler/util/PCollectors.java | 38 ++++++++++++++++++++++ 4 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/util/PCollectors.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 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 positional, List named, Source source ) implements TypedNode { + public Stream 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 environment; + private final Set boundVariables; private final POrderedSet freeVariables; - public TypeCheckerContext(PMap environment, POrderedSet freeVariables) { + public TypeCheckerContext( + PMap environment, + Set boundVariables, + POrderedSet freeVariables + ) { this.environment = environment; + this.boundVariables = boundVariables; this.freeVariables = freeVariables; } public TypeCheckerContext enter(PMap environment) { - return new TypeCheckerContext(this.environment.plusAll(environment), Empty.orderedSet()); + return new TypeCheckerContext( + this.environment.plusAll(environment), + environment.keySet(), + Empty.orderedSet() + ); } public TypeCheckerResult> 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 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 TypeCheckerResult 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 Collector, PMapCollector, PMap> toMap() { + return Collector.of( + PMapCollector::new, + PMapCollector::add, + PMapCollector::addAll, + PMapCollector::toMap + ); + } + + private static class PMapCollector { + private PMap map = Empty.map(); + + void add(Map.Entry entry) { + map = map.plus(entry.getKey(), entry.getValue()); + } + + PMapCollector addAll(PMapCollector other) { + map = map.plusAll(other.map); + return this; + } + + PMap toMap() { + return map; + } + } +} -- cgit v1.2.3