Added a number of tests

Fix: skip() would not work without peek() on iteration 0 or 1.
This commit is contained in:
Johan B.W. de Vries 2025-02-02 15:13:03 +01:00
parent ad99832959
commit 17841954de
23 changed files with 237 additions and 64 deletions

View File

@ -27,6 +27,8 @@ def peek():
return PEEK
peek()
def skip():
global LINE
global PEEK
@ -316,6 +318,8 @@ def emitheader():
emit(" PEEK = char\n")
emit(" return PEEK\n")
emit("\n")
emit("peek()\n")
emit("\n")
emit("def skip():\n")
emit(" global LINE\n")
emit(" global PEEK\n")

View File

@ -309,42 +309,42 @@ parsefunc:
skipchar eol
emit "):\n"
emit " pass # ahead declaration\n"
emit "\n"
emit eol
return
/
skipchar ":"
skipchar eol
emit "):\n"
parseblock " "
emit "\n"
emit eol
/
emitheader:
emit "import os\n"
emit "import sys\n"
emit "\n"
emit eol
emit "def eq(a, b):\n"
emit " return a == b\n"
emit "\n"
emit eol
emit "def lt(a, b):\n"
emit " return a[0] < b[0]\n"
emit "\n"
emit eol
emit "def addstringchar(a, b):\n"
emit " return a + b[0]\n"
emit "\n"
emit eol
emit "def emit(string):\n"
emit " sys.stdout.write(string)\n"
emit "\n"
emit eol
emit "def trace(header, value):\n"
emit " if os.environ.get('TRACE'):\n"
emit " sys.stderr.write(f'{header}={value!r}\\n')\n"
emit "\n"
emit eol
emit "eof = chr(0)\n"
emit "eol = chr(10)\n"
emit "quote = chr(34)\n"
emit "PEEK = None\n"
emit "LINE = 1\n"
emit "\n"
emit eol
emit "def peek():\n"
emit " global PEEK\n"
emit " if PEEK is None:\n"
@ -355,19 +355,21 @@ emitheader:
emit " else:\n"
emit " PEEK = char\n"
emit " return PEEK\n"
emit "\n"
emit eol
emit "peek()\n"
emit eol
emit "def skip():\n"
emit " global LINE\n"
emit " global PEEK\n"
emit " if eol == PEEK:\n"
emit " LINE += 1\n"
emit " PEEK = None\n"
emit "\n"
emit eol
emit "def skipchar(char):\n"
emit " global LINE\n"
emit " assert char == peek(), (LINE, char, peek())\n"
emit " skip()\n"
emit "\n"
emit eol
/
emitfooter:

View File

@ -49,6 +49,32 @@ Indentation is done using tabs.
### Parsing
#### Pre declaration (functions)
Functions need to be pre-declared if you intend to use them before you have defined them:
```
func result/
...
func result:
return result
/
```
#### Pre declaration (variables)
Variables will need to be declared before you can use them:
```
func:
declare result
set result "Result"
return result
/
```
### Variables
#### calc var func args*
@ -69,6 +95,10 @@ Sets var to "const".
Exits the deepest `forever` loop.
#### func args*
Calls the function name `func` with the given arguments. The result, if any, is ignored.
#### if arg
Evaluates arg. If found to be true, descends in the block. Otherwise, skips the block
@ -81,27 +111,13 @@ Repeats the block until `break` or `return` is called.
Returns the given value. You can not give an argument if your function is never used in `call`.
#### func args*
Calls the given function with the given arguments. The result, if any, is ignored.
### Builtins
#### trace
Writes the name and value of the variable passed to stderr if the TRACE environment variable is set.
#### Standard library functions
#### eq a b
Return true if the given strings are the same.
#### lt a b
`a` and `b` are expected to have length 1.
Return true if a would sort before b.
### Standard library functions
#### addstringchar a b
@ -113,6 +129,16 @@ Creates a new string with `b` appended to `a`.
Writes the given string to standard output.
#### eq a b
Return true if the given strings are the same.
#### lt a b
`a` and `b` are expected to have length 1.
Return true if a would sort before b.
#### peek
Checks stdin for the next character and returns it.

11
tests/.gitignore vendored
View File

@ -1,12 +1 @@
/*.it0
/*.it0.c
/*.it0.o
/*.it0.py
/*.it1
/*.it1.c
/*.it1.o
/*.it1.py
/*.it2
/*.it2.c
/*.it2.o
/*.results

View File

@ -8,64 +8,64 @@ CC=gcc
TESTLIST=$(shell ls *.lang0 | sed 's/.lang0//')
all: all-it0.results all-it1.results all-it2.results
all: check
all-it0.results: $(addsuffix .it0, $(TESTLIST))
-rm -f $@
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; ./$(test).it0 >> $@ ; echo "" >> $@)
! grep -v 'Success' $@
check: all-it0.results all-it1.results all-it2.results
! grep -v 'Success' $^
all-it1.results: $(addsuffix .it1, $(TESTLIST))
all-it0.results: $(addprefix build/,$(addsuffix .it0, $(TESTLIST)))
-rm -f $@
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; ./$(test).it1 >> $@ ; echo "" >> $@)
! grep -v 'Success' $@
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it0 >> $@ ; echo "" >> $@ ;)
all-it2.results: $(addsuffix .it2, $(TESTLIST))
all-it1.results: $(addprefix build/,$(addsuffix .it1, $(TESTLIST)))
-rm -f $@
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; ./$(test).it2 >> $@ ; echo "" >> $@)
! grep -v 'Success' $@
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it1 >> $@ ; echo "" >> $@ ;)
all-it2.results: $(addprefix build/,$(addsuffix .it2, $(TESTLIST)))
-rm -f $@
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it2 >> $@ ; echo "" >> $@ ;)
clean:
-rm -f *.result *.it0* *.it1* *.it2*
-rm -f *.results build/*.it0* build/*.it1* build/*.it2*
###
# it0
%.it0.py: %.lang0 ../0-lang0py/lang0py.exe
build/%.it0.py: %.lang0 ../0-lang0py/lang0py.exe
cat $< | ../0-lang0py/lang0py.exe > $@
%.it0.c: %.it0.py
build/%.it0.c: build/%.it0.py
$(CYTHON) -3 --embed -o $@ $^
%.it0.o: %.it0.c
$(CC) -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
build/%.it0.o: build/%.it0.c
$(CC) -o $@ -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
%.it0: %.it0.o
build/%.it0: build/%.it0.o
$(CC) -o $@ $^ -lpython$(PYVERSION)
###
# it1
%.it1.py: %.lang0 ../1-lang0py/lang0py.exe
build/%.it1.py: %.lang0 ../1-lang0py/lang0py.exe
cat $< | ../1-lang0py/lang0py.exe > $@
%.it1.c: %.it1.py
build/%.it1.c: build/%.it1.py
$(CYTHON) -3 --embed -o $@ $^
%.it1.o: %.it1.c
$(CC) -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
build/%.it1.o: build/%.it1.c
$(CC) -o $@ -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
%.it1: %.it1.o
build/%.it1: build/%.it1.o
$(CC) -o $@ $^ -lpython$(PYVERSION)
###
# it2
%.it2.c: %.lang0 ../2-lang0c/lang0c.exe
build/%.it2.c: %.lang0 ../2-lang0c/lang0c.exe
cat $< | ../2-lang0c/lang0c.exe > $@
%.it2.o: %.it2.c
$(CC) -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
build/%.it2.o: build/%.it2.c
$(CC) -o $@ -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
%.it2: %.it2.o
build/%.it2: build/%.it2.o
$(CC) -o $@ $^ -lpython$(PYVERSION)

11
tests/build/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/*.it0
/*.it0.c
/*.it0.o
/*.it0.py
/*.it1
/*.it1.c
/*.it1.o
/*.it1.py
/*.it2
/*.it2.c
/*.it2.o

6
tests/flowbreak.lang0 Normal file
View File

@ -0,0 +1,6 @@
main:
forever
break
/
emit "Success"
/

8
tests/flowcall.lang0 Normal file
View File

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

8
tests/flowiffalse.lang0 Normal file
View File

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

7
tests/flowiftrue.lang0 Normal file
View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
main:
declare result
calc result addstringchar "Succes" "s"
emit result
/

View File

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

7
tests/stdlibeqtrue.lang0 Normal file
View File

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

View File

@ -0,0 +1,8 @@
main:
declare bool
calc bool lt "b" "a"
if bool
return
/
emit "Success"
/

7
tests/stdliblttrue.lang0 Normal file
View File

@ -0,0 +1,7 @@
main:
declare bool
calc bool lt "a" "b"
if bool
emit "Success"
/
/

9
tests/stdlibpeek.lang0 Normal file
View File

@ -0,0 +1,9 @@
main:
declare char
declare ish
calc char peek
calc ish eq char "H"
if ish
emit "Success"
/
/

24
tests/stdlibskip.lang0 Normal file
View File

@ -0,0 +1,24 @@
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
/
skip
skip
skip
calc char peek
calc iso eq char "o"
calc notiso not iso
if notish
return
/
emit "Success"
/

View File

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

5
tests/variablesset.lang0 Normal file
View File

@ -0,0 +1,5 @@
main:
declare result
set result "Success"
emit result
/