Extends the test framework to prepare for compilation tests

Feat: add now can add two full strings

Fix: it2 would have different working for emit eof

Fix: eq and lt would return bools on it0 and it1

Fix: Functions always return something (there is no such
thing as an empty type).

Fix: Return value from main is now always ignored.

Fix: Output from check is same on all iterations
This commit is contained in:
Johan B.W. de Vries 2025-05-04 12:40:40 +02:00
parent 1b8333fcfa
commit 6055cddab2
75 changed files with 660 additions and 282 deletions

View File

@ -2,14 +2,14 @@ import os
import sys import sys
def emit(string): def emit(string):
sys.stdout.write(string) sys.stdout.buffer.write(string.encode('latin_1'))
sys.stdout.flush() sys.stdout.flush()
def trace(header, value): def trace(header, value):
if os.environ.get('TRACE'): if os.environ.get('TRACE'):
sys.stderr.write(f'{header}={value!r}\n') sys.stderr.write(f'{header}={value!r}\n')
eof = chr(0) eof = chr(0xFF)
eol = chr(10) eol = chr(10)
quote = chr(34) quote = chr(34)
PEEK = None PEEK = None
@ -166,13 +166,15 @@ def parsestatreturn(indent):
parseconststring() parseconststring()
else: else:
parseexprvarref() parseexprvarref()
else:
emit('""')
emit(eol) emit(eol)
skipchar(eol) skipchar(eol)
def parsestatcheck(indent): def parsestatcheck(indent):
skipchar(' ') skipchar(' ')
emit(' ' * indent) emit(' ' * indent)
emit('assert ') emit('if not ')
func_name = lexident() func_name = lexident()
emit(func_name) emit(func_name)
@ -197,7 +199,9 @@ def parsestatcheck(indent):
skipchar(':') skipchar(':')
emit('), (') emitln('):')
emit(' ' * (indent + 1))
emit('sys.stderr.write(\' \'.join(["ERROR:", ')
notfirst = False notfirst = False
while True: while True:
@ -214,7 +218,11 @@ def parsestatcheck(indent):
if eol == peek(): if eol == peek():
break break
notfirst = True notfirst = True
emitln(')') emitln(']))')
emit(' ' * (indent + 1))
emitln('sys.stderr.write(eol)')
emit(' ' * (indent + 1))
emitln('sys.exit(1)')
def parsestattrace(indent): def parsestattrace(indent):
skipchar(' ') skipchar(' ')
@ -344,24 +352,24 @@ def emitheader():
emitln("import os") emitln("import os")
emitln("import sys") emitln("import sys")
emitln("") emitln("")
emitln("def eq(a, b):") emitln("def eq(a: str, b: str) -> str:")
emitln(" return a == b") emitln(" return '1' if a == b else ''")
emitln("") emitln("")
emitln("def lt(a, b):") emitln("def lt(a: str, b: str) -> str:")
emitln(" return a[0] < b[0]") emitln(" return '1' if a < b else ''")
emitln("") emitln("")
emitln("def addstringchar(a, b):") emitln("def add(a: str, b: str) -> str:")
emitln(" return a + b[0]") emitln(" return a + b")
emitln("") emitln("")
emitln("def emit(string):") emitln("def emit(string):")
emitln(" sys.stdout.write(string)") emitln(" sys.stdout.buffer.write(string.encode('latin_1'))")
emitln(" sys.stdout.flush()") emitln(" sys.stdout.flush()")
emitln("") emitln("")
emitln("def trace(header, value):") emitln("def trace(header, value):")
emitln(" if os.environ.get('TRACE'):") emitln(" if os.environ.get('TRACE'):")
emitln(" sys.stderr.write(f'{header}={value!r}\\n')") emitln(" sys.stderr.write(f'{header}={value!r}\\n')")
emitln("") emitln("")
emitln("eof = chr(0)") emitln("eof = chr(0xFF)")
emitln("eol = chr(10)") emitln("eol = chr(10)")
emitln("quote = chr(34)") emitln("quote = chr(34)")
emitln("") emitln("")

View File

@ -15,10 +15,7 @@ emitln data:
/ /
increaseindent indent: increaseindent indent:
calc indent addstringchar indent " " calc indent add indent " "
calc indent addstringchar indent " "
calc indent addstringchar indent " "
calc indent addstringchar indent " "
return indent return indent
/ /
@ -35,7 +32,7 @@ lexident:
if isafterz if isafterz
break break
/ /
calc word addstringchar word char calc word add word char
skip skip
/ /
return word return word
@ -160,6 +157,7 @@ parsestatreturn indent:
emit "return " emit "return "
calc char peek calc char peek
calc isspace eq char " " calc isspace eq char " "
calc isnotspace not isspace
if isspace if isspace
skip skip
calc char peek calc char peek
@ -172,6 +170,10 @@ parsestatreturn indent:
parseexprvarref parseexprvarref
/ /
/ /
if isnotspace
emit quote
emit quote
/
emit eol emit eol
skipchar eol skipchar eol
/ /
@ -186,7 +188,7 @@ parsestatcheck indent:
skipchar " " skipchar " "
emit indent emit indent
emit "assert " emit "if not "
calc funcname lexident calc funcname lexident
emit funcname emit funcname
@ -220,7 +222,11 @@ parsestatcheck indent:
skipchar ":" skipchar ":"
emit "), (" emitln "):"
calc indent increaseindent indent
emit indent
emit "sys.stderr.write(' '.join(['ERROR:', "
set notfirst "" set notfirst ""
forever forever
@ -249,7 +255,11 @@ parsestatcheck indent:
set notfirst "1" set notfirst "1"
/ /
emitln ")" emitln "]))"
emit indent
emitln "sys.stderr.write(eol)"
emit indent
emitln "sys.exit(1)"
/ /
parsestattrace indent: parsestattrace indent:
@ -421,24 +431,24 @@ emitheader:
emitln "import os" emitln "import os"
emitln "import sys" emitln "import sys"
emitln "" emitln ""
emitln "def eq(a, b):" emitln "def eq(a: str, b: str) -> str:"
emitln " return a == b" emitln " return '1' if a == b else ''"
emitln "" emitln ""
emitln "def lt(a, b):" emitln "def lt(a: str, b: str) -> str:"
emitln " return a[0] < b[0]" emitln " return '1' if a < b else ''"
emitln "" emitln ""
emitln "def addstringchar(a, b):" emitln "def add(a: str, b :str) -> str:"
emitln " return a + b[0]" emitln " return a + b"
emitln "" emitln ""
emitln "def emit(string):" emitln "def emit(string):"
emitln " sys.stdout.write(string)" emitln " sys.stdout.buffer.write(string.encode('latin_1'))"
emitln " sys.stdout.flush()" emitln " sys.stdout.flush()"
emitln "" emitln ""
emitln "def trace(header, value):" emitln "def trace(header, value):"
emitln " if os.environ.get('TRACE'):" emitln " if os.environ.get('TRACE'):"
emitln " sys.stderr.write(f'{header}={value!r}\\n')" emitln " sys.stderr.write(f'{header}={value!r}\\n')"
emitln "" emitln ""
emitln "eof = chr(0)" emitln "eof = chr(0xFF)"
emitln "eol = chr(10)" emitln "eol = chr(10)"
emitln "quote = chr(34)" emitln "quote = chr(34)"
emitln "" emitln ""

View File

@ -15,10 +15,7 @@ emitln data:
/ /
increaseindent indent: increaseindent indent:
calc indent addstringchar indent " " calc indent add indent " "
calc indent addstringchar indent " "
calc indent addstringchar indent " "
calc indent addstringchar indent " "
return indent return indent
/ /
@ -38,7 +35,7 @@ lexident:
if isafterz if isafterz
break break
/ /
calc word addstringchar word char calc word add word char
skip skip
/ /
return word return word
@ -227,7 +224,8 @@ parsestatreturn indent:
/ /
/ /
if isnotspace if isnotspace
emit "0" emit quote
emit quote
/ /
emit ";" emit ";"
emit eol emit eol
@ -284,6 +282,7 @@ parsestatcheck indent:
emit indent emit indent
emitln "{" emitln "{"
emit indent
emit " fprintf(stderr, " emit " fprintf(stderr, "
emit quote emit quote
emit "%s" emit "%s"
@ -321,6 +320,14 @@ parsestatcheck indent:
/ /
/ /
emit indent
emit " fprintf(stderr, "
emit quote
emit "%s"
emit quote
emit ", var_eol"
emitln ");"
emit indent emit indent
emitln " exit(1);" emitln " exit(1);"
emit indent emit indent
@ -479,14 +486,23 @@ parsefunc:
declare funcname declare funcname
declare iseoblock declare iseoblock
declare isfirst declare isfirst
declare ismain
declare isnotmain
declare isspace declare isspace
declare isnotfirst declare isnotfirst
declare isnotspace declare isnotspace
declare var declare var
calc funcname lexident calc funcname lexident
calc ismain eq funcname "main"
calc isnotmain not ismain
trace funcname trace funcname
emit "char * " emit "char * "
if ismain
emit "__main"
/
if isnotmain
emit funcname emit funcname
/
emit "(" emit "("
set first "1" set first "1"
forever forever
@ -532,7 +548,7 @@ emitheader:
emitln "#include <string.h>" emitln "#include <string.h>"
emitln "" emitln ""
emitln "" emitln ""
emitln "char var_eof[2] = {-1, 0};" emitln "char var_eof[2] = {0xFF, 0};"
emitln "char var_eol[2] = {10, 0};" emitln "char var_eol[2] = {10, 0};"
emitln "char var_quote[2] = {34, 0};" emitln "char var_quote[2] = {34, 0};"
emitln "char var_false[1] = {0};" emitln "char var_false[1] = {0};"
@ -553,14 +569,14 @@ emitheader:
emitln " return (strcmp(a, var_true) != 0) ? var_true : var_false;" emitln " return (strcmp(a, var_true) != 0) ? var_true : var_false;"
emitln "}" emitln "}"
emitln "" emitln ""
emitln "char * addstringchar(char * str, char * chr)" emitln "char * add(char * lft, char * rgt)"
emitln "{" emitln "{"
emitln " int str_len = strlen(str);" emitln " int lft_len = strlen(lft);"
emitln " assert(strlen(chr) == 1);" emitln " int rgt_len = strlen(rgt);"
emitln " char * res = malloc((str_len + 2) * sizeof(char));" emitln " char * res = malloc((lft_len + rgt_len + 1) * sizeof(char));"
emitln " strcpy(res, str);" emitln " strcpy(res, lft);"
emitln " res[str_len + 0] = chr[0];" emitln " strcpy(res + lft_len, rgt);"
emitln " res[str_len + 1] = 0;" emitln " res[lft_len + rgt_len] = 0;"
emitln " return res;" emitln " return res;"
emitln "}" emitln "}"
emitln "" emitln ""
@ -644,7 +660,10 @@ emitheader:
/ /
emitfooter: emitfooter:
emit "" emitln "int main() {"
emitln " __main();"
emitln " return 0;"
emitln "}"
return return
/ /

View File

@ -97,7 +97,7 @@ Exits the deepest `forever` loop.
#### func args* #### func args*
Calls the function name `func` with the given arguments. The result, if any, is ignored. Calls the function name `func` with the given arguments. The return value is ignored.
#### if arg #### if arg
@ -109,7 +109,7 @@ Repeats the block until `break` or `return` is called.
#### return var? #### return var?
Returns the given value. You can not give an argument if your function is never used in `call`. Returns the given value. If you don't give something to return, the function will return the empty string.
### Builtins ### Builtins
@ -121,11 +121,23 @@ Calls the given function with the given arguments. If the function's return valu
Writes the name and value of the variable passed to stderr if the TRACE environment variable is set. Writes the name and value of the variable passed to stderr if the TRACE environment variable is set.
### Standard library constants
#### eof
End of file character, zero byte.
#### eol
End of line character.
#### quote
Double quote character.
### Standard library functions ### Standard library functions
#### addstringchar a b #### add a b
`b` is expected to have length 1.
Creates a new string with `b` appended to `a`. Creates a new string with `b` appended to `a`.

2
tests/.gitignore vendored
View File

@ -1 +1 @@
/*.results /Makefile.mk

View File

@ -1,6 +1,5 @@
.SUFFIXES: .SUFFIXES:
.PHONY: all clean .PHONY: all clean
.PRECIOUS: build/%.it0.py build/%.it0.c
.DELETE_ON_ERROR: .DELETE_ON_ERROR:
PYVERSION=3.12 PYVERSION=3.12
@ -8,31 +7,29 @@ PYPREFIX=/usr
CYTHON=cython3 CYTHON=cython3
CC=gcc CC=gcc
# builtincheckfalse is separate since it's supposed to crash. It's a test for the test 'framework', if you will. all: verify-results
TESTLIST=$(shell ls *.lang0 | grep -v 'builtincheckfalse' | sed 's/.lang0//')
all: check Makefile.mk: generate-recipes.py $(wildcard test_*/test_*)
python3 generate-recipes.py Makefile.mk it0 it1 it2
check: all-it0.results all-it1.results all-it2.results include Makefile.mk
! grep -v 'Success' $^
all-it0.results: $(addprefix build/,$(addsuffix .it0, $(TESTLIST))) build/builtincheckfalse.it0
-rm -f $@
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'
$(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'
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; cat test-input.txt | ./build/$(test).it2 >> $@ ; echo "" >> $@ ;)
clean: clean:
-rm -f *.results build/*.it0* build/*.it1* build/*.it2* 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
### ###
# it0 # it0

View File

@ -3,12 +3,21 @@
/*.it0.o /*.it0.o
/*.it0.py /*.it0.py
/*.it0.py.tmp /*.it0.py.tmp
/*.it0.result
/*.it0.stderr
/*.it0.stdout
/*.it1 /*.it1
/*.it1.c /*.it1.c
/*.it1.o /*.it1.o
/*.it1.py /*.it1.py
/*.it1.py.tmp /*.it1.py.tmp
/*.it1.result
/*.it1.stderr
/*.it1.stdout
/*.it2 /*.it2
/*.it2.c /*.it2.c
/*.it2.c.tmp /*.it2.c.tmp
/*.it2.o /*.it2.o
/*.it2.result
/*.it2.stderr
/*.it2.stdout

View File

@ -0,0 +1,23 @@
/*.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 Normal file
View File

@ -0,0 +1,23 @@
/*.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

View File

@ -0,0 +1,23 @@
/*.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

View File

@ -0,0 +1,23 @@
/*.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 Normal file
View File

@ -0,0 +1,23 @@
/*.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

View File

@ -1,3 +0,0 @@
main:
check not "1" : "Success"
/

View File

@ -1,4 +0,0 @@
main:
check not "" : "Failure"
emit "Success"
/

View File

@ -1,8 +0,0 @@
main:
declare bool
set bool ""
if bool
return
/
emit "Success"
/

View File

@ -1,7 +0,0 @@
main:
declare bool
set bool "1"
if bool
emit "Success"
/
/

View File

@ -1,8 +0,0 @@
func:
return
/
main:
func
emit "Success"
/

View File

@ -1,11 +0,0 @@
func:
declare result
set result "Success"
return result
/
main:
declare result
calc result func
emit result
/

View File

@ -1,9 +0,0 @@
func:
return "Success"
/
main:
declare result
calc result func
emit result
/

106
tests/generate-recipes.py Normal file
View File

@ -0,0 +1,106 @@
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)

View File

@ -1,10 +0,0 @@
func/
main:
check func : "The function should return 1, even though it is not defined yet"
emit "Success"
/
func:
return "1"
/

View File

@ -1,10 +0,0 @@
func arg/
main:
check func "1" : "The function should return 1, even though it is not defined yet"
emit "Success"
/
func arg:
return arg
/

View File

@ -1,86 +0,0 @@
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"
/

View File

@ -1,6 +0,0 @@
main:
declare result
calc result addstringchar "abc" "d"
check eq result "abcd" : "Adding abc and d should be abcd"
emit "Success"
/

View File

@ -1,3 +0,0 @@
main:
emit "Success"
/

View File

@ -1,6 +0,0 @@
main:
declare bool
calc bool eq "1" "2"
check not bool : "1 should not equal 2"
emit "Success"
/

View File

@ -1,5 +0,0 @@
main:
declare bool
check eq "1" "1" : "1 should equal 1"
emit "Success"
/

View File

@ -1,6 +0,0 @@
main:
declare bool
calc bool lt "b" "a"
check not bool : "a should should sort before b"
emit "Success"
/

View File

@ -1,5 +0,0 @@
main:
declare bool
check lt "a" "b" : "a should should sort before b"
emit "Success"
/

View File

@ -1,6 +0,0 @@
main:
declare char
calc char peek
check eq char "H" : "The first byte we're passed is expected to be an 'H'"
emit "Success"
/

View File

@ -1,12 +0,0 @@
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"
/

View File

@ -1,3 +0,0 @@
Hello!
This is an example of standard input.

View File

@ -0,0 +1 @@
ERROR: Check failed successfully

View File

@ -0,0 +1 @@
Still alive

View File

@ -0,0 +1,8 @@
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
/

View File

@ -0,0 +1 @@
Success

View File

@ -1,6 +1,7 @@
main: main:
forever forever
emit "Suc"
break break
/ /
emit "Success" emit "cess"
/ /

View File

@ -0,0 +1 @@
Success

View File

@ -0,0 +1,2 @@
1 is true
A is true

View File

@ -0,0 +1,18 @@
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
/
/

View File

@ -0,0 +1,3 @@
funca Constant
funcb Variable
funcc

View File

@ -0,0 +1,32 @@
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
/

View File

@ -0,0 +1,2 @@
Predeclared without argument: 1
Predeclared with argument: 2

View File

@ -0,0 +1,24 @@
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
/

View File

@ -0,0 +1 @@
<EFBFBD>

View File

@ -0,0 +1,3 @@
main:
emit eof
/

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,3 @@
main:
emit eol
/

View File

@ -0,0 +1 @@
"

View File

@ -0,0 +1,3 @@
main:
emit quote
/

View File

@ -0,0 +1,3 @@
1 + 2 = 12
10 + 20 = 1020
101 + 202 = 101202

View File

@ -0,0 +1,29 @@
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
/

View File

@ -0,0 +1 @@
Hello, world!

View File

@ -0,0 +1,4 @@
main:
emit "Hello"
emit ", world!"
/

View File

@ -0,0 +1,4 @@
eq A A: 1
eq A B:
eq AA AA: 1
eq AA AB:

View File

@ -0,0 +1,19 @@
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
/

View File

@ -0,0 +1,6 @@
lt A A:
lt A B: 1
lt B A:
lt AA AA:
lt AA AB: 1
lt AB AA:

View File

@ -0,0 +1,27 @@
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
/

View File

@ -0,0 +1 @@
AAA

View File

@ -0,0 +1,9 @@
main:
declare char
calc char peek
emit char
calc char peek
emit char
calc char peek
emit char
/

View File

@ -0,0 +1 @@
ABC

View File

@ -0,0 +1 @@
ABD

View File

@ -0,0 +1,12 @@
main:
declare char
calc char peek
emit char
skip
calc char peek
emit char
skip
skip
calc char peek
emit char
/

View File

@ -0,0 +1 @@
ABCD

View File

@ -0,0 +1,4 @@
"A" 1
"
" 2
"B" 1

View File

@ -0,0 +1,35 @@
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
/

View File

@ -0,0 +1,3 @@
A
B
C

View File

@ -0,0 +1,4 @@
"A" 1
"
" 1
"B" 2

View File

@ -0,0 +1,35 @@
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
/

View File

@ -0,0 +1,3 @@
A
B
C

View File

@ -0,0 +1 @@
Success

View File

@ -0,0 +1 @@
Success