// dvec.c


// outgoing externals

external
[
//
Dvec
DefaultArgs1
]


// incoming externals

external
[
FrameSize; CallersFrame; Usc; errhlt
]

manifest endCode=#335


// let Dvec(caller, newVecs, nil, nil, nil, nil, nil, nil,
// nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
// nil; numargs na)=valof [
//
//
let myArgs=lv caller
//
let cf=CallersFrame()
//
let cfs=FrameSize(caller)
//
let top=cf+cfs
//
//
let length=0
//
let i=0
//
while i ls na-1 do [
//
i=i+1
//
if myArgs!i eq 0 then break
//
length=length+rv myArgs!i+1
//
rv myArgs!i=top-length
//
]
//
//
while i ls na-1 do [
//
i=i+1
//
let t=rv myArgs!i
//
if t ge cf & t ls top then rv myArgs!i=t-length
//
]
//
//
let newCf=cf-length
//
if Usc(newCf, rv endCode) le 0 then errhlt("Stack overflow")
//
// BMOVE(cf, newCf, cfs-1)
// resultis newCf+cfs
//
let DoMove=table [
//
#35003// lda 3 extraArgs,2
//
#131400// inc 1 2
//
#173000// add 3 2
//
#61005// blt
//
#121400// inc 1 0return address of first new word
//
#35001// lda 3 savedPC,2
//
#1401// jmp 1,3
//
]
//
//
DoMove(cf-1, newCf+cfs-1, -cfs)
//
]

let DefaultArgs1(lvNa, base, defaultValue, nil, nil, nil, nil,
nil, nil, nil, nil, nil; numargs na) be [

if na ls 2 then base=0
let defaultOnZero=false
if base ls 0 then [ defaultOnZero=true; base=-base ]

let dvVec=lv defaultValue-base
let actualNumDVs=na-3+base
let defaultDV=(na ls 3 ? 0, dvVec!actualNumDVs)
let callersFormals=CallersFrame()+4

if rv lvNa ls base then errhlt("Too few arguments")

for i=base to (lvNa-callersFormals-1) do
if i ge rv lvNa % (defaultOnZero &
callersFormals!i eq 0) then
callersFormals!i=(i le actualNumDVs ?
dvVec!i, defaultDV)
]