add pushScope/popScope for Power Users

This commit is contained in:
Chris Wanstrath 2025-11-05 13:49:19 -08:00
parent 0f39e9401e
commit 54cd9ce8e8
2 changed files with 50 additions and 0 deletions

View File

@ -60,6 +60,14 @@ export class VM {
this.scope.set(name, { type: 'native', fn, value: '<function>' }) this.scope.set(name, { type: 'native', fn, value: '<function>' })
} }
pushScope() {
this.scope = new Scope(this.scope)
}
popScope() {
this.scope = this.scope.parent!
}
async run(): Promise<Value> { async run(): Promise<Value> {
this.pc = 0 this.pc = 0
this.stopped = false this.stopped = false

42
tests/vm.test.ts Normal file
View File

@ -0,0 +1,42 @@
import { test, expect, describe } from "bun:test"
import { VM } from "#vm"
import { toBytecode } from "#bytecode"
import { toValue } from "#value"
describe("VM scope methods", () => {
test("pushScope creates isolated child scope", async () => {
const bytecode = toBytecode([["HALT"]])
const vm = new VM(bytecode)
vm.set("x", 42)
vm.pushScope()
const xValue = vm.scope.get("x")
expect(xValue).toEqual({ type: "number", value: 42 })
vm.set("y", 100)
expect(vm.scope.get("x")).toEqual({ type: "number", value: 42 })
expect(vm.scope.get("y")).toEqual({ type: "number", value: 100 })
})
test("popScope returns to parent scope and child variables are not accessible", async () => {
const bytecode = toBytecode([["HALT"]])
const vm = new VM(bytecode)
vm.set("x", 42)
vm.pushScope()
vm.set("y", 100)
expect(vm.scope.get("x")).toEqual({ type: "number", value: 42 })
expect(vm.scope.get("y")).toEqual({ type: "number", value: 100 })
vm.popScope()
expect(vm.scope.get("x")).toEqual({ type: "number", value: 42 })
expect(vm.scope.get("y")).toBeUndefined()
})
})