structure of som5 compiler
(to modify it for som5.1)

main
  loadfile source
  genfinal
  hashsym
  listing
  outobject

loadfile
  parse
  runimm

genfinal
  patchcalli
  outc "call main"
  outc "stop"

listing
  showcode

outobject
  reloc global
  outCS
  outM data
  dumpSym

parse
  lex
  while not EOF
    top-level-parse
    if define-fun
      genex 
    else
      append im

runimm
  patchcalli
  genex from im
  eval

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

genex
  if atom genatom
  case op
    bop:  genbop
    blok: while not NIL
            final genex
            next
    call: genex param pass
          outc "call v1 v2 ref"
    mac:  genex subst
    to:   genfun 
          improv
          relocJmp
    mdef: setref

    asg:  if isatom LHS
            genatom LHS
            genput LHS RHS
          else LHS is vec
            genex idx
            genatom base
            genex RHS
            outc "stx RHS base idx"

    vecR: genatom base
          genex idx
          outc "ldx base idx"

    if:   optJmp jf
          final genex ACT
          patchArg ads

    ifel: optJmp jf
          final genex ACT
          outJmp
          patchArg ads
          final genex ACF
          patchArg ads

    whle: outJmp
          final genex body
          optJmp jt
          patchArg ads
          patchbreak
    
    for:  genatom idx
          make init-1
          genput idx (init-1)
          genex end
          outJmp 
          final genex body
          patchArg ads
          outc "efor idx end"
          patchbreak

    case: gencase        
    brek: outJmp
    not:
    array:
    sys:   ...

genatom
  type STRING, ADS, NUM, LNAME, GNAME

// optimise by trying to combine jcond with lastop
optJmp
  if lastOp can be combined with jt/jf
    patch combine
  else
    outc normal jmp

outJmp
  add jump-list
  outc "jmp"

genbop op e1 e2
  if isnum e1 && isnum e2
    genNum evalbop op e1 e2
  else
    genex e1
    genex e2
    outc "bop newv e1 e2"

genput v e
  genex e
  if islocal e && not atom e
    patchArg lastCP v
  else
    outc "mov v e"

genNum n
  if smallnum n
    400+n
  else
    v = newdata
    M[v] = n
    v

genfun
  outc "fun arity 0"
  genex body
  patchbreak
  if tailcall
    patchArg lastCP callt
  update fun header lv
  outc "ret v fs"

gencase
  genex cond
  get lo hi
  outc "case cond lo hi"
  create empty jump vector
  outJmp  (for else)
  while not NIL  (list of case)
    get label
    patch entry in jump vector
    final genex each case
    outJmp eloc
    next
  patchArg else
  patch empty entry to else
  final genex elsecase
  update backchain eloc

final v
// if v is singleton, mov it to RETVAL
// if op has dest and dest is temp, diffuse RETVAL

15 Dec 2010
