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 }