From f1cc717711edb776e0c3db957fb96fc6021d5e1f Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Wed, 5 Nov 2025 13:55:59 -0800 Subject: [PATCH] pushScope accepts locals --- src/vm.ts | 6 +++++- tests/vm.test.ts | 22 +++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/vm.ts b/src/vm.ts index ab06280..4afe9b3 100644 --- a/src/vm.ts +++ b/src/vm.ts @@ -60,8 +60,12 @@ export class VM { this.scope.set(name, { type: 'native', fn, value: '' }) } - pushScope() { + pushScope(locals?: Record) { this.scope = new Scope(this.scope) + + if (locals) + for (const [name, value] of Object.entries(locals)) + this.set(name, value) } popScope() { diff --git a/tests/vm.test.ts b/tests/vm.test.ts index f7b8817..2a965b2 100644 --- a/tests/vm.test.ts +++ b/tests/vm.test.ts @@ -9,14 +9,12 @@ describe("VM scope methods", () => { 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 }) }) @@ -26,7 +24,6 @@ describe("VM scope methods", () => { const vm = new VM(bytecode) vm.set("x", 42) - vm.pushScope() vm.set("y", 100) @@ -34,9 +31,24 @@ describe("VM scope methods", () => { 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() + }) })