// eval4 in nut
// global : M fp sp, must be passed

(def head (e m) ()
  (if (= e 0) 0 (vec m e)))

(def tail (e m) ()
  (if (= e 0) 0 (vec (+ m 1))))

// implement: lit, get, add, fun
(def evaln (e m fp sp) (op arg e1 e2 v fs k)
  (do
  (if (= e 0) 0
  (if (not (isatom e))
    (do
	(set e1 (tail e m))
	(set e2 (tail e1 m))
	(set e (head e m)))
	0)
  (set op (& (shiftr e 24) 127)))
  (set arg (& e 0x0ffffff))
  (if (= op xLIT)
    arg
  (if (= op xGET)
    (vec m (- fp arg))
  (if (= op xADD)
    (do
	(set e1 (head e1 m))
	(set e1 (evaln e1 m fp sp))
	(set e2 (head e2 m))
	(set e2 (evaln e2 m fp sp))
	(+ e1 e2)
  (if (= op xFUN)
    (do
	(set fs (& arg 255))
	(set k (shiftr arg 8))
	(setv m (+ sp k) fp)
	(set fp (+ sp k))
	(set sp fp)
	(set e1 (head e1))
	(set v (evaln e1 m fp sp))
	(set sp (- fp fs))
	(set fp (vec m fp))
	v)))))))
  0)))))))

(def main () (m fp sp start)
  (do
  (set m (new 2000))
// start = loadobj
  (evaln start m STKBASE STKBASE)))

