This commit is contained in:
yuzu 2025-05-29 20:09:25 -05:00
parent da94cc608a
commit ee15bef4e1
3 changed files with 54 additions and 15 deletions

View File

@ -233,6 +233,7 @@ pub fn getValue(
},
.array => |arr| {
var out = try allocator.alloc(JsonInput, arr.len);
errdefer allocator.free(out);
var c = arr.start;
for (0..arr.len) |i| {
const v = try self.getValue(allocator, c);
@ -255,6 +256,10 @@ pub fn getValue(
const s = self.skipSlots(tip);
tip += s;
} else {
//for (self.property_map.keys(), self.property_map.values()) |k, v| {
//std.debug.print("{}: {s}\n", .{ v.tip, @tagName(self.index.get(k)) });
//std.debug.print("tip: {d}\n", .{tip});
//}
return error.MissingKey;
};
return .{ .object = map };
@ -277,8 +282,12 @@ pub fn parse(self: *Self, tokenizer: *Tokenizer) !usize {
flag: switch (token.type) {
.eof => {
assert(query.slice().len == 0);
assert(root == 0);
if (root != 0) {
return error.InvalidSyntax;
}
if (query.slice().len != 0) {
return error.InvalidSyntax;
}
return root;
},
.property => {
@ -290,7 +299,18 @@ pub fn parse(self: *Self, tokenizer: *Tokenizer) !usize {
//std.debug.print("prop: {s} \n", .{token.value.?.string});
const pidx = try self.addProperty(allocator, token.value.?.string);
self.property_map.putAssumeCapacity(scope.len + 1, .{ .tip = @enumFromInt(pidx) });
var accum: usize = 0;
for (query.slice(), 0..) |id, i| {
// std.debug.print("once\n", .{});
accum += switch (self.index.get(id)) {
.object => id + i,
.array => id + i,
else => unreachable,
};
}
accum += scope.len + 1;
self.property_map.putAssumeCapacity(accum, .{ .tip = @enumFromInt(pidx) });
// std.debug.print("{s}/{d}\n", .{ token.value.?.string, accum });
allocator.free(token.value.?.string);
self.index.set(scope_idx, .{ .object = ObjectEntry{
@ -298,6 +318,9 @@ pub fn parse(self: *Self, tokenizer: *Tokenizer) !usize {
.tip = scope.tip,
} });
},
.array => {
return error.InvalidSyntax;
},
else => return error.InvalidSyntax,
}
@ -355,9 +378,15 @@ pub fn parse(self: *Self, tokenizer: *Tokenizer) !usize {
},
.object_end, .array_end => {
tokenizer.skipWhitespace();
if (query.pop() == null)
return error.InvalidSyntax; // double close
if (query.slice().len == 0)
return root;
const next = it.next() orelse
return root;
token = next;
switch (next.type) {
.comma => continue :flag .comma,
@ -440,9 +469,10 @@ pub fn parse(self: *Self, tokenizer: *Tokenizer) !usize {
if (query.len == 0) {
// root
const idx = try self.addString(allocator, token.value.?.string);
_ = try self.addString(allocator, token.value.?.string);
allocator.free(token.value.?.string);
self.index.set(root, .{ .string = @enumFromInt(idx) });
// hardcoded shite
self.index.set(root, .{ .string = @enumFromInt(0) });
return root;
}
@ -549,8 +579,15 @@ test getValue {
const allocator = std.testing.allocator;
const text =
\\{"a":"b","c":"d"}
;
\\{
\\ "a":"b",
\\ "c":"d",
\\ "f": {
\\ "g": "h"
\\ },
\\ "i": "j"
\\}
; // eg 1: b, 2: c, 3: f, 4: g, 5: i
var tokenizer: Tokenizer = try .init(allocator, text);
defer tokenizer.deinit();

View File

@ -28,8 +28,8 @@ test Language {
defer tokenizer.deinit();
var self = try allocator.create(Language);
self.* = Language.init;
defer allocator.destroy(self);
self.* = Language.init;
defer self.deinit(allocator);
const idx: usize = try self.parse(&tokenizer);
@ -180,7 +180,7 @@ test { try expectPass("/y_structure_lonely_negative_real.json"); }
test { try expectPass("/y_structure_lonely_null.json"); }
test { try expectPass("/y_structure_lonely_string.json"); }
test { try expectPass("/y_structure_lonely_true.json"); }
//test { try expectPass("/y_structure_string_empty.json"); }
test { try expectPass("/y_structure_string_empty.json"); }
test { try expectPass("/y_structure_trailing_newline.json"); }
test { try expectPass("/y_structure_true_in_array.json"); }
test { try expectPass("/y_structure_whitespace_array.json"); }
@ -327,29 +327,29 @@ test { try expectFail("/n_string_unescaped_newline.json"); }
test { try expectFail("/n_string_unescaped_tab.json"); }
// test { try expectFail("/n_string_unicode_CapitalU.json"); }
// possibly stack overflow
// test { try expectFail("/n_string_with_trailing_garbage.json"); }
test { try expectFail("/n_string_with_trailing_garbage.json"); }
test { try expectFail("/n_structure_100000_opening_arrays.json"); }
// test { try expectFail("/n_structure_angle_bracket_..json"); }
//test { try expectFail("/n_structure_angle_bracket_..json"); }
test { try expectFail("/n_structure_angle_bracket_null.json"); }
test { try expectFail("/n_structure_array_trailing_garbage.json"); }
test { try expectFail("/n_structure_array_with_extra_array_close.json"); }
test { try expectFail("/n_structure_array_with_unclosed_string.json"); }
//test { try expectFail("/n_structure_ascii-unicode-identifier.json"); }
test { try expectFail("/n_structure_capitalized_True.json"); }
//test { try expectFail("/n_structure_close_unopened_array.json"); }
test { try expectFail("/n_structure_close_unopened_array.json"); }
test { try expectFail("/n_structure_comma_instead_of_closing_brace.json"); }
test { try expectFail("/n_structure_double_array.json"); }
//test { try expectFail("/n_structure_end_array.json"); }
test { try expectFail("/n_structure_end_array.json"); }
//test { try expectFail("/n_structure_incomplete_UTF8_BOM.json"); }
//test { try expectFail("/n_structure_lone-invalid-utf-8.json"); }
test { try expectFail("/n_structure_lone-open-bracket.json"); }
//test { try expectFail("/n_structure_no_data.json"); }
test { try expectFail("/n_structure_null-byte-outside-string.json"); }
//test { try expectFail("/n_structure_number_with_trailing_garbage.json"); }
test { try expectFail("/n_structure_number_with_trailing_garbage.json"); }
test { try expectFail("/n_structure_object_followed_by_closing_object.json"); }
test { try expectFail("/n_structure_object_unclosed_no_value.json"); }
test { try expectFail("/n_structure_object_with_comment.json"); }
//test { try expectFail("/n_structure_object_with_trailing_garbage.json"); }
test { try expectFail("/n_structure_object_with_trailing_garbage.json"); }
test { try expectFail("/n_structure_open_array_apostrophe.json"); }
test { try expectFail("/n_structure_open_array_comma.json"); }
test { try expectFail("/n_structure_open_array_object.json"); }

View File

@ -454,6 +454,8 @@ pub const Iterator = struct {
pub fn next(it: *Iterator) ?Token {
defer it.tokenizer.skipWhitespace();
errdefer it.tokenizer.deinit();
if (it.tokenizer.endOfInput()) {
// std.debug.print("got eof\n", .{});
return null;