From 9634a735ee39d58096f57501e71c9308d8ae5e24 Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Tue, 5 Sep 2023 02:20:46 -0700 Subject: [PATCH] evaluator: ensure function definitions use root scope --- .../pizza/pork/evaluator/EvaluationContext.kt | 10 +++++----- .../pizza/pork/evaluator/EvaluationVisitor.kt | 8 ++++---- .../gay/pizza/pork/evaluator/Evaluator.kt | 2 +- .../kotlin/gay/pizza/pork/evaluator/Scope.kt | 18 +++--------------- 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationContext.kt b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationContext.kt index d1d5fa2..2114d61 100644 --- a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationContext.kt +++ b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationContext.kt @@ -10,10 +10,10 @@ class EvaluationContext( ) { private var isAlreadySetup = false - val internalScope = rootScope.fork() - val externalScope = rootScope.fork() + val internalRootScope = rootScope.fork() + val externalRootScope = rootScope.fork() - private val evaluationVisitor = EvaluationVisitor(internalScope) + private val evaluationVisitor = EvaluationVisitor(internalRootScope) fun setup() { if (isAlreadySetup) { @@ -23,13 +23,13 @@ class EvaluationContext( val imports = compilationUnit.declarations.filterIsInstance() for (import in imports) { val evaluationContext = evaluationContextProvider.provideEvaluationContext(import.path.text) - internalScope.inherit(evaluationContext.externalScope) + internalRootScope.inherit(evaluationContext.externalRootScope) } for (definition in compilationUnit.definitions) { evaluationVisitor.visit(definition) if (definition.modifiers.export) { - externalScope.define(definition.symbol.id, internalScope.value(definition.symbol.id)) + externalRootScope.define(definition.symbol.id, internalRootScope.value(definition.symbol.id)) } } } diff --git a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationVisitor.kt b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationVisitor.kt index 699dfcc..ae47c62 100644 --- a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationVisitor.kt +++ b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationVisitor.kt @@ -2,7 +2,7 @@ package gay.pizza.pork.evaluator import gay.pizza.pork.ast.* -class EvaluationVisitor(root: Scope) : NodeVisitor { +class EvaluationVisitor(val root: Scope) : NodeVisitor { private var currentScope: Scope = root override fun visitIntLiteral(node: IntLiteral): Any = node.value @@ -104,15 +104,15 @@ class EvaluationVisitor(root: Scope) : NodeVisitor { override fun visitFunctionDefinition(node: FunctionDefinition): Any { val blockFunction = visitBlock(node.block) as BlockFunction val function = CallableFunction { arguments -> - currentScope = currentScope.fork(inheritFastCache = true) - currentScope.fastVariableCache.put(node.symbol.id, currentScope.value(node.symbol.id)) + val formerScope = currentScope + currentScope = root.fork() for ((index, argumentSymbol) in node.arguments.withIndex()) { currentScope.define(argumentSymbol.id, arguments.values[index]) } try { return@CallableFunction blockFunction.call() } finally { - currentScope = currentScope.leave() + currentScope = formerScope } } currentScope.define(node.symbol.id, function) diff --git a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Evaluator.kt b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Evaluator.kt index e5fe1a0..8b37212 100644 --- a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Evaluator.kt +++ b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Evaluator.kt @@ -7,7 +7,7 @@ class Evaluator(val world: World, val scope: Scope) : EvaluationContextProvider fun evaluate(path: String): Scope { val context = provideEvaluationContext(path) - return context.externalScope + return context.externalRootScope } override fun provideEvaluationContext(path: String): EvaluationContext { diff --git a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Scope.kt b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Scope.kt index e736522..296bfff 100644 --- a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Scope.kt +++ b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Scope.kt @@ -1,15 +1,10 @@ package gay.pizza.pork.evaluator -class Scope( - val parent: Scope? = null, - inherits: List = emptyList(), - val fastVariableCache: FastVariableCache = FastVariableCache() -) { +class Scope(val parent: Scope? = null, inherits: List = emptyList()) { private val inherited = inherits.toMutableList() private val variables = mutableMapOf() fun define(name: String, value: Any) { - fastVariableCache.invalidate(name) if (variables.containsKey(name)) { throw RuntimeException("Variable '${name}' is already defined") } @@ -17,11 +12,6 @@ class Scope( } fun value(name: String): Any { - val fastCached = fastVariableCache.lookup(name) - if (fastCached != FastVariableCache.NotFound) { - return fastCached - } - val value = valueOrNotFound(name) if (value == NotFound) { throw RuntimeException("Variable '${name}' not defined.") @@ -58,10 +48,8 @@ class Scope( return value.call(arguments) } - fun fork(inheritFastCache: Boolean = false): Scope { - val fastCache = if (inheritFastCache) fastVariableCache else FastVariableCache() - return Scope(this, fastVariableCache = fastCache) - } + fun fork(): Scope = + Scope(this) fun leave(): Scope { if (parent == null) {