aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/jq
diff options
context:
space:
mode:
Diffstat (limited to 'src/jq')
-rw-r--r--src/jq/compile.zig2
-rw-r--r--src/jq/execute.zig88
-rw-r--r--src/jq/tokenize.zig4
3 files changed, 72 insertions, 22 deletions
diff --git a/src/jq/compile.zig b/src/jq/compile.zig
index a28c10a..ddb4be5 100644
--- a/src/jq/compile.zig
+++ b/src/jq/compile.zig
@@ -19,7 +19,7 @@ pub const Instr = union(Opcode) {
};
pub fn compile(allocator: std.mem.Allocator, compile_allocator: std.mem.Allocator, ast: *const Ast) ![]Instr {
- var instrs = try std.array_list.Aligned(Instr, null).initCapacity(allocator, 16);
+ var instrs = try std.ArrayList(Instr).initCapacity(allocator, 16);
switch (ast.*) {
.identity => try instrs.append(allocator, .nop),
diff --git a/src/jq/execute.zig b/src/jq/execute.zig
index dfad6c4..a07204a 100644
--- a/src/jq/execute.zig
+++ b/src/jq/execute.zig
@@ -8,11 +8,71 @@ pub const ExecuteError = error{
InternalError,
};
+const ValueStack = struct {
+ const Self = @This();
+ const Stack = std.ArrayList(jv.Value);
+
+ stack: Stack,
+ allocator: std.mem.Allocator,
+
+ pub fn init(allocator: std.mem.Allocator) !Self {
+ return .{
+ .stack = try Stack.initCapacity(allocator, 16),
+ .allocator = allocator,
+ };
+ }
+
+ pub fn deinit(self: *Self) void {
+ self.stack.deinit(self.allocator);
+ }
+
+ pub fn push(self: *Self, value: jv.Value) !void {
+ try self.stack.append(self.allocator, value);
+ }
+
+ pub fn pop(self: *Self) ExecuteError!jv.Value {
+ return self.stack.pop() orelse return error.InternalError;
+ }
+
+ pub fn popInteger(self: *Self) ExecuteError!i64 {
+ const value = try self.pop();
+ return switch (value) {
+ .integer => |i| i,
+ else => error.InvalidType,
+ };
+ }
+
+ pub fn popNumber(self: *Self) ExecuteError!f64 {
+ const value = try self.pop();
+ return switch (value) {
+ .integer => |i| @floatFromInt(i),
+ .float => |f| f,
+ else => error.InvalidType,
+ };
+ }
+
+ pub fn popString(self: *Self) ExecuteError![]const u8 {
+ const value = try self.pop();
+ return switch (value) {
+ .string => |s| s,
+ else => error.InvalidType,
+ };
+ }
+
+ pub fn popArray(self: *Self) ExecuteError!jv.Array {
+ const value = try self.pop();
+ return switch (value) {
+ .array => |a| a,
+ else => error.InvalidType,
+ };
+ }
+};
+
pub fn execute(allocator: std.mem.Allocator, instrs: []const Instr, input: jv.Value) !jv.Value {
- var value_stack = try std.array_list.Aligned(jv.Value, null).initCapacity(allocator, 16);
- defer value_stack.deinit(allocator);
+ var value_stack = try ValueStack.init(allocator);
+ defer value_stack.deinit();
- try value_stack.append(allocator, input);
+ try value_stack.push(input);
const len = instrs.len;
var pc: usize = 0;
@@ -21,27 +81,17 @@ pub fn execute(allocator: std.mem.Allocator, instrs: []const Instr, input: jv.Va
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);
+ const index: usize = @intCast(try value_stack.popInteger());
+ const array = try value_stack.popArray();
+ const result = if (index < array.items.len) array.items[index] else .null;
+ try value_stack.push(result);
},
.literal => |value| {
- try value_stack.append(allocator, value.*);
+ try value_stack.push(value.*);
},
}
pc += 1;
}
- const result = value_stack.pop() orelse return error.InternalError;
- return result;
+ return value_stack.pop();
}
diff --git a/src/jq/tokenize.zig b/src/jq/tokenize.zig
index 75113f0..9086571 100644
--- a/src/jq/tokenize.zig
+++ b/src/jq/tokenize.zig
@@ -120,7 +120,7 @@ fn isIdentifierContinue(c: u8) bool {
}
fn tokenizeIdentifier(allocator: std.mem.Allocator, reader: *std.Io.Reader, first: u8) ![]const u8 {
- var buffer = try std.array_list.Aligned(u8, null).initCapacity(allocator, 16);
+ var buffer = try std.ArrayList(u8).initCapacity(allocator, 16);
try buffer.append(allocator, first);
while (true) {
@@ -169,7 +169,7 @@ fn tokenizeNumber(reader: *std.Io.Reader, first: u8) error{ReadFailed}!i64 {
}
pub fn tokenize(allocator: std.mem.Allocator, reader: *std.Io.Reader) ![]Token {
- var tokens = try std.array_list.Aligned(Token, null).initCapacity(allocator, 16);
+ var tokens = try std.ArrayList(Token).initCapacity(allocator, 16);
while (true) {
const c = reader.takeByte() catch |err| switch (err) {