From 38f3a0a74a6f6b8dd4a3341d76a4e3db7872e084 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 5 Nov 2023 12:45:05 +0000 Subject: Prevent capturing of var --- .../shedlang/compiler/ast/typed/FreeVariable.java | 3 +++ .../shedlang/compiler/typechecker/TypeChecker.java | 21 +++++++++++++++++++++ .../typechecker/errors/CannotCaptureVarError.java | 17 +++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 src/main/java/org/shedlang/compiler/typechecker/errors/CannotCaptureVarError.java (limited to 'src/main/java') 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 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; + } +} -- cgit v1.2.3