Skip to content

Commit

Permalink
evaluator: prevent double lookup when looking up value in a scope
Browse files Browse the repository at this point in the history
  • Loading branch information
azenla committed Sep 5, 2023
1 parent 7de8f8c commit cc23789
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions evaluator/src/main/kotlin/gay/pizza/pork/evaluator/Scope.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ class Scope(val parent: Scope? = null, inherits: List<Scope> = emptyList()) {
private val inherited = inherits.toMutableList()
private val variables = mutableMapOf<String, Any>()

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")
Expand All @@ -17,20 +12,30 @@ class Scope(val parent: Scope? = null, inherits: List<Scope> = 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
}
Expand All @@ -57,4 +62,6 @@ class Scope(val parent: Scope? = null, inherits: List<Scope> = emptyList()) {
internal fun inherit(scope: Scope) {
inherited.add(scope)
}

private object NotFound
}

0 comments on commit cc23789

Please sign in to comment.