evaluator: introduce and expose scope tracking

This commit is contained in:
2023-09-08 00:04:36 -07:00
parent 38efbe1844
commit bf474f6b69
5 changed files with 44 additions and 18 deletions

View File

@ -9,10 +9,11 @@ import gay.pizza.pork.frontend.ImportLocator
class CompilationUnitContext(
val compilationUnit: CompilationUnit,
val evaluator: Evaluator,
rootScope: Scope
rootScope: Scope,
name: String = "unknown"
) {
val internalScope = rootScope.fork()
val externalScope = rootScope.fork()
val internalScope = rootScope.fork("internal $name")
val externalScope = rootScope.fork("external $name")
private var initialized = false

View File

@ -14,7 +14,7 @@ class Evaluator(val world: World, val scope: Scope) {
val unit = world.load(locator)
val identity = world.stableIdentity(locator)
val context = contexts.computeIfAbsent(identity) {
CompilationUnitContext(unit, this, scope)
CompilationUnitContext(unit, this, scope, name = "${locator.form} ${locator.path}")
}
context.initIfNeeded()
return context

View File

@ -1,6 +1,10 @@
package gay.pizza.pork.evaluator
class Scope(val parent: Scope? = null, inherits: List<Scope> = emptyList()) {
class Scope(
val parent: Scope? = null,
inherits: List<Scope> = emptyList(),
val name: String? = null
) {
private val inherited = inherits.toMutableList()
private val variables = mutableMapOf<String, Any>()
@ -41,8 +45,8 @@ class Scope(val parent: Scope? = null, inherits: List<Scope> = emptyList()) {
return value
}
fun fork(): Scope =
Scope(this)
fun fork(name: String? = null): Scope =
Scope(this, name = name)
internal fun inherit(scope: Scope) {
inherited.add(scope)
@ -55,5 +59,26 @@ class Scope(val parent: Scope? = null, inherits: List<Scope> = emptyList()) {
return parent
}
fun crawlScopePath(
path: List<String> = mutableListOf(name ?: "unknown"),
block: (String, List<String>) -> Unit
) {
for (key in variables.keys) {
block(key, path)
}
for (inherit in inherited) {
val mutablePath = path.toMutableList()
mutablePath.add("inherit ${inherit.name ?: "unknown"}")
inherit.crawlScopePath(mutablePath, block)
}
if (parent != null) {
val mutablePath = path.toMutableList()
mutablePath.add("parent ${parent.name ?: "unknown"}")
parent.crawlScopePath(mutablePath, block)
}
}
private object NotFound
}