zahl

Log | Files | Refs | README

chunk.zig (3041B)


      1 const std = @import("std");
      2 const value = @import("value.zig");
      3 
      4 pub const Op = union(enum) {
      5     // Finish execution of current function
      6     @"return",
      7 
      8     // Set current pc to this if the condition is false
      9     jumpfalse: u32,
     10 
     11     // Jump absolute to the target
     12     jump: u32,
     13 
     14     // ..[a] -> ..
     15     pop,
     16 
     17     // .. -> ..[c]
     18     @"constant": u32,
     19 
     20     // ..[v].. -> ..[v]..[v]
     21     @"local": u32,
     22 
     23     // .. -> ..[g]
     24     get_global: u32,
     25 
     26     // ..[g] -> ..
     27     define_global: u32,
     28 
     29     // ..[scope...][top...] -> ..[top...]
     30     popscope: struct {
     31         offset: u16,
     32         scope: u16
     33     },
     34 
     35     // ..[a] -> ..[-a]
     36     negate,
     37 
     38     // ..[args..] -> ..[ret]
     39     call: usize,
     40 
     41     // ..[r][l] -> ..[l op r]
     42     add,
     43     substract,
     44     multiply,
     45     pow,
     46 
     47     // ..[r][l] -> ..[l cmp r]
     48     compare: std.math.CompareOperator,
     49 
     50     // ..[v] -> ..[v]
     51     print,
     52 
     53     // ..[r][l] -> ..[l/r][l%r]
     54     div,
     55 
     56     // ..[(lst.. )][h] -> ..[(h lst..)]
     57     cons,
     58 
     59     // ..[(h lst..)] -> ..[(lst..)][h]
     60     uncons,
     61 };
     62 
     63 var _ = std.debug.assert(@sizeOf(Op) == 4);
     64 
     65 pub const Chunk = struct {
     66     const Self = @This();
     67 
     68     const Instrs = std.ArrayList(Op);
     69     const Values = std.ArrayList(*value.Value);
     70 
     71     instrs: Instrs,
     72     values: Values,
     73 
     74     pub fn init(all: std.mem.Allocator) Self {
     75         return Self {
     76             .instrs = Instrs.init(all),
     77             .values = Values.init(all)
     78         };
     79     }
     80 
     81     pub fn deinit(self: *Self) void {
     82         self.instrs.deinit();
     83 
     84         for (self.values.items) |val| {
     85             val.unref();
     86         }
     87 
     88         self.values.deinit();
     89     }
     90 
     91     pub fn write(self: *Self, instr: Op) !void {
     92         try self.instrs.append(instr);
     93     }
     94 
     95     pub fn addConstant(self: *Self, val: *value.Value) !u32 {
     96         try self.values.append(val);
     97         return @intCast(self.values.items.len - 1);
     98     }
     99 
    100     pub fn disassembleInstr(self: Self, instr: Op) void {
    101         std.debug.print("{s} ", .{@tagName(instr)});
    102         switch (instr) {
    103             inline .@"constant", .get_global, .define_global => |vindex| {
    104                 const num = self.values.items[vindex];
    105                 std.debug.print("{}", .{num.formatter()});
    106             },
    107 
    108             inline .call, .compare => |cval| {
    109                 std.debug.print("{}", .{cval});
    110             },
    111 
    112             inline .@"local", .jumpfalse, .jump => |vindex| {
    113                 std.debug.print("{}", .{vindex});
    114             },
    115 
    116             .popscope => |params| {
    117                 std.debug.print("offset={} scope={}", .{params.offset, params.scope});
    118             },
    119 
    120             inline else => {},
    121         }
    122         std.debug.print("\n", .{});
    123     }
    124 
    125     pub fn disassemble(self: Self) void {
    126         for (self.instrs.items, 0..) |instr, pc| {
    127             std.debug.print("{:04} |\t", .{pc});
    128             self.disassembleInstr(instr);
    129         }
    130     }
    131 
    132     pub fn lastInstrRef(self: *Self) usize {
    133         return self.instrs.items.len - 1;
    134     }
    135 
    136     pub fn nextPc(self: *const Self) u32 {
    137         return @intCast(self.instrs.items.len);
    138     }
    139 };
    140