diff options
Diffstat (limited to 'src/jq/parse.zig')
| -rw-r--r-- | src/jq/parse.zig | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/src/jq/parse.zig b/src/jq/parse.zig index 0554dca..5269ef5 100644 --- a/src/jq/parse.zig +++ b/src/jq/parse.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const jv = @import("../jv.zig"); const Token = @import("./tokenize.zig").Token; pub const ParseError = error{ @@ -8,26 +9,74 @@ pub const ParseError = error{ pub const AstKind = enum { identity, + array_index, + literal, }; -pub const Ast = struct { - kind: AstKind, +pub const Ast = union(AstKind) { + identity, + array_index: *Ast, + literal: *jv.Value, + + pub fn kind(self: @This()) AstKind { + return self; + } }; pub fn parse(allocator: std.mem.Allocator, tokens: []const Token) !*Ast { - if (tokens.len != 2) { - return ParseError.InvalidQuery; + if (tokens.len < 2) { + return error.InvalidQuery; + } + + var i: usize = 0; + const t1 = tokens[i]; + if (t1.kind() != .dot) { + return error.InvalidQuery; + } + i += 1; + const t2 = tokens[i]; + + if (t2.kind() == .end) { + const root = try allocator.create(Ast); + root.* = .identity; + return root; + } + + if (t2.kind() != .bracket_left) { + return error.InvalidQuery; + } + + i += 1; + if (tokens.len < 5) { + return error.UnexpectedEnd; + } + const t3 = tokens[i]; + i += 1; + const t4 = tokens[i]; + i += 1; + const t5 = tokens[i]; + + if (t3.kind() != .number) { + return error.InvalidQuery; } - const t1 = tokens[0]; - const t2 = tokens[1]; - if (t1.kind != .identity) { - return ParseError.InvalidQuery; + if (t4.kind() != .bracket_right) { + return error.InvalidQuery; } - if (t2.kind != .end) { - return ParseError.UnexpectedEnd; + if (t5.kind() != .end) { + return error.InvalidQuery; } + const index_value = try allocator.create(jv.Value); + index_value.* = .{ + .integer = t3.number, + }; + const index_node = try allocator.create(Ast); + index_node.* = .{ + .literal = index_value, + }; const root = try allocator.create(Ast); - root.kind = .identity; + root.* = .{ + .array_index = index_node, + }; return root; } |
