Adds emitln to reduce complexity

This commit is contained in:
Johan B.W. de Vries 2025-02-02 15:30:40 +01:00
parent 17841954de
commit a08084230e
3 changed files with 230 additions and 215 deletions

View File

@ -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")

View File

@ -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:

View File

@ -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
/