commit 443781e92502d53fafb64a6914b66f221e9c3bf6
parent 830dead3769cf6c3a2c37e2700818cb4666d875f
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Tue, 27 Jan 2026 21:34:14 +0000
started interpreter
Diffstat:
7 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1 +0,0 @@
-bf
diff --git a/Makefile b/Makefile
@@ -12,6 +12,9 @@ HARE_SOURCES != find . -name '*.ha'
all: bf
+bf: $(HARE_SOURCES)
+ $(HARE) build $(HAREFLAGS) -o $@ cmd/$@/
+
clean:
rm -f bf
@@ -23,5 +26,3 @@ check:
.PHONY: all check clean install uninstall
-bf: $(HARE_SOURCES)
- $(HARE) build $(HAREFLAGS) -o $@ cmd/$@/
diff --git a/bf b/bf
Binary files differ.
diff --git a/brainf/parse.ha b/brainf/parse.ha
@@ -0,0 +1,29 @@
+use io;
+use fmt;
+use bufio;
+
+export fn load(h: io::handle, inblock: bool = false) (*block | io::EOF | io::error) = {
+ let insts: [](u8 | *block) = [];
+
+ for (true) {
+ let c = match (bufio::read_byte(h)?) {
+ case let c: u8 => yield c;
+ case io::EOF =>
+ if (inblock) fmt::fatal("unexpected EOF");
+ return alloc(insts)!: *block;
+ };
+
+ switch (c) {
+ case '+', '-', '>', '<', '.', ',' => append(insts, c)!;
+ case '[' =>
+ let nested = load(h, true)! as *block;
+ append(insts, nested)!;
+ case ']' => return alloc(insts)!: *block;
+ case => fmt::fatalf("unexpected token type {}", c: rune);
+ };
+ };
+};
+
+export fn finish(b: *block) void = {
+ free(b);
+};
diff --git a/brainf/run.ha b/brainf/run.ha
@@ -0,0 +1,25 @@
+use fmt;
+
+export fn run(b: *block, arr: *[]u8, ptr: i32 = 0) void = {
+ for (let inst .. b) {
+ match (inst) {
+ case let nested: *block =>
+ for (arr[ptr] != 0)
+ run(nested, arr, ptr);
+ case let c: u8 =>
+ switch (c: rune) {
+ case '+' => arr[ptr] += 1;
+ case '-' => arr[ptr] -= 1;
+ case '>' =>
+ ptr += 1;
+ if (ptr > (len(arr) - 1): i32) ptr = 0;
+ case '<' =>
+ ptr -= 1;
+ if (ptr < 0) ptr = (len(arr) - 1): i32;
+ case ',' => arr[ptr] = 0; // TODO stdin
+ case '.' => fmt::print(arr[ptr]: rune)!;
+ case => abort();
+ };
+ };
+ };
+};
diff --git a/brainf/types.ha b/brainf/types.ha
@@ -0,0 +1 @@
+export type block = [](u8 | *block);
diff --git a/cmd/bf/main.ha b/cmd/bf/main.ha
@@ -0,0 +1,27 @@
+use fmt;
+use io;
+use bufio;
+use memio;
+use strings;
+
+use brainf;
+
+fn printblock(b: *brainf::block) void = {
+ for (let inst .. b) {
+ match (inst) {
+ case let c: u8 => fmt::print(c: rune)!;
+ case let b: *brainf::block =>
+ fmt::println()!;
+ printblock(b);
+ fmt::println()!;
+ };
+ };
+};
+
+export fn main() void = {
+ let in = &memio::fixed(strings::toutf8("+[[->]-[-<]>-]>.>>>>.<<<<-.>>-.>.<<.>>>>-.<<<<<++.>>++.")).stream;
+ let b = brainf::load(in) as *brainf::block;
+
+ let arr: []u8 = alloc([0...], 30000)!;
+ brainf::run(b, &arr);
+};