aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/jq/execute.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/jq/execute.zig')
-rw-r--r--src/jq/execute.zig109
1 files changed, 8 insertions, 101 deletions
diff --git a/src/jq/execute.zig b/src/jq/execute.zig
index 2afb7b7..9e3a0d5 100644
--- a/src/jq/execute.zig
+++ b/src/jq/execute.zig
@@ -9,7 +9,7 @@ pub const ExecuteError = error{
Unimplemented,
InvalidType,
InternalError,
-};
+} || jv.ops.OpsError;
const SaveableStack = @import("./saveable_stack.zig").SaveableStack;
@@ -193,25 +193,7 @@ pub const Runtime = struct {
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,
- };
+ const result = try jv.ops.index(base, key);
try self.values.push(result);
},
.add => {
@@ -265,7 +247,7 @@ pub const Runtime = struct {
_ = self.values.pop();
const lhs = self.values.pop();
const rhs = self.values.pop();
- const result = try compareValues(lhs, rhs, .eq);
+ const result = try jv.ops.compare(lhs, rhs, .eq);
try self.values.push(.{ .bool = result });
},
.ne => {
@@ -274,7 +256,7 @@ pub const Runtime = struct {
_ = self.values.pop();
const lhs = self.values.pop();
const rhs = self.values.pop();
- const result = try compareValues(lhs, rhs, .ne);
+ const result = try jv.ops.compare(lhs, rhs, .ne);
try self.values.push(.{ .bool = result });
},
.lt => {
@@ -283,7 +265,7 @@ pub const Runtime = struct {
_ = self.values.pop();
const lhs = self.values.pop();
const rhs = self.values.pop();
- const result = try compareValues(lhs, rhs, .lt);
+ const result = try jv.ops.compare(lhs, rhs, .lt);
try self.values.push(.{ .bool = result });
},
.gt => {
@@ -292,7 +274,7 @@ pub const Runtime = struct {
_ = self.values.pop();
const lhs = self.values.pop();
const rhs = self.values.pop();
- const result = try compareValues(lhs, rhs, .gt);
+ const result = try jv.ops.compare(lhs, rhs, .gt);
try self.values.push(.{ .bool = result });
},
.le => {
@@ -301,7 +283,7 @@ pub const Runtime = struct {
_ = self.values.pop();
const lhs = self.values.pop();
const rhs = self.values.pop();
- const result = try compareValues(lhs, rhs, .le);
+ const result = try jv.ops.compare(lhs, rhs, .le);
try self.values.push(.{ .bool = result });
},
.ge => {
@@ -310,7 +292,7 @@ pub const Runtime = struct {
_ = self.values.pop();
const lhs = self.values.pop();
const rhs = self.values.pop();
- const result = try compareValues(lhs, rhs, .ge);
+ const result = try jv.ops.compare(lhs, rhs, .ge);
try self.values.push(.{ .bool = result });
},
.@"const" => |idx| {
@@ -337,78 +319,3 @@ pub const Runtime = struct {
}
}
};
-
-const CompareOp = enum { eq, ne, lt, gt, le, ge };
-
-fn compareValues(lhs: jv.Value, rhs: jv.Value, op: CompareOp) ExecuteError!bool {
- const lhs_tag = std.meta.activeTag(lhs);
- const rhs_tag = std.meta.activeTag(rhs);
-
- if (lhs_tag != rhs_tag) {
- const lhs_is_number = lhs_tag == .integer or lhs_tag == .float;
- const rhs_is_number = rhs_tag == .integer or rhs_tag == .float;
- if (lhs_is_number and rhs_is_number) {
- return compareNumbers(lhs, rhs, op);
- }
- return error.InvalidType;
- }
-
- return switch (lhs) {
- .null => switch (op) {
- .eq => true,
- .ne => false,
- .lt, .gt, .le, .ge => error.Unimplemented,
- },
- .bool => |lhs_bool| {
- const rhs_bool = rhs.bool;
- return switch (op) {
- .eq => lhs_bool == rhs_bool,
- .ne => lhs_bool != rhs_bool,
- .lt, .gt, .le, .ge => error.Unimplemented,
- };
- },
- .integer, .float => compareNumbers(lhs, rhs, op),
- .string => |lhs_str| {
- const rhs_str = rhs.string;
- const order = std.mem.order(u8, lhs_str, rhs_str);
- return switch (op) {
- .eq => order == .eq,
- .ne => order != .eq,
- .lt => order == .lt,
- .gt => order == .gt,
- .le => order == .lt or order == .eq,
- .ge => order == .gt or order == .eq,
- };
- },
- .array => switch (op) {
- .eq, .ne => error.Unimplemented,
- .lt, .gt, .le, .ge => error.Unimplemented,
- },
- .object => switch (op) {
- .eq, .ne => error.Unimplemented,
- .lt, .gt, .le, .ge => error.Unimplemented,
- },
- .number_string => error.Unimplemented,
- };
-}
-
-fn compareNumbers(lhs: jv.Value, rhs: jv.Value, op: CompareOp) bool {
- const lhs_f: f64 = switch (lhs) {
- .integer => |i| @floatFromInt(i),
- .float => |f| f,
- else => unreachable,
- };
- const rhs_f: f64 = switch (rhs) {
- .integer => |i| @floatFromInt(i),
- .float => |f| f,
- else => unreachable,
- };
- return switch (op) {
- .eq => lhs_f == rhs_f,
- .ne => lhs_f != rhs_f,
- .lt => lhs_f < rhs_f,
- .gt => lhs_f > rhs_f,
- .le => lhs_f <= rhs_f,
- .ge => lhs_f >= rhs_f,
- };
-}