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.zig37
1 files changed, 31 insertions, 6 deletions
diff --git a/src/jq/execute.zig b/src/jq/execute.zig
index 9857d46..dfad6c4 100644
--- a/src/jq/execute.zig
+++ b/src/jq/execute.zig
@@ -4,19 +4,44 @@ const Instr = @import("./compile.zig").Instr;
pub const ExecuteError = error{
Unimplemented,
+ InvalidType,
+ InternalError,
};
pub fn execute(allocator: std.mem.Allocator, instrs: []const Instr, input: jv.Value) !jv.Value {
- _ = allocator;
+ var value_stack = try std.array_list.Aligned(jv.Value, null).initCapacity(allocator, 16);
+ defer value_stack.deinit(allocator);
+
+ try value_stack.append(allocator, input);
+
const len = instrs.len;
var pc: usize = 0;
while (pc < len) {
const cur = instrs[pc];
- _ = switch (cur.op) {
- .nop => void,
- .identity => return input,
- };
+ switch (cur) {
+ .nop => {},
+ .array_index => {
+ const v1 = value_stack.pop() orelse return error.InternalError;
+ const v1_integer = switch (v1) {
+ .integer => |integer| integer,
+ else => return error.InvalidType,
+ };
+ const v2 = value_stack.pop() orelse return error.InternalError;
+ const v2_array = switch (v2) {
+ .array => |array| array,
+ else => return error.InvalidType,
+ };
+ const index: usize = @intCast(v1_integer);
+ const result = if (index < v2_array.items.len) v2_array.items[index] else .null;
+ try value_stack.append(allocator, result);
+ },
+ .literal => |value| {
+ try value_stack.append(allocator, value.*);
+ },
+ }
pc += 1;
}
- return ExecuteError.Unimplemented;
+
+ const result = value_stack.pop() orelse return error.InternalError;
+ return result;
}