summaryrefslogtreecommitdiff
path: root/tests/bf.toc
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-03-03 17:05:28 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-03-03 17:05:28 -0500
commit2bf840925ba7781d16406ac28438f8bdc5f7d08c (patch)
treee70ca149eafd8eb4366a6ecf1edb1d4bed9e5aee /tests/bf.toc
parent0a3bb0c9ce4a2e96c7be3d0519aa0f5fa458c1af (diff)
new, better test system
Diffstat (limited to 'tests/bf.toc')
-rw-r--r--tests/bf.toc120
1 files changed, 120 insertions, 0 deletions
diff --git a/tests/bf.toc b/tests/bf.toc
new file mode 100644
index 0000000..e1f8781
--- /dev/null
+++ b/tests/bf.toc
@@ -0,0 +1,120 @@
+readfile ::= fn(filename: []char) []char {
+#C("extern void *fopen(char *name, char const *mode); extern char *fgets(char *buf, size_t sz, void *f);");
+ fp : &u8 = #C("fopen(&(((char *)filename.data)[0]), \"r\")");
+ contents : []char;
+ contents_sz : int;
+ contents_len : int;
+ buffer : [1024]char;
+ while #C("fgets(buffer, 1024, fp)") {
+ buffer_len : int;
+ while buffer[buffer_len] {
+ buffer_len = buffer_len + 1;
+ }
+ if contents_sz < contents_len + buffer_len {
+ old_contents := contents;
+ contents_sz = 2*contents_sz + 1024;
+ contents = new(char, contents_sz);
+ i := 0;
+ while i < contents_len {
+ contents[i] = old_contents[i];
+ i = i + 1;
+ }
+ del(old_contents);
+ }
+ i := 0;
+ while i < buffer_len {
+ contents[contents_len] = buffer[i];
+ contents_len = contents_len + 1;
+ i = i + 1;
+ }
+ }
+ contents[contents_len] = 0 as char;
+ contents
+};
+
+puti ::= fn(x: int) {
+ #C("#ifndef __TINYC__
+extern int printf(const char *fmt, ...);
+#endif
+");
+ #C("printf(\"%ld\\n\", x);");
+};
+
+runfile ::= fn(filename: []char) {
+ #C("extern int putchar(int c);");
+ code := readfile(filename);
+ 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] == '-' {
+ tape[ptr] = tape[ptr]-1;
+ } elif code[i] == '>' {
+ ptr = ptr + 1;
+ if ptr >= tape_sz {
+ // 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 {
+ // 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 to matching ]
+ level := 0;
+ while level >= 0 {
+ i = i + 1;
+ level = level + (if code[i] == '[' { 1 } elif code[i] == ']' { -1 } else {0});
+ }
+ }
+ } elif code[i] == ']' {
+ if tape[ptr] {
+ // jump to matching [
+ level := 0;
+ while level <= 0 {
+ i = i - 1;
+ level = level + (if code[i] == '[' { 1 } elif code[i] == ']' { -1 } else {0});
+ }
+ }
+ } elif code[i] == '.' {
+ c := tape[ptr] as char;
+ #C("putchar(c);");
+ } elif code[i] == ',' {
+ // Input doesn't really work, because you
+ // need to send an EOF to end the program.
+ }
+ i = i + 1;
+ }
+ del(tape);
+ del(code);
+};
+
+main ::= fn() {
+ runfile("bf_hw0");
+ runfile("bf_hw1");
+};