put builtin global functions into a higher scope

This commit is contained in:
Chris Wanstrath 2025-10-26 08:53:51 -07:00
parent da61c1de50
commit bf6607d368
2 changed files with 26 additions and 7 deletions

View File

@ -19,19 +19,18 @@ export class VM {
labels: Map<number, string> = new Map()
nativeFunctions: Map<string, NativeFunction> = new Map()
constructor(bytecode: Bytecode, nativeFunctions?: Record<string, TypeScriptFunction>, valueFunctions?: Record<string, NativeFunction>) {
constructor(bytecode: Bytecode, globalFunctions?: Record<string, TypeScriptFunction>) {
this.instructions = bytecode.instructions
this.constants = bytecode.constants
this.labels = bytecode.labels || new Map()
this.scope = new Scope()
if (nativeFunctions)
for (const name of Object.keys(nativeFunctions))
this.registerFunction(name, nativeFunctions[name]!)
if (globalFunctions) {
for (const name of Object.keys(globalFunctions))
this.registerFunction(name, globalFunctions[name]!)
if (valueFunctions)
for (const name of Object.keys(valueFunctions))
this.registerValueFunction(name, valueFunctions[name]!)
this.scope = new Scope(this.scope)
}
}
async call(name: string, ...args: any) {

View File

@ -1741,3 +1741,23 @@ test("vm.call() with native function - variadic parameters", async () => {
const result = await vm.call('sum', 1, 2, 3, 4, 5)
expect(result).toEqual({ type: 'number', value: 15 })
})
test("builtin global functions are placed into a higher level scope", async () => {
const bytecode = toBytecode(`
PUSH 1
STORE x
HALT
`)
const vm = new VM(bytecode, {
sum: (...nums: number[]) => nums.reduce((acc, n) => acc + n, 0),
greet: (name: string, greeting = 'Hello') => `${greeting}, ${name}!`
})
await vm.run()
const locals = Array.from(vm.scope.locals.entries()).map(([name,]) => name)
const globals = Array.from(vm.scope.parent!.locals.entries()).map(([name,]) => name)
expect(globals).toEqual(['sum', 'greet'])
expect(locals).toEqual(['x'])
})