| ... | ... | @@ -36,6 +36,9 @@ pub fn parse(alloc: std.mem.Allocator, path: string, inreader: anytype) anyerror |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | fn parseElement(alloc: std.mem.Allocator, p: *Parser) anyerror!ValueIndex { |
| 39 | const t = tracer.trace(@src(), "", .{}); |
| 40 | defer t.end(); |
| 41 | |
| 39 | 42 | try parseWs(p); |
| 40 | 43 | const v = try parseValue(alloc, p); |
| 41 | 44 | parseWs(p) catch |err| switch (err) { |
| ... | ... | @@ -46,6 +49,9 @@ fn parseElement(alloc: std.mem.Allocator, p: *Parser) anyerror!ValueIndex { |
| 46 | 49 | } |
| 47 | 50 | |
| 48 | 51 | fn parseValue(alloc: std.mem.Allocator, p: *Parser) anyerror!ValueIndex { |
| 52 | const t = tracer.trace(@src(), "", .{}); |
| 53 | defer t.end(); |
| 54 | |
| 49 | 55 | if (try p.eat("null")) |_| return @enumFromInt(1); |
| 50 | 56 | if (try p.eat("true")) |_| return @enumFromInt(2); |
| 51 | 57 | if (try p.eat("false")) |_| return @enumFromInt(3); |
| ... | ... | @@ -57,6 +63,9 @@ fn parseValue(alloc: std.mem.Allocator, p: *Parser) anyerror!ValueIndex { |
| 57 | 63 | } |
| 58 | 64 | |
| 59 | 65 | fn parseObject(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| 66 | const t = tracer.trace(@src(), "", .{}); |
| 67 | defer t.end(); |
| 68 | |
| 60 | 69 | _ = try p.eatByte('{') orelse return null; |
| 61 | 70 | |
| 62 | 71 | var sfa = std.heap.stackFallback(std.mem.page_size, alloc); |
| ... | ... | @@ -86,6 +95,9 @@ fn parseObject(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| 86 | 95 | } |
| 87 | 96 | |
| 88 | 97 | fn parseArray(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| 98 | const t = tracer.trace(@src(), "", .{}); |
| 99 | defer t.end(); |
| 100 | |
| 89 | 101 | _ = try p.eatByte('[') orelse return null; |
| 90 | 102 | |
| 91 | 103 | var sfa = std.heap.stackFallback(std.mem.page_size, alloc); |
| ... | ... | @@ -111,6 +123,9 @@ fn parseArray(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| 111 | 123 | } |
| 112 | 124 | |
| 113 | 125 | fn parseString(alloc: std.mem.Allocator, p: *Parser) anyerror!?StringIndex { |
| 126 | const t = tracer.trace(@src(), "", .{}); |
| 127 | defer t.end(); |
| 128 | |
| 114 | 129 | var stack_fallback = std.heap.stackFallback(std.mem.page_size, alloc); |
| 115 | 130 | var characters = std.ArrayList(u8).init(stack_fallback.get()); |
| 116 | 131 | defer characters.deinit(); |
| ... | ... | @@ -152,6 +167,9 @@ fn parseString(alloc: std.mem.Allocator, p: *Parser) anyerror!?StringIndex { |
| 152 | 167 | } |
| 153 | 168 | |
| 154 | 169 | fn parseNumber(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| 170 | const t = tracer.trace(@src(), "", .{}); |
| 171 | defer t.end(); |
| 172 | |
| 155 | 173 | var stack_fallback = std.heap.stackFallback(std.mem.page_size, alloc); |
| 156 | 174 | var characters = std.ArrayList(u8).init(stack_fallback.get()); |
| 157 | 175 | defer characters.deinit(); |
| ... | ... | @@ -194,6 +212,9 @@ fn parseNumber(alloc: std.mem.Allocator, p: *Parser) anyerror!?ValueIndex { |
| 194 | 212 | } |
| 195 | 213 | |
| 196 | 214 | fn parseWs(p: *Parser) !void { |
| 215 | const t = tracer.trace(@src(), "", .{}); |
| 216 | defer t.end(); |
| 217 | |
| 197 | 218 | while (true) { |
| 198 | 219 | if (try p.eatByte(0x20)) |_| continue; // space |
| 199 | 220 | if (try p.eatByte(0x0A)) |_| continue; // NL |
| ... | ... | @@ -257,6 +278,9 @@ const Parser = struct { |
| 257 | 278 | } |
| 258 | 279 | |
| 259 | 280 | pub fn eatByte(p: *Parser, test_c: u8) !?u8 { |
| 281 | const t = tracer.trace(@src(), " '{c}'", .{test_c}); |
| 282 | defer t.end(); |
| 283 | |
| 260 | 284 | try p.peekAmt(1); |
| 261 | 285 | if (p.slice()[0] == test_c) { |
| 262 | 286 | p.idx += 1; |
| ... | ... | @@ -266,6 +290,9 @@ const Parser = struct { |
| 266 | 290 | } |
| 267 | 291 | |
| 268 | 292 | pub fn eatAnyScalar(p: *Parser, test_s: string) !?u8 { |
| 293 | const t = tracer.trace(@src(), " ({s})", .{test_s}); |
| 294 | defer t.end(); |
| 295 | |
| 269 | 296 | std.debug.assert(extras.matchesAll(u8, test_s, std.ascii.isASCII)); |
| 270 | 297 | try p.peekAmt(1); |
| 271 | 298 | if (std.mem.indexOfScalar(u8, test_s, p.slice()[0])) |idx| { |
| ... | ... | @@ -290,6 +317,9 @@ const Parser = struct { |
| 290 | 317 | } |
| 291 | 318 | |
| 292 | 319 | pub fn addObject(p: *Parser, alloc: std.mem.Allocator, members: *ObjectHashMap) !ValueIndex { |
| 320 | const t = tracer.trace(@src(), "({d})", .{members.entries.len}); |
| 321 | defer t.end(); |
| 322 | |
| 293 | 323 | const r = p.extras.items.len; |
| 294 | 324 | const l = members.entries.len; |
| 295 | 325 | if (l > std.math.maxInt(u32)) return error.JsonExpectedTODO; |
| ... | ... | @@ -302,6 +332,9 @@ const Parser = struct { |
| 302 | 332 | } |
| 303 | 333 | |
| 304 | 334 | pub fn addArray(p: *Parser, alloc: std.mem.Allocator, items: []const ValueIndex) !ValueIndex { |
| 335 | const t = tracer.trace(@src(), "({d})", .{items.len}); |
| 336 | defer t.end(); |
| 337 | |
| 305 | 338 | const r = p.extras.items.len; |
| 306 | 339 | const l = items.len; |
| 307 | 340 | if (l > std.math.maxInt(u32)) return error.JsonExpectedTODO; |
| ... | ... | @@ -313,6 +346,9 @@ const Parser = struct { |
| 313 | 346 | } |
| 314 | 347 | |
| 315 | 348 | pub fn addStr(p: *Parser, alloc: std.mem.Allocator, str: string) !StringIndex { |
| 349 | const t = tracer.trace(@src(), "({d})", .{str.len}); |
| 350 | defer t.end(); |
| 351 | |
| 316 | 352 | const adapter: Adapter = .{ .p = p }; |
| 317 | 353 | const res = try p.strings_map.getOrPutAdapted(alloc, str, adapter); |
| 318 | 354 | if (res.found_existing) return res.value_ptr.*; |
| ... | ... | @@ -345,6 +381,9 @@ const Parser = struct { |
| 345 | 381 | }; |
| 346 | 382 | |
| 347 | 383 | pub fn addNumber(p: *Parser, alloc: std.mem.Allocator, v: []const u8) !ValueIndex { |
| 384 | const t = tracer.trace(@src(), "({s})", .{v}); |
| 385 | defer t.end(); |
| 386 | |
| 348 | 387 | const r = p.extras.items.len; |
| 349 | 388 | const l = v.len; |
| 350 | 389 | if (l > std.math.maxInt(u8)) return error.JsonExpectedTODO; |