evaluator: introduce and expose scope tracking

This commit is contained in:
Alex Zenla 2023-09-08 00:04:36 -07:00
parent 38efbe1844
commit bf474f6b69
Signed by: alex
GPG Key ID: C0780728420EBFE5
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
}

View File

@ -1,13 +1,7 @@
import java java.lang.System
import java java.io.PrintStream
import java java.io.InputStreamReader
import java java.io.BufferedReader
export func main() {
let input = java_lang_System_in_get()
let reader = java_io_InputStreamReader_new_inputstream(input)
let bufferedReader = java_io_BufferedReader_new_reader(reader)
let line = java_io_BufferedReader_readLine(bufferedReader)
let stream = java_lang_System_err_get()
java_io_PrintStream_println_string(stream, line)
java_io_PrintStream_println_string(stream, "Hello World")
}

View File

@ -5,10 +5,7 @@ import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
import gay.pizza.dough.fs.PlatformFsProvider
import gay.pizza.pork.evaluator.Arguments
import gay.pizza.pork.evaluator.CallableFunction
import gay.pizza.pork.evaluator.None
import gay.pizza.pork.evaluator.Scope
import gay.pizza.pork.evaluator.*
import gay.pizza.pork.ffi.JavaNativeProvider
import gay.pizza.pork.ffi.JnaNativeProvider
@ -16,6 +13,7 @@ class RunCommand : CliktCommand(help = "Run Program", name = "run") {
val loop by option("--loop", help = "Loop Program").flag()
val measure by option("--measure", help = "Measure Time").flag()
val quiet by option("--quiet", help = "Silence Prints").flag()
val dumpScope by option("--dump-scope", help = "Dump Scope").flag()
val path by argument("file")
override fun run() {
@ -36,6 +34,14 @@ class RunCommand : CliktCommand(help = "Run Program", name = "run") {
addNativeFunctionProvider("java", JavaNativeProvider())
})
if (dumpScope) {
val functionContext = main as FunctionContext
val internalScope = functionContext.compilationUnitContext.internalScope
internalScope.crawlScopePath { key, path ->
println("[scope] $key [${path.joinToString(" -> ")}]")
}
}
maybeLoopAndMeasure(loop, measure) {
main.call(Arguments(emptyList()))
}