eval in nut

There is no reason why eval() for n-machine can not be implemented in Nut itself.  We take eval4() in C and morph it into Nut.  The tricky part is that Nut has no global variables therefore memory M[.], fp, sp must be modeled as local variables and passed as parameters to evaln().

// 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))))

(def isatom (x) ()
  (& x 0x80000000))

(def not (x) ()
  (if x 0 else 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 start)
  (do
  (set m (new 2000))
// start = loadobj
  (evaln start m STKBASE STKBASE)))

The code above shows only four instructions: lit, get, add, fun to give some idea how it is acutally implemented.  This is not a runnable code.  The line

// start = loadobj

must get an executable object code (that is to be executed by eval) and puts it into the memory somehow.  We do not concern the detail here.  Many symbols, such as xADD, ox0ffffff, must in fact be integer constants.  The functions : shiftr, &   must be defined elsewhere.

8 December 2004
P. Chongstitvatana