From ee15bef4e14031eaaf147c3c51ec8d65532eb00a Mon Sep 17 00:00:00 2001 From: yuzu Date: Thu, 29 May 2025 20:09:25 -0500 Subject: [PATCH] xd --- language.zig | 51 ++++++++++++++++++++++++++++++++++++++++++++------- test.zig | 16 ++++++++-------- tokenizer.zig | 2 ++ 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/language.zig b/language.zig index 9078831..5799a70 100644 --- a/language.zig +++ b/language.zig @@ -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(); diff --git a/test.zig b/test.zig index ed5d95e..05a12b1 100644 --- a/test.zig +++ b/test.zig @@ -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"); } diff --git a/tokenizer.zig b/tokenizer.zig index 49b662a..7ccb2cc 100644 --- a/tokenizer.zig +++ b/tokenizer.zig @@ -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;