og.zig (2596B) - raw
1 const std = @import("std"); 2 const common = @import("common.zig"); 3 const Program = common.Program; 4 5 pub fn main() anyerror!void { 6 try common.runInterpreter(common.parseProgram, interpret); 7 } 8 9 test "og: interpret hello world" { 10 try common.testHelloWorld(common.parseProgram, interpret); 11 } 12 13 fn interpret(program: Program, memory: []u8, rdr: anytype, wtr: anytype, alloc: std.mem.Allocator) !void { 14 _ = alloc; 15 16 const instructions = program.instructions; 17 var pc: usize = 0; 18 var dataptr: usize = 0; 19 20 while (pc < instructions.len) { 21 const instruction = instructions[pc]; 22 23 switch (instruction) { 24 '>' => dataptr += 1, 25 '<' => dataptr -= 1, 26 '+' => memory[dataptr] += 1, 27 '-' => memory[dataptr] -= 1, 28 ',' => memory[dataptr] = try rdr.readByte(), 29 '.' => try wtr.writeByte(memory[dataptr]), 30 // jumps to next matching ']' if curr_data == 0 31 '[' => blk: { 32 if (memory[dataptr] != 0) { 33 break :blk; 34 } 35 36 var bracket_nesting: usize = 1; 37 const saved_pc = pc; // used for error message only 38 39 while (bracket_nesting != 0 and pc < instructions.len - 1) { 40 pc += 1; 41 42 if (instructions[pc] == ']') { 43 bracket_nesting -= 1; 44 } else if (instructions[pc] == '[') { 45 bracket_nesting += 1; 46 } 47 } 48 49 if (bracket_nesting != 0) { 50 std.debug.print("unmatched '[' at pc={}", .{saved_pc}); 51 } 52 }, 53 // jumps to previous matching ']' if curr data != 0 54 ']' => blk: { 55 if (memory[dataptr] == 0) { 56 break :blk; 57 } 58 59 var bracket_nesting: usize = 1; 60 const saved_pc = pc; // used for error message only 61 62 while (bracket_nesting != 0 and pc > 0) { 63 pc -= 1; 64 65 if (instructions[pc] == '[') { 66 bracket_nesting -= 1; 67 } else if (instructions[pc] == ']') { 68 bracket_nesting += 1; 69 } 70 } 71 72 if (bracket_nesting != 0) { 73 std.debug.print("unmatched ']' at pc={}", .{saved_pc}); 74 } 75 }, 76 else => { 77 return error.unreachableChar; 78 }, 79 } 80 81 pc += 1; 82 } 83 }