;;;; Copyright 2002, Jonathan Bachrach.  See file TERMS.

(use goo/boot)
(use goo/macros)
(use goo/cols/col)

(df napp (proc|<fun> nexts args|...)
  (def ilen       (@+ (@olen args) -1))
  (def lelt       (@oelt args ilen))
  (def lelt-opts? (@== (%class-of lelt) <opts>))
  (def tlen       (@+ ilen (if lelt-opts? (@olen lelt) (len lelt))))
  (def stackspace (%lb (%allocate-stack (%i+ (%raw 2) (%iu tlen)))))
  (def frameend   (%sp-reg))
  (def argtop     (@+ tlen -1))

  (rep loop1 ((i 0))
    (when (@< i ilen)
      (set (%loc-off stackspace (%i- (%iu argtop) (%iu i))) (@oelt args i))
      (loop1 (@+ i 1))))
  (if lelt-opts?
      (rep loop2 ((j 0) (i ilen))
        (unless (@== i tlen)
          (set (%loc-off stackspace (%i- (%iu argtop) (%iu i))) (@oelt lelt j))
          (loop2 (@+ j 1) (@+ i 1))))
      (rep loop2 ((s (enum lelt)) (i ilen))
        (unless (fin? s)
          (set (%loc-off stackspace (%i- (%iu argtop) (%iu i))) (now s))
          (loop2 (nxt s) (@+ i 1)))))
  (set (%loc-off stackspace (%iu tlen))                (%iu tlen))
  (set (%loc-off stackspace (%i+ (%raw 1) (%iu tlen))) proc)
  (set (%sp-reg)                                       frameend)
  (%check-call-types)
  (%raw-call proc nexts))

