aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/jq
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-08 15:52:26 +0900
committernsfisis <nsfisis@gmail.com>2026-02-08 15:52:26 +0900
commitc9db46235ed5b8c51935ac105874909400e9ec93 (patch)
tree30cad69a359a8f9a58550e0b73065218242b57cd /src/jq
parentbeff4b6048cc3783d538769a307f8e679a33894c (diff)
downloadzgjq-c9db46235ed5b8c51935ac105874909400e9ec93.tar.gz
zgjq-c9db46235ed5b8c51935ac105874909400e9ec93.tar.zst
zgjq-c9db46235ed5b8c51935ac105874909400e9ec93.zip
support --debug-dump-disasm
Diffstat (limited to 'src/jq')
-rw-r--r--src/jq/codegen.zig39
-rw-r--r--src/jq/execute.zig10
2 files changed, 44 insertions, 5 deletions
diff --git a/src/jq/codegen.zig b/src/jq/codegen.zig
index 23383bf..1fc889d 100644
--- a/src/jq/codegen.zig
+++ b/src/jq/codegen.zig
@@ -38,6 +38,22 @@ pub const Opcode = enum {
store,
append,
each,
+
+ pub fn name(self: Opcode) []const u8 {
+ switch (self) {
+ inline else => |tag| {
+ const tag_name = @tagName(tag);
+ const upper_tag_name = comptime blk: {
+ var buf: [tag_name.len]u8 = undefined;
+ for (tag_name, 0..) |c, i| {
+ buf[i] = std.ascii.toUpper(c);
+ }
+ break :blk buf;
+ };
+ return &upper_tag_name;
+ },
+ }
+ }
};
pub const Instr = union(Opcode) {
@@ -304,3 +320,26 @@ pub fn codegen(allocator: std.mem.Allocator, ast: *const Ast) ![]Instr {
try gen.emit(.ret);
return gen.toOwnedSlice();
}
+
+pub fn disasm(allocator: std.mem.Allocator, instrs: []const Instr, constants: []const jv.Value, writer: *std.Io.Writer) !void {
+ for (instrs, 0..) |instr, i| {
+ try writer.print("{d:0>4} ", .{i});
+ try writer.writeAll(instr.op().name());
+ switch (instr) {
+ // program address
+ .jump, .jump_unless, .fork => |offset| try writer.print(" {d:0>4}", .{i + offset}),
+ // constant index
+ .@"const" => |idx| {
+ try writer.writeAll(" ");
+ const k = try jv.stringify(allocator, constants[@intFromEnum(idx)]);
+ defer allocator.free(k);
+ try writer.writeAll(k);
+ },
+ // variable index
+ .load, .store, .append => |idx| try writer.print(" ${d}", .{@intFromEnum(idx)}),
+ // no arguments
+ else => {},
+ }
+ try writer.writeAll("\n");
+ }
+}
diff --git a/src/jq/execute.zig b/src/jq/execute.zig
index d8081e6..cee7845 100644
--- a/src/jq/execute.zig
+++ b/src/jq/execute.zig
@@ -4,6 +4,7 @@ const tokenize = @import("./tokenize.zig").tokenize;
const parse = @import("./parse.zig").parse;
const Instr = @import("./codegen.zig").Instr;
const codegen = @import("./codegen.zig").codegen;
+const disasm = @import("./codegen.zig").disasm;
pub const ExecuteError = error{
Unimplemented,
@@ -189,11 +190,6 @@ pub const Runtime = struct {
const ast = try parse(self.allocator, compile_allocator.allocator(), tokens, &self.constants);
const instrs = try codegen(self.allocator, ast);
self.instrs = instrs;
- // std.debug.print("BEGIN\n", .{});
- // for (self.instrs) |instr| {
- // std.debug.print("{}\n", .{instr});
- // }
- // std.debug.print("END\n", .{});
}
pub fn compileFromSlice(self: *Self, query: []const u8) !void {
@@ -201,6 +197,10 @@ pub const Runtime = struct {
return self.compileFromReader(&reader);
}
+ pub fn dumpDisasm(self: *const Self, writer: *std.Io.Writer) !void {
+ try disasm(self.allocator, self.instrs, self.constants.items, writer);
+ }
+
pub fn start(self: *Self, input: jv.Value) !void {
try self.values.push(input.clone());
}