increaseindent indent: calc indent addstringchar indent " " calc indent addstringchar indent " " calc indent addstringchar indent " " calc indent addstringchar indent " " return indent / lexident: set word "" forever calc char peek calc isbeforea lt char "a" if isbeforea break / calc isafterz lt "z" char if isafterz break / calc word addstringchar word char skip / return word / parseconststring: skipchar quote emit quote forever calc char peek calc iseof eq char eof if iseof break / calc isquote eq char quote if isquote break / emit char skip / skipchar quote emit quote / parseexprvarref: calc varname lexident emit "var_" emit varname / parseexprcall: calc funcname lexident emit funcname 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 ")" / parsestatset indent: skipchar " " calc var lexident skipchar " " emit indent emit "char * var_" emit var emit " = " parseconststring emit ";" emit eol skipchar eol / parsestatcalc indent: skipchar " " calc var lexident skipchar " " emit indent emit "char * var_" emit var emit " = " parseexprcall emit ";" emit eol skipchar eol / parsestatif indent: skipchar " " emit indent emit "if (" parseexprvarref emit ")\n" emit indent emit "{\n" skipchar eol calc indentt increaseindent indent parseblock indentt emit indent emit "}\n" / parsestatforever indent: emit indent emit "while (1)\n" emit indent emit "{\n" skipchar eol calc indentt increaseindent indent parseblock indentt emit indent emit "}\n" / parsestatbreak indent: emit indent emit "break;\n" skipchar eol / parsestatreturn indent: emit indent emit "return " calc char peek calc isspace eq char " " if isspace skip parseexprvarref / emit ";" emit eol skipchar eol / parsestatemit indent: emit indent emit "emit(" skipchar " " calc char peek calc isquote eq char quote calc isnotquote not isquote if isquote parseconststring / if isnotquote parseexprvarref / emit ");\n" skipchar eol / parsestattrace indent: emit indent emit "trace(" emit quote skipchar " " calc varname lexident emit varname emit quote emit ", " emit varname emit ")\n" skipchar eol / parsestatskipchar indent: skipchar " " emit indent emit "skipchar(" calc char peek calc isquote eq char quote calc isnotquote not isquote if isquote parseconststring / if isnotquote parseexprvarref / emit ");\n" skipchar eol / parsestat indent: calc call lexident trace call calc isset eq call "set" if isset parsestatset indent return / calc iscalc eq call "calc" if iscalc parsestatcalc indent return / calc isif eq call "if" if isif parsestatif indent return / calc isforever eq call "forever" if isforever parsestatforever indent return / calc isbreak eq call "break" if isbreak parsestatbreak indent return / calc isreturn eq call "return" if isreturn parsestatreturn indent return / calc isemit eq call "emit" if isemit parsestatemit indent return / calc istrace eq call "trace" if istrace parsestattrace indent return / calc isskipchar eq call "skipchar" if isskipchar parsestatskipchar indent return / emit indent emit call 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 if isquote parseconststring / if isnotquote parseexprvarref / calc isfirst eq first "1" calc isnotfirst not isfirst if isnotfirst emit ", " / set first "0" / skipchar eol emit ");\n" / parseblock indent: 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 / / parsefunc: calc funcname lexident trace funcname emit "void " emit funcname emit "(" set first "1" forever calc char peek calc isspace eq char " " calc isnotspace not isspace if isnotspace break / skip calc var lexident calc isfirst eq first "1" calc isnotfirst not isfirst if isnotfirst emit ", " / emit "char * var_" emit var set first "0" / skipchar ":" skipchar eol emit ")\n{\n" parseblock " " emit "}\n\n" / emitheader: emit "char * addstringchar(char * str, char * chr)\n" emit "{\n" emit "}\n" emit "\n" emit "\n" / emitfooter: emit "" / main: emitheader 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 /