aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-11-05 12:45:05 +0000
committerMichael Williamson <mike@zwobble.org>2023-11-05 12:45:05 +0000
commit38f3a0a74a6f6b8dd4a3341d76a4e3db7872e084 (patch)
tree1e559a1f0b07f350ba344f2a0d16f4f998a06fb8 /src/main/java
parent1ed30cb57b8ae48ac60576aee807d5dfc86d8646 (diff)
Prevent capturing of var
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/ast/typed/FreeVariable.java3
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java21
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/errors/CannotCaptureVarError.java17
3 files changed, 41 insertions, 0 deletions
diff --git a/src/main/java/org/shedlang/compiler/ast/typed/FreeVariable.java b/src/main/java/org/shedlang/compiler/ast/typed/FreeVariable.java
index f1791a9a..dc755b63 100644
--- a/src/main/java/org/shedlang/compiler/ast/typed/FreeVariable.java
+++ b/src/main/java/org/shedlang/compiler/ast/typed/FreeVariable.java
@@ -5,4 +5,7 @@ import org.shedlang.compiler.sources.Source;
import java.util.Set;
public record FreeVariable(int index, String name, Set<Source> referenceSources) {
+ public Source firstReferenceSource() {
+ return referenceSources.stream().findFirst().orElseThrow();
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index 1a27345e..05e89031 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -622,6 +622,27 @@ public class TypeChecker {
context = context.exit();
+ for (var freeVariable : freeVariables) {
+ var variable = context.compileTimeLookup(freeVariable.name())
+ .orElseThrow(() -> new UnknownVariableError(
+ freeVariable.name(),
+ freeVariable.firstReferenceSource()
+ ));
+
+ switch (variable.variableType()) {
+ case CONSTANT -> {}
+ case IMPORT -> {}
+ case PARAM -> {}
+ case VAL -> {}
+
+ case VAR ->
+ throw new CannotCaptureVarError(
+ freeVariable.name(),
+ freeVariable.firstReferenceSource()
+ );
+ };
+ }
+
var typed = new TypedFunctionBodyNode(
freeVariables,
typedBody,
diff --git a/src/main/java/org/shedlang/compiler/typechecker/errors/CannotCaptureVarError.java b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotCaptureVarError.java
new file mode 100644
index 00000000..93d93fb3
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/typechecker/errors/CannotCaptureVarError.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 CannotCaptureVarError extends SourceError {
+ private final String name;
+
+ public CannotCaptureVarError(String name, Source source) {
+ super("var " + name + " cannot be captured", source);
+ this.name = name;
+ }
+
+ public String name() {
+ return name;
+ }
+}