import os import sys def emit(string): sys.stdout.buffer.write(string.encode('latin_1')) sys.stdout.flush() def trace(header, value): if os.environ.get('TRACE'): sys.stderr.write(f'{header}={value!r}\n') eof = chr(0xFF) eol = chr(10) quote = chr(34) PEEK = None LINE = 1 def peek(): global PEEK if PEEK is None: char = sys.stdin.read(1) trace('char', char) if not char: PEEK = eof else: PEEK = char return PEEK peek() def skip(): global LINE global PEEK if eol == PEEK: LINE += 1 PEEK = None def __check(func, args: list[str], msg: list[str]) -> None: result = func(*args) if result: return sys.stderr.write('ERROR: ' + ' '.join(msg) + '\n') sys.stderr.flush() exit(1) MAPSTORE = {} def mapclear(mapname: str) -> str: MAPSTORE.pop(mapname) return "" def mapgetkey(mapname: str, key: str, default: str) -> str: return MAPSTORE.get(mapname, {}).get(key, default) def mapsetkey(mapname: str, key: str, value: str) -> str: MAPSTORE.setdefault(mapname, {}) MAPSTORE[mapname][key] = value return "" def registerid(id: str) -> str: idname = mapgetkey("REGISTERID", id, "") if idname: return idname idname = "id_" + id return idname def emitln(data): emit(data) emit(eol) def lexident(): word = '' while True: char = peek() if char < 'a' or char > 'z': break word += char skip() return word def skipchar(char): global LINE assert char == peek(), (LINE, char, peek()) skip() def parseconststring(): skipchar(quote) emit(quote) escaped = False while True: char = peek() if char == eof: break if char == quote: break emit(char) skip() skipchar(quote) emit(quote) def parseexprvarref(): varname = lexident() varid = registerid(varname) emit(varid) def parseexprcall(): funcname = lexident() __check(mapgetkey, ["FUNCREG", funcname, ""], ["Function", funcname, "does not exist"]) funcid = registerid(funcname) emit(funcid) emit('(') first = True while ' ' == peek(): skip() if not first: emit(', ') if quote == peek(): parseconststring() else: parseexprvarref() first = False emit(')') def parsestatdeclare(indent): skipchar(' ') var = lexident() skipchar(eol) def parsestatset(indent): skipchar(' ') varname = lexident() varid = registerid(varname) skipchar(' ') emit(' ' * indent) emit(varid) emit(' = ') parseconststring() emit(eol) skipchar(eol) def parsestatcalc(indent): skipchar(' ') varname = lexident() varid = registerid(varname) skipchar(' ') emit(' ' * indent) emit(varid) emit(' = ') parseexprcall() emit(eol) skipchar(eol) def parsestatif(indent): skipchar(' ') emit(' ' * indent) emit('if ') parseexprvarref() emitln(':') skipchar(eol) parseblock(indent + 1) def parsestatforever(indent): emit(' ' * indent) emitln('while True:') skipchar(eol) parseblock(indent + 1) def parsestatbreak(indent): emit(' ' * indent) emitln('break') skipchar(eol) def parsestatreturn(indent): emit(' ' * indent) emit('return ') if ' ' == peek(): skip() if quote == peek(): parseconststring() else: parseexprvarref() else: emit('""') emit(eol) skipchar(eol) def parsestatcheck(indent): skipchar(' ') emit(' ' * indent) emit('__check(') funcname = lexident() funcid = registerid(funcname) trace("funcid", funcid) emit(funcid) emit(', [') notfirst = False while True: skipchar(' ') if ':' == peek(): break if notfirst: emit(', ') if quote == peek(): parseconststring() else: parseexprvarref() notfirst = True skipchar(':') emit('], [') notfirst = False while True: skipchar(' ') if notfirst: emit(', ') if quote == peek(): parseconststring() else: parseexprvarref() if eol == peek(): break notfirst = True emitln('])') def parsestattrace(indent): skipchar(' ') emit(' ' * indent) emit('__trace("') varname = lexident() varid = registerid(varname) skipchar(eol) emit(varname) emit('", ') emit(varid) emitln(')') def parsestat(indent): call = lexident() trace('call', call) if call == "declare": parsestatdeclare(indent) return if call == "set": parsestatset(indent) return if call == "calc": parsestatcalc(indent) return if call == "if": parsestatif(indent) return if call == "forever": parsestatforever(indent) return if call == "break": parsestatbreak(indent) return if call == "return": parsestatreturn(indent) return if call == "check": parsestatcheck(indent) return if call == "trace": parsestattrace(indent) return funcid = registerid(call) emit(' ' * indent) emit(funcid) emit('(') first = True while ' ' == peek(): skip() if not first: emit(", ") if '"' == peek(): parseconststring() else: parseexprvarref() first = False skipchar(eol) emitln(')') def parseblock(indent): while True: while eol == peek(): skip() for _ in range(indent - 1): skipchar('\t') if '/' == peek(): skip() skipchar(eol) break skipchar('\t') parsestat(indent) def parsefunc(): funcname = lexident() funcid = registerid(funcname) mapsetkey("FUNCREG", funcname, "1") trace('funcname', funcname) emit('def ') emit(funcid) emit('(') first = True while ' ' == peek(): skip() varname = lexident() varid = registerid(varname) if not first: emit(", ") emit(varid) first = False if '/' == peek(): # Ahead declaration skipchar('/') skipchar(eol) emitln("):") emitln(" pass # ahead declaration") emit(eol) return skipchar(':') skipchar(eol) emitln('):') parseblock(1) emit(eol) def emitheader(): emitln("import os") emitln("import sys") emitln("") emitln("def __eq(a: str, b: str) -> str:") emitln(" return '1' if a == b else ''") emitln("") emitln("def __lt(a: str, b: str) -> str:") emitln(" return '1' if a < b else ''") emitln("") emitln("def __add(a: str, b: str) -> str:") emitln(" return a + b") emitln("") emitln("def __emit(string):") emitln(" sys.stdout.buffer.write(string.encode('latin_1'))") emitln(" sys.stdout.flush()") 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(0xFF)") emitln("__EOL = chr(10)") emitln("__QUOTE = chr(34)") emitln("") emitln("STDINCOLNO = 0") emitln("STDINLINENO = 1") emitln("STDINPEEK = None") emitln("") emitln("def _readchar():") emitln(" char = sys.stdin.read(1)") emitln(" __trace('char', char)") emitln(" if not char:") emitln(" return __EOF") emitln(" return char") emitln("") emitln("def __peek():") emitln(" return STDINPEEK") emitln("") emitln("def __skip():") emitln(" global STDINCOLNO") emitln(" global STDINLINENO") emitln(" global STDINPEEK") emitln(" if __EOL == STDINPEEK:") emitln(" STDINLINENO += 1") emitln(" STDINCOLNO = 0") emitln(" STDINCOLNO += 1") emitln(" STDINPEEK = _readchar()") emitln("") emitln("def __stdinlineno():") emitln(" global STDINLINENO") emitln(" return str(STDINLINENO)") emitln("") emitln("def __stdincolno():") emitln(" global STDINCOLNO") emitln(" return str(STDINCOLNO)") emitln("") emitln("__skip()") emitln("") emitln("MAPSTORE = {}") emitln("") emitln("def __mapclear(mapname: str) -> str:") emitln(" MAPSTORE.pop(mapname)") emitln(" return ''") emitln("") emitln("def __mapgetkey(mapname: str, key: str, default: str) -> str:") emitln(" return MAPSTORE.get(mapname, {}).get(key, default)") emitln("") emitln("def __mapsetkey(mapname: str, key: str, value: str) -> str:") emitln(" MAPSTORE.setdefault(mapname, {})") emitln(" MAPSTORE[mapname][key] = value") emitln(" return ''") emitln("") emitln("def __not(a: str) -> str:") emitln(" if a:") emitln(" return ''") emitln(" return '1'") emitln("") emitln("def __check(func, args: list[str], msg: list[str]) -> None:") emitln(" result = func(*args)") emitln(" if result:") emitln(" return") emitln("") emitln(" sys.stderr.write('ERROR: ' + ' '.join(msg) + '\\n')") emitln(" sys.stderr.flush()") emitln(" exit(1)") def emitfooter(): mainname = registerid("main") emitln("if __name__ == '__main__':") emit(" ") emit(mainname) emitln("()") def main(): emitheader() # Standard library constants mapsetkey("REGISTERID", "eof", "__EOF") mapsetkey("REGISTERID", "eol", "__EOL") mapsetkey("REGISTERID", "quote", "__QUOTE") # Standard library functions mapsetkey("FUNCREG", "add", "1") mapsetkey("REGISTERID", "add", "__add") mapsetkey("FUNCREG", "emit", "1") mapsetkey("REGISTERID", "emit", "__emit") mapsetkey("FUNCREG", "eq", "1") mapsetkey("REGISTERID", "eq", "__eq") mapsetkey("FUNCREG", "lt", "1") mapsetkey("REGISTERID", "lt", "__lt") mapsetkey("FUNCREG", "not", "1") mapsetkey("REGISTERID", "not", "__not") mapsetkey("FUNCREG", "mapclear", "1") mapsetkey("REGISTERID", "mapclear", "__mapclear") mapsetkey("FUNCREG", "mapgetkey", "1") mapsetkey("REGISTERID", "mapgetkey", "__mapgetkey") mapsetkey("FUNCREG", "mapsetkey", "1") mapsetkey("REGISTERID", "mapsetkey", "__mapsetkey") mapsetkey("FUNCREG", "peek", "1") mapsetkey("REGISTERID", "peek", "__peek") mapsetkey("FUNCREG", "skip", "1") mapsetkey("REGISTERID", "skip", "__skip") mapsetkey("FUNCREG", "stdincolno", "1") mapsetkey("REGISTERID", "stdincolno", "__stdincolno") mapsetkey("FUNCREG", "stdinlineno", "1") mapsetkey("REGISTERID", "stdinlineno", "__stdinlineno") while True: if eof == peek(): break while eol == peek(): skip() parsefunc() emitfooter() if __name__ == '__main__': main()