Adds emitln to reduce complexity
This commit is contained in:
parent
17841954de
commit
a08084230e
@ -43,6 +43,10 @@ def skipchar(char):
|
||||
assert char == peek(), (LINE, char, peek())
|
||||
skip()
|
||||
|
||||
def emitln(data):
|
||||
emit(data)
|
||||
emit(eol)
|
||||
|
||||
def lexident():
|
||||
word = ''
|
||||
while True:
|
||||
@ -135,21 +139,21 @@ def parsestatif(indent):
|
||||
emit(' ' * indent)
|
||||
emit('if ')
|
||||
parseexprvarref()
|
||||
emit(':\n')
|
||||
emitln(':')
|
||||
skipchar(eol)
|
||||
|
||||
parseblock(indent + 1)
|
||||
|
||||
def parsestatforever(indent):
|
||||
emit(' ' * indent)
|
||||
emit('while True:\n')
|
||||
emitln('while True:')
|
||||
skipchar(eol)
|
||||
|
||||
parseblock(indent + 1)
|
||||
|
||||
def parsestatbreak(indent):
|
||||
emit(' ' * indent)
|
||||
emit('break\n')
|
||||
emitln('break')
|
||||
skipchar(eol)
|
||||
|
||||
def parsestatreturn(indent):
|
||||
@ -172,7 +176,7 @@ def parsestattrace(indent):
|
||||
emit(var_name)
|
||||
emit('", ')
|
||||
emit(var_name)
|
||||
emit(')\n')
|
||||
emitln(')')
|
||||
|
||||
def parsestat(indent):
|
||||
call = lexident()
|
||||
@ -227,7 +231,7 @@ def parsestat(indent):
|
||||
|
||||
skipchar(eol)
|
||||
|
||||
emit(')\n')
|
||||
emitln(')')
|
||||
|
||||
def parseblock(indent):
|
||||
while True:
|
||||
@ -267,71 +271,71 @@ def parsefunc():
|
||||
# Ahead declaration
|
||||
skipchar('/')
|
||||
skipchar(eol)
|
||||
emit("):\n")
|
||||
emit(" pass # ahead declaration\n")
|
||||
emit("\n")
|
||||
emitln("):")
|
||||
emitln(" pass # ahead declaration")
|
||||
emit(eol)
|
||||
return
|
||||
|
||||
skipchar(':')
|
||||
skipchar(eol)
|
||||
|
||||
emit('):\n')
|
||||
emitln('):')
|
||||
|
||||
parseblock(1)
|
||||
|
||||
emit("\n")
|
||||
emit(eol)
|
||||
|
||||
def 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("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")
|
||||
emitln("import os")
|
||||
emitln("import sys")
|
||||
emitln("")
|
||||
emitln("def eq(a, b):")
|
||||
emitln(" return a == b")
|
||||
emitln("")
|
||||
emitln("def lt(a, b):")
|
||||
emitln(" return a[0] < b[0]")
|
||||
emitln("")
|
||||
emitln("def addstringchar(a, b):")
|
||||
emitln(" return a + b[0]")
|
||||
emitln("")
|
||||
emitln("def emit(string):")
|
||||
emitln(" sys.stdout.write(string)")
|
||||
emitln("")
|
||||
emitln("def trace(header, value):")
|
||||
emitln(" if os.environ.get('TRACE'):")
|
||||
emitln(" sys.stderr.write(f'{header}={value!r}\\n')")
|
||||
emitln("")
|
||||
emitln("eof = chr(0)")
|
||||
emitln("eol = chr(10)")
|
||||
emitln("quote = chr(34)")
|
||||
emitln("PEEK = None")
|
||||
emitln("LINE = 1")
|
||||
emitln("")
|
||||
emitln("def peek():")
|
||||
emitln(" global PEEK")
|
||||
emitln(" if PEEK is None:")
|
||||
emitln(" char = sys.stdin.read(1)")
|
||||
emitln(" trace('char', char)")
|
||||
emitln(" if not char:")
|
||||
emitln(" PEEK = eof")
|
||||
emitln(" else:")
|
||||
emitln(" PEEK = char")
|
||||
emitln(" return PEEK")
|
||||
emitln("")
|
||||
emitln("peek()")
|
||||
emitln("")
|
||||
emitln("def skip():")
|
||||
emitln(" global LINE")
|
||||
emitln(" global PEEK")
|
||||
emitln(" if eol == PEEK:")
|
||||
emitln(" LINE += 1")
|
||||
emitln(" PEEK = None")
|
||||
emitln("")
|
||||
emitln("def skipchar(char):")
|
||||
emitln(" global LINE")
|
||||
emitln(" assert char == peek(), (LINE, char, peek())")
|
||||
emitln(" skip()")
|
||||
emitln("")
|
||||
|
||||
def emitfooter():
|
||||
emit("if __name__ == '__main__':\n")
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
emitln data:
|
||||
emit data
|
||||
emit eol
|
||||
/
|
||||
|
||||
increaseindent indent:
|
||||
calc indent addstringchar indent " "
|
||||
calc indent addstringchar indent " "
|
||||
@ -119,7 +124,7 @@ parsestatif indent:
|
||||
emit indent
|
||||
emit "if "
|
||||
parseexprvarref
|
||||
emit ":\n"
|
||||
emitln ":"
|
||||
skipchar eol
|
||||
calc indent increaseindent indent
|
||||
parseblock indent
|
||||
@ -127,7 +132,7 @@ parsestatif indent:
|
||||
|
||||
parsestatforever indent:
|
||||
emit indent
|
||||
emit "while True:\n"
|
||||
emitln "while True:"
|
||||
skipchar eol
|
||||
calc indent increaseindent indent
|
||||
parseblock indent
|
||||
@ -135,7 +140,7 @@ parsestatforever indent:
|
||||
|
||||
parsestatbreak indent:
|
||||
emit indent
|
||||
emit "break\n"
|
||||
emitln "break"
|
||||
skipchar eol
|
||||
/
|
||||
|
||||
@ -162,7 +167,7 @@ parsestattrace indent:
|
||||
emit quote
|
||||
emit ", "
|
||||
emit varname
|
||||
emit ")\n"
|
||||
emitln ")"
|
||||
skipchar eol
|
||||
/
|
||||
|
||||
@ -238,7 +243,7 @@ parsestat indent:
|
||||
set first "0"
|
||||
/
|
||||
skipchar eol
|
||||
emit ")\n"
|
||||
emitln ")"
|
||||
/
|
||||
|
||||
parseblock indent:
|
||||
@ -307,74 +312,74 @@ parsefunc:
|
||||
if iseoblock
|
||||
skipchar "/"
|
||||
skipchar eol
|
||||
emit "):\n"
|
||||
emit " pass # ahead declaration\n"
|
||||
emitln "):"
|
||||
emitln " pass # ahead declaration"
|
||||
emit eol
|
||||
return
|
||||
/
|
||||
skipchar ":"
|
||||
skipchar eol
|
||||
emit "):\n"
|
||||
emitln "):"
|
||||
parseblock " "
|
||||
emit eol
|
||||
/
|
||||
|
||||
emitheader:
|
||||
emit "import os\n"
|
||||
emit "import sys\n"
|
||||
emit eol
|
||||
emit "def eq(a, b):\n"
|
||||
emit " return a == b\n"
|
||||
emit eol
|
||||
emit "def lt(a, b):\n"
|
||||
emit " return a[0] < b[0]\n"
|
||||
emit eol
|
||||
emit "def addstringchar(a, b):\n"
|
||||
emit " return a + b[0]\n"
|
||||
emit eol
|
||||
emit "def emit(string):\n"
|
||||
emit " sys.stdout.write(string)\n"
|
||||
emit eol
|
||||
emit "def trace(header, value):\n"
|
||||
emit " if os.environ.get('TRACE'):\n"
|
||||
emit " sys.stderr.write(f'{header}={value!r}\\n')\n"
|
||||
emit eol
|
||||
emit "eof = chr(0)\n"
|
||||
emit "eol = chr(10)\n"
|
||||
emit "quote = chr(34)\n"
|
||||
emit "PEEK = None\n"
|
||||
emit "LINE = 1\n"
|
||||
emit eol
|
||||
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 eol
|
||||
emit "peek()\n"
|
||||
emit eol
|
||||
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 eol
|
||||
emit "def skipchar(char):\n"
|
||||
emit " global LINE\n"
|
||||
emit " assert char == peek(), (LINE, char, peek())\n"
|
||||
emit " skip()\n"
|
||||
emit eol
|
||||
emitln "import os"
|
||||
emitln "import sys"
|
||||
emitln ""
|
||||
emitln "def eq(a, b):"
|
||||
emitln " return a == b"
|
||||
emitln ""
|
||||
emitln "def lt(a, b):"
|
||||
emitln " return a[0] < b[0]"
|
||||
emitln ""
|
||||
emitln "def addstringchar(a, b):"
|
||||
emitln " return a + b[0]"
|
||||
emitln ""
|
||||
emitln "def emit(string):"
|
||||
emitln " sys.stdout.write(string)"
|
||||
emitln ""
|
||||
emitln "def trace(header, value):"
|
||||
emitln " if os.environ.get('TRACE'):"
|
||||
emitln " sys.stderr.write(f'{header}={value!r}\')"
|
||||
emitln ""
|
||||
emitln "eof = chr(0)"
|
||||
emitln "eol = chr(10)"
|
||||
emitln "quote = chr(34)"
|
||||
emitln "PEEK = None"
|
||||
emitln "LINE = 1"
|
||||
emitln ""
|
||||
emitln "def peek():"
|
||||
emitln " global PEEK"
|
||||
emitln " if PEEK is None:"
|
||||
emitln " char = sys.stdin.read(1)"
|
||||
emitln " trace('char', char)"
|
||||
emitln " if not char:"
|
||||
emitln " PEEK = eof"
|
||||
emitln " else:"
|
||||
emitln " PEEK = char"
|
||||
emitln " return PEEK"
|
||||
emitln ""
|
||||
emitln "peek()"
|
||||
emitln ""
|
||||
emitln "def skip():"
|
||||
emitln " global LINE"
|
||||
emitln " global PEEK"
|
||||
emitln " if eol == PEEK:"
|
||||
emitln " LINE += 1"
|
||||
emitln " PEEK = None"
|
||||
emitln ""
|
||||
emitln "def skipchar(char):"
|
||||
emitln " global LINE"
|
||||
emitln " assert char == peek(), (LINE, char, peek())"
|
||||
emitln " skip()"
|
||||
emitln ""
|
||||
/
|
||||
|
||||
emitfooter:
|
||||
emit "if __name__ == '__main__':\n"
|
||||
emit " main()\n"
|
||||
emitln "if __name__ == '__main__':"
|
||||
emitln " main()"
|
||||
/
|
||||
|
||||
main:
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
emitln data:
|
||||
emit data
|
||||
emit eol
|
||||
/
|
||||
|
||||
increaseindent indent:
|
||||
calc indent addstringchar indent " "
|
||||
calc indent addstringchar indent " "
|
||||
@ -155,34 +160,34 @@ parsestatif indent:
|
||||
emit indent
|
||||
emit "if ( 0 < strlen("
|
||||
parseexprvarref
|
||||
emit ") )\n"
|
||||
emitln ") )"
|
||||
emit indent
|
||||
emit "{\n"
|
||||
emitln "{"
|
||||
skipchar eol
|
||||
calc indentt increaseindent indent
|
||||
parseblock indentt
|
||||
emit indent
|
||||
emit "}\n"
|
||||
emitln "}"
|
||||
return
|
||||
/
|
||||
|
||||
parsestatforever indent:
|
||||
declare indentt
|
||||
emit indent
|
||||
emit "while (1)\n"
|
||||
emitln "while (1)"
|
||||
emit indent
|
||||
emit "{\n"
|
||||
emitln "{"
|
||||
skipchar eol
|
||||
calc indentt increaseindent indent
|
||||
parseblock indentt
|
||||
emit indent
|
||||
emit "}\n"
|
||||
emitln "}"
|
||||
return
|
||||
/
|
||||
|
||||
parsestatbreak indent:
|
||||
emit indent
|
||||
emit "break;\n"
|
||||
emitln "break;"
|
||||
skipchar eol
|
||||
return
|
||||
/
|
||||
@ -220,7 +225,7 @@ parsestattrace indent:
|
||||
emit quote
|
||||
emit ", var_"
|
||||
emit varname
|
||||
emit ");\n"
|
||||
emitln ");"
|
||||
skipchar eol
|
||||
return
|
||||
/
|
||||
@ -307,7 +312,7 @@ parsestat indent:
|
||||
set first "0"
|
||||
/
|
||||
skipchar eol
|
||||
emit ");\n"
|
||||
emitln ");"
|
||||
return
|
||||
/
|
||||
|
||||
@ -389,113 +394,114 @@ parsefunc:
|
||||
if iseoblock
|
||||
skipchar "/"
|
||||
skipchar eol
|
||||
emit ");"
|
||||
emit "\n"
|
||||
emitln ");"
|
||||
return
|
||||
/
|
||||
skipchar ":"
|
||||
skipchar eol
|
||||
emit ")\n{\n"
|
||||
emitln ")"
|
||||
emitln "{"
|
||||
parseblock " "
|
||||
emit "}\n\n"
|
||||
emitln "}"
|
||||
emit eol
|
||||
return
|
||||
/
|
||||
|
||||
emitheader:
|
||||
emit "#include <assert.h>\n"
|
||||
emit "#include <stdio.h>\n"
|
||||
emit "#include <stdlib.h>\n"
|
||||
emit "#include <string.h>\n"
|
||||
emit eol
|
||||
emit eol
|
||||
emit "char var_eof[2] = {-1, 0};\n"
|
||||
emit "char var_eol[2] = {10, 0};\n"
|
||||
emit "char var_quote[2] = {34, 0};\n"
|
||||
emit "char var_false[1] = {0};\n"
|
||||
emit "char var_true[2] = {'1', 0};\n"
|
||||
emit eol
|
||||
emit eol
|
||||
emit "char * eq(char * a, char * b)\n"
|
||||
emit "{\n"
|
||||
emit " return (strcmp(a, b) == 0) ? var_true : var_false;\n"
|
||||
emit "}\n"
|
||||
emit "\n"
|
||||
emit "char * lt(char * a, char * b)\n"
|
||||
emit "{\n"
|
||||
emit " return (strcmp(a, b) < 0) ? var_true : var_false;\n"
|
||||
emit "}\n"
|
||||
emit "char * not(char * a)\n"
|
||||
emit "{\n"
|
||||
emit " return (strcmp(a, var_true) != 0) ? var_true : var_false;\n"
|
||||
emit "}\n"
|
||||
emit "\n"
|
||||
emit "char * addstringchar(char * str, char * chr)\n"
|
||||
emit "{\n"
|
||||
emit " int str_len = strlen(str);\n"
|
||||
emit " assert(strlen(chr) == 1);\n"
|
||||
emit " char * res = malloc((str_len + 2) * sizeof(char));\n"
|
||||
emit " strcpy(res, str);\n"
|
||||
emit " res[str_len + 0] = chr[0];\n"
|
||||
emit " res[str_len + 1] = 0;\n"
|
||||
emit " return res;\n"
|
||||
emit "}\n"
|
||||
emit "\n"
|
||||
emit "char * emit(char * str)\n"
|
||||
emit "{\n"
|
||||
emit " fputs(str, stdout);\n"
|
||||
emit " return 0;\n"
|
||||
emit "}\n"
|
||||
emit "\n"
|
||||
emit "char * trace(char * var_name, char * var_value)\n"
|
||||
emit "{\n"
|
||||
emitln "#include <assert.h>"
|
||||
emitln "#include <stdio.h>"
|
||||
emitln "#include <stdlib.h>"
|
||||
emitln "#include <string.h>"
|
||||
emitln ""
|
||||
emitln ""
|
||||
emitln "char var_eof[2] = {-1, 0};"
|
||||
emitln "char var_eol[2] = {10, 0};"
|
||||
emitln "char var_quote[2] = {34, 0};"
|
||||
emitln "char var_false[1] = {0};"
|
||||
emitln "char var_true[2] = {'1', 0};"
|
||||
emitln ""
|
||||
emitln ""
|
||||
emitln "char * eq(char * a, char * b)"
|
||||
emitln "{"
|
||||
emitln " return (strcmp(a, b) == 0) ? var_true : var_false;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "char * lt(char * a, char * b)"
|
||||
emitln "{"
|
||||
emitln " return (strcmp(a, b) < 0) ? var_true : var_false;"
|
||||
emitln "}"
|
||||
emitln "char * not(char * a)"
|
||||
emitln "{"
|
||||
emitln " return (strcmp(a, var_true) != 0) ? var_true : var_false;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "char * addstringchar(char * str, char * chr)"
|
||||
emitln "{"
|
||||
emitln " int str_len = strlen(str);"
|
||||
emitln " assert(strlen(chr) == 1);"
|
||||
emitln " char * res = malloc((str_len + 2) * sizeof(char));"
|
||||
emitln " strcpy(res, str);"
|
||||
emitln " res[str_len + 0] = chr[0];"
|
||||
emitln " res[str_len + 1] = 0;"
|
||||
emitln " return res;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "char * emit(char * str)"
|
||||
emitln "{"
|
||||
emitln " fputs(str, stdout);"
|
||||
emitln " return 0;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "char * trace(char * var_name, char * var_value)"
|
||||
emitln "{"
|
||||
emit " const char * env_trace = getenv("
|
||||
emit quote
|
||||
emit "TRACE"
|
||||
emit quote
|
||||
emit ");\n"
|
||||
emit " if( !env_trace ) return 0;\n"
|
||||
emit " fputs(var_name, stderr);\n"
|
||||
emitln ");"
|
||||
emitln " if( !env_trace ) return 0;"
|
||||
emitln " fputs(var_name, stderr);"
|
||||
emit " fputs("
|
||||
emit quote
|
||||
emit "="
|
||||
emit quote
|
||||
emit ", stderr);\n"
|
||||
emit " fputs(var_value, stderr);\n"
|
||||
emit " fputs(var_eol, stderr);\n"
|
||||
emit " return 0;\n"
|
||||
emit "}\n"
|
||||
emit eol
|
||||
emit "int LINE = 1;\n"
|
||||
emit eol
|
||||
emit "char * peek()\n"
|
||||
emit "{\n"
|
||||
emit " char * res = malloc(2*sizeof(char));\n"
|
||||
emit " res[0] = getc(stdin);\n"
|
||||
emit " res[1] = 0;\n"
|
||||
emit " ungetc(res[0], stdin);\n"
|
||||
emit " return res;\n"
|
||||
emit "}\n"
|
||||
emit "\n"
|
||||
emit "void skip()\n"
|
||||
emit "{\n"
|
||||
emit " char c = getc(stdin);\n"
|
||||
emit " if( c == 10 ) LINE += 1;\n"
|
||||
emit "}\n"
|
||||
emit "\n"
|
||||
emit "void skipchar(char * chr)\n"
|
||||
emit "{\n"
|
||||
emit " assert(strlen(chr) == 1);\n"
|
||||
emit " char * act = peek();\n"
|
||||
emit " assert(strlen(act) == 1);\n"
|
||||
emit " if( chr[0] == act[0] ) {skip(); return;};\n"
|
||||
emitln ", stderr);"
|
||||
emitln " fputs(var_value, stderr);"
|
||||
emitln " fputs(var_eol, stderr);"
|
||||
emitln " return 0;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "int LINE = 1;"
|
||||
emitln ""
|
||||
emitln "char * peek()"
|
||||
emitln "{"
|
||||
emitln " char * res = malloc(2*sizeof(char));"
|
||||
emitln " res[0] = getc(stdin);"
|
||||
emitln " res[1] = 0;"
|
||||
emitln " ungetc(res[0], stdin);"
|
||||
emitln " return res;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "void skip()"
|
||||
emitln "{"
|
||||
emitln " char c = getc(stdin);"
|
||||
emitln " if( c == 10 ) LINE += 1;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "void skipchar(char * chr)"
|
||||
emitln "{"
|
||||
emitln " assert(strlen(chr) == 1);"
|
||||
emitln " char * act = peek();"
|
||||
emitln " assert(strlen(act) == 1);"
|
||||
emitln " if( chr[0] == act[0] ) {skip(); return;};"
|
||||
emit " fprintf(stderr, "
|
||||
emit quote
|
||||
emit "Expected '%c' on line %d but saw '%c' instead%c"
|
||||
emit quote
|
||||
emit ", chr[0], LINE, act[0], 10);\n"
|
||||
emit " exit(1);\n"
|
||||
emit "}\n"
|
||||
emit "\n"
|
||||
emitln ", chr[0], LINE, act[0], 10);"
|
||||
emitln " exit(1);"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
return
|
||||
/
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user