diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | com.c | 13 | ||||
-rwxr-xr-x | run_tests.sh | 39 | ||||
-rw-r--r-- | state.h | 2 | ||||
-rw-r--r-- | test.bþ | 1 | ||||
-rw-r--r-- | tests/compile_error.bþ | 1 | ||||
-rw-r--r-- | tests/compile_error.out | 1 | ||||
-rw-r--r-- | tests/fizzbuzz.bþ (renamed from fizzbuzz.bþ) | 0 | ||||
-rw-r--r-- | tests/fizzbuzz.out | 30 | ||||
-rw-r--r-- | tests/four.bþ | 1 | ||||
-rw-r--r-- | tests/four.out | 1 | ||||
-rw-r--r-- | tests/vars.bþ | 9 | ||||
-rw-r--r-- | tests/vars.out | 5 | ||||
-rw-r--r-- | val.c | 2 | ||||
-rw-r--r-- | vm.c | 7 |
16 files changed, 107 insertions, 13 deletions
@@ -2,3 +2,4 @@ prs.c prs.h bþ vm +gmon.out @@ -1,6 +1,6 @@ CS=ast.c com.c dis.c ht.c mem.c prs.c read.c state.c val.c vm.c HS=ast.h dis.h ht.h mem.h prs.h read.h state.h val.h vm.h -CFLAGS=-O3 -lm -Wall -Wpedantic -Werror=implicit-function-declaration +CFLAGS=$(EXTRA_CFLAGS) -O3 -lm -Wall -Wpedantic -Werror=implicit-function-declaration bþ: $(CS) $(HS) Makefile $(CC) $(CFLAGS) -o bþ $(CS) @@ -8,7 +8,10 @@ bþ: $(CS) $(HS) Makefile prs.c: g.peg packcc -o prs g.peg +test: bþ + ./run_tests.sh + clean: rm bþ prs.c prs.h -.PHONY: clean +.PHONY: clean test @@ -47,7 +47,7 @@ static void compile_node(State *S, Chunk *ch, AstNode a) { } case AST_LIST: { AstVec l = a.as.list; - #define CK(cond, msg) if (!(cond)) { puts(msg); exit(1); } + #define CK(cond, msg) if (!(cond)) { fputs(msg "\n", stderr); exit(1); } CK(l.len > 0, "can't handle empty list"); CK(l.vals[0].ty == AST_IDENT, "can only call ops"); @@ -150,7 +150,7 @@ static void compile_node(State *S, Chunk *ch, AstNode a) { } -int main() { +int main(int argc, char **argv) { State st = state_new(); State *S = &st; Thread th = thread_new(S); @@ -158,12 +158,14 @@ int main() { Chunk ch = chunk_new(S); th.ch = &ch; + S->do_disasm = (argc > 1 && 0 == strcmp(argv[1], "-l")); + char n1[] = "foo"; char n2[] = "bar"; char n3[] = "baz"; - ObjString *o1 = objstring_copy(S, n1, 3); - ObjString *o2 = objstring_copy(S, n2, 3); - ObjString *o3 = objstring_copy(S, n3, 3); + ObjString *o1 = objstring_copy_cstr(S, n1); + ObjString *o2 = objstring_copy_cstr(S, n2); + ObjString *o3 = objstring_copy_cstr(S, n3); ht_put(S, &st.globals, o1, VAL_NUM(69)); ht_put(S, &st.globals, o2, VAL_NUM(2)); @@ -175,7 +177,6 @@ int main() { chunk_wbc(S, &ch, OP_PRINT); chunk_wbc(S, &ch, OP_RET); - puts("compile done"); return runvm(S); } diff --git a/run_tests.sh b/run_tests.sh new file mode 100755 index 0000000..3c561a7 --- /dev/null +++ b/run_tests.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +pass=0 +fail=0 + +for testfile in tests/*.bþ; do + outfile=${testfile%.bþ}.out + output="$(./bþ <$testfile 2>&1)" + run_res=$? + echo "$output" | diff $outfile - >/dev/null + diff_res=$? + testname=${testfile#tests/} + testname=${testname%.bþ} + case $diff_res in + 0) printf '\033[32m\033[1mPASS\033[0m %s\n' "$testname" + pass=$((pass + 1)) ;; + 1) printf '\033[31m\033[1mFAIL\033[0m %s\n' "$testname" + printf "\tgot output: %s\n" "$output" + printf "\texpected: " + cat $outfile + fail=$((fail + 1)) ;; + esac +done + +echo +printf "\033[32m%s\033[0m passed; " $pass +if [ $fail -eq 0 ]; then + printf "0 failed; " +else + printf "\033[31m%s\033[0m failed; " $fail +fi +printf "%s total\n" $((pass + fail)) + +if [ $fail -eq 0 ]; then + exit 0 +else + exit 1 +fi + @@ -10,6 +10,8 @@ struct _state { Thread *th; Ht strings; Ht globals; + + bool do_disasm; }; State state_new(); diff --git a/test.bþ b/test.bþ deleted file mode 100644 index 641d9f2..0000000 --- a/test.bþ +++ /dev/null @@ -1 +0,0 @@ -(+ "abc" (* 9 25)) diff --git a/tests/compile_error.bþ b/tests/compile_error.bþ new file mode 100644 index 0000000..b151c2f --- /dev/null +++ b/tests/compile_error.bþ @@ -0,0 +1 @@ +(while) diff --git a/tests/compile_error.out b/tests/compile_error.out new file mode 100644 index 0000000..b7b8184 --- /dev/null +++ b/tests/compile_error.out @@ -0,0 +1 @@ +while requires at least 2 arguments diff --git a/fizzbuzz.bþ b/tests/fizzbuzz.bþ index e70c2c1..e70c2c1 100644 --- a/fizzbuzz.bþ +++ b/tests/fizzbuzz.bþ diff --git a/tests/fizzbuzz.out b/tests/fizzbuzz.out new file mode 100644 index 0000000..51ff50b --- /dev/null +++ b/tests/fizzbuzz.out @@ -0,0 +1,30 @@ +1 +2 +fizz +4 +buzz +fizz +7 +8 +fizz +buzz +11 +fizz +13 +14 +fizzbuzz +16 +17 +fizz +19 +buzz +fizz +22 +23 +fizz +buzz +26 +fizz +28 +29 +nil diff --git a/tests/four.bþ b/tests/four.bþ new file mode 100644 index 0000000..8804fe4 --- /dev/null +++ b/tests/four.bþ @@ -0,0 +1 @@ +(+ 2 2) diff --git a/tests/four.out b/tests/four.out new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/tests/four.out @@ -0,0 +1 @@ +4 diff --git a/tests/vars.bþ b/tests/vars.bþ new file mode 100644 index 0000000..7799acf --- /dev/null +++ b/tests/vars.bþ @@ -0,0 +1,9 @@ +(do + (set a 5) + (set b 10) + (set thethe 1234) + (print (+ a b)) + (print (- thethe a)) + (print (+ (set a 90) b)) + (print a) + nil) diff --git a/tests/vars.out b/tests/vars.out new file mode 100644 index 0000000..bef4ee4 --- /dev/null +++ b/tests/vars.out @@ -0,0 +1,5 @@ +15 +1229 +100 +90 +nil @@ -54,7 +54,7 @@ void print_val(Val v) { printf("nil"); break; case TY_NUM: - printf("%f",AS_NUM(v)); + printf("%g",AS_NUM(v)); break; case TY_BOOL: printf("%s",AS_BOOL(v) ? "true" : "false"); @@ -57,7 +57,10 @@ int runvm(State *S) { int status = 1; - disasm_chunk(ch); + if (S->do_disasm) { + disasm_chunk(ch); + puts("---"); + } #define RBYTE() (ch->bc.d[th->ip++]) #define RSHORT() (th->ip += 2, (uint16_t)( ch->bc.d[th->ip-2] | ch->bc.d[th->ip-1] << 8 )) @@ -66,13 +69,11 @@ int runvm(State *S) { #define POP() (th->stack[--th->sp]) #define PEEK() (th->stack[th->sp-1]) - puts("---"); while (1) { uint8_t instr = RBYTE(); switch (instr) { case OP_RET: status = 0; - printf("done!\n"); goto done; break; case OP_LOADK: { |