increaseindent indent: calc indent addstringchar indent " " calc indent addstringchar indent " " calc indent addstringchar indent " " calc indent addstringchar indent " " return indent / lexident: 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 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 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 ")" / parsestatdeclare indent: skipchar " " calc var lexident skipchar eol / parsestatset indent: skipchar " " calc var lexident skipchar " " emit indent emit var emit " = " parseconststring emit eol skipchar eol / parsestatcalc indent: skipchar " " calc var lexident skipchar " " emit indent emit var emit " = " parseexprcall emit eol skipchar eol / parseblock indent/ parsestatif indent: skipchar " " emit indent emit "if " parseexprvarref emit ":\n" skipchar eol calc indent increaseindent indent parseblock indent / parsestatforever indent: emit indent emit "while True:\n" skipchar eol calc indent increaseindent indent parseblock indent / 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 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 "declare" if isset parsestatdeclare indent return / 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 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" / 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 calc char peek calc iseoblock eq char "/" if iseoblock return / trace funcname emit "def " 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 var set first "0" / calc char peek calc iseoblock eq char "/" if iseoblock skipchar "/" skipchar eol emit "):\n" emit " pass # ahead declaration\n" emit "\n" return / skipchar ":" skipchar eol emit "):\n" parseblock " " emit "\n" / emitheader: emit "import os\n" emit "import sys\n" emit "\n" emit "def eq(a, b):\n" emit " return a == b\n" emit "\n" emit "def lt(a, b):\n" emit " return a[0] < b[0]\n" emit "\n" emit "def addstringchar(a, b):\n" emit " return a + b[0]\n" emit "\n" emit "def emit(string):\n" emit " sys.stdout.write(string)\n" emit "\n" emit "def trace(header, value):\n" emit " if os.environ.get('TRACE'):\n" emit " sys.stderr.write(f'{header}={value!r}\\n')\n" emit "\n" emit "eof = chr(0)\n" emit "eol = chr(10)\n" emit "quote = chr(34)\n" emit "PEEK = None\n" emit "LINE = 1\n" emit "\n" emit "def peek():\n" emit " global PEEK\n" emit " if PEEK is None:\n" emit " char = sys.stdin.read(1)\n" emit " trace('char', char)\n" emit " if not char:\n" emit " PEEK = eof\n" emit " else:\n" emit " PEEK = char\n" emit " return PEEK\n" emit "\n" emit "def skip():\n" emit " global LINE\n" emit " global PEEK\n" emit " if eol == PEEK:\n" emit " LINE += 1\n" emit " PEEK = None\n" emit "\n" emit "def skipchar(char):\n" emit " global LINE\n" emit " assert char == peek(), (LINE, char, peek())\n" emit " skip()\n" emit "\n" / emitfooter: emit "if __name__ == '__main__':\n" emit " main()\n" / 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 /