nut compiler  (based on nut3)


main
  readinfile
  parse
  resolve
  outobj

readinfile
  read stdin to inbuf[]

parse
  tokenise
  while not EOF
    expect "("
    tokenise
    if token == "def"
      parseDef
    if token == "let"
      parseLet
    if token == "enum"
      parseEnum
    tokenise

resolve
  for all func in symtab
    reName call and local var

reName
  if op == get, put, ldx, stx
    rename local var  (lv-arg+1)  1..n to n..1
  if op == call
    update reference

parseDef
  tokenise	; get fun name
  parseNL	; get formal arg
  parseNL	; get local
  tokenise
  e = parseExp	; get body
  tokenise	; skip ")"
  update symtab
  out (fun.k e)

parseLet
  tokenise
  while token != ")"
    install token
    update symtab type = GVAR, val = newdata
    tokenise

parseEnum
  tokenise
  k = atoi token
  tokenise
  while token != ")"
    install token
    update symtab type = ENUM, val = k
    k++
    tokenise

parseNL
  tokenise
  if token == "("
    tokenise
    while token != ")"
      installLocal token
      tokenise
  else
    installLocal token

;  it a list, number, string or names
parseExp
  if token == "("
    tokenise
    nm = parseName
    e = parseEL
    out (nm e)
  if isNumber token
    n = atoi token
    out lit.n
  if isString token
    e = makestring token+1
    out str.e
  parseName	; it is OP, OPX, VAR, FUN

parseName
  get symbol token
  v = symbol.val
  switch type
    OP: out v
    VAR: out get.v
    GVAR: out ld.v
    FUN: out call.idx
    OPX:
      tokenise		; get var name
      get symbol token
      v2 = symbol.val
      if type == VAR
        switch v
          SET: out put.v2
          SETV: out stx.v2
          VEC:  out ldx.v2
      else if type == GVAR
        switch v
          SET: out st.v2
          SETV: out sty.v2
          VEC:  out ldy.v2
    SYS:
      tokenise
      k = atoi token
      out sys.k
    ENUM:
      out lit.v
        
parseEL
  tokenise
  if token == ")" return NIL
  e = parseExp
  e2 = parseEL
  out (e e2)

; ------- low level in C -------

readinfile
  read stdin into inbuf[] all at once  
  inbuf[] size maximum MAXFIN (50000 bytes)

tokenise
  skip blank
  get a char
  if isSpecial  return
  if isQuote (it is a string)
    get to other quote
  else  
    get to delimiter ( LP RP blank)

tokenise leaves a token string in token[]

