nut compiler 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.a.v 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[]