From f0cbda1f2ea12bf9c18044822eefce15ac76674f Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Thu, 19 Mar 2020 15:43:48 -0400 Subject: [PATCH] tests: add Forth tests Modest first step --- emul/forth/forth.c | 13 ++++++++++++- forth/dictionary.txt | 4 ++++ forth/str.fs | 3 +++ tests/Makefile | 3 ++- tests/forth/harness.fs | 9 +++++++++ tests/forth/runtests.sh | 27 +++++++++++++++++++++++++++ tests/forth/test_ari.fs | 5 +++++ 7 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 tests/forth/harness.fs create mode 100755 tests/forth/runtests.sh create mode 100644 tests/forth/test_ari.fs diff --git a/emul/forth/forth.c b/emul/forth/forth.c index 739f550..873b4c1 100644 --- a/emul/forth/forth.c +++ b/emul/forth/forth.c @@ -8,9 +8,13 @@ // in sync with glue.asm #define RAMSTART 0x900 #define STDIO_PORT 0x00 +// This binary is also used for automated tests and those tests, when +// failing, send a non-zero value to RET_PORT to indicate failure +#define RET_PORT 0x01 static int running; static FILE *fp; +static int retcode = 0; static uint8_t iord_stdio() { @@ -30,6 +34,12 @@ static void iowr_stdio(uint8_t val) } } +static void iowr_ret(uint8_t val) +{ + retcode = val; +} + + int main(int argc, char *argv[]) { bool tty = false; @@ -61,6 +71,7 @@ int main(int argc, char *argv[]) m->ramstart = RAMSTART; m->iord[STDIO_PORT] = iord_stdio; m->iowr[STDIO_PORT] = iowr_stdio; + m->iowr[RET_PORT] = iowr_ret; // initialize memory for (int i=0; imem[i] = KERNEL[i]; @@ -78,5 +89,5 @@ int main(int argc, char *argv[]) emul_printdebug(); } fclose(fp); - return 0; + return retcode; } diff --git a/forth/dictionary.txt b/forth/dictionary.txt index 397e62a..c420699 100644 --- a/forth/dictionary.txt +++ b/forth/dictionary.txt @@ -194,3 +194,7 @@ PC! c a -- Spit c to port a PC@ a -- c Fetch c from port a WORD -- a Read one word from buffered input and push its addr +There are also ascii const emitters: +LF +SPC + diff --git a/forth/str.fs b/forth/str.fs index b877be0..8dbe95a 100644 --- a/forth/str.fs +++ b/forth/str.fs @@ -5,3 +5,6 @@ 1 + AGAIN ; + +: LF 10 EMIT ; +: SPC 32 EMIT ; diff --git a/tests/Makefile b/tests/Makefile index 21be294..43acc96 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -2,8 +2,9 @@ EMULDIR = ../emul .PHONY: run run: - $(MAKE) -C $(EMULDIR) zasm/zasm zasm/avra runbin/runbin shell/shell + $(MAKE) -C $(EMULDIR) zasm/zasm zasm/avra runbin/runbin shell/shell forth/forth cd unit && ./runtests.sh cd zasm && ./runtests.sh cd avra && ./runtests.sh cd shell && ./runtests.sh + cd forth && ./runtests.sh diff --git a/tests/forth/harness.fs b/tests/forth/harness.fs new file mode 100644 index 0000000..f6dc940 --- /dev/null +++ b/tests/forth/harness.fs @@ -0,0 +1,9 @@ +( Forth testing harness + "#" means "assert". We stop at first failure, indicating + the failure through IO on port 1 ) + +: fail SPC ." failed" LF 1 1 PC! BYE ; + +: # SKIP? fail SPC ." pass" LF ; + +: #eq 2DUP SWAP . SPC '=' EMIT SPC . '?' EMIT = # ; diff --git a/tests/forth/runtests.sh b/tests/forth/runtests.sh new file mode 100755 index 0000000..08f861f --- /dev/null +++ b/tests/forth/runtests.sh @@ -0,0 +1,27 @@ +#!/bin/sh -e + +BASE=../.. +EXEC="${BASE}/emul/forth/forth" +FDIR="${BASE}/forth" +TMP=$(mktemp) + +chk() { + echo "Running test $1" + cat harness.fs $1 > ${TMP} + if ! ${EXEC} ${TMP}; then + exit 1 + fi +} + +if [ ! -z $1 ]; then + chk $1 + exit 0 +fi + +# those tests run without any builtin +for fn in test_*.fs; do + chk "${fn}" +done + +echo "All tests passed!" +rm ${TMP} diff --git a/tests/forth/test_ari.fs b/tests/forth/test_ari.fs new file mode 100644 index 0000000..99b8e40 --- /dev/null +++ b/tests/forth/test_ari.fs @@ -0,0 +1,5 @@ +48 13 + 61 #eq +48 13 - 35 #eq +48 13 * 624 #eq +48 13 / 3 #eq +48 13 MOD 9 #eq