registerid id: declare idname declare newidx calc idname mapgetkey "REGISTERID" id "" if idname return idname / declare idnamea calc idnamea add "%id_" id return idnamea / emitln data: emit data emit eol return "" / lexident: declare char declare isbeforea declare isafterz declare word set word "" forever calc char peek calc isbeforea lt char "a" if isbeforea break / calc isafterz lt "z" char if isafterz break / calc word add word char skip / return word / skipchar exp: declare act declare lineno declare colno calc act peek calc lineno stdinlineno calc colno stdincolno check eq exp act : "Unexpected character" act "expected" exp "at" lineno colno skip / increaseindent indent: calc indent add indent " " return indent / parseconststring: declare char declare iseof declare isquote declare str set str "" skipchar quote forever calc char peek calc iseof eq char eof if iseof break / calc isquote eq char quote if isquote break / calc str add str char skip / skipchar quote declare constid calc constid mapgetkey "stringconst" str "" declare isempty calc isempty eq constid "" if isempty calc constid mapgetkey "stringconst" "___count___" "0" calc constid add constid "1" mapsetkey "stringconst" "___count___" constid / mapsetkey "stringconst" str constid mapsetkey "stringconst" constid str emit "i8* @str." emit constid return / parseexprvarref: declare varid declare varname calc varname lexident calc varid registerid varname emit "i8* " emit varid return / parseexprcall: declare char declare first declare funcid declare funcname declare isspace declare isnotspace declare isfirst declare isnotfirst declare isquote declare isnotquote calc funcname lexident check mapgetkey "FUNCREG" funcname "" : "Function" funcname "does not exist" calc funcid registerid funcname emit funcid emit "(" set first "1" forever calc char peek calc isspace eq char " " calc isnotspace not isspace if isnotspace break / skip calc isfirst eq first "1" calc isnotfirst not isfirst if isnotfirst emit ", " / calc char peek calc isquote eq char quote calc isnotquote not isquote if isquote parseconststring / if isnotquote parseexprvarref / set first "0" / emit ")" return / parsestatdeclare indent: declare varid declare varname skipchar " " calc varname lexident skipchar eol return / parsestatset indent: declare varid declare varname skipchar " " calc varname lexident calc varid registerid varname skipchar " " emit indent emit varid emit " = call i8* @__drop_i8_type(" parseconststring emit ")" emit eol skipchar eol return / parsestatcalc indent: declare varid declare varname declare varidx skipchar " " calc varname lexident calc varid registerid varname skipchar " " emit indent emit varid calc varidx mapgetkey "funcvarused" varid "" calc varidx add varidx "1" mapsetkey "funcvarused" varid varidx emit " = call i8* @" parseexprcall emit eol skipchar eol return / parseblock indent/ parsestatif indent: skipchar " " declare strlenvar calc strlenvar mapgetkey "localvarused" "" "" calc strlenvar add strlenvar "1" mapsetkey "localvarused" "" strlenvar trace strlenvar emit indent emit "%tmp" emit strlenvar emit " = call i64 @__strlen(" parseexprvarref skipchar eol emitln ")" declare strnotemptyvar calc strnotemptyvar mapgetkey "localvarused" "" "" calc strnotemptyvar add strnotemptyvar "1" mapsetkey "localvarused" "" strnotemptyvar trace strnotemptyvar emit indent emit "%tmp" emit strnotemptyvar emit " = icmp ne i64 %tmp" emit strlenvar emitln ", 0" declare labelnotempty calc labelnotempty mapgetkey "locallabelused" "" "" calc labelnotempty add labelnotempty "1" mapsetkey "locallabelused" "" labelnotempty trace labelnotempty declare labelempty calc labelempty mapgetkey "locallabelused" "" "" calc labelempty add labelempty "1" mapsetkey "locallabelused" "" labelempty trace labelempty emit indent emit "br i1 %tmp" emit strnotemptyvar emit ", label %lbl" emit labelnotempty emit ", label %lbl" emitln labelempty emit "lbl" emit labelnotempty emitln ":" declare indentt calc indentt increaseindent indent parseblock indentt emit "lbl" emit labelempty emitln ":" return / parsestatforever indent: declare indentt emit indent emitln "while (1)" emit indent emitln "{" skipchar eol calc indentt increaseindent indent parseblock indentt emit indent emitln "}" return / parsestatbreak indent: emit indent emitln "break;" skipchar eol return / parsestatreturn indent: declare char declare isspace declare isnotquote declare isquote declare isnotspace emit indent emit "ret " calc char peek calc isspace eq char " " calc isnotspace not isspace if isspace skip calc char peek calc isquote eq char quote calc isnotquote not isquote if isquote parseconststring / if isnotquote parseexprvarref / / if isnotspace emit "i18* 0" / emit eol skipchar eol return / parsestatcheck indent: declare char declare funcid declare funcname declare iscolon declare iseol declare isnotquote declare isquote declare notfirst skipchar " " emit indent emit "if( 0 == strlen(" calc funcname lexident calc funcid registerid funcname emit funcid emit "(" set notfirst "" forever skipchar " " calc char peek calc iscolon eq char ":" if iscolon break / if notfirst emit ", " / calc char peek calc isquote eq char quote calc isnotquote not isquote if isquote parseconststring / if isnotquote parseexprvarref / set notfirst "1" / skipchar ":" emitln ")) )" emit indent emitln "{" emit indent emit " fprintf(stderr, " emit quote emit "%s" emit quote emit ", " emit quote emit "ERROR:" emit quote emitln ");" forever skipchar " " emit indent emit " fprintf(stderr, " emit quote emit " %s" emit quote emit ", " calc char peek calc isquote eq char quote calc isnotquote not isquote if isquote parseconststring / if isnotquote parseexprvarref / emitln ");" calc char peek calc iseol eq char eol if iseol break / / emit indent emit " fprintf(stderr, " emit quote emit "%s" emit quote emit ", __EOL" emitln ");" emit indent emitln " exit(1);" emit indent emitln "}" / parsestattrace indent: declare varid declare varname emit indent emit "__trace(" emit quote skipchar " " calc varname lexident calc varid registerid varname emit varname emit quote emit ", " emit varid emitln ");" skipchar eol return / parsestat indent: declare call declare callid declare char declare first declare iscall declare isfirst declare isspace declare isquote declare isnotfirst declare isnotspace declare isnotquote calc call lexident trace call calc iscall eq call "declare" if iscall parsestatdeclare indent return / calc iscall eq call "set" if iscall parsestatset indent return / calc iscall eq call "calc" if iscall parsestatcalc indent return / calc iscall eq call "if" if iscall parsestatif indent return / calc iscall eq call "forever" if iscall parsestatforever indent return / calc iscall eq call "break" if iscall parsestatbreak indent return / calc iscall eq call "return" if iscall parsestatreturn indent return / calc iscall eq call "check" if iscall parsestatcheck indent return / calc iscall eq call "trace" if iscall parsestattrace indent return / check mapgetkey "FUNCREG" call "" : "Function" call "does not exist" calc callid registerid call emit indent emit "call i8* @" emit callid emit "(" set first "1" forever calc char peek calc isspace eq char " " calc isnotspace not isspace if isnotspace break / skip calc char peek calc isquote eq char quote calc isnotquote not isquote calc isfirst eq first "1" calc isnotfirst not isfirst if isnotfirst emit ", " / if isquote parseconststring / if isnotquote parseexprvarref / set first "0" / skipchar eol emitln ")" return / parseblock indent: declare char declare copy declare iseol declare isnoteol declare isdone declare iseoblock forever forever calc char peek calc iseol eq char eol calc isnoteol not iseol if isnoteol break / skip / set copy " " forever calc isdone eq copy indent if isdone break / skipchar "\t" calc copy increaseindent copy / calc char peek calc iseoblock eq char "/" if iseoblock skip skipchar eol break / skipchar "\t" parsestat indent / return / parsefunc: declare char declare first declare funcid declare funcname declare iseoblock declare isfirst declare ismain declare isnotmain declare isspace declare isnotfirst declare isnotspace declare varid declare varname calc funcname lexident mapsetkey "FUNCREG" funcname "1" calc funcid registerid funcname trace funcname emit "define i8* @" emit funcname emit "(" set first "1" forever calc char peek calc isspace eq char " " calc isnotspace not isspace if isnotspace break / skip calc varname lexident calc varid registerid varname calc isfirst eq first "1" calc isnotfirst not isfirst if isnotfirst emit ", " / emit "i8* " emit varid mapsetkey "funcvarused" varid "0" set first "0" / calc char peek calc iseoblock eq char "/" if iseoblock skipchar "/" skipchar eol emitln ");" return / skipchar ":" skipchar eol emitln ")" emitln "{" parseblock " " emitln "}" emit eol return / emitheader: emit "target datalayout = " emit quote emit "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" emit quote emit eol emit "target triple = " emit quote emit "x86_64-pc-linux-gnu" emit quote emit eol emit eol emit "@__EOL = internal constant [2 x i8] c" emit quote emit "\\0A\\00" emitln quote emit eol emitln "define i8* @__drop_i8_type(i8* %0) alwaysinline readnone" emitln "{" emitln " ret i8* %0" emitln "}" emit eol return / emitfooter: declare constid declare str declare dontusethisstr set dontusethisstr "__dontusethisstr__" set constid "01" forever calc str mapgetkey "stringconst" constid dontusethisstr declare unused calc unused eq str dontusethisstr if unused break / emit "@str." emit constid emit " = internal constant [33 x i8] c" emit quote emit str emitln quote calc constid add constid "1" / emit "" return / main: declare char declare iseof declare iseol declare isnoteol emitheader mapsetkey "REGISTERID" "eof" "@__EOF" mapsetkey "REGISTERID" "eol" "@__EOL" mapsetkey "REGISTERID" "quote" "@__QUOTE" mapsetkey "FUNCREG" "add" "1" mapsetkey "REGISTERID" "add" "__add" mapsetkey "FUNCREG" "emit" "1" mapsetkey "REGISTERID" "emit" "__emit" mapsetkey "FUNCREG" "eq" "1" mapsetkey "REGISTERID" "eq" "__eq" mapsetkey "FUNCREG" "lt" "1" mapsetkey "REGISTERID" "lt" "__lt" mapsetkey "FUNCREG" "not" "1" mapsetkey "REGISTERID" "not" "__not" mapsetkey "FUNCREG" "mapclear" "1" mapsetkey "REGISTERID" "mapclear" "__mapclear" mapsetkey "FUNCREG" "mapgetkey" "1" mapsetkey "REGISTERID" "mapgetkey" "__mapgetkey" mapsetkey "FUNCREG" "mapsetkey" "1" mapsetkey "REGISTERID" "mapsetkey" "__mapsetkey" mapsetkey "FUNCREG" "peek" "1" mapsetkey "REGISTERID" "peek" "__peek" mapsetkey "FUNCREG" "skip" "1" mapsetkey "REGISTERID" "skip" "__skip" mapsetkey "FUNCREG" "stdincolno" "1" mapsetkey "REGISTERID" "stdincolno" "__stdincolno" mapsetkey "FUNCREG" "stdinlineno" "1" mapsetkey "REGISTERID" "stdinlineno" "__stdinlineno" forever calc char peek calc iseof eq char eof if iseof break / forever calc char peek calc iseol eq char eol calc isnoteol not iseol if isnoteol break / skip / parsefunc / emitfooter return /