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