fix for using named positional args

This commit is contained in:
Chris Wanstrath 2025-10-14 12:32:19 -07:00
parent 4898a6bb5a
commit 0844e99d2d

View File

@ -430,6 +430,9 @@ export class VM {
if (fn.variadic) fixedParamCount-- if (fn.variadic) fixedParamCount--
if (fn.named) fixedParamCount-- if (fn.named) fixedParamCount--
// Track which positional args have been consumed
let positionalArgIndex = 0
// Bind fixed parameters using priority: named arg > positional arg > default > null // Bind fixed parameters using priority: named arg > positional arg > default > null
for (let i = 0; i < fixedParamCount; i++) { for (let i = 0; i < fixedParamCount; i++) {
const paramName = fn.params[i]! const paramName = fn.params[i]!
@ -438,8 +441,9 @@ export class VM {
if (namedArgs.has(paramName)) { if (namedArgs.has(paramName)) {
this.scope.set(paramName, namedArgs.get(paramName)!) this.scope.set(paramName, namedArgs.get(paramName)!)
namedArgs.delete(paramName) // Remove from named args so it won't go to named namedArgs.delete(paramName) // Remove from named args so it won't go to named
} else if (positionalArgs[i] !== undefined) { } else if (positionalArgIndex < positionalArgs.length) {
this.scope.set(paramName, positionalArgs[i]!) this.scope.set(paramName, positionalArgs[positionalArgIndex]!)
positionalArgIndex++
} else if (fn.defaults[paramName] !== undefined) { } else if (fn.defaults[paramName] !== undefined) {
const defaultIdx = fn.defaults[paramName]! const defaultIdx = fn.defaults[paramName]!
const defaultValue = this.constants[defaultIdx]! const defaultValue = this.constants[defaultIdx]!
@ -454,7 +458,7 @@ export class VM {
// Handle variadic parameter (collect remaining positional args) // Handle variadic parameter (collect remaining positional args)
if (fn.variadic) { if (fn.variadic) {
const variadicParamName = fn.params[fn.params.length - (fn.named ? 2 : 1)]! const variadicParamName = fn.params[fn.params.length - (fn.named ? 2 : 1)]!
const remainingArgs = positionalArgs.slice(fixedParamCount) const remainingArgs = positionalArgs.slice(positionalArgIndex)
this.scope.set(variadicParamName, { type: 'array', value: remainingArgs }) this.scope.set(variadicParamName, { type: 'array', value: remainingArgs })
} }
@ -509,6 +513,9 @@ export class VM {
if (tailFn.variadic) tailFixedParamCount-- if (tailFn.variadic) tailFixedParamCount--
if (tailFn.named) tailFixedParamCount-- if (tailFn.named) tailFixedParamCount--
// Track which positional args have been consumed
let tailPositionalArgIndex = 0
// Bind fixed parameters // Bind fixed parameters
for (let i = 0; i < tailFixedParamCount; i++) { for (let i = 0; i < tailFixedParamCount; i++) {
const paramName = tailFn.params[i]! const paramName = tailFn.params[i]!
@ -516,8 +523,9 @@ export class VM {
if (tailNamedArgs.has(paramName)) { if (tailNamedArgs.has(paramName)) {
this.scope.set(paramName, tailNamedArgs.get(paramName)!) this.scope.set(paramName, tailNamedArgs.get(paramName)!)
tailNamedArgs.delete(paramName) tailNamedArgs.delete(paramName)
} else if (tailPositionalArgs[i] !== undefined) { } else if (tailPositionalArgIndex < tailPositionalArgs.length) {
this.scope.set(paramName, tailPositionalArgs[i]!) this.scope.set(paramName, tailPositionalArgs[tailPositionalArgIndex]!)
tailPositionalArgIndex++
} else if (tailFn.defaults[paramName] !== undefined) { } else if (tailFn.defaults[paramName] !== undefined) {
const defaultIdx = tailFn.defaults[paramName]! const defaultIdx = tailFn.defaults[paramName]!
const defaultValue = this.constants[defaultIdx]! const defaultValue = this.constants[defaultIdx]!
@ -532,7 +540,7 @@ export class VM {
// Handle variadic parameter // Handle variadic parameter
if (tailFn.variadic) { if (tailFn.variadic) {
const variadicParamName = tailFn.params[tailFn.params.length - (tailFn.named ? 2 : 1)]! const variadicParamName = tailFn.params[tailFn.params.length - (tailFn.named ? 2 : 1)]!
const remainingArgs = tailPositionalArgs.slice(tailFixedParamCount) const remainingArgs = tailPositionalArgs.slice(tailPositionalArgIndex)
this.scope.set(variadicParamName, { type: 'array', value: remainingArgs }) this.scope.set(variadicParamName, { type: 'array', value: remainingArgs })
} }