diff options
Diffstat (limited to 'src/jq/codegen.zig')
| -rw-r--r-- | src/jq/codegen.zig | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/src/jq/codegen.zig b/src/jq/codegen.zig index 21c5832..6ca5382 100644 --- a/src/jq/codegen.zig +++ b/src/jq/codegen.zig @@ -1,9 +1,10 @@ const std = @import("std"); const jv = @import("../jv.zig"); +const ConstIndex = @import("./constant_table.zig").ConstIndex; const Ast = @import("./parse.zig").Ast; const BinaryOp = @import("./parse.zig").BinaryOp; -pub const ConstIndex = enum(u32) { _ }; +pub const VariableIndex = enum(u32) { _ }; pub const Opcode = enum { nop, @@ -11,6 +12,7 @@ pub const Opcode = enum { jump, jump_unless, fork, + backtrack, dup, pop, subexp_begin, @@ -30,8 +32,9 @@ pub const Opcode = enum { ge, alt, @"const", - const_true, - const_false, + load, + store, + append, }; pub const Instr = union(Opcode) { @@ -42,6 +45,7 @@ pub const Instr = union(Opcode) { jump: usize, jump_unless: usize, fork: usize, + backtrack, dup, pop, subexp_begin, @@ -61,8 +65,9 @@ pub const Instr = union(Opcode) { ge, alt, @"const": ConstIndex, - const_true, - const_false, + load: VariableIndex, + store: VariableIndex, + append: VariableIndex, pub fn op(self: Self) Opcode { return self; @@ -72,11 +77,13 @@ pub const Instr = union(Opcode) { const Codegen = struct { instrs: std.ArrayList(Instr), allocator: std.mem.Allocator, + variables_count: usize, fn init(allocator: std.mem.Allocator) !Codegen { return .{ .instrs = try std.ArrayList(Instr).initCapacity(allocator, 16), .allocator = allocator, + .variables_count = 0, }; } @@ -122,12 +129,12 @@ const Codegen = struct { // POP // <rhs> // JUMP_UNLESS l1 - // CONST_TRUE + // CONST true // JUMP l2 - // l1: CONST_FALSE + // l1: CONST false // l2: JUMP l4 // l3: POP - // CONST_FALSE + // CONST false // l4: try self.emit(.dup); try self.generate(and_expr.lhs); @@ -137,17 +144,17 @@ const Codegen = struct { try self.generate(and_expr.rhs); const jump2_idx = self.pos(); try self.emit(.{ .jump_unless = 0 }); - try self.emit(.const_true); + try self.emit(.{ .@"const" = .true }); const jump3_idx = self.pos(); try self.emit(.{ .jump = 0 }); const l1 = self.pos(); - try self.emit(.const_false); + try self.emit(.{ .@"const" = .false }); const jump4_idx = self.pos(); const l2 = self.pos(); try self.emit(.{ .jump = 0 }); const l3 = self.pos(); try self.emit(.pop); - try self.emit(.const_false); + try self.emit(.{ .@"const" = .false }); const l4 = self.pos(); self.patchLabel(jump1_idx, l3); @@ -160,21 +167,21 @@ const Codegen = struct { // <lhs> // JUMP_UNLESS l1 // POP - // CONST_TRUE + // CONST true // JUMP l3 // l1: POP // <rhs> // JUMP_UNLESS l2 - // CONST_TRUE + // CONST true // JUMP l3 - // l2: CONST_FALSE + // l2: CONST false // l3: try self.emit(.dup); try self.generate(or_expr.lhs); const jump1_idx = self.pos(); try self.emit(.{ .jump_unless = 0 }); try self.emit(.pop); - try self.emit(.const_true); + try self.emit(.{ .@"const" = .true }); const jump2_idx = self.pos(); try self.emit(.{ .jump = 0 }); const l1 = self.pos(); @@ -182,11 +189,11 @@ const Codegen = struct { try self.generate(or_expr.rhs); const jump3_idx = self.pos(); try self.emit(.{ .jump_unless = 0 }); - try self.emit(.const_true); + try self.emit(.{ .@"const" = .true }); const jump4_idx = self.pos(); try self.emit(.{ .jump = 0 }); const l2 = self.pos(); - try self.emit(.const_false); + try self.emit(.{ .@"const" = .false }); const l3 = self.pos(); self.patchLabel(jump1_idx, l1); @@ -215,6 +222,24 @@ const Codegen = struct { self.patchLabel(fork_index, l1); self.patchLabel(jump_index, l2); }, + .construct_array => |arr| { + // DUP + // CONST [] + // STORE v + // <items> + // APPEND v + // BACKTRACK + // LOAD v + const v: VariableIndex = @enumFromInt(self.variables_count); + self.variables_count += 1; + try self.emit(.dup); + try self.emit(.{ .@"const" = .empty_array }); + try self.emit(.{ .store = v }); + try self.generate(arr.items); + try self.emit(.{ .append = v }); + try self.emit(.backtrack); + try self.emit(.{ .load = v }); + }, } } |
