Compare commits

...

2 Commits

2 changed files with 33 additions and 8 deletions

View File

@ -468,14 +468,6 @@ export class VM {
} }
} }
// Handle variadic parameter (TypeScript rest parameters)
// For TypeScript functions with ...rest, we spread the remaining args
// rather than wrapping them in an array
if (paramInfo.variadic) {
const remainingArgs = positionalArgs.slice(nativePositionalArgIndex)
nativeArgs.push(...remainingArgs)
}
// Handle named parameter (collect remaining unmatched named args) // Handle named parameter (collect remaining unmatched named args)
// Parameter names matching atXxx pattern (e.g., atOptions, atNamed) collect extra named args // Parameter names matching atXxx pattern (e.g., atOptions, atNamed) collect extra named args
if (paramInfo.named) { if (paramInfo.named) {
@ -488,6 +480,14 @@ export class VM {
nativeArgs.push(toValue(namedObj)) nativeArgs.push(toValue(namedObj))
} }
// Handle variadic parameter (TypeScript rest parameters)
// For TypeScript functions with ...rest, we spread the remaining args
// rather than wrapping them in an array
if (paramInfo.variadic) {
const remainingArgs = positionalArgs.slice(nativePositionalArgIndex)
nativeArgs.push(...remainingArgs)
}
// Call the native function with bound args // Call the native function with bound args
const result = await fn.fn(...nativeArgs) const result = await fn.fn(...nativeArgs)
this.stack.push(result) this.stack.push(result)

View File

@ -534,6 +534,31 @@ test("@named pattern - basic atNamed parameter", async () => {
expect(result).toEqual({ type: 'string', value: 'Hi, Alice! Extra: value' }) expect(result).toEqual({ type: 'string', value: 'Hi, Alice! Extra: value' })
}) })
test('@named pattern - atNamed parameters with varadic args', async () => {
const bytecode = toBytecode(`
TRY_LOAD cmd
TRY_LOAD rest1
TRY_LOAD rest2
PUSH 'named'
TRY_LOAD named-value
PUSH 2
PUSH 1
CALL
HALT
`)
const vm = new VM(bytecode)
vm.registerFunction('cmd', (atNamed: any = {}, ...rest: string[]) => {
return { rest, namedArg: atNamed['named'] }
})
const result = await vm.run()
expect(result.type).toBe('dict')
if (!(result.value instanceof Map)) throw new Error('Expected dict')
expect(result.value.get('rest')).toEqual(toValue(['rest1', 'rest2']))
expect(result.value.get('namedArg')).toEqual(toValue('named-value'))
})
test("@named pattern - mixed positional and atOptions", async () => { test("@named pattern - mixed positional and atOptions", async () => {
const bytecode = toBytecode(` const bytecode = toBytecode(`
LOAD configure LOAD configure