diff --git a/projects/src/samples/vm/vm.ts b/projects/src/samples/vm/vm.ts index e556a15ed..32cf84a80 100644 --- a/projects/src/samples/vm/vm.ts +++ b/projects/src/samples/vm/vm.ts @@ -1,4 +1,4 @@ -export const SIMPLE_FUNCTION = ` +export const BRANCHING_FUNCTION = ` // __implicit push constant 3 push constant 4 diff --git a/simulator/src/vm/vm.test.ts b/simulator/src/vm/vm.test.ts index d67d0e3ff..c52b1a043 100644 --- a/simulator/src/vm/vm.test.ts +++ b/simulator/src/vm/vm.test.ts @@ -1,8 +1,9 @@ import { unwrap } from "@davidsouther/jiffies/lib/esm/result.js"; +import { vm as SIMPLE_FUNCTION } from "@nand2tetris/projects/project_08/20_simple_function.js"; import { FIBONACCI } from "@nand2tetris/projects/samples/vm/fibonnaci.js"; import { + BRANCHING_FUNCTION, NESTED_FUNCTION, - SIMPLE_FUNCTION, STATIC, } from "@nand2tetris/projects/samples/vm/vm.js"; import { VM } from "../languages/vm.js"; @@ -207,6 +208,20 @@ test("07 / Memory Access / Pointer Test", () => { expect(test).toEqual([6084, 3030, 3040, 32, 46]); }); +test("08 / Branching Function", () => { + const { instructions } = unwrap(VM.parse(BRANCHING_FUNCTION)); + const vm = unwrap(Vm.build(instructions)); + + vm.write([]); + + for (let i = 0; i < 100; i++) { + vm.step(); + } + + const test = vm.read([0, 256]); + expect(test).toEqual([257, 12]); +}); + const LOOP_TEST = ` push constant 0 pop local 0 // initializes sum = 0 @@ -309,18 +324,11 @@ test("08 / Program Flow / Fibonacci Series", () => { expect(test).toEqual([0, 1, 1, 2, 3, 5]); }); -test("08 / Simple Function / Simple Function", () => { +test("08 / Functions / SimpleFunction", () => { const { instructions } = unwrap(VM.parse(SIMPLE_FUNCTION)); const vm = unwrap(Vm.build(instructions)); - vm.write([]); - - for (let i = 0; i < 100; i++) { - vm.step(); - } - - const test = vm.read([0, 256]); - expect(test).toEqual([257, 12]); + expect(() => vm.vmStack()).not.toThrow("Assertion failed"); }); test("08 / Functions / NestedCall", () => { diff --git a/simulator/src/vm/vm.ts b/simulator/src/vm/vm.ts index 0273f6c9d..2d67f414c 100644 --- a/simulator/src/vm/vm.ts +++ b/simulator/src/vm/vm.ts @@ -847,6 +847,7 @@ export class Vm { const nArg = this.segmentInitializations["argument"].n; const nLocal = this.segmentInitializations["local"].n; const nThis = this.invocation.thisN ?? 0; + const stackCount = frameEnd - stackBase; return { fn, args: { @@ -861,8 +862,11 @@ export class Vm { }, stack: { base: 256, - count: frameEnd - stackBase, - values: [...this.memory.map((_, v) => v, stackBase, frameEnd)], + count: Math.max(0, stackCount), + values: + stackCount > 0 + ? [...this.memory.map((_, v) => v, stackBase, frameEnd)] + : [], }, this: { base: THIS,