diff options
Diffstat (limited to 'src/jq/execute.zig')
| -rw-r--r-- | src/jq/execute.zig | 37 |
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; } |
