Adds check builtin

This commit is contained in:
Johan B.W. de Vries 2025-02-09 15:02:25 +01:00
parent 931a861fef
commit 5fa042c5cd
14 changed files with 251 additions and 39 deletions

View File

@ -166,6 +166,53 @@ def parsestatreturn(indent):
emit(eol)
skipchar(eol)
def parsestatcheck(indent):
skipchar(' ')
emit(' ' * indent)
emit('assert ')
func_name = lexident()
emit(func_name)
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)
@ -211,6 +258,10 @@ def parsestat(indent):
parsestatreturn(indent)
return
if call == "check":
parsestatcheck(indent)
return
if call == "trace":
parsestattrace(indent)
return

View File

@ -157,6 +157,82 @@ parsestatreturn indent:
skipchar eol
/
parsestatcheck indent:
declare char
declare funcname
declare iscolon
declare isnotquote
declare isquote
declare notfirst
skipchar " "
emit indent
emit "assert "
calc funcname lexident
emit funcname
emit "("
set notfirst ""
forever
skipchar " "
calc char peek
calc iscolon eq char ":"
if iscolon
break
/
if notfirst
emit ", "
/
calc char peek
calc isquote eq char quote
calc isnotquote not isquote
if isquote
parseconststring
/
if isnotquote
parseexprvarref
/
set notfirst "1"
/
skipchar ":"
emit "), ("
set notfirst ""
forever
skipchar " "
if notfirst
emit ", "
/
calc char peek
calc isquote eq char quote
calc isnotquote not isquote
if isquote
parseconststring
/
if isnotquote
parseexprvarref
/
calc char peek
calc iseol eq char eol
if iseol
break
/
set notfirst "1"
/
emitln ")"
/
parsestattrace indent:
emit indent
emit "trace("
@ -214,6 +290,11 @@ parsestat indent:
parsestattrace indent
return
/
calc ischeck eq call "check"
if ischeck
parsestatcheck indent
return
/
emit indent
emit call
emit "("

View File

@ -214,6 +214,88 @@ parsestatreturn indent:
return
/
parsestatcheck indent:
declare char
declare funcname
declare iscolon
declare iseol
declare isnotquote
declare isquote
declare notfirst
skipchar " "
emit indent
emit "if( 0 == strlen("
calc funcname lexident
emit funcname
emit "("
set notfirst ""
forever
skipchar " "
calc char peek
calc iscolon eq char ":"
if iscolon
break
/
if notfirst
emit ", "
/
calc char peek
calc isquote eq char quote
calc isnotquote not isquote
if isquote
parseconststring
/
if isnotquote
parseexprvarref
/
set notfirst "1"
/
skipchar ":"
emitln ")) )"
emit indent
emitln "{"
forever
skipchar " "
emit indent
emit " fprintf(stderr, "
emit quote
emit "%s "
emit quote
emit ", "
calc char peek
calc isquote eq char quote
calc isnotquote not isquote
if isquote
parseconststring
/
if isnotquote
parseexprvarref
/
emitln ");"
calc char peek
calc iseol eq char eol
if iseol
break
/
/
emit indent
emitln " exit(1);"
emit indent
emitln "}"
/
parsestattrace indent:
declare varname
emit indent
@ -278,6 +360,11 @@ parsestat indent:
parsestatreturn indent
return
/
calc iscall eq call "check"
if iscall
parsestatcheck indent
return
/
calc iscall eq call "trace"
if iscall
parsestattrace indent

View File

@ -113,6 +113,10 @@ Returns the given value. You can not give an argument if your function is never
### Builtins
#### check func [arg0..] : msg [arg0..]
Calls the given function with the given arguments. If the function's return value is not found to be true, outputs the given `msg` and halts the program.
#### trace
Writes the name and value of the variable passed to stderr if the TRACE environment variable is set.

View File

@ -8,23 +8,27 @@ PYPREFIX=/usr
CYTHON=cython3
CC=gcc
TESTLIST=$(shell ls *.lang0 | sed 's/.lang0//')
# 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 'builtincheckfalse' | sed 's/.lang0//')
all: check
check: all-it0.results all-it1.results all-it2.results
! grep -v 'Success' $^
all-it0.results: $(addprefix build/,$(addsuffix .it0, $(TESTLIST)))
all-it0.results: $(addprefix build/,$(addsuffix .it0, $(TESTLIST))) build/builtincheckfalse.it0
-rm -f $@
echo "Hello" | build/builtincheckfalse.it0 2> /dev/null 2>&1 | grep 'Success'
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it0 >> $@ ; echo "" >> $@ ;)
all-it1.results: $(addprefix build/,$(addsuffix .it1, $(TESTLIST)))
all-it1.results: $(addprefix build/,$(addsuffix .it1, $(TESTLIST))) build/builtincheckfalse.it0
-rm -f $@
echo "Hello" | build/builtincheckfalse.it0 2> /dev/null 2>&1 | grep 'Success'
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it1 >> $@ ; echo "" >> $@ ;)
all-it2.results: $(addprefix build/,$(addsuffix .it2, $(TESTLIST)))
all-it2.results: $(addprefix build/,$(addsuffix .it2, $(TESTLIST))) build/builtincheckfalse.it0
-rm -f $@
echo "Hello" | build/builtincheckfalse.it0 2> /dev/null 2>&1 | grep 'Success'
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it2 >> $@ ; echo "" >> $@ ;)
clean:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,24 +1,12 @@
main:
declare char
declare ish
declare iso
declare notish
declare notiso
skip
calc char peek
calc ish eq char "e"
calc notish not ish
if notish
return
/
check eq char "e" : "The second byte we're passed is expected to be an 'e'"
skip
skip
skip
calc char peek
calc iso eq char "o"
calc notiso not iso
if notish
return
/
check eq char "o" : "The fifth byte we're passed is expected to be an 'o'"
emit "Success"
/