Add explicit script import prep APIs and VM regression tests
This commit is contained in:
1 parent
3d8bfe8863
commit
ecc4d8b9ed
8 files changed
+271
-1
No files matched your search
@@ -46,6 +46,28 @@ class Script(
|
||||
// private val catchReturn: Boolean = false,
|
||||
) : Statement() {
|
||||
fun statements(): List<Statement> = statements
|
||||
|
||||
/**
|
||||
* Explicitly apply this script's import/module bindings to [scope] without executing the script.
|
||||
* This is intended for embedding scenarios where the host owns scope lifecycle and wants
|
||||
* script-specific imports to be a separate, opt-in preparation step.
|
||||
*/
|
||||
suspend fun importInto(scope: Scope, seedScope: Scope = scope): Scope {
|
||||
prepareScriptScope(scope, seedScope)
|
||||
return scope
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fresh raw module scope and apply this script's import/module bindings to it.
|
||||
* If [seedScope] is provided, its import provider is reused and seed-bound imports resolve from it.
|
||||
*/
|
||||
suspend fun instantiateModule(seedScope: Scope? = null, pos: Pos = this.pos): ModuleScope {
|
||||
val provider = seedScope?.currentImportProvider ?: defaultImportManager
|
||||
val module = provider.newModuleAt(pos)
|
||||
prepareScriptScope(module, seedScope ?: module)
|
||||
return module
|
||||
}
|
||||
|
||||
override suspend fun execute(scope: Scope): Obj {
|
||||
scope.pos = pos
|
||||
val execScope = resolveModuleScope(scope) ?: scope
|
||||
@@ -75,6 +97,19 @@ class Script(
|
||||
return ObjVoid
|
||||
}
|
||||
|
||||
private suspend fun prepareScriptScope(scope: Scope, seedScope: Scope) {
|
||||
if (importBindings.isNotEmpty() || importedModules.isNotEmpty()) {
|
||||
seedImportBindings(scope, seedScope)
|
||||
}
|
||||
if (moduleSlotPlan.isNotEmpty()) {
|
||||
scope.applySlotPlan(moduleSlotPlan)
|
||||
for (name in moduleSlotPlan.keys) {
|
||||
val record = scope.objects[name] ?: scope.localBindings[name] ?: continue
|
||||
scope.updateSlotFor(name, record)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun seedModuleSlots(scope: Scope, seedScope: Scope) {
|
||||
if (importBindings.isEmpty() && importedModules.isEmpty()) return
|
||||
seedImportBindings(scope, seedScope)
|
||||
|
||||
@@ -36,7 +36,7 @@ internal suspend fun seedFrameLocalsFromScope(frame: CmdFrame, scope: Scope) {
|
||||
} else {
|
||||
record.value
|
||||
}
|
||||
if (value is net.sergeych.lyng.FrameSlotRef && value.refersTo(frame.frame, base + i)) {
|
||||
if (value is net.sergeych.lyng.FrameSlotRef && value.refersTo(frame.frame, i)) {
|
||||
continue
|
||||
}
|
||||
frame.setObjUnchecked(base + i, value)
|
||||
|
||||
Reference in new issue
Block a user