.. this is nut v2.0
.. add ld, st, ldy, sty
.. eliminate rt, save -> pushe, new -> sys 3  5 jan 2005
.s
xe
xe1
xe2
xfp
xsp
xrv
ye
ye1
ye2
yfp
ysp
yrv
de
de1
de2
dfp
dsp
drv
sM
sT
ss2
sarg
sfs
sk
snil
add
sub
inc
eq
lt
gt
isnil
isatom
pass1
pass2
mR
mW
lmar
pushe
sys
recur
ret
jmp
jT
jF
switchop
.m
.. start of microprogram
.. <start>
.. if e = NIL return NIL
:begin 	xe isnil jT /exit ;
  	xe isatom jT /decode ;
.. e1 = tail e
  	xe inc lmar ;
  	mR sM de1 ;
..  e2 = tail e1
  	xe1 inc lmar ;
  	mR sM de2 ;
..  e = head e
  	xe pass1 lmar ;
  	mR sM de ;
.. <decode>
:decode 	switchop ;
.. <xlit> retval = arg
:xlit  	sarg pass2 sT drv  ret ;
.. <xadd>  e1 = head e1
:xadd 	xe1 pass1 lmar ;
  	mR sM de1 ;
..  e1 = eval e1
  	xe1 pass1 sT pushe recur ;
  	xrv pass1 sT de1 ;
..  e2 = head e2
  	xe2 pass1 lmar ;
  	mR sM de2 ;
..  e2 = eval e2
  	xe2 pass1 sT pushe recur ;
  	xrv pass1 sT de2 ;
..  retval = e1 + e2
  	xe1 ye2 ss2 add sT drv ret ;
.. <xsub>
:xsub 	xe1 pass1 lmar ;
  	mR sM de1 ;
..  e1 = eval e1
  	xe1 pass1 sT pushe recur ;
  	xrv pass1 sT de1 ;
..  e2 = head e2
  	xe2 pass1 lmar ;
  	mR sM de2 ;
..  e2 = eval e2
  	xe2 pass1 sT pushe recur ;
  	xrv pass1 sT de2 ;
..  retval = e1 - e2
  	xe1 ye2 ss2 sub sT drv ret ;
.. <xeq>
:xeq 	xe1 pass1 lmar ;
  	mR sM de1 ;
..  e1 = eval e1
  	xe1 pass1 sT pushe recur ;
  	xrv pass1 sT de1 ;
..  e2 = head e2
  	xe2 pass1 lmar ;
  	mR sM de2 ;
..  e2 = eval e2
  	xe2 pass1 sT pushe recur ;
  	xrv pass1 sT de2 ;
..  retval = e1 == e2
  	xe1 ye2 ss2 eq sT drv ret ;
.. <xlt>
:xlt 	xe1 pass1 lmar ;
  	mR sM de1 ;
..  e1 = eval e1
  	xe1 pass1 sT pushe recur ;
  	xrv pass1 sT de1 ;
..  e2 = head e2
  	xe2 pass1 lmar ;
  	mR sM de2 ;
..  e2 = eval e2
  	xe2 pass1 sT pushe recur ;
  	xrv pass1 sT de2 ;
..  retval = e1 < e2
  	xe1 ye2 ss2 lt sT drv ret ;
.. <xgt>
:xgt 	xe1 pass1 lmar ;
  	mR sM de1 ;
..  e1 = eval e1
  	xe1 pass1 sT pushe recur ;
  	xrv pass1 sT de1 ;
..  e2 = head e2
  	xe2 pass1 lmar ;
  	mR sM de2 ;
..  e2 = eval e2
  	xe2 pass1 sT pushe recur ;
  	xrv pass1 sT de2 ;
..  retval = e1 > e2
  	xe1 ye2 ss2 gt sT drv ret ;
.. <xfun>
.. SS[sp+k] = fp;		// new frame
:xfun	xsp sk add lmar ;
	xfp pass1 mW ;
.. fp = sp+k;
	xsp sk add sT dfp ;
.. sp = fp;
	xfp pass1 sT dsp ;
.. e1 = head(e1);
	xe1 pass1 lmar ;
	mR sM de1 ;
.. retval = eval4(e1);
	xe1 pass1 sT pushe recur ;
.. sp = fp - fs;		// delete frame
	xfp sfs sub sT dsp ;
.. fp = SS[fp];
	xfp pass1 lmar ;
	mR sM dfp ret ;
.. <xget> return SS[fp-arg]
:xget 	xfp sarg sub lmar ;
	mR sM drv ret ;
.. <xld> return M[arg]
:xld 	sarg pass2 lmar ;
	mR sM drv ret ;
.. <xput> e1 = head(e1)
:xput 	xe1 pass1 lmar ;
	mR sM de1 ;
.. v = eval4(e1)
	xe1 pass1 sT pushe recur ;
.. SS[fp-arg] = v
	xfp sarg sub lmar ;
	xrv pass1 mW ret ;
.. <xst> e1 = head(e1)
:xst 	xe1 pass1 lmar ;
	mR sM de1 ;
.. v = eval4(e1)
	xe1 pass1 sT pushe recur ;
.. M[arg] = v
	sarg pass2 lmar ;
	xrv pass1 mW ret ;
.. <xcall> while e1 != NIL
:xcall 	xe1 isnil jT /ewhile ;
.. e2 = head(e1)
	xe1 pass1 lmar ;
	mR sM de2 ;
.. v = eval4(e)
	xe2 pass1 sT pushe recur ;
.. push(v)
	xsp inc sT dsp lmar ;
	xrv pass1 mW ;
.. e1 = tail(e1)
	xe1 inc lmar ;
	mR sM de1 jmp /xcall ;
.. v = eval4(arg)
:ewhile	sarg pass2 sT pushe recur ;
	ret ;
.. <xif>
.. e1 = head(e1)
:xif	xe1 pass1 lmar ;
	mR sM de1 ;
.. v = eval4(e1)
	xe1 pass1 sT pushe recur ;
.. if( v != 0){
	xrv isnil jT /ifelse ;
.. e2 = head(e2)
	xe2 pass1 lmar ;
	mR sM de2 ;
.. v = eval4(e2)
	xe2 pass1 sT pushe recur ;
.. return v
	ret ;
.. }else{ e2 = tail(e2);
:ifelse	xe2 inc lmar ;
	mR sM de2 ;
.. e2 = head(e2)
	xe2 pass1 lmar ;
	mR sM de2 ;
.. v = eval4(e2)
	xe2 pass1 pushe recur ;
.. return v
	ret ;
.. }
.. <xwhile>
.. e1 = head(e1)
:xwhile	xe1 pass1 lmar ;
	mR sM de1 ;
.. e2 = head(e2)
	xe2 pass1 lmar ;
	mR sM de2 ;
.. e = eval4(e1)
	xe1 pass1 sT pushe recur ;
.. use retval for e
.. while( e != NIL ){
:wloop	xrv isnil jT /ewloop ;
.. v = eval4(e2);	// body
	xe2 pass1 sT pushe recur ;
	xrv pass1 sT de ;
.. e = eval4(e1);	// cond
	xe1 pass1 sT pushe recur ;
	jmp /wloop ;
.. }
.. return v;
:ewloop	xe pass1 sT drv ret ;
.. <xdo>
.. while( e1 != NIL ){
:xdo	xe1 isnil jT /edo ;
.. e = head(e1)
	xe1 pass1 lmar ;
	mR sM de ;
.. v = eval4(e)
	xe pass1 sT pushe recur ;
.. e1 = tail(e1)
	xe1 inc lmar ;
	mR sM de1 jmp /xdo ;
.. }
.. return v
:edo	ret ;
.. <xldx>
.. e1 = head(e1)
:xldx	xe1 pass1 lmar ;
	mR sM de1 ;
.. e = eval4(e1)	// index
	xe1 pass1 sT pushe recur ;
.. v = SS[fp-arg] + e
	xfp sarg sub lmar ;
:xldx1	mR sM de1 ;
	xe1 yrv ss2 add lmar ;
.. v = heap[v]
.. return v
	mR sM drv ret ;
.. <xldy>
:xldy	xe1 pass1 lmar ;
	mR sM de1 ;
.. e = eval4(e1)	// index
	xe1 pass1 sT pushe recur ;
.. v = M[arg] + e
	sarg pass2 lmar jmp /xldx1 ;
.. <xstx>
.. e1 = head(e1)
:xstx	xe1 pass1 lmar ;
	mR sM de1 ;
.. rv = eval4(e1)	// index
	xe1 pass1 sT pushe recur ;
.. rt = SS[fp-arg]
	xfp sarg sub lmar ;
:xstx1	mR sM de1 ;
	xe1 yrv ss2 add sT de1 ;
.. e2 = head(e2)
	xe2 pass1 lmar ;
	mR sM de2 ;
.. rv = eval4(e2)	// value
	xe2 pass1 sT pushe recur ;
.. M[e1] = rv return
	xe1 pass1 lmar ;
	xrv pass1 mW ret ;
.. <xsty>
.. e1 = head(e1)
:xsty	xe1 pass1 lmar ;
	mR sM de1 ;
.. rv = eval4(e1)	// index
	xe1 pass1 sT pushe recur ;
.. rt = M[arg]
	sarg pass2 lmar jmp /xstx1 ;
.. <xsys>
.. e1 = head(e1)
:xsys	xe1 pass1 lmar ;
	mR sM de1 ;
.. v = eval4(e1)
	xe1 pass1 sT pushe recur ;
	sys ret ;
..  <exit>  retval = NIL
:exit 	snil pass2 sT drv ret ;
.e
