commit 7a7226da8471bf74df4fb0de08efd21a17a243e9
parent 1d17a5014c2bde5c7c11b1d422af3a6de292d0bc
Author: Walther Chen <walther.chen@gmail.com>
Date: Sun, 6 Nov 2022 23:15:31 -0500
parse for real
Diffstat:
M | src/main.zig | | | 50 | +++++++++++++++++++++++++++++++++++++++----------- |
1 file changed, 39 insertions(+), 11 deletions(-)
diff --git a/src/main.zig b/src/main.zig
@@ -21,15 +21,30 @@ pub fn main() anyerror!void {
var stdout = std.io.getStdOut();
var memory = [_]u8{0} ** MEMORY_SIZE;
- try interpret(src, &memory, stdin.reader(), stdout.writer());
+ const program = try parse(src, alloc);
+ defer program.deinit();
+ try interpret(program, &memory, stdin.reader(), stdout.writer());
}
-fn interpret(src: []const u8, memory: []u8, rdr: anytype, wtr: anytype) !void {
+fn parse(src: []const u8, alloc: std.mem.Allocator) !Program {
+ var instructions = ArrayList(u8).init(alloc);
+
+ for (src) |c| {
+ switch (c) {
+ '>', '<', '+', '-', '.', ',', '[', ']' => try instructions.append(c),
+ else => {},
+ }
+ }
+ return .{ .instructions = instructions.toOwnedSlice(), .alloc = alloc };
+}
+
+fn interpret(program: Program, memory: []u8, rdr: anytype, wtr: anytype) !void {
var pc: usize = 0;
var dataptr: usize = 0;
- while (pc < src.len) {
- const instruction = src[pc];
+ while (pc < program.instructions.len) {
+ const instructions = program.instructions;
+ const instruction = instructions[pc];
switch (instruction) {
'>' => dataptr += 1,
@@ -47,12 +62,12 @@ fn interpret(src: []const u8, memory: []u8, rdr: anytype, wtr: anytype) !void {
var bracket_nesting: usize = 1;
var saved_pc = pc; // used for error message only
- while (bracket_nesting != 0 and pc < src.len - 1) {
+ while (bracket_nesting != 0 and pc < instructions.len - 1) {
pc += 1;
- if (src[pc] == ']') {
+ if (instructions[pc] == ']') {
bracket_nesting -= 1;
- } else if (src[pc] == '[') {
+ } else if (instructions[pc] == '[') {
bracket_nesting += 1;
}
}
@@ -73,9 +88,9 @@ fn interpret(src: []const u8, memory: []u8, rdr: anytype, wtr: anytype) !void {
while (bracket_nesting != 0 and pc > 0) {
pc -= 1;
- if (src[pc] == '[') {
+ if (instructions[pc] == '[') {
bracket_nesting -= 1;
- } else if (src[pc] == ']') {
+ } else if (instructions[pc] == ']') {
bracket_nesting += 1;
}
}
@@ -84,13 +99,24 @@ fn interpret(src: []const u8, memory: []u8, rdr: anytype, wtr: anytype) !void {
std.debug.print("unmatched ']' at pc={}", .{saved_pc});
}
},
- else => {},
+ else => {
+ return error.unreachableChar;
+ },
}
pc += 1;
}
}
+const Program = struct {
+ alloc: std.mem.Allocator,
+ instructions: []const u8,
+
+ fn deinit(self: Program) void {
+ self.alloc.free(self.instructions);
+ }
+};
+
test "hello world" {
const hello_world = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";
@@ -104,6 +130,8 @@ test "hello world" {
var rdr = empty_in.reader();
var wtr = list.writer();
- try interpret(hello_world, &memory, rdr, wtr);
+ const program = try parse(hello_world, std.testing.allocator);
+ defer program.deinit();
+ try interpret(program, &memory, rdr, wtr);
try expectEqualSlices(u8, "Hello World!\n", list.items);
}