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( class CompilationUnitContext(
val compilationUnit: CompilationUnit, val compilationUnit: CompilationUnit,
val evaluator: Evaluator, val evaluator: Evaluator,
rootScope: Scope rootScope: Scope,
name: String = "unknown"
) { ) {
val internalScope = rootScope.fork() val internalScope = rootScope.fork("internal $name")
val externalScope = rootScope.fork() val externalScope = rootScope.fork("external $name")
private var initialized = false private var initialized = false

View File

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

View File

@ -1,6 +1,10 @@
package gay.pizza.pork.evaluator 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 inherited = inherits.toMutableList()
private val variables = mutableMapOf<String, Any>() private val variables = mutableMapOf<String, Any>()
@ -41,8 +45,8 @@ class Scope(val parent: Scope? = null, inherits: List<Scope> = emptyList()) {
return value return value
} }
fun fork(): Scope = fun fork(name: String? = null): Scope =
Scope(this) Scope(this, name = name)
internal fun inherit(scope: Scope) { internal fun inherit(scope: Scope) {
inherited.add(scope) inherited.add(scope)
@ -55,5 +59,26 @@ class Scope(val parent: Scope? = null, inherits: List<Scope> = emptyList()) {
return parent 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 private object NotFound
} }

View File

@ -1,13 +1,7 @@
import java java.lang.System import java java.lang.System
import java java.io.PrintStream import java java.io.PrintStream
import java java.io.InputStreamReader
import java java.io.BufferedReader
export func main() { 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() 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.flag
import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.options.option
import gay.pizza.dough.fs.PlatformFsProvider import gay.pizza.dough.fs.PlatformFsProvider
import gay.pizza.pork.evaluator.Arguments import gay.pizza.pork.evaluator.*
import gay.pizza.pork.evaluator.CallableFunction
import gay.pizza.pork.evaluator.None
import gay.pizza.pork.evaluator.Scope
import gay.pizza.pork.ffi.JavaNativeProvider import gay.pizza.pork.ffi.JavaNativeProvider
import gay.pizza.pork.ffi.JnaNativeProvider 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 loop by option("--loop", help = "Loop Program").flag()
val measure by option("--measure", help = "Measure Time").flag() val measure by option("--measure", help = "Measure Time").flag()
val quiet by option("--quiet", help = "Silence Prints").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") val path by argument("file")
override fun run() { override fun run() {
@ -36,6 +34,14 @@ class RunCommand : CliktCommand(help = "Run Program", name = "run") {
addNativeFunctionProvider("java", JavaNativeProvider()) 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) { maybeLoopAndMeasure(loop, measure) {
main.call(Arguments(emptyList())) main.call(Arguments(emptyList()))
} }