s2 code generator for rz

base on eval()


gen(e)

if e == nil ret nil
if isatom e  ret genatom e

e1 = tail e  // argument list
e = head e   // operator

op = tail e
switch op

case if
case else
case while
case do

case plus   genbop add e1
case minus  genbop sub e1
case star   genbop mul e1
case slash   genbop div e1
case andand  genbop logand e1
case oror    genbop logor e1
case ne     genbop ne e1
case lt     genbop lt e1
case le     genbop le e1
case gt     genbop gt e1
case ge     genbop ge e1

case unot   genunot e1
case uminus genuminus e1
case deref  genderef e1
case ads    genads e1

case call
case return
case fun

case vec   genvec e1
case eq    genassg e1
case print  genprint e1

default  error("unknown op");

ret nil

-----------------

genbop op e      // e is arglist

 r1 = gen head e   // arg1
 r2 = gen arg2 e   // arg2
 r3 = newR
 out op r3 r1 r2
 freeR r1 r2
 ret r3

-------------------

genunot e
  r1 = gen head e
  out not r1 r1 
  ret r1

genuminus e
  r1 = gen head e
  out sub r1 r0 r1
  ret r1

genderef e
  r1 = gen head e
  out ld r1 @0 r1
  ret r1

genads e  ???

-------------------

genvec e             // RHS
  r1 = gen head e
  r2 = gen arg2 e    // index
  r3 = newR
  out ld r3 +r1 r2
  freeR r1 r2
  ret r3

genassg e

  if isderef head e   

LHS
  {gv,lv,vec}

  v = gen arg2 e    //  RHS 
  switch lhs
  case gv: 
    a = (getRef gv) + base_data
    out st a v
  case lv:
    out st @lv fp v
  case vec:          // e1 = (vec nm idx)
    r1 = gen arg2 e1
    r2 = gen arg3 e1
    out st +r1 r2 v
    freeR r1 r2

  *{gv,lv,vec}

  switch lhs
  case *gv:
    a = (getRef gv) + base_data
    r1 = newR
    out ld r1 a
    out st r1 v
    freeR r1
  case *lv:
    r1 = newR
    out ld r1 @lv fp
    out st r1 v
    freeR r1
  case *vec:          // e1 = (vec nm idx)
    r1 = gen arg2 e1
    r2 = gen arg3 e1
    r3 = newR
    out ld r3 +r1 r2
    out st @0 r3 v
    freeR r1 r2 r3

  freeR v
  ret nil
---------------------

genprint e

while e != nil
  e2 = head e
  if isatom e2
     ty = head e2
     v = tail e2
     switch ty
     case NUM:  
        out call printnum v
     case STRING:
        out call printstring &strbuf[v]
     case GNAME:
        r1 = newR
        a = (getRef v) + base_data
        out ld r1 a
        out call printnum r1
        freeR r1
     case LNAME:
        r1 = newR
        out ld r1 +v fp
        out call printnum r1
        freeR r1
  else
     r1 = gen e2
     out call printnum r1
     freeR r1
  e = tail e

ret nil

--------------
end    16 Nov 2010
