From cc23789203e416cc7e32112efa8073a9f0a3b450 Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Tue, 5 Sep 2023 01:09:26 -0700 Subject: [PATCH] evaluator: prevent double lookup when looking up value in a scope --- .../kotlin/gay/pizza/pork/evaluator/Scope.kt | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) 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 d2a8fa7..b18e104 100644 --- a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Scope.kt +++ b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Scope.kt @@ -4,11 +4,6 @@ class Scope(val parent: Scope? = null, inherits: List = emptyList()) { private val inherited = inherits.toMutableList() private val variables = mutableMapOf() - fun has(name: String): Boolean = - variables.containsKey(name) || - (parent?.has(name) ?: false) || - inherited.any { inherit -> inherit.has(name) } - fun define(name: String, value: Any) { if (variables.containsKey(name)) { throw RuntimeException("Variable '${name}' is already defined") @@ -17,20 +12,30 @@ class Scope(val parent: Scope? = null, inherits: List = emptyList()) { } fun value(name: String): Any { + val value = valueOrNotFound(name) + if (value == NotFound) { + throw RuntimeException("Variable '${name}' not defined.") + } + return value + } + + private fun valueOrNotFound(name: String): Any { val value = variables[name] if (value == null) { if (parent != null) { - if (parent.has(name)) { - return parent.value(name) + val parentMaybeFound = parent.valueOrNotFound(name) + if (parentMaybeFound != NotFound) { + return parentMaybeFound } } for (inherit in inherited) { - if (inherit.has(name)) { - return inherit.value(name) + val inheritMaybeFound = inherit.valueOrNotFound(name) + if (inheritMaybeFound != NotFound) { + return inheritMaybeFound } } - throw RuntimeException("Variable '${name}' not defined.") + return NotFound } return value } @@ -57,4 +62,6 @@ class Scope(val parent: Scope? = null, inherits: List = emptyList()) { internal fun inherit(scope: Scope) { inherited.add(scope) } + + private object NotFound }