lang0/1-lang0py/lang0py.lang0
2025-02-02 15:30:40 +01:00

406 lines
6.0 KiB
Plaintext

emitln data:
emit data
emit eol
/
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
emitln ":"
skipchar eol
calc indent increaseindent indent
parseblock indent
/
parsestatforever indent:
emit indent
emitln "while True:"
skipchar eol
calc indent increaseindent indent
parseblock indent
/
parsestatbreak indent:
emit indent
emitln "break"
skipchar eol
/
parsestatreturn indent:
emit indent
emit "return "
calc char peek
calc isspace eq char " "
if isspace
skip
parseexprvarref
/
emit eol
skipchar eol
/
parsestattrace indent:
emit indent
emit "trace("
emit quote
skipchar " "
calc varname lexident
emit varname
emit quote
emit ", "
emit varname
emitln ")"
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 istrace eq call "trace"
if istrace
parsestattrace 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
emitln ")"
/
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
emitln "):"
emitln " pass # ahead declaration"
emit eol
return
/
skipchar ":"
skipchar eol
emitln "):"
parseblock " "
emit eol
/
emitheader:
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:
emitln "if __name__ == '__main__':"
emitln " main()"
/
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
/