Added a number of tests
Fix: skip() would not work without peek() on iteration 0 or 1.
This commit is contained in:
parent
ad99832959
commit
17841954de
@ -27,6 +27,8 @@ def peek():
|
|||||||
|
|
||||||
return PEEK
|
return PEEK
|
||||||
|
|
||||||
|
peek()
|
||||||
|
|
||||||
def skip():
|
def skip():
|
||||||
global LINE
|
global LINE
|
||||||
global PEEK
|
global PEEK
|
||||||
@ -316,6 +318,8 @@ def emitheader():
|
|||||||
emit(" PEEK = char\n")
|
emit(" PEEK = char\n")
|
||||||
emit(" return PEEK\n")
|
emit(" return PEEK\n")
|
||||||
emit("\n")
|
emit("\n")
|
||||||
|
emit("peek()\n")
|
||||||
|
emit("\n")
|
||||||
emit("def skip():\n")
|
emit("def skip():\n")
|
||||||
emit(" global LINE\n")
|
emit(" global LINE\n")
|
||||||
emit(" global PEEK\n")
|
emit(" global PEEK\n")
|
||||||
|
|||||||
@ -309,42 +309,42 @@ parsefunc:
|
|||||||
skipchar eol
|
skipchar eol
|
||||||
emit "):\n"
|
emit "):\n"
|
||||||
emit " pass # ahead declaration\n"
|
emit " pass # ahead declaration\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
return
|
return
|
||||||
/
|
/
|
||||||
skipchar ":"
|
skipchar ":"
|
||||||
skipchar eol
|
skipchar eol
|
||||||
emit "):\n"
|
emit "):\n"
|
||||||
parseblock " "
|
parseblock " "
|
||||||
emit "\n"
|
emit eol
|
||||||
/
|
/
|
||||||
|
|
||||||
emitheader:
|
emitheader:
|
||||||
emit "import os\n"
|
emit "import os\n"
|
||||||
emit "import sys\n"
|
emit "import sys\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
emit "def eq(a, b):\n"
|
emit "def eq(a, b):\n"
|
||||||
emit " return a == b\n"
|
emit " return a == b\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
emit "def lt(a, b):\n"
|
emit "def lt(a, b):\n"
|
||||||
emit " return a[0] < b[0]\n"
|
emit " return a[0] < b[0]\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
emit "def addstringchar(a, b):\n"
|
emit "def addstringchar(a, b):\n"
|
||||||
emit " return a + b[0]\n"
|
emit " return a + b[0]\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
emit "def emit(string):\n"
|
emit "def emit(string):\n"
|
||||||
emit " sys.stdout.write(string)\n"
|
emit " sys.stdout.write(string)\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
emit "def trace(header, value):\n"
|
emit "def trace(header, value):\n"
|
||||||
emit " if os.environ.get('TRACE'):\n"
|
emit " if os.environ.get('TRACE'):\n"
|
||||||
emit " sys.stderr.write(f'{header}={value!r}\\n')\n"
|
emit " sys.stderr.write(f'{header}={value!r}\\n')\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
emit "eof = chr(0)\n"
|
emit "eof = chr(0)\n"
|
||||||
emit "eol = chr(10)\n"
|
emit "eol = chr(10)\n"
|
||||||
emit "quote = chr(34)\n"
|
emit "quote = chr(34)\n"
|
||||||
emit "PEEK = None\n"
|
emit "PEEK = None\n"
|
||||||
emit "LINE = 1\n"
|
emit "LINE = 1\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
emit "def peek():\n"
|
emit "def peek():\n"
|
||||||
emit " global PEEK\n"
|
emit " global PEEK\n"
|
||||||
emit " if PEEK is None:\n"
|
emit " if PEEK is None:\n"
|
||||||
@ -355,19 +355,21 @@ emitheader:
|
|||||||
emit " else:\n"
|
emit " else:\n"
|
||||||
emit " PEEK = char\n"
|
emit " PEEK = char\n"
|
||||||
emit " return PEEK\n"
|
emit " return PEEK\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
|
emit "peek()\n"
|
||||||
|
emit eol
|
||||||
emit "def skip():\n"
|
emit "def skip():\n"
|
||||||
emit " global LINE\n"
|
emit " global LINE\n"
|
||||||
emit " global PEEK\n"
|
emit " global PEEK\n"
|
||||||
emit " if eol == PEEK:\n"
|
emit " if eol == PEEK:\n"
|
||||||
emit " LINE += 1\n"
|
emit " LINE += 1\n"
|
||||||
emit " PEEK = None\n"
|
emit " PEEK = None\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
emit "def skipchar(char):\n"
|
emit "def skipchar(char):\n"
|
||||||
emit " global LINE\n"
|
emit " global LINE\n"
|
||||||
emit " assert char == peek(), (LINE, char, peek())\n"
|
emit " assert char == peek(), (LINE, char, peek())\n"
|
||||||
emit " skip()\n"
|
emit " skip()\n"
|
||||||
emit "\n"
|
emit eol
|
||||||
/
|
/
|
||||||
|
|
||||||
emitfooter:
|
emitfooter:
|
||||||
|
|||||||
56
README.md
56
README.md
@ -49,6 +49,32 @@ Indentation is done using tabs.
|
|||||||
|
|
||||||
### Parsing
|
### 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
|
### Variables
|
||||||
|
|
||||||
#### calc var func args*
|
#### calc var func args*
|
||||||
@ -69,6 +95,10 @@ Sets var to "const".
|
|||||||
|
|
||||||
Exits the deepest `forever` loop.
|
Exits the deepest `forever` loop.
|
||||||
|
|
||||||
|
#### func args*
|
||||||
|
|
||||||
|
Calls the function name `func` with the given arguments. The result, if any, is ignored.
|
||||||
|
|
||||||
#### if arg
|
#### if arg
|
||||||
|
|
||||||
Evaluates arg. If found to be true, descends in the block. Otherwise, skips the block
|
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`.
|
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
|
### Builtins
|
||||||
|
|
||||||
#### trace
|
#### trace
|
||||||
|
|
||||||
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 functions
|
### 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.
|
|
||||||
|
|
||||||
#### addstringchar a b
|
#### addstringchar a b
|
||||||
|
|
||||||
@ -113,6 +129,16 @@ Creates a new string with `b` appended to `a`.
|
|||||||
|
|
||||||
Writes the given string to standard output.
|
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
|
#### peek
|
||||||
|
|
||||||
Checks stdin for the next character and returns it.
|
Checks stdin for the next character and returns it.
|
||||||
|
|||||||
11
tests/.gitignore
vendored
11
tests/.gitignore
vendored
@ -1,12 +1 @@
|
|||||||
/*.it0
|
|
||||||
/*.it0.c
|
|
||||||
/*.it0.o
|
|
||||||
/*.it0.py
|
|
||||||
/*.it1
|
|
||||||
/*.it1.c
|
|
||||||
/*.it1.o
|
|
||||||
/*.it1.py
|
|
||||||
/*.it2
|
|
||||||
/*.it2.c
|
|
||||||
/*.it2.o
|
|
||||||
/*.results
|
/*.results
|
||||||
|
|||||||
@ -8,64 +8,64 @@ CC=gcc
|
|||||||
|
|
||||||
TESTLIST=$(shell ls *.lang0 | sed 's/.lang0//')
|
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))
|
check: all-it0.results all-it1.results all-it2.results
|
||||||
-rm -f $@
|
! grep -v 'Success' $^
|
||||||
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; ./$(test).it0 >> $@ ; echo "" >> $@)
|
|
||||||
! grep -v 'Success' $@
|
|
||||||
|
|
||||||
all-it1.results: $(addsuffix .it1, $(TESTLIST))
|
all-it0.results: $(addprefix build/,$(addsuffix .it0, $(TESTLIST)))
|
||||||
-rm -f $@
|
-rm -f $@
|
||||||
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; ./$(test).it1 >> $@ ; echo "" >> $@)
|
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it0 >> $@ ; echo "" >> $@ ;)
|
||||||
! grep -v 'Success' $@
|
|
||||||
|
|
||||||
all-it2.results: $(addsuffix .it2, $(TESTLIST))
|
all-it1.results: $(addprefix build/,$(addsuffix .it1, $(TESTLIST)))
|
||||||
-rm -f $@
|
-rm -f $@
|
||||||
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; ./$(test).it2 >> $@ ; echo "" >> $@)
|
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it1 >> $@ ; echo "" >> $@ ;)
|
||||||
! grep -v 'Success' $@
|
|
||||||
|
all-it2.results: $(addprefix build/,$(addsuffix .it2, $(TESTLIST)))
|
||||||
|
-rm -f $@
|
||||||
|
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it2 >> $@ ; echo "" >> $@ ;)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f *.result *.it0* *.it1* *.it2*
|
-rm -f *.results build/*.it0* build/*.it1* build/*.it2*
|
||||||
|
|
||||||
###
|
###
|
||||||
# it0
|
# it0
|
||||||
|
|
||||||
%.it0.py: %.lang0 ../0-lang0py/lang0py.exe
|
build/%.it0.py: %.lang0 ../0-lang0py/lang0py.exe
|
||||||
cat $< | ../0-lang0py/lang0py.exe > $@
|
cat $< | ../0-lang0py/lang0py.exe > $@
|
||||||
|
|
||||||
%.it0.c: %.it0.py
|
build/%.it0.c: build/%.it0.py
|
||||||
$(CYTHON) -3 --embed -o $@ $^
|
$(CYTHON) -3 --embed -o $@ $^
|
||||||
|
|
||||||
%.it0.o: %.it0.c
|
build/%.it0.o: build/%.it0.c
|
||||||
$(CC) -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
|
$(CC) -o $@ -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
|
||||||
|
|
||||||
%.it0: %.it0.o
|
build/%.it0: build/%.it0.o
|
||||||
$(CC) -o $@ $^ -lpython$(PYVERSION)
|
$(CC) -o $@ $^ -lpython$(PYVERSION)
|
||||||
|
|
||||||
###
|
###
|
||||||
# it1
|
# it1
|
||||||
|
|
||||||
%.it1.py: %.lang0 ../1-lang0py/lang0py.exe
|
build/%.it1.py: %.lang0 ../1-lang0py/lang0py.exe
|
||||||
cat $< | ../1-lang0py/lang0py.exe > $@
|
cat $< | ../1-lang0py/lang0py.exe > $@
|
||||||
|
|
||||||
%.it1.c: %.it1.py
|
build/%.it1.c: build/%.it1.py
|
||||||
$(CYTHON) -3 --embed -o $@ $^
|
$(CYTHON) -3 --embed -o $@ $^
|
||||||
|
|
||||||
%.it1.o: %.it1.c
|
build/%.it1.o: build/%.it1.c
|
||||||
$(CC) -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
|
$(CC) -o $@ -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
|
||||||
|
|
||||||
%.it1: %.it1.o
|
build/%.it1: build/%.it1.o
|
||||||
$(CC) -o $@ $^ -lpython$(PYVERSION)
|
$(CC) -o $@ $^ -lpython$(PYVERSION)
|
||||||
|
|
||||||
###
|
###
|
||||||
# it2
|
# it2
|
||||||
|
|
||||||
%.it2.c: %.lang0 ../2-lang0c/lang0c.exe
|
build/%.it2.c: %.lang0 ../2-lang0c/lang0c.exe
|
||||||
cat $< | ../2-lang0c/lang0c.exe > $@
|
cat $< | ../2-lang0c/lang0c.exe > $@
|
||||||
|
|
||||||
%.it2.o: %.it2.c
|
build/%.it2.o: build/%.it2.c
|
||||||
$(CC) -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
|
$(CC) -o $@ -c $^ -I$(PYPREFIX)/include/python$(PYVERSION)
|
||||||
|
|
||||||
%.it2: %.it2.o
|
build/%.it2: build/%.it2.o
|
||||||
$(CC) -o $@ $^ -lpython$(PYVERSION)
|
$(CC) -o $@ $^ -lpython$(PYVERSION)
|
||||||
|
|||||||
11
tests/build/.gitignore
vendored
Normal file
11
tests/build/.gitignore
vendored
Normal 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
6
tests/flowbreak.lang0
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
main:
|
||||||
|
forever
|
||||||
|
break
|
||||||
|
/
|
||||||
|
emit "Success"
|
||||||
|
/
|
||||||
8
tests/flowcall.lang0
Normal file
8
tests/flowcall.lang0
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
func:
|
||||||
|
emit "Success"
|
||||||
|
return
|
||||||
|
/
|
||||||
|
|
||||||
|
main:
|
||||||
|
func
|
||||||
|
/
|
||||||
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
|
||||||
|
/
|
||||||
11
tests/parsingpredeclaredfunction.lang0
Normal file
11
tests/parsingpredeclaredfunction.lang0
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
func result/
|
||||||
|
|
||||||
|
main:
|
||||||
|
declare result
|
||||||
|
calc result func "Success"
|
||||||
|
emit result
|
||||||
|
/
|
||||||
|
|
||||||
|
func result:
|
||||||
|
return result
|
||||||
|
/
|
||||||
5
tests/stdlibaddstringchar.lang0
Normal file
5
tests/stdlibaddstringchar.lang0
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
main:
|
||||||
|
declare result
|
||||||
|
calc result addstringchar "Succes" "s"
|
||||||
|
emit result
|
||||||
|
/
|
||||||
8
tests/stdlibeqfalse.lang0
Normal file
8
tests/stdlibeqfalse.lang0
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
main:
|
||||||
|
declare bool
|
||||||
|
calc bool eq "1" "2"
|
||||||
|
if bool
|
||||||
|
return
|
||||||
|
/
|
||||||
|
emit "Success"
|
||||||
|
/
|
||||||
7
tests/stdlibeqtrue.lang0
Normal file
7
tests/stdlibeqtrue.lang0
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
main:
|
||||||
|
declare bool
|
||||||
|
calc bool eq "1" "1"
|
||||||
|
if bool
|
||||||
|
emit "Success"
|
||||||
|
/
|
||||||
|
/
|
||||||
8
tests/stdlibltfalse.lang0
Normal file
8
tests/stdlibltfalse.lang0
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
main:
|
||||||
|
declare bool
|
||||||
|
calc bool lt "b" "a"
|
||||||
|
if bool
|
||||||
|
return
|
||||||
|
/
|
||||||
|
emit "Success"
|
||||||
|
/
|
||||||
7
tests/stdliblttrue.lang0
Normal file
7
tests/stdliblttrue.lang0
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
main:
|
||||||
|
declare bool
|
||||||
|
calc bool lt "a" "b"
|
||||||
|
if bool
|
||||||
|
emit "Success"
|
||||||
|
/
|
||||||
|
/
|
||||||
9
tests/stdlibpeek.lang0
Normal file
9
tests/stdlibpeek.lang0
Normal 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
24
tests/stdlibskip.lang0
Normal 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"
|
||||||
|
/
|
||||||
9
tests/variablescalc.lang0
Normal file
9
tests/variablescalc.lang0
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
func result:
|
||||||
|
return result
|
||||||
|
/
|
||||||
|
|
||||||
|
main:
|
||||||
|
declare result
|
||||||
|
calc result func "Success"
|
||||||
|
emit result
|
||||||
|
/
|
||||||
5
tests/variablesset.lang0
Normal file
5
tests/variablesset.lang0
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
main:
|
||||||
|
declare result
|
||||||
|
set result "Success"
|
||||||
|
emit result
|
||||||
|
/
|
||||||
Loading…
x
Reference in New Issue
Block a user