Compare commits
1 Commits
68e3c12d80
...
7220bb82d2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7220bb82d2 |
@ -1,15 +1,18 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
def eq(a, b):
|
||||
return a == b
|
||||
|
||||
def emit(string):
|
||||
sys.stdout.buffer.write(string.encode('latin_1'))
|
||||
sys.stdout.write(string)
|
||||
sys.stdout.flush()
|
||||
|
||||
def trace(header, value):
|
||||
if os.environ.get('TRACE'):
|
||||
sys.stderr.write(f'{header}={value!r}\n')
|
||||
|
||||
eof = chr(0xFF)
|
||||
eof = chr(0)
|
||||
eol = chr(10)
|
||||
quote = chr(34)
|
||||
PEEK = None
|
||||
@ -44,10 +47,16 @@ def __check(func, args: list[str], msg: list[str]) -> None:
|
||||
if result:
|
||||
return
|
||||
|
||||
sys.stderr.write('ERROR: ' + ' '.join(msg) + '\n')
|
||||
sys.stderr.write(' '.join(msg) + '\n')
|
||||
sys.stderr.flush()
|
||||
exit(1)
|
||||
|
||||
def intinc(a: str) -> str:
|
||||
if not a:
|
||||
return "1"
|
||||
|
||||
return str(int(a) + 1)
|
||||
|
||||
MAPSTORE = {}
|
||||
|
||||
def mapclear(mapname: str) -> str:
|
||||
@ -66,7 +75,11 @@ def registerid(id: str) -> str:
|
||||
idname = mapgetkey("REGISTERID", id, "")
|
||||
if idname:
|
||||
return idname
|
||||
idname = "id_" + id
|
||||
newidx = mapgetkey("REGISTERID", "__len__", "0")
|
||||
idname = "identifier" + newidx
|
||||
mapsetkey("REGISTERID", id, idname)
|
||||
newlen = intinc(newidx)
|
||||
mapsetkey("REGISTERID", "__len__", newlen)
|
||||
return idname
|
||||
|
||||
def emitln(data):
|
||||
@ -201,8 +214,6 @@ def parsestatreturn(indent):
|
||||
parseconststring()
|
||||
else:
|
||||
parseexprvarref()
|
||||
else:
|
||||
emit('""')
|
||||
emit(eol)
|
||||
skipchar(eol)
|
||||
|
||||
@ -253,13 +264,12 @@ def parsestatcheck(indent):
|
||||
if eol == peek():
|
||||
break
|
||||
notfirst = True
|
||||
|
||||
emitln('])')
|
||||
|
||||
def parsestattrace(indent):
|
||||
skipchar(' ')
|
||||
emit(' ' * indent)
|
||||
emit('__trace("')
|
||||
emit('trace("')
|
||||
|
||||
varname = lexident()
|
||||
varid = registerid(varname)
|
||||
@ -380,7 +390,8 @@ def parsefunc():
|
||||
skipchar(':')
|
||||
skipchar(eol)
|
||||
|
||||
emitln('):')
|
||||
emit('): # ')
|
||||
emitln(funcname)
|
||||
|
||||
parseblock(1)
|
||||
|
||||
@ -390,24 +401,24 @@ 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("def __eq(a, b):")
|
||||
emitln(" return a == b")
|
||||
emitln("")
|
||||
emitln("def __lt(a: str, b: str) -> str:")
|
||||
emitln(" return '1' if a < b else ''")
|
||||
emitln("def __lt(a, b):")
|
||||
emitln(" return a[0] < b[0]")
|
||||
emitln("")
|
||||
emitln("def __add(a: str, b: str) -> str:")
|
||||
emitln(" return a + b")
|
||||
emitln("def __addstringchar(a, b):")
|
||||
emitln(" return a + b[0]")
|
||||
emitln("")
|
||||
emitln("def __emit(string):")
|
||||
emitln(" sys.stdout.buffer.write(string.encode('latin_1'))")
|
||||
emitln(" sys.stdout.write(string)")
|
||||
emitln(" sys.stdout.flush()")
|
||||
emitln("")
|
||||
emitln("def __trace(header, value):")
|
||||
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("__EOF = chr(0)")
|
||||
emitln("__EOL = chr(10)")
|
||||
emitln("__QUOTE = chr(34)")
|
||||
emitln("")
|
||||
@ -417,7 +428,7 @@ def emitheader():
|
||||
emitln("")
|
||||
emitln("def _readchar():")
|
||||
emitln(" char = sys.stdin.read(1)")
|
||||
emitln(" __trace('char', char)")
|
||||
emitln(" trace('char', char)")
|
||||
emitln(" if not char:")
|
||||
emitln(" return __EOF")
|
||||
emitln(" return char")
|
||||
@ -447,14 +458,14 @@ def emitheader():
|
||||
emitln("")
|
||||
emitln("MAPSTORE = {}")
|
||||
emitln("")
|
||||
emitln("def __mapclear(mapname: str) -> str:")
|
||||
emitln("def mapclear(mapname: str) -> str:")
|
||||
emitln(" MAPSTORE.pop(mapname)")
|
||||
emitln(" return ''")
|
||||
emitln("")
|
||||
emitln("def __mapgetkey(mapname: str, key: str, default: str) -> str:")
|
||||
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("def mapsetkey(mapname: str, key: str, value: str) -> str:")
|
||||
emitln(" MAPSTORE.setdefault(mapname, {})")
|
||||
emitln(" MAPSTORE[mapname][key] = value")
|
||||
emitln(" return ''")
|
||||
@ -469,7 +480,7 @@ def emitheader():
|
||||
emitln(" if result:")
|
||||
emitln(" return")
|
||||
emitln("")
|
||||
emitln(" sys.stderr.write('ERROR: ' + ' '.join(msg) + '\\n')")
|
||||
emitln(" sys.stderr.write(' '.join(msg) + '\\n')")
|
||||
emitln(" sys.stderr.flush()")
|
||||
emitln(" exit(1)")
|
||||
|
||||
@ -489,8 +500,8 @@ def main():
|
||||
mapsetkey("REGISTERID", "quote", "__QUOTE")
|
||||
|
||||
# Standard library functions
|
||||
mapsetkey("FUNCREG", "add", "1")
|
||||
mapsetkey("REGISTERID", "add", "__add")
|
||||
mapsetkey("FUNCREG", "addstringchar", "1")
|
||||
mapsetkey("REGISTERID", "addstringchar", "__addstringchar")
|
||||
mapsetkey("FUNCREG", "emit", "1")
|
||||
mapsetkey("REGISTERID", "emit", "__emit")
|
||||
mapsetkey("FUNCREG", "eq", "1")
|
||||
@ -500,11 +511,8 @@ def main():
|
||||
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")
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
registerid id:
|
||||
declare idname
|
||||
declare newidx
|
||||
|
||||
calc idname mapgetkey "REGISTERID" id ""
|
||||
if idname
|
||||
return idname
|
||||
/
|
||||
|
||||
calc idname add "id_" id
|
||||
return idname
|
||||
skipchar exp:
|
||||
declare act
|
||||
declare lineno
|
||||
declare colno
|
||||
calc act peek
|
||||
calc lineno stdinlineno
|
||||
calc colno stdincolno
|
||||
check eq exp act : "Unexpected character" act "expected" exp "at" lineno colno
|
||||
skip
|
||||
/
|
||||
|
||||
emitln data:
|
||||
@ -16,6 +14,14 @@ emitln 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 ""
|
||||
@ -29,28 +35,12 @@ lexident:
|
||||
if isafterz
|
||||
break
|
||||
/
|
||||
calc word add word char
|
||||
calc word addstringchar word char
|
||||
skip
|
||||
/
|
||||
return word
|
||||
/
|
||||
|
||||
skipchar exp:
|
||||
declare act
|
||||
declare lineno
|
||||
declare colno
|
||||
calc act peek
|
||||
calc lineno stdinlineno
|
||||
calc colno stdincolno
|
||||
check eq exp act : "Unexpected character" act "expected" exp "at" lineno colno
|
||||
skip
|
||||
/
|
||||
|
||||
increaseindent indent:
|
||||
calc indent add indent " "
|
||||
return indent
|
||||
/
|
||||
|
||||
parseconststring:
|
||||
skipchar quote
|
||||
emit quote
|
||||
@ -73,15 +63,12 @@ parseconststring:
|
||||
|
||||
parseexprvarref:
|
||||
calc varname lexident
|
||||
calc varid registerid varname
|
||||
emit varid
|
||||
emit varname
|
||||
/
|
||||
|
||||
parseexprcall:
|
||||
calc funcname lexident
|
||||
calc funcid registerid funcname
|
||||
check mapgetkey "FUNCREG" funcname "" : "Function" funcname "does not exist"
|
||||
emit funcid
|
||||
emit funcname
|
||||
emit "("
|
||||
set first "1"
|
||||
forever
|
||||
@ -113,18 +100,16 @@ parseexprcall:
|
||||
|
||||
parsestatdeclare indent:
|
||||
skipchar " "
|
||||
calc varname lexident
|
||||
calc varid registerid varname
|
||||
calc var lexident
|
||||
skipchar eol
|
||||
/
|
||||
|
||||
parsestatset indent:
|
||||
skipchar " "
|
||||
calc varname lexident
|
||||
calc varid registerid varname
|
||||
calc var lexident
|
||||
skipchar " "
|
||||
emit indent
|
||||
emit varid
|
||||
emit var
|
||||
emit " = "
|
||||
parseconststring
|
||||
emit eol
|
||||
@ -133,11 +118,10 @@ parsestatset indent:
|
||||
|
||||
parsestatcalc indent:
|
||||
skipchar " "
|
||||
calc varname lexident
|
||||
calc varid registerid varname
|
||||
calc var lexident
|
||||
skipchar " "
|
||||
emit indent
|
||||
emit varid
|
||||
emit var
|
||||
emit " = "
|
||||
parseexprcall
|
||||
emit eol
|
||||
@ -176,7 +160,6 @@ parsestatreturn indent:
|
||||
emit "return "
|
||||
calc char peek
|
||||
calc isspace eq char " "
|
||||
calc isnotspace not isspace
|
||||
if isspace
|
||||
skip
|
||||
calc char peek
|
||||
@ -189,10 +172,6 @@ parsestatreturn indent:
|
||||
parseexprvarref
|
||||
/
|
||||
/
|
||||
if isnotspace
|
||||
emit quote
|
||||
emit quote
|
||||
/
|
||||
emit eol
|
||||
skipchar eol
|
||||
/
|
||||
@ -207,12 +186,11 @@ parsestatcheck indent:
|
||||
|
||||
skipchar " "
|
||||
emit indent
|
||||
emit "__check("
|
||||
emit "assert "
|
||||
|
||||
calc funcname lexident
|
||||
calc funcid registerid funcname
|
||||
emit funcid
|
||||
emit ", ["
|
||||
emit funcname
|
||||
emit "("
|
||||
|
||||
set notfirst ""
|
||||
forever
|
||||
@ -242,8 +220,7 @@ parsestatcheck indent:
|
||||
|
||||
skipchar ":"
|
||||
|
||||
emit "], ["
|
||||
|
||||
emit "), ("
|
||||
set notfirst ""
|
||||
|
||||
forever
|
||||
@ -272,20 +249,19 @@ parsestatcheck indent:
|
||||
set notfirst "1"
|
||||
/
|
||||
|
||||
emitln "])"
|
||||
emitln ")"
|
||||
/
|
||||
|
||||
parsestattrace indent:
|
||||
emit indent
|
||||
emit "__trace("
|
||||
emit "trace("
|
||||
emit quote
|
||||
skipchar " "
|
||||
calc varname lexident
|
||||
calc varid registerid varname
|
||||
emit varname
|
||||
emit quote
|
||||
emit ", "
|
||||
emit varid
|
||||
emit varname
|
||||
emitln ")"
|
||||
skipchar eol
|
||||
/
|
||||
@ -338,9 +314,8 @@ parsestat indent:
|
||||
parsestatcheck indent
|
||||
return
|
||||
/
|
||||
calc callid registerid call
|
||||
emit indent
|
||||
emit callid
|
||||
emit call
|
||||
emit "("
|
||||
set first "1"
|
||||
forever
|
||||
@ -405,11 +380,9 @@ parseblock indent:
|
||||
|
||||
parsefunc:
|
||||
calc funcname lexident
|
||||
calc funcid registerid funcname
|
||||
trace funcname
|
||||
mapsetkey "FUNCREG" funcname "1"
|
||||
emit "def "
|
||||
emit funcid
|
||||
emit funcname
|
||||
emit "("
|
||||
set isnotfirst ""
|
||||
forever
|
||||
@ -420,12 +393,11 @@ parsefunc:
|
||||
break
|
||||
/
|
||||
skip
|
||||
calc varname lexident
|
||||
calc varid registerid varname
|
||||
calc var lexident
|
||||
if isnotfirst
|
||||
emit ", "
|
||||
/
|
||||
emit varid
|
||||
emit var
|
||||
set isnotfirst "1"
|
||||
/
|
||||
calc char peek
|
||||
@ -449,31 +421,26 @@ emitheader:
|
||||
emitln "import os"
|
||||
emitln "import sys"
|
||||
emitln ""
|
||||
emitln "def __eq(a: str, b: str) -> str:"
|
||||
emitln " return '1' if a == b else ''"
|
||||
emitln "def eq(a, b):"
|
||||
emitln " return a == b"
|
||||
emitln ""
|
||||
emitln "def __lt(a: str, b: str) -> str:"
|
||||
emitln " return '1' if a < b else ''"
|
||||
emitln "def lt(a, b):"
|
||||
emitln " return a[0] < b[0]"
|
||||
emitln ""
|
||||
emitln "def __not(a: str) -> str:"
|
||||
emitln " if a:"
|
||||
emitln " return ''"
|
||||
emitln " return '1'"
|
||||
emitln "def addstringchar(a, b):"
|
||||
emitln " return a + b[0]"
|
||||
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 "def emit(string):"
|
||||
emitln " sys.stdout.write(string)"
|
||||
emitln " sys.stdout.flush()"
|
||||
emitln ""
|
||||
emitln "def __trace(header, value):"
|
||||
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 "eof = chr(0)"
|
||||
emitln "eol = chr(10)"
|
||||
emitln "quote = chr(34)"
|
||||
emitln ""
|
||||
emitln "STDINCOLNO = 0"
|
||||
emitln "STDINLINENO = 1"
|
||||
@ -481,102 +448,43 @@ emitheader:
|
||||
emitln ""
|
||||
emitln "def _readchar():"
|
||||
emitln " char = sys.stdin.read(1)"
|
||||
emitln " __trace('char', char)"
|
||||
emitln " trace('char', char)"
|
||||
emitln " if not char:"
|
||||
emitln " return __EOF"
|
||||
emitln " return eof"
|
||||
emitln " return char"
|
||||
emitln ""
|
||||
emitln "def __peek():"
|
||||
emitln "def peek():"
|
||||
emitln " return STDINPEEK"
|
||||
emitln ""
|
||||
emitln "def __skip():"
|
||||
emitln "def skip():"
|
||||
emitln " global STDINCOLNO"
|
||||
emitln " global STDINLINENO"
|
||||
emitln " global STDINPEEK"
|
||||
emitln " if __EOL == STDINPEEK:"
|
||||
emitln " if eol == STDINPEEK:"
|
||||
emitln " STDINLINENO += 1"
|
||||
emitln " STDINCOLNO = 0"
|
||||
emitln " STDINCOLNO += 1"
|
||||
emitln " STDINPEEK = _readchar()"
|
||||
emitln ""
|
||||
emitln "def __stdinlineno():"
|
||||
emitln "def stdinlineno():"
|
||||
emitln " global STDINLINENO"
|
||||
emitln " return str(STDINLINENO)"
|
||||
emitln ""
|
||||
emitln "def __stdincolno():"
|
||||
emitln "def stdincolno():"
|
||||
emitln " global STDINCOLNO"
|
||||
emitln " return str(STDINCOLNO)"
|
||||
emitln ""
|
||||
emitln "__skip()"
|
||||
emitln "skip()"
|
||||
emitln ""
|
||||
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 __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)"
|
||||
/
|
||||
|
||||
emitfooter:
|
||||
declare mainname
|
||||
calc mainname registerid "main"
|
||||
|
||||
emitln "if __name__ == '__main__':"
|
||||
emit " "
|
||||
emit mainname
|
||||
emitln "()"
|
||||
emitln " main()"
|
||||
/
|
||||
|
||||
main:
|
||||
emitheader
|
||||
|
||||
mapsetkey "REGISTERID" "eof" "__EOF"
|
||||
mapsetkey "REGISTERID" "eol" "__EOL"
|
||||
mapsetkey "REGISTERID" "quote" "__QUOTE"
|
||||
|
||||
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"
|
||||
|
||||
|
||||
forever
|
||||
calc char peek
|
||||
calc iseof eq char eof
|
||||
|
||||
@ -15,7 +15,10 @@ emitln data:
|
||||
/
|
||||
|
||||
increaseindent indent:
|
||||
calc indent add indent " "
|
||||
calc indent addstringchar indent " "
|
||||
calc indent addstringchar indent " "
|
||||
calc indent addstringchar indent " "
|
||||
calc indent addstringchar indent " "
|
||||
return indent
|
||||
/
|
||||
|
||||
@ -35,7 +38,7 @@ lexident:
|
||||
if isafterz
|
||||
break
|
||||
/
|
||||
calc word add word char
|
||||
calc word addstringchar word char
|
||||
skip
|
||||
/
|
||||
return word
|
||||
@ -224,8 +227,7 @@ parsestatreturn indent:
|
||||
/
|
||||
/
|
||||
if isnotspace
|
||||
emit quote
|
||||
emit quote
|
||||
emit "0"
|
||||
/
|
||||
emit ";"
|
||||
emit eol
|
||||
@ -282,7 +284,6 @@ parsestatcheck indent:
|
||||
emit indent
|
||||
emitln "{"
|
||||
|
||||
emit indent
|
||||
emit " fprintf(stderr, "
|
||||
emit quote
|
||||
emit "%s"
|
||||
@ -320,14 +321,6 @@ parsestatcheck indent:
|
||||
/
|
||||
/
|
||||
|
||||
emit indent
|
||||
emit " fprintf(stderr, "
|
||||
emit quote
|
||||
emit "%s"
|
||||
emit quote
|
||||
emit ", var_eol"
|
||||
emitln ");"
|
||||
|
||||
emit indent
|
||||
emitln " exit(1);"
|
||||
emit indent
|
||||
@ -486,23 +479,14 @@ parsefunc:
|
||||
declare funcname
|
||||
declare iseoblock
|
||||
declare isfirst
|
||||
declare ismain
|
||||
declare isnotmain
|
||||
declare isspace
|
||||
declare isnotfirst
|
||||
declare isnotspace
|
||||
declare var
|
||||
calc funcname lexident
|
||||
calc ismain eq funcname "main"
|
||||
calc isnotmain not ismain
|
||||
trace funcname
|
||||
emit "char * "
|
||||
if ismain
|
||||
emit "__main"
|
||||
/
|
||||
if isnotmain
|
||||
emit funcname
|
||||
/
|
||||
emit funcname
|
||||
emit "("
|
||||
set first "1"
|
||||
forever
|
||||
@ -548,7 +532,7 @@ emitheader:
|
||||
emitln "#include <string.h>"
|
||||
emitln ""
|
||||
emitln ""
|
||||
emitln "char var_eof[2] = {0xFF, 0};"
|
||||
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};"
|
||||
@ -569,14 +553,14 @@ emitheader:
|
||||
emitln " return (strcmp(a, var_true) != 0) ? var_true : var_false;"
|
||||
emitln "}"
|
||||
emitln ""
|
||||
emitln "char * add(char * lft, char * rgt)"
|
||||
emitln "char * addstringchar(char * str, char * chr)"
|
||||
emitln "{"
|
||||
emitln " int lft_len = strlen(lft);"
|
||||
emitln " int rgt_len = strlen(rgt);"
|
||||
emitln " char * res = malloc((lft_len + rgt_len + 1) * sizeof(char));"
|
||||
emitln " strcpy(res, lft);"
|
||||
emitln " strcpy(res + lft_len, rgt);"
|
||||
emitln " res[lft_len + rgt_len] = 0;"
|
||||
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 ""
|
||||
@ -660,10 +644,7 @@ emitheader:
|
||||
/
|
||||
|
||||
emitfooter:
|
||||
emitln "int main() {"
|
||||
emitln " __main();"
|
||||
emitln " return 0;"
|
||||
emitln "}"
|
||||
emit ""
|
||||
return
|
||||
/
|
||||
|
||||
|
||||
@ -97,7 +97,7 @@ Exits the deepest `forever` loop.
|
||||
|
||||
#### func args*
|
||||
|
||||
Calls the function name `func` with the given arguments. The return value is ignored.
|
||||
Calls the function name `func` with the given arguments. The result, if any, is ignored.
|
||||
|
||||
#### if arg
|
||||
|
||||
@ -109,7 +109,7 @@ Repeats the block until `break` or `return` is called.
|
||||
|
||||
#### return var?
|
||||
|
||||
Returns the given value. If you don't give something to return, the function will return the empty string.
|
||||
Returns the given value. You can not give an argument if your function is never used in `call`.
|
||||
|
||||
### Builtins
|
||||
|
||||
@ -137,7 +137,9 @@ Double quote character.
|
||||
|
||||
### Standard library functions
|
||||
|
||||
#### add a b
|
||||
#### addstringchar a b
|
||||
|
||||
`b` is expected to have length 1.
|
||||
|
||||
Creates a new string with `b` appended to `a`.
|
||||
|
||||
|
||||
2
tests/.gitignore
vendored
2
tests/.gitignore
vendored
@ -1 +1 @@
|
||||
/Makefile.mk
|
||||
/*.results
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
.SUFFIXES:
|
||||
.PHONY: all clean
|
||||
.PRECIOUS: build/%.it0.py build/%.it0.c
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
PYVERSION=3.12
|
||||
@ -7,29 +8,34 @@ PYPREFIX=/usr
|
||||
CYTHON=cython3
|
||||
CC=gcc
|
||||
|
||||
all: verify-results
|
||||
# builtincheckfalse is separate since it's supposed to crash. It's a test for the test 'framework', if you will.
|
||||
TESTLIST=$(shell ls *.lang0 | grep -v -e 'builtincheckfalse' -e 'funcnotexists' | sed 's/.lang0//')
|
||||
|
||||
Makefile.mk: generate-recipes.py $(wildcard test_*/test_*)
|
||||
python3 generate-recipes.py Makefile.mk it0 it1 it2
|
||||
all: check
|
||||
|
||||
include Makefile.mk
|
||||
check: all-it0.results all-it1.results all-it2.results
|
||||
! grep -v 'Success' $^
|
||||
|
||||
all-it0.results: $(addprefix build/,$(addsuffix .it0, $(TESTLIST))) build/builtincheckfalse.it0
|
||||
-rm -f $@
|
||||
(cat funcnotexists.lang0 | ../0-lang0py/lang0py.exe 2>&1 1>/dev/null || true) | grep 'Function forgottodeclare does not exist'
|
||||
cat test-input.txt | build/builtincheckfalse.it0 2> /dev/null 2>&1 | grep 'Success'
|
||||
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; cat test-input.txt | ./build/$(test).it0 >> $@ ; echo "" >> $@ ;)
|
||||
|
||||
all-it1.results: $(addprefix build/,$(addsuffix .it1, $(TESTLIST))) build/builtincheckfalse.it1
|
||||
-rm -f $@
|
||||
cat test-input.txt | build/builtincheckfalse.it1 2> /dev/null 2>&1 | grep 'Success'
|
||||
(cat funcnotexists.lang0 | ../1-lang0py/lang0py.exe 2>&1 1>/dev/null || true) | grep 'Function forgottodeclare does not exist'
|
||||
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; cat test-input.txt | ./build/$(test).it1 >> $@ ; echo "" >> $@ ;)
|
||||
|
||||
all-it2.results: $(addprefix build/,$(addsuffix .it2, $(TESTLIST))) build/builtincheckfalse.it2
|
||||
-rm -f $@
|
||||
cat test-input.txt | build/builtincheckfalse.it2 2> /dev/null 2>&1 | grep 'Success'
|
||||
(cat funcnotexists.lang0 | ../2-lang0py/lang0c.exe 2>&1 1>/dev/null || true) | grep 'Function forgottodeclare does not exist'
|
||||
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; cat test-input.txt | ./build/$(test).it2 >> $@ ; echo "" >> $@ ;)
|
||||
|
||||
clean:
|
||||
find build -name '*.c' -delete
|
||||
find build -name '*.it0' -delete
|
||||
find build -name '*.it0.result' -delete
|
||||
find build -name '*.it0.stderr' -delete
|
||||
find build -name '*.it0.stdout' -delete
|
||||
find build -name '*.it1' -delete
|
||||
find build -name '*.it1.result' -delete
|
||||
find build -name '*.it1.stderr' -delete
|
||||
find build -name '*.it1.stdout' -delete
|
||||
find build -name '*.it2' -delete
|
||||
find build -name '*.it2.result' -delete
|
||||
find build -name '*.it2.stderr' -delete
|
||||
find build -name '*.it2.stdout' -delete
|
||||
find build -name '*.py' -delete
|
||||
find build -name '*.tmp' -delete
|
||||
-rm -f *.results build/*.it0* build/*.it1* build/*.it2*
|
||||
|
||||
###
|
||||
# it0
|
||||
|
||||
@ -3,21 +3,12 @@
|
||||
/*.it0.o
|
||||
/*.it0.py
|
||||
/*.it0.py.tmp
|
||||
/*.it0.result
|
||||
/*.it0.stderr
|
||||
/*.it0.stdout
|
||||
/*.it1
|
||||
/*.it1.c
|
||||
/*.it1.o
|
||||
/*.it1.py
|
||||
/*.it1.py.tmp
|
||||
/*.it1.result
|
||||
/*.it1.stderr
|
||||
/*.it1.stdout
|
||||
/*.it2
|
||||
/*.it2.c
|
||||
/*.it2.c.tmp
|
||||
/*.it2.o
|
||||
/*.it2.result
|
||||
/*.it2.stderr
|
||||
/*.it2.stdout
|
||||
23
tests/build/test_flow_control/.gitignore
vendored
23
tests/build/test_flow_control/.gitignore
vendored
@ -1,23 +0,0 @@
|
||||
/*.it0
|
||||
/*.it0.c
|
||||
/*.it0.o
|
||||
/*.it0.py
|
||||
/*.it0.py.tmp
|
||||
/*.it0.result
|
||||
/*.it0.stderr
|
||||
/*.it0.stdout
|
||||
/*.it1
|
||||
/*.it1.c
|
||||
/*.it1.o
|
||||
/*.it1.py
|
||||
/*.it1.py.tmp
|
||||
/*.it1.result
|
||||
/*.it1.stderr
|
||||
/*.it1.stdout
|
||||
/*.it2
|
||||
/*.it2.c
|
||||
/*.it2.c.tmp
|
||||
/*.it2.o
|
||||
/*.it2.result
|
||||
/*.it2.stderr
|
||||
/*.it2.stdout
|
||||
23
tests/build/test_parsing/.gitignore
vendored
23
tests/build/test_parsing/.gitignore
vendored
@ -1,23 +0,0 @@
|
||||
/*.it0
|
||||
/*.it0.c
|
||||
/*.it0.o
|
||||
/*.it0.py
|
||||
/*.it0.py.tmp
|
||||
/*.it0.result
|
||||
/*.it0.stderr
|
||||
/*.it0.stdout
|
||||
/*.it1
|
||||
/*.it1.c
|
||||
/*.it1.o
|
||||
/*.it1.py
|
||||
/*.it1.py.tmp
|
||||
/*.it1.result
|
||||
/*.it1.stderr
|
||||
/*.it1.stdout
|
||||
/*.it2
|
||||
/*.it2.c
|
||||
/*.it2.c.tmp
|
||||
/*.it2.o
|
||||
/*.it2.result
|
||||
/*.it2.stderr
|
||||
/*.it2.stdout
|
||||
23
tests/build/test_stdlib_constants/.gitignore
vendored
23
tests/build/test_stdlib_constants/.gitignore
vendored
@ -1,23 +0,0 @@
|
||||
/*.it0
|
||||
/*.it0.c
|
||||
/*.it0.o
|
||||
/*.it0.py
|
||||
/*.it0.py.tmp
|
||||
/*.it0.result
|
||||
/*.it0.stderr
|
||||
/*.it0.stdout
|
||||
/*.it1
|
||||
/*.it1.c
|
||||
/*.it1.o
|
||||
/*.it1.py
|
||||
/*.it1.py.tmp
|
||||
/*.it1.result
|
||||
/*.it1.stderr
|
||||
/*.it1.stdout
|
||||
/*.it2
|
||||
/*.it2.c
|
||||
/*.it2.c.tmp
|
||||
/*.it2.o
|
||||
/*.it2.result
|
||||
/*.it2.stderr
|
||||
/*.it2.stdout
|
||||
23
tests/build/test_stdlib_functions/.gitignore
vendored
23
tests/build/test_stdlib_functions/.gitignore
vendored
@ -1,23 +0,0 @@
|
||||
/*.it0
|
||||
/*.it0.c
|
||||
/*.it0.o
|
||||
/*.it0.py
|
||||
/*.it0.py.tmp
|
||||
/*.it0.result
|
||||
/*.it0.stderr
|
||||
/*.it0.stdout
|
||||
/*.it1
|
||||
/*.it1.c
|
||||
/*.it1.o
|
||||
/*.it1.py
|
||||
/*.it1.py.tmp
|
||||
/*.it1.result
|
||||
/*.it1.stderr
|
||||
/*.it1.stdout
|
||||
/*.it2
|
||||
/*.it2.c
|
||||
/*.it2.c.tmp
|
||||
/*.it2.o
|
||||
/*.it2.result
|
||||
/*.it2.stderr
|
||||
/*.it2.stdout
|
||||
23
tests/build/test_variables/.gitignore
vendored
23
tests/build/test_variables/.gitignore
vendored
@ -1,23 +0,0 @@
|
||||
/*.it0
|
||||
/*.it0.c
|
||||
/*.it0.o
|
||||
/*.it0.py
|
||||
/*.it0.py.tmp
|
||||
/*.it0.result
|
||||
/*.it0.stderr
|
||||
/*.it0.stdout
|
||||
/*.it1
|
||||
/*.it1.c
|
||||
/*.it1.o
|
||||
/*.it1.py
|
||||
/*.it1.py.tmp
|
||||
/*.it1.result
|
||||
/*.it1.stderr
|
||||
/*.it1.stdout
|
||||
/*.it2
|
||||
/*.it2.c
|
||||
/*.it2.c.tmp
|
||||
/*.it2.o
|
||||
/*.it2.result
|
||||
/*.it2.stderr
|
||||
/*.it2.stdout
|
||||
3
tests/builtincheckfalse.lang0
Normal file
3
tests/builtincheckfalse.lang0
Normal file
@ -0,0 +1,3 @@
|
||||
main:
|
||||
check not "1" : "Success"
|
||||
/
|
||||
4
tests/builtinchecktrue.lang0
Normal file
4
tests/builtinchecktrue.lang0
Normal file
@ -0,0 +1,4 @@
|
||||
main:
|
||||
check not "" : "Failure"
|
||||
emit "Success"
|
||||
/
|
||||
@ -1,7 +1,6 @@
|
||||
main:
|
||||
forever
|
||||
emit "Suc"
|
||||
break
|
||||
/
|
||||
emit "cess"
|
||||
emit "Success"
|
||||
/
|
||||
8
tests/flowiffalse.lang0
Normal file
8
tests/flowiffalse.lang0
Normal file
@ -0,0 +1,8 @@
|
||||
main:
|
||||
declare bool
|
||||
set bool ""
|
||||
if bool
|
||||
return
|
||||
/
|
||||
emit "Success"
|
||||
/
|
||||
7
tests/flowiftrue.lang0
Normal file
7
tests/flowiftrue.lang0
Normal file
@ -0,0 +1,7 @@
|
||||
main:
|
||||
declare bool
|
||||
set bool "1"
|
||||
if bool
|
||||
emit "Success"
|
||||
/
|
||||
/
|
||||
8
tests/flowreturnnothing.lang0
Normal file
8
tests/flowreturnnothing.lang0
Normal file
@ -0,0 +1,8 @@
|
||||
func:
|
||||
return
|
||||
/
|
||||
|
||||
main:
|
||||
func
|
||||
emit "Success"
|
||||
/
|
||||
11
tests/flowreturnvalue.lang0
Normal file
11
tests/flowreturnvalue.lang0
Normal file
@ -0,0 +1,11 @@
|
||||
func:
|
||||
declare result
|
||||
set result "Success"
|
||||
return result
|
||||
/
|
||||
|
||||
main:
|
||||
declare result
|
||||
calc result func
|
||||
emit result
|
||||
/
|
||||
9
tests/flowreturnvalueconstant.lang0
Normal file
9
tests/flowreturnvalueconstant.lang0
Normal file
@ -0,0 +1,9 @@
|
||||
func:
|
||||
return "Success"
|
||||
/
|
||||
|
||||
main:
|
||||
declare result
|
||||
calc result func
|
||||
emit result
|
||||
/
|
||||
4
tests/funcnotexists.lang0
Normal file
4
tests/funcnotexists.lang0
Normal file
@ -0,0 +1,4 @@
|
||||
main:
|
||||
declare foo
|
||||
calc foo forgottodeclare "1" "2"
|
||||
/
|
||||
@ -1,106 +0,0 @@
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
|
||||
class Rule:
|
||||
def __init__(self, target: str, prerequisites: list[str], recipe: list[str]) -> None:
|
||||
self.target = target
|
||||
self.prerequisites = prerequisites
|
||||
self.recipe = recipe
|
||||
|
||||
def make_lines(self):
|
||||
return [
|
||||
self.target + ': ' + ' '.join(self.prerequisites),
|
||||
] + [
|
||||
'\t' + line
|
||||
for line in self.recipe
|
||||
] + ['']
|
||||
|
||||
def get_file_list():
|
||||
return sorted(glob.glob('test_*/*.lang0'))
|
||||
|
||||
def make_rules(file_path, lang0it):
|
||||
result: list[Rule] = []
|
||||
|
||||
stdin = file_path.replace('.lang0', '.stdin')
|
||||
exp_stdout = file_path.replace('.lang0', '.exp.stdout')
|
||||
exp_stderr = file_path.replace('.lang0', '.exp.stderr')
|
||||
|
||||
act_result = 'build/' + file_path.replace('.lang0', f'.{lang0it}.result')
|
||||
act_stderr = 'build/' + file_path.replace('.lang0', f'.{lang0it}.stderr')
|
||||
act_stdout = 'build/' + file_path.replace('.lang0', f'.{lang0it}.stdout')
|
||||
program = 'build/' + file_path.replace('.lang0', f'.{lang0it}')
|
||||
|
||||
if os.path.isfile(exp_stdout) or os.path.isfile(exp_stderr):
|
||||
result.append(Rule(
|
||||
act_stdout,
|
||||
[program] + ([stdin] if os.path.isfile(stdin) else []),
|
||||
[
|
||||
'-' + (f'cat {stdin} | ' if os.path.isfile(stdin) else 'echo x | ')
|
||||
+ f'{program} 1> {act_stdout} 2> {act_stderr}',
|
||||
]
|
||||
))
|
||||
|
||||
exp_list = [exp_stdout, exp_stderr]
|
||||
act_list = [act_stdout, act_stderr]
|
||||
|
||||
result.append(Rule(
|
||||
act_result,
|
||||
[act_stdout] + [
|
||||
x
|
||||
for x in exp_list
|
||||
if os.path.isfile(x)
|
||||
],
|
||||
[
|
||||
'rm -f $@',
|
||||
] + [
|
||||
f'-diff {exp_file} {act_file} >> $@'
|
||||
for exp_file, act_file in zip(exp_list, act_list, strict=True)
|
||||
if os.path.isfile(exp_file)
|
||||
] + [
|
||||
f'-diff /dev/null {act_file} >> $@'
|
||||
for exp_file, act_file in zip(exp_list, act_list, strict=True)
|
||||
if not os.path.isfile(exp_file)
|
||||
]
|
||||
))
|
||||
|
||||
assert result[-1].prerequisites, f'Missing expectations for {file_path}'
|
||||
|
||||
return result
|
||||
|
||||
def main(program, write_to, *lang0it):
|
||||
rule_list_list = [
|
||||
make_rules(file_path, it)
|
||||
for file_path in get_file_list()
|
||||
for it in lang0it
|
||||
]
|
||||
|
||||
result_targets = [
|
||||
rule.target
|
||||
for rule_list in rule_list_list
|
||||
for rule in rule_list
|
||||
if rule.target.endswith('.result')
|
||||
]
|
||||
|
||||
rule_list_list.append([Rule(
|
||||
'verify-results',
|
||||
result_targets,
|
||||
[
|
||||
'@echo Finding failed test results...',
|
||||
'@find $^ -not -empty -print -exec false {} +',
|
||||
'@echo All tests passed.'
|
||||
]
|
||||
)])
|
||||
|
||||
data = '\n'.join(
|
||||
line
|
||||
for rule_list in rule_list_list
|
||||
for rule in rule_list
|
||||
for line in rule.make_lines()
|
||||
)
|
||||
|
||||
with open(write_to, 'wt', encoding='ASCII') as fil:
|
||||
fil.write(data)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(*sys.argv)
|
||||
10
tests/parsingpredeclaredfunction0.lang0
Normal file
10
tests/parsingpredeclaredfunction0.lang0
Normal file
@ -0,0 +1,10 @@
|
||||
func/
|
||||
|
||||
main:
|
||||
check func : "The function should return 1, even though it is not defined yet"
|
||||
emit "Success"
|
||||
/
|
||||
|
||||
func:
|
||||
return "1"
|
||||
/
|
||||
10
tests/parsingpredeclaredfunction1.lang0
Normal file
10
tests/parsingpredeclaredfunction1.lang0
Normal file
@ -0,0 +1,10 @@
|
||||
func arg/
|
||||
|
||||
main:
|
||||
check func "1" : "The function should return 1, even though it is not defined yet"
|
||||
emit "Success"
|
||||
/
|
||||
|
||||
func arg:
|
||||
return arg
|
||||
/
|
||||
86
tests/stdinlineno.lang0
Normal file
86
tests/stdinlineno.lang0
Normal file
@ -0,0 +1,86 @@
|
||||
main:
|
||||
declare char
|
||||
declare colno
|
||||
declare lineno
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char "H" : "Read: H" char
|
||||
check eq colno "1" : "The column number should not have advanced yet" colno
|
||||
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char "e" : "Read: e" char
|
||||
check eq colno "2" : "The column number should have been advanced by 1" colno
|
||||
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char "l" : "Read: l" char
|
||||
check eq colno "3" : "The column number should have been advanced by 2" colno
|
||||
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char "l" : "Read: l" char
|
||||
check eq colno "4" : "The column number should have been advanced by 3" colno
|
||||
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char "o" : "Read: o" char
|
||||
check eq colno "5" : "The column number should have been advanced by 4" colno
|
||||
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char "!" : "Read: !" char
|
||||
check eq colno "6" : "The column number should have been advanced by 5" colno
|
||||
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char eol : "Read: eol" char
|
||||
check eq colno "7" : "The column number should have been advanced by 6" colno
|
||||
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char eol : "Read: eol" char
|
||||
check eq colno "1" : "The column number should have been reset" colno
|
||||
check eq lineno "2" : "The line number should have advanced by 1" lineno
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char "T" : "Read: T" char
|
||||
check eq colno "1" : "The column number should have been reset again" colno
|
||||
check eq lineno "3" : "The line number should have advanced by 2" lineno
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
calc lineno stdinlineno
|
||||
check eq char "h" : "Read: h" char
|
||||
check eq colno "2" : "The line number should not have been advanced by 1" colno
|
||||
check eq lineno "3" : "The line number should not have advanced further" lineno
|
||||
|
||||
emit "Success"
|
||||
/
|
||||
6
tests/stdlibaddstringchar.lang0
Normal file
6
tests/stdlibaddstringchar.lang0
Normal file
@ -0,0 +1,6 @@
|
||||
main:
|
||||
declare result
|
||||
calc result addstringchar "abc" "d"
|
||||
check eq result "abcd" : "Adding abc and d should be abcd"
|
||||
emit "Success"
|
||||
/
|
||||
3
tests/stdlibemit.lang0
Normal file
3
tests/stdlibemit.lang0
Normal file
@ -0,0 +1,3 @@
|
||||
main:
|
||||
emit "Success"
|
||||
/
|
||||
6
tests/stdlibeqfalse.lang0
Normal file
6
tests/stdlibeqfalse.lang0
Normal file
@ -0,0 +1,6 @@
|
||||
main:
|
||||
declare bool
|
||||
calc bool eq "1" "2"
|
||||
check not bool : "1 should not equal 2"
|
||||
emit "Success"
|
||||
/
|
||||
5
tests/stdlibeqtrue.lang0
Normal file
5
tests/stdlibeqtrue.lang0
Normal file
@ -0,0 +1,5 @@
|
||||
main:
|
||||
declare bool
|
||||
check eq "1" "1" : "1 should equal 1"
|
||||
emit "Success"
|
||||
/
|
||||
6
tests/stdlibltfalse.lang0
Normal file
6
tests/stdlibltfalse.lang0
Normal file
@ -0,0 +1,6 @@
|
||||
main:
|
||||
declare bool
|
||||
calc bool lt "b" "a"
|
||||
check not bool : "a should should sort before b"
|
||||
emit "Success"
|
||||
/
|
||||
5
tests/stdliblttrue.lang0
Normal file
5
tests/stdliblttrue.lang0
Normal file
@ -0,0 +1,5 @@
|
||||
main:
|
||||
declare bool
|
||||
check lt "a" "b" : "a should should sort before b"
|
||||
emit "Success"
|
||||
/
|
||||
6
tests/stdlibpeek.lang0
Normal file
6
tests/stdlibpeek.lang0
Normal file
@ -0,0 +1,6 @@
|
||||
main:
|
||||
declare char
|
||||
calc char peek
|
||||
check eq char "H" : "The first byte we're passed is expected to be an 'H'"
|
||||
emit "Success"
|
||||
/
|
||||
12
tests/stdlibskip.lang0
Normal file
12
tests/stdlibskip.lang0
Normal file
@ -0,0 +1,12 @@
|
||||
main:
|
||||
declare char
|
||||
skip
|
||||
calc char peek
|
||||
check eq char "e" : "The second byte we're passed is expected to be an 'e'"
|
||||
skip
|
||||
skip
|
||||
skip
|
||||
calc char peek
|
||||
check eq char "o" : "The fifth byte we're passed is expected to be an 'o'"
|
||||
emit "Success"
|
||||
/
|
||||
3
tests/test-input.txt
Normal file
3
tests/test-input.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Hello!
|
||||
|
||||
This is an example of standard input.
|
||||
@ -1 +0,0 @@
|
||||
ERROR: Check failed successfully
|
||||
@ -1 +0,0 @@
|
||||
Still alive
|
||||
@ -1,8 +0,0 @@
|
||||
main:
|
||||
check not "" : "This should not trigger"
|
||||
emit "Still alive"
|
||||
emit eol
|
||||
check not "1" : "Check failed successfully"
|
||||
emit "This should not be output"
|
||||
emit eol
|
||||
/
|
||||
@ -1 +0,0 @@
|
||||
Success
|
||||
@ -1 +0,0 @@
|
||||
Success
|
||||
@ -1,2 +0,0 @@
|
||||
1 is true
|
||||
A is true
|
||||
@ -1,18 +0,0 @@
|
||||
main:
|
||||
declare bool
|
||||
set bool ""
|
||||
if bool
|
||||
emit "empty string is true"
|
||||
emit eol
|
||||
/
|
||||
set bool "1"
|
||||
if bool
|
||||
emit "1 is true"
|
||||
emit eol
|
||||
/
|
||||
set bool "A"
|
||||
if bool
|
||||
emit "A is true"
|
||||
emit eol
|
||||
/
|
||||
/
|
||||
@ -1,3 +0,0 @@
|
||||
funca Constant
|
||||
funcb Variable
|
||||
funcc
|
||||
@ -1,32 +0,0 @@
|
||||
funca:
|
||||
return "Constant"
|
||||
/
|
||||
|
||||
funcb:
|
||||
declare var
|
||||
set var "Variable"
|
||||
return var
|
||||
/
|
||||
|
||||
funcc:
|
||||
return
|
||||
/
|
||||
|
||||
main:
|
||||
declare var
|
||||
|
||||
calc var funca
|
||||
emit "funca "
|
||||
emit var
|
||||
emit eol
|
||||
|
||||
calc var funcb
|
||||
emit "funcb "
|
||||
emit var
|
||||
emit eol
|
||||
|
||||
calc var funcc
|
||||
emit "funcc "
|
||||
emit var
|
||||
emit eol
|
||||
/
|
||||
@ -1,2 +0,0 @@
|
||||
Predeclared without argument: 1
|
||||
Predeclared with argument: 2
|
||||
@ -1,24 +0,0 @@
|
||||
funca/
|
||||
funcb arg/
|
||||
|
||||
main:
|
||||
declare var
|
||||
|
||||
calc var funca
|
||||
emit "Predeclared without argument: "
|
||||
emit var
|
||||
emit eol
|
||||
|
||||
calc var funcb "2"
|
||||
emit "Predeclared with argument: "
|
||||
emit var
|
||||
emit eol
|
||||
/
|
||||
|
||||
funca:
|
||||
return "1"
|
||||
/
|
||||
|
||||
funcb arg:
|
||||
return arg
|
||||
/
|
||||
@ -1 +0,0 @@
|
||||
<EFBFBD>
|
||||
@ -1,3 +0,0 @@
|
||||
main:
|
||||
emit eof
|
||||
/
|
||||
@ -1 +0,0 @@
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
main:
|
||||
emit eol
|
||||
/
|
||||
@ -1 +0,0 @@
|
||||
"
|
||||
@ -1,3 +0,0 @@
|
||||
main:
|
||||
emit quote
|
||||
/
|
||||
@ -1,3 +0,0 @@
|
||||
1 + 2 = 12
|
||||
10 + 20 = 1020
|
||||
101 + 202 = 101202
|
||||
@ -1,29 +0,0 @@
|
||||
func tst a b:
|
||||
declare var
|
||||
calc var add a b
|
||||
emit a
|
||||
emit " + "
|
||||
emit b
|
||||
emit " = "
|
||||
emit var
|
||||
emit eol
|
||||
/
|
||||
|
||||
main:
|
||||
declare var
|
||||
|
||||
calc var add "1" "2"
|
||||
emit "1 + 2 = "
|
||||
emit var
|
||||
emit eol
|
||||
|
||||
calc var add "10" "20"
|
||||
emit "10 + 20 = "
|
||||
emit var
|
||||
emit eol
|
||||
|
||||
calc var add "101" "202"
|
||||
emit "101 + 202 = "
|
||||
emit var
|
||||
emit eol
|
||||
/
|
||||
@ -1 +0,0 @@
|
||||
Hello, world!
|
||||
@ -1,4 +0,0 @@
|
||||
main:
|
||||
emit "Hello"
|
||||
emit ", world!"
|
||||
/
|
||||
@ -1,4 +0,0 @@
|
||||
eq A A: 1
|
||||
eq A B:
|
||||
eq AA AA: 1
|
||||
eq AA AB:
|
||||
@ -1,19 +0,0 @@
|
||||
main:
|
||||
declare result
|
||||
emit "eq A A: "
|
||||
calc result eq "A" "A"
|
||||
emit result
|
||||
emit eol
|
||||
emit "eq A B: "
|
||||
calc result eq "A" "B"
|
||||
emit result
|
||||
emit eol
|
||||
emit "eq AA AA: "
|
||||
calc result eq "AA" "AA"
|
||||
emit result
|
||||
emit eol
|
||||
emit "eq AA AB: "
|
||||
calc result eq "AA" "AB"
|
||||
emit result
|
||||
emit eol
|
||||
/
|
||||
@ -1,6 +0,0 @@
|
||||
lt A A:
|
||||
lt A B: 1
|
||||
lt B A:
|
||||
lt AA AA:
|
||||
lt AA AB: 1
|
||||
lt AB AA:
|
||||
@ -1,27 +0,0 @@
|
||||
main:
|
||||
declare result
|
||||
emit "lt A A: "
|
||||
calc result lt "A" "A"
|
||||
emit result
|
||||
emit eol
|
||||
emit "lt A B: "
|
||||
calc result lt "A" "B"
|
||||
emit result
|
||||
emit eol
|
||||
emit "lt B A: "
|
||||
calc result lt "B" "A"
|
||||
emit result
|
||||
emit eol
|
||||
emit "lt AA AA: "
|
||||
calc result lt "AA" "AA"
|
||||
emit result
|
||||
emit eol
|
||||
emit "lt AA AB: "
|
||||
calc result lt "AA" "AB"
|
||||
emit result
|
||||
emit eol
|
||||
emit "lt AB AA: "
|
||||
calc result lt "AB" "AA"
|
||||
emit result
|
||||
emit eol
|
||||
/
|
||||
@ -1 +0,0 @@
|
||||
AAA
|
||||
@ -1,9 +0,0 @@
|
||||
main:
|
||||
declare char
|
||||
calc char peek
|
||||
emit char
|
||||
calc char peek
|
||||
emit char
|
||||
calc char peek
|
||||
emit char
|
||||
/
|
||||
@ -1 +0,0 @@
|
||||
ABC
|
||||
@ -1 +0,0 @@
|
||||
ABD
|
||||
@ -1,12 +0,0 @@
|
||||
main:
|
||||
declare char
|
||||
calc char peek
|
||||
emit char
|
||||
skip
|
||||
calc char peek
|
||||
emit char
|
||||
skip
|
||||
skip
|
||||
calc char peek
|
||||
emit char
|
||||
/
|
||||
@ -1 +0,0 @@
|
||||
ABCD
|
||||
@ -1,4 +0,0 @@
|
||||
"A" 1
|
||||
"
|
||||
" 2
|
||||
"B" 1
|
||||
@ -1,35 +0,0 @@
|
||||
main:
|
||||
declare char
|
||||
declare colno
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
emit quote
|
||||
emit char
|
||||
emit quote
|
||||
emit " "
|
||||
emit colno
|
||||
emit eol
|
||||
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
emit quote
|
||||
emit char
|
||||
emit quote
|
||||
emit " "
|
||||
emit colno
|
||||
emit eol
|
||||
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc colno stdincolno
|
||||
emit quote
|
||||
emit char
|
||||
emit quote
|
||||
emit " "
|
||||
emit colno
|
||||
emit eol
|
||||
/
|
||||
@ -1,3 +0,0 @@
|
||||
A
|
||||
B
|
||||
C
|
||||
@ -1,4 +0,0 @@
|
||||
"A" 1
|
||||
"
|
||||
" 1
|
||||
"B" 2
|
||||
@ -1,35 +0,0 @@
|
||||
main:
|
||||
declare char
|
||||
declare lineno
|
||||
|
||||
calc char peek
|
||||
calc lineno stdinlineno
|
||||
emit quote
|
||||
emit char
|
||||
emit quote
|
||||
emit " "
|
||||
emit lineno
|
||||
emit eol
|
||||
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc lineno stdinlineno
|
||||
emit quote
|
||||
emit char
|
||||
emit quote
|
||||
emit " "
|
||||
emit lineno
|
||||
emit eol
|
||||
|
||||
skip
|
||||
|
||||
calc char peek
|
||||
calc lineno stdinlineno
|
||||
emit quote
|
||||
emit char
|
||||
emit quote
|
||||
emit " "
|
||||
emit lineno
|
||||
emit eol
|
||||
/
|
||||
@ -1,3 +0,0 @@
|
||||
A
|
||||
B
|
||||
C
|
||||
@ -1 +0,0 @@
|
||||
Success
|
||||
@ -1 +0,0 @@
|
||||
Success
|
||||
Loading…
x
Reference in New Issue
Block a user