diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-01-25 19:52:35 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-01-25 19:52:40 +0900 |
| commit | 7fb93cc98fc7738e160bd6bc896cbafe7a1aadcc (patch) | |
| tree | 9d57e69cbd84754ca623fc32f9c4f6b4be5bd076 | |
| parent | f9c85486d8ecac3b5e151a4b89f142167e46356c (diff) | |
| download | zgjq-7fb93cc98fc7738e160bd6bc896cbafe7a1aadcc.tar.gz zgjq-7fb93cc98fc7738e160bd6bc896cbafe7a1aadcc.tar.zst zgjq-7fb93cc98fc7738e160bd6bc896cbafe7a1aadcc.zip | |
merge array_index and object_key into index
| -rw-r--r-- | src/jq/compile.zig | 22 | ||||
| -rw-r--r-- | src/jq/execute.zig | 38 | ||||
| -rw-r--r-- | src/jq/parse.zig | 16 |
3 files changed, 38 insertions, 38 deletions
diff --git a/src/jq/compile.zig b/src/jq/compile.zig index 5ed1806..9a62bc0 100644 --- a/src/jq/compile.zig +++ b/src/jq/compile.zig @@ -12,7 +12,7 @@ pub const Opcode = enum { fork, subexp_begin, subexp_end, - array_index, + index, add, sub, mul, @@ -24,7 +24,6 @@ pub const Opcode = enum { gt, le, ge, - object_key, @"const", }; @@ -37,7 +36,7 @@ pub const Instr = union(Opcode) { fork: usize, subexp_begin, subexp_end, - array_index, + index, add, sub, mul, @@ -49,19 +48,11 @@ pub const Instr = union(Opcode) { gt, le, ge, - object_key: []const u8, @"const": ConstIndex, pub fn op(self: Self) Opcode { return self; } - - pub fn deinit(self: Self, allocator: std.mem.Allocator) void { - switch (self) { - .object_key => |key| allocator.free(key), - else => {}, - } - } }; fn compileExpr(allocator: std.mem.Allocator, compile_allocator: std.mem.Allocator, ast: *const Ast) ![]Instr { @@ -69,18 +60,17 @@ fn compileExpr(allocator: std.mem.Allocator, compile_allocator: std.mem.Allocato switch (ast.*) { .identity => try instrs.append(allocator, .nop), - .array_index => |arr_idx| { - const base_instrs = try compileExpr(allocator, compile_allocator, arr_idx.base); + .index => |index| { + const base_instrs = try compileExpr(allocator, compile_allocator, index.base); defer allocator.free(base_instrs); - const index_instrs = try compileExpr(allocator, compile_allocator, arr_idx.index); + const index_instrs = try compileExpr(allocator, compile_allocator, index.index); defer allocator.free(index_instrs); try instrs.appendSlice(allocator, base_instrs); try instrs.append(allocator, .subexp_begin); try instrs.appendSlice(allocator, index_instrs); try instrs.append(allocator, .subexp_end); - try instrs.append(allocator, .array_index); + try instrs.append(allocator, .index); }, - .object_key => |key| try instrs.append(allocator, .{ .object_key = key }), .literal => |idx| try instrs.append(allocator, .{ .@"const" = idx }), .binary_expr => |binary_expr| { const rhs_instrs = try compileExpr(allocator, compile_allocator, binary_expr.rhs); diff --git a/src/jq/execute.zig b/src/jq/execute.zig index ce8a2fc..2afb7b7 100644 --- a/src/jq/execute.zig +++ b/src/jq/execute.zig @@ -136,12 +136,7 @@ pub const Runtime = struct { } } self.constants.deinit(self.allocator); - - for (self.instrs) |instr| { - instr.deinit(self.allocator); - } self.allocator.free(self.instrs); - self.values.deinit(); self.forks.deinit(self.allocator); } @@ -193,12 +188,30 @@ pub const Runtime = struct { }, .subexp_begin => try self.values.dup(), .subexp_end => try self.values.swap(), - .array_index => { + .index => { std.debug.assert(self.values.ensureSize(2)); - const array = try self.values.popArray(); - const index: usize = @intCast(try self.values.popInteger()); - const result = if (index < array.items.len) array.items[index] else .null; + const base = self.values.pop(); + const key = self.values.pop(); + + const result = switch (base) { + .array => |arr| blk: { + const idx: usize = @intCast(switch (key) { + .integer => |i| i, + else => return error.InvalidType, + }); + break :blk if (idx < arr.items.len) arr.items[idx] else .null; + }, + .object => |obj| blk: { + const k = switch (key) { + .string => |s| s, + else => return error.InvalidType, + }; + break :blk obj.get(k) orelse .null; + }, + .null => .null, + else => return error.InvalidType, + }; try self.values.push(result); }, .add => { @@ -300,13 +313,6 @@ pub const Runtime = struct { const result = try compareValues(lhs, rhs, .ge); try self.values.push(.{ .bool = result }); }, - .object_key => |key| { - std.debug.assert(self.values.ensureSize(1)); - - const obj = try self.values.popObject(); - const result = obj.get(key) orelse .null; - try self.values.push(result); - }, .@"const" => |idx| { std.debug.assert(self.values.ensureSize(1)); diff --git a/src/jq/parse.zig b/src/jq/parse.zig index afcf0e6..b257567 100644 --- a/src/jq/parse.zig +++ b/src/jq/parse.zig @@ -11,8 +11,7 @@ pub const ParseError = error{ pub const AstKind = enum { identity, - array_index, - object_key, + index, literal, binary_expr, pipe, @@ -46,8 +45,7 @@ pub const BinaryOp = enum { pub const Ast = union(AstKind) { identity, - array_index: struct { base: *Ast, index: *Ast }, - object_key: []const u8, + index: struct { base: *Ast, index: *Ast }, literal: ConstIndex, binary_expr: struct { op: BinaryOp, lhs: *Ast, rhs: *Ast }, pipe: struct { lhs: *Ast, rhs: *Ast }, @@ -390,8 +388,14 @@ const Parser = struct { }, .field => |name| { _ = try self.tokens.next(); + const base_ast = try self.parse_allocator.create(Ast); + base_ast.* = .identity; + try self.constants.append(self.allocator, .{ .string = try self.allocator.dupe(u8, name) }); + const idx: ConstIndex = @enumFromInt(self.constants.items.len - 1); + const key_ast = try self.parse_allocator.create(Ast); + key_ast.* = .{ .literal = idx }; const ast = try self.parse_allocator.create(Ast); - ast.* = .{ .object_key = try self.allocator.dupe(u8, name) }; + ast.* = .{ .index = .{ .base = base_ast, .index = key_ast } }; return ast; }, else => return error.InvalidQuery, @@ -409,7 +413,7 @@ const Parser = struct { index_node.* = .{ .literal = idx }; const ast = try self.parse_allocator.create(Ast); - ast.* = .{ .array_index = .{ .base = base, .index = index_node } }; + ast.* = .{ .index = .{ .base = base, .index = index_node } }; return ast; } }; |
