getstdin ::= fn() []char { contents : []char; contents_sz : int; contents_len : int; buffer : [1024]char; while #C("fgets(buffer, 1024, stdin)") { 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("printf(\"%ld\\n\", x)"); }; main ::= fn() { code := getstdin(); 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("putc(c, stdout)"); } 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); };