summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2024-06-21 12:56:30 +0100
committerubq323 <ubq323@ubq323.website>2024-06-21 12:56:30 +0100
commit21994864559386f1d11c001d6d27714cbf624a15 (patch)
treeb9a5e76bdc8be9a41970cd6620aab7a3637b7e6a
parent671645c370498955eb101695bd9099bf4caf5aea (diff)
add tests, and make dumping disasm optional
-rw-r--r--.gitignore1
-rw-r--r--Makefile7
-rw-r--r--com.c13
-rwxr-xr-xrun_tests.sh39
-rw-r--r--state.h2
-rw-r--r--test.bþ1
-rw-r--r--tests/compile_error.bþ1
-rw-r--r--tests/compile_error.out1
-rw-r--r--tests/fizzbuzz.bþ (renamed from fizzbuzz.bþ)0
-rw-r--r--tests/fizzbuzz.out30
-rw-r--r--tests/four.bþ1
-rw-r--r--tests/four.out1
-rw-r--r--tests/vars.bþ9
-rw-r--r--tests/vars.out5
-rw-r--r--val.c2
-rw-r--r--vm.c7
16 files changed, 107 insertions, 13 deletions
diff --git a/.gitignore b/.gitignore
index 276812f..17743a8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ prs.c
prs.h
vm
+gmon.out
diff --git a/Makefile b/Makefile
index 596f2a3..917c481 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/com.c b/com.c
index fbc93ac..93b0b59 100644
--- a/com.c
+++ b/com.c
@@ -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
+
diff --git a/state.h b/state.h
index 9563376..dab9a97 100644
--- a/state.h
+++ b/state.h
@@ -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
diff --git a/val.c b/val.c
index 18d0ffa..8e351ff 100644
--- a/val.c
+++ b/val.c
@@ -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");
diff --git a/vm.c b/vm.c
index 1dc40e0..667ceed 100644
--- a/vm.c
+++ b/vm.c
@@ -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: {