aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/jq
diff options
context:
space:
mode:
Diffstat (limited to 'src/jq')
-rw-r--r--src/jq/compile.zig3
-rw-r--r--src/jq/execute.zig13
-rw-r--r--src/jq/parse.zig15
3 files changed, 31 insertions, 0 deletions
diff --git a/src/jq/compile.zig b/src/jq/compile.zig
index ddb4be5..0c30a3d 100644
--- a/src/jq/compile.zig
+++ b/src/jq/compile.zig
@@ -5,12 +5,14 @@ const Ast = @import("./parse.zig").Ast;
pub const Opcode = enum {
nop,
array_index,
+ object_key,
literal,
};
pub const Instr = union(Opcode) {
nop,
array_index,
+ object_key: []const u8,
literal: *jv.Value,
pub fn op(self: @This()) Opcode {
@@ -29,6 +31,7 @@ pub fn compile(allocator: std.mem.Allocator, compile_allocator: std.mem.Allocato
try instrs.appendSlice(allocator, index_instrs);
try instrs.append(allocator, .array_index);
},
+ .object_key => |key| try instrs.append(allocator, .{ .object_key = key }),
.literal => |value| try instrs.append(allocator, .{ .literal = value }),
}
diff --git a/src/jq/execute.zig b/src/jq/execute.zig
index a07204a..8e9bbb0 100644
--- a/src/jq/execute.zig
+++ b/src/jq/execute.zig
@@ -66,6 +66,14 @@ const ValueStack = struct {
else => error.InvalidType,
};
}
+
+ pub fn popObject(self: *Self) ExecuteError!jv.Object {
+ const value = try self.pop();
+ return switch (value) {
+ .object => |o| o,
+ else => error.InvalidType,
+ };
+ }
};
pub fn execute(allocator: std.mem.Allocator, instrs: []const Instr, input: jv.Value) !jv.Value {
@@ -86,6 +94,11 @@ pub fn execute(allocator: std.mem.Allocator, instrs: []const Instr, input: jv.Va
const result = if (index < array.items.len) array.items[index] else .null;
try value_stack.push(result);
},
+ .object_key => |key| {
+ const obj = try value_stack.popObject();
+ const result = obj.get(key) orelse .null;
+ try value_stack.push(result);
+ },
.literal => |value| {
try value_stack.push(value.*);
},
diff --git a/src/jq/parse.zig b/src/jq/parse.zig
index 5269ef5..dc9f6b9 100644
--- a/src/jq/parse.zig
+++ b/src/jq/parse.zig
@@ -10,12 +10,14 @@ pub const ParseError = error{
pub const AstKind = enum {
identity,
array_index,
+ object_key,
literal,
};
pub const Ast = union(AstKind) {
identity,
array_index: *Ast,
+ object_key: []const u8,
literal: *jv.Value,
pub fn kind(self: @This()) AstKind {
@@ -42,6 +44,19 @@ pub fn parse(allocator: std.mem.Allocator, tokens: []const Token) !*Ast {
return root;
}
+ if (t2.kind() == .identifier) {
+ i += 1;
+ const t3 = tokens[i];
+ if (t3.kind() != .end) {
+ return error.InvalidQuery;
+ }
+ const root = try allocator.create(Ast);
+ root.* = .{
+ .object_key = t2.identifier,
+ };
+ return root;
+ }
+
if (t2.kind() != .bracket_left) {
return error.InvalidQuery;
}