55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
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()
|
|
})
|
|
|
|
test("pushScope with locals initializes child scope with variables", async () => {
|
|
const bytecode = toBytecode([["HALT"]])
|
|
const vm = new VM(bytecode)
|
|
|
|
vm.set("x", 42)
|
|
vm.pushScope({ y: 100, z: "hello" })
|
|
|
|
expect(vm.scope.get("x")).toEqual({ type: "number", value: 42 })
|
|
expect(vm.scope.get("y")).toEqual({ type: "number", value: 100 })
|
|
expect(vm.scope.get("z")).toEqual({ type: "string", value: "hello" })
|
|
|
|
vm.popScope()
|
|
expect(vm.scope.get("x")).toEqual({ type: "number", value: 42 })
|
|
expect(vm.scope.get("y")).toBeUndefined()
|
|
expect(vm.scope.get("z")).toBeUndefined()
|
|
})
|
|
})
|