summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--main.c9
-rw-r--r--tests/bf/bf.toc (renamed from tests/bf.toc)52
-rw-r--r--tests/bf/hw0.bf1
-rw-r--r--tests/bf/hw1.bf2
-rwxr-xr-xtests/bf/test.sh9
-rwxr-xr-xtests/test.sh29
7 files changed, 88 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore
index 9da0770..02d75f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
toc
a.out
out.c
+tests/**/*.c
+tests/**/*.bin
diff --git a/main.c b/main.c
index 419ed04..aafdd19 100644
--- a/main.c
+++ b/main.c
@@ -24,6 +24,13 @@ int main(int argc, char **argv) {
}
const char *in_filename = argv[1];
+ const char *out_filename = "out.c";
+
+ for (int i = 2; i < argc-1; i++) {
+ if (strcmp(argv[i], "-o") == 0)
+ out_filename = argv[i+1];
+ }
+
FILE *in = fopen(in_filename, "r");
if (!in) {
fprintf(stderr, "Could not open file: %s.\n", argv[1]);
@@ -89,7 +96,7 @@ int main(int argc, char **argv) {
parse_printing_after_types = true;
fprint_parsed_file(stdout, &f);
- FILE *out = fopen("out.c", "w");
+ FILE *out = fopen(out_filename, "w");
if (!out) {
err_fprint(TEXT_IMPORTANT("Could not open output file (out.c).\n"));
return EXIT_FAILURE;
diff --git a/tests/bf.toc b/tests/bf/bf.toc
index d0ca413..ef0c086 100644
--- a/tests/bf.toc
+++ b/tests/bf/bf.toc
@@ -8,7 +8,7 @@ getstdin @= fn() []char {
while buffer[buffer_len] {
buffer_len = buffer_len + 1;
}
- if contents_sz < buffer_len {
+ if contents_sz < contents_len + buffer_len {
old_contents := contents;
contents_sz = 2*contents_sz + 1024;
contents = new(char, contents_sz);
@@ -30,13 +30,19 @@ getstdin @= fn() []char {
contents
};
+puti @= fn(x: int) {
+ #C("printf(\"%ld\\n\", x)");
+};
+
main @= fn() {
code := getstdin();
- tape_sz := 100;
+ tape_sz := 3;
tape := new(int, tape_sz);
ptr := tape_sz / 2;
i := 0;
while code[i] {
+ // puti(ptr);
+ // puti(tape_sz);
if code[i] == '+' {
tape[ptr] = tape[ptr]+1;
} elif code[i] == '-' {
@@ -44,43 +50,59 @@ main @= fn() {
} elif code[i] == '>' {
ptr = ptr + 1;
if ptr >= tape_sz {
- // TODO
+ // extend to the right
+ newtape := new(int, 2*tape_sz);
+ j := 0;
+ while j < tape_sz {
+ newtape[j] = tape[j];
+ j = j + 1;
+ }
+ tape_sz = tape_sz * 2;
+ del(tape);
+ tape = newtape;
}
} elif code[i] == '<' {
ptr = ptr - 1;
if ptr < 0 {
- // TODO
+ // extend to the left
+ newtape := new(int, 2*tape_sz);
+ j := 0;
+ while j < tape_sz {
+ newtape[j+tape_sz] = tape[j];
+ j = j + 1;
+ }
+ tape_sz = tape_sz * 2;
+ del(tape);
+ tape = newtape;
+ ptr = ptr + tape_sz;
}
} elif code[i] == '[' {
if !tape[ptr] {
- // jump past matching ]
+ // jump to matching ]
level := 0;
- i = i + 1;
while level >= 0 {
- level = level + (if code[i] == '[' { 1 } elif code[i] == ']' { -1 } else {0});
i = i + 1;
+ level = level + (if code[i] == '[' { 1 } elif code[i] == ']' { -1 } else {0});
}
- i = i + 1;
}
} elif code[i] == ']' {
if tape[ptr] {
- // jump to right after matching [
+ // jump to matching [
level := 0;
- i = i - 1;
while level <= 0 {
- level = level + (if code[i] == '[' { 1 } elif code[i] == ']' { -1 } else {0});
i = i - 1;
+ level = level + (if code[i] == '[' { 1 } elif code[i] == ']' { -1 } else {0});
}
- i = i + 1;
}
} elif code[i] == '.' {
c := tape[ptr] as char;
#C("putc(c, stdout)");
} elif code[i] == ',' {
- c : char = #C("getc(stdin)");
- tape[ptr] = c as int;
+ // Input doesn't really work, because you
+ // need to send an EOF to end the program.
}
i = i + 1;
}
-
+ del(tape);
+ del(code);
}; \ No newline at end of file
diff --git a/tests/bf/hw0.bf b/tests/bf/hw0.bf
new file mode 100644
index 0000000..ea2b641
--- /dev/null
+++ b/tests/bf/hw0.bf
@@ -0,0 +1 @@
+++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++. \ No newline at end of file
diff --git a/tests/bf/hw1.bf b/tests/bf/hw1.bf
new file mode 100644
index 0000000..db5525f
--- /dev/null
+++ b/tests/bf/hw1.bf
@@ -0,0 +1,2 @@
+>++++++++[-<+++++++++>]<.>>+>-[+]++>++>+++[>[->+++<<+++>]<<]>-----.>->
++++..+++.>-.<<+[>[+>+]>>]<--------------.>>.+++.------.--------.>+.>+. \ No newline at end of file
diff --git a/tests/bf/test.sh b/tests/bf/test.sh
new file mode 100755
index 0000000..8b76794
--- /dev/null
+++ b/tests/bf/test.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+if [ "$(cat hw0.bf | ./bf.bin)" != "Hello World!" ]; then
+ echo "hello world 0 failed."
+ exit 1
+fi
+if [ "$(cat hw1.bf | ./bf.bin)" != "Hello World!" ]; then
+ echo "hello world 1 failed."
+ exit 1
+fi
diff --git a/tests/test.sh b/tests/test.sh
new file mode 100755
index 0000000..470251e
--- /dev/null
+++ b/tests/test.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+DIR=$(dirname $0)
+TOC=$DIR/../toc
+CFLAGS="-g -Wno-parentheses-equality"
+if [ "$COMPILERS" = "" ]; then
+ COMPILERS="gcc tcc clang"
+fi
+
+echo $$
+
+compile() {
+ $TOC $DIR/$1/$1.toc -o $DIR/$1/$1.c > /dev/null || exit 1
+ $CC $EXTRA_CFLAGS $CFLAGS -o $DIR/$1/$1.bin $DIR/$1/$1.c || exit 1
+}
+
+STARTPWD="$(pwd)"
+
+for CC in $COMPILERS; do
+
+ for EXTRA_CFLAGS in "-O0 -g" "-O3 -s"; do
+ echo "Running tests with C compiler $CC and flags $EXTRA_CFLAGS."
+ printf "bf... "
+ compile bf
+ cd $DIR/bf
+ ./test.sh || exit 1
+ echo "passed!"
+ cd $STARTPWD
+ done
+done