aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jq/compile.zig22
-rw-r--r--src/jq/execute.zig38
-rw-r--r--src/jq/parse.zig16
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;
}
};