; eval in nut

; global : mem fp sp

(let mem fp sp)

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

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

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

(def main () (start)
  (do
  (set mem (new 2000))
  (set fp STKBASE)
  (set sp STKBASE)
  (set start (loadobj))
  (eval start)))
