| ... | ... | @@ -43,11 +43,13 @@ pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!Tree { |
| 43 | 43 | .errors = .{}, |
| 44 | 44 | .nodes = .{}, |
| 45 | 45 | .extra_data = .{}, |
| 46 | .scratch = .{}, |
| 46 | 47 | .tok_i = 0, |
| 47 | 48 | }; |
| 48 | 49 | defer parser.errors.deinit(gpa); |
| 49 | 50 | defer parser.nodes.deinit(gpa); |
| 50 | 51 | defer parser.extra_data.deinit(gpa); |
| 52 | defer parser.scratch.deinit(gpa); |
| 51 | 53 | |
| 52 | 54 | // Empirically, Zig source code has a 2:1 ratio of tokens to AST nodes. |
| 53 | 55 | // Make sure at least 1 so we can use appendAssumeCapacity on the root node below. |
| ... | ... | @@ -93,18 +95,7 @@ const Parser = struct { |
| 93 | 95 | errors: std.ArrayListUnmanaged(AstError), |
| 94 | 96 | nodes: ast.NodeList, |
| 95 | 97 | extra_data: std.ArrayListUnmanaged(Node.Index), |
| 96 | | |
| 97 | | const SmallSpan = union(enum) { |
| 98 | | zero_or_one: Node.Index, |
| 99 | | multi: []Node.Index, |
| 100 | | |
| 101 | | fn deinit(self: SmallSpan, gpa: *Allocator) void { |
| 102 | | switch (self) { |
| 103 | | .zero_or_one => {}, |
| 104 | | .multi => |list| gpa.free(list), |
| 105 | | } |
| 106 | | } |
| 107 | | }; |
| 98 | scratch: std.ArrayListUnmanaged(Node.Index), |
| 108 | 99 | |
| 109 | 100 | const Members = struct { |
| 110 | 101 | len: usize, |
| ... | ... | @@ -204,8 +195,8 @@ const Parser = struct { |
| 204 | 195 | /// / |
| 205 | 196 | /// TopLevelComptime <- KEYWORD_comptime BlockExpr |
| 206 | 197 | fn parseContainerMembers(p: *Parser) !Members { |
| 207 | | var list = std.ArrayList(Node.Index).init(p.gpa); |
| 208 | | defer list.deinit(); |
| 198 | const scratch_top = p.scratch.items.len; |
| 199 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 209 | 200 | |
| 210 | 201 | var field_state: union(enum) { |
| 211 | 202 | /// No fields have been seen. |
| ... | ... | @@ -233,7 +224,7 @@ const Parser = struct { |
| 233 | 224 | if (field_state == .seen) { |
| 234 | 225 | field_state = .{ .end = test_decl_node }; |
| 235 | 226 | } |
| 236 | | try list.append(test_decl_node); |
| 227 | try p.scratch.append(p.gpa, test_decl_node); |
| 237 | 228 | } |
| 238 | 229 | trailing = false; |
| 239 | 230 | }, |
| ... | ... | @@ -254,7 +245,7 @@ const Parser = struct { |
| 254 | 245 | field_state = .err; |
| 255 | 246 | }, |
| 256 | 247 | } |
| 257 | | try list.append(container_field); |
| 248 | try p.scratch.append(p.gpa, container_field); |
| 258 | 249 | switch (p.token_tags[p.tok_i]) { |
| 259 | 250 | .comma => { |
| 260 | 251 | p.tok_i += 1; |
| ... | ... | @@ -294,7 +285,7 @@ const Parser = struct { |
| 294 | 285 | if (field_state == .seen) { |
| 295 | 286 | field_state = .{ .end = comptime_node }; |
| 296 | 287 | } |
| 297 | | try list.append(comptime_node); |
| 288 | try p.scratch.append(p.gpa, comptime_node); |
| 298 | 289 | } |
| 299 | 290 | trailing = false; |
| 300 | 291 | }, |
| ... | ... | @@ -310,7 +301,7 @@ const Parser = struct { |
| 310 | 301 | if (field_state == .seen) { |
| 311 | 302 | field_state = .{ .end = top_level_decl }; |
| 312 | 303 | } |
| 313 | | try list.append(top_level_decl); |
| 304 | try p.scratch.append(p.gpa, top_level_decl); |
| 314 | 305 | } |
| 315 | 306 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; |
| 316 | 307 | }, |
| ... | ... | @@ -320,7 +311,7 @@ const Parser = struct { |
| 320 | 311 | if (field_state == .seen) { |
| 321 | 312 | field_state = .{ .end = node }; |
| 322 | 313 | } |
| 323 | | try list.append(node); |
| 314 | try p.scratch.append(p.gpa, node); |
| 324 | 315 | } |
| 325 | 316 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; |
| 326 | 317 | }, |
| ... | ... | @@ -338,7 +329,7 @@ const Parser = struct { |
| 338 | 329 | if (field_state == .seen) { |
| 339 | 330 | field_state = .{ .end = top_level_decl }; |
| 340 | 331 | } |
| 341 | | try list.append(top_level_decl); |
| 332 | try p.scratch.append(p.gpa, top_level_decl); |
| 342 | 333 | } |
| 343 | 334 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; |
| 344 | 335 | }, |
| ... | ... | @@ -357,7 +348,7 @@ const Parser = struct { |
| 357 | 348 | field_state = .err; |
| 358 | 349 | }, |
| 359 | 350 | } |
| 360 | | try list.append(container_field); |
| 351 | try p.scratch.append(p.gpa, container_field); |
| 361 | 352 | switch (p.token_tags[p.tok_i]) { |
| 362 | 353 | .comma => { |
| 363 | 354 | p.tok_i += 1; |
| ... | ... | @@ -393,7 +384,8 @@ const Parser = struct { |
| 393 | 384 | } |
| 394 | 385 | } |
| 395 | 386 | |
| 396 | | switch (list.items.len) { |
| 387 | const items = p.scratch.items[scratch_top..]; |
| 388 | switch (items.len) { |
| 397 | 389 | 0 => return Members{ |
| 398 | 390 | .len = 0, |
| 399 | 391 | .lhs = 0, |
| ... | ... | @@ -402,20 +394,20 @@ const Parser = struct { |
| 402 | 394 | }, |
| 403 | 395 | 1 => return Members{ |
| 404 | 396 | .len = 1, |
| 405 | | .lhs = list.items[0], |
| 397 | .lhs = items[0], |
| 406 | 398 | .rhs = 0, |
| 407 | 399 | .trailing = trailing, |
| 408 | 400 | }, |
| 409 | 401 | 2 => return Members{ |
| 410 | 402 | .len = 2, |
| 411 | | .lhs = list.items[0], |
| 412 | | .rhs = list.items[1], |
| 403 | .lhs = items[0], |
| 404 | .rhs = items[1], |
| 413 | 405 | .trailing = trailing, |
| 414 | 406 | }, |
| 415 | 407 | else => { |
| 416 | | const span = try p.listToSpan(list.items); |
| 408 | const span = try p.listToSpan(items); |
| 417 | 409 | return Members{ |
| 418 | | .len = list.items.len, |
| 410 | .len = items.len, |
| 419 | 411 | .lhs = span.start, |
| 420 | 412 | .rhs = span.end, |
| 421 | 413 | .trailing = trailing, |
| ... | ... | @@ -647,8 +639,10 @@ const Parser = struct { |
| 647 | 639 | const fn_proto_index = try p.reserveNode(); |
| 648 | 640 | |
| 649 | 641 | _ = p.eatToken(.identifier); |
| 642 | const scratch_top = p.scratch.items.len; |
| 643 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 644 | // parseParamDeclList does not shrink scratch buffer, but we will |
| 650 | 645 | const params = try p.parseParamDeclList(); |
| 651 | | defer params.deinit(p.gpa); |
| 652 | 646 | const align_expr = try p.parseByteAlign(); |
| 653 | 647 | const section_expr = try p.parseLinkSection(); |
| 654 | 648 | const callconv_expr = try p.parseCallconv(); |
| ... | ... | @@ -662,17 +656,17 @@ const Parser = struct { |
| 662 | 656 | } |
| 663 | 657 | |
| 664 | 658 | if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) { |
| 665 | | switch (params) { |
| 666 | | .zero_or_one => |param| return p.setNode(fn_proto_index, .{ |
| 659 | switch (params.len) { |
| 660 | 0, 1 => return p.setNode(fn_proto_index, .{ |
| 667 | 661 | .tag = .fn_proto_simple, |
| 668 | 662 | .main_token = fn_token, |
| 669 | 663 | .data = .{ |
| 670 | | .lhs = param, |
| 664 | .lhs = if (params.len > 0) params[0] else 0, |
| 671 | 665 | .rhs = return_type_expr, |
| 672 | 666 | }, |
| 673 | 667 | }), |
| 674 | | .multi => |list| { |
| 675 | | const span = try p.listToSpan(list); |
| 668 | else => { |
| 669 | const span = try p.listToSpan(params); |
| 676 | 670 | return p.setNode(fn_proto_index, .{ |
| 677 | 671 | .tag = .fn_proto_multi, |
| 678 | 672 | .main_token = fn_token, |
| ... | ... | @@ -687,13 +681,13 @@ const Parser = struct { |
| 687 | 681 | }, |
| 688 | 682 | } |
| 689 | 683 | } |
| 690 | | switch (params) { |
| 691 | | .zero_or_one => |param| return p.setNode(fn_proto_index, .{ |
| 684 | switch (params.len) { |
| 685 | 0, 1 => return p.setNode(fn_proto_index, .{ |
| 692 | 686 | .tag = .fn_proto_one, |
| 693 | 687 | .main_token = fn_token, |
| 694 | 688 | .data = .{ |
| 695 | 689 | .lhs = try p.addExtra(Node.FnProtoOne{ |
| 696 | | .param = param, |
| 690 | .param = if (params.len > 0) params[0] else 0, |
| 697 | 691 | .align_expr = align_expr, |
| 698 | 692 | .section_expr = section_expr, |
| 699 | 693 | .callconv_expr = callconv_expr, |
| ... | ... | @@ -701,8 +695,8 @@ const Parser = struct { |
| 701 | 695 | .rhs = return_type_expr, |
| 702 | 696 | }, |
| 703 | 697 | }), |
| 704 | | .multi => |list| { |
| 705 | | const span = try p.listToSpan(list); |
| 698 | else => { |
| 699 | const span = try p.listToSpan(params); |
| 706 | 700 | return p.setNode(fn_proto_index, .{ |
| 707 | 701 | .tag = .fn_proto, |
| 708 | 702 | .main_token = fn_token, |
| ... | ... | @@ -1894,20 +1888,20 @@ const Parser = struct { |
| 1894 | 1888 | }); |
| 1895 | 1889 | } |
| 1896 | 1890 | |
| 1897 | | var statements = std.ArrayList(Node.Index).init(p.gpa); |
| 1898 | | defer statements.deinit(); |
| 1891 | const scratch_top = p.scratch.items.len; |
| 1892 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 1899 | 1893 | |
| 1900 | | try statements.appendSlice(&.{ stmt_one, stmt_two }); |
| 1894 | try p.scratch.appendSlice(p.gpa, &.{ stmt_one, stmt_two }); |
| 1901 | 1895 | |
| 1902 | 1896 | while (true) { |
| 1903 | 1897 | const statement = try p.expectStatementRecoverable(); |
| 1904 | 1898 | if (statement == 0) break; |
| 1905 | | try statements.append(statement); |
| 1899 | try p.scratch.append(p.gpa, statement); |
| 1906 | 1900 | if (p.token_tags[p.tok_i] == .r_brace) break; |
| 1907 | 1901 | } |
| 1908 | 1902 | _ = try p.expectToken(.r_brace); |
| 1909 | 1903 | const semicolon = p.token_tags[p.tok_i - 2] == .semicolon; |
| 1910 | | const statements_span = try p.listToSpan(statements.items); |
| 1904 | const statements_span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 1911 | 1905 | return p.addNode(.{ |
| 1912 | 1906 | .tag = if (semicolon) .block_semicolon else .block, |
| 1913 | 1907 | .main_token = lbrace, |
| ... | ... | @@ -2041,14 +2035,14 @@ const Parser = struct { |
| 2041 | 2035 | }); |
| 2042 | 2036 | } |
| 2043 | 2037 | |
| 2044 | | var init_list = std.ArrayList(Node.Index).init(p.gpa); |
| 2045 | | defer init_list.deinit(); |
| 2038 | const scratch_top = p.scratch.items.len; |
| 2039 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2046 | 2040 | |
| 2047 | | try init_list.append(field_init); |
| 2041 | try p.scratch.append(p.gpa, field_init); |
| 2048 | 2042 | |
| 2049 | 2043 | while (true) { |
| 2050 | 2044 | const next = try p.expectFieldInit(); |
| 2051 | | try init_list.append(next); |
| 2045 | try p.scratch.append(p.gpa, next); |
| 2052 | 2046 | |
| 2053 | 2047 | switch (p.token_tags[p.nextToken()]) { |
| 2054 | 2048 | .comma => { |
| ... | ... | @@ -2068,7 +2062,7 @@ const Parser = struct { |
| 2068 | 2062 | }, |
| 2069 | 2063 | } |
| 2070 | 2064 | } |
| 2071 | | const span = try p.listToSpan(init_list.items); |
| 2065 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2072 | 2066 | return p.addNode(.{ |
| 2073 | 2067 | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .struct_init_comma else .struct_init, |
| 2074 | 2068 | .main_token = lbrace, |
| ... | ... | @@ -2098,22 +2092,22 @@ const Parser = struct { |
| 2098 | 2092 | try p.warnExpected(.comma); |
| 2099 | 2093 | } |
| 2100 | 2094 | |
| 2101 | | var init_list = std.ArrayList(Node.Index).init(p.gpa); |
| 2102 | | defer init_list.deinit(); |
| 2095 | const scratch_top = p.scratch.items.len; |
| 2096 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2103 | 2097 | |
| 2104 | | try init_list.append(elem_init); |
| 2098 | try p.scratch.append(p.gpa, elem_init); |
| 2105 | 2099 | |
| 2106 | 2100 | var trailing_comma = true; |
| 2107 | 2101 | var next = try p.parseExpr(); |
| 2108 | 2102 | while (next != 0) : (next = try p.parseExpr()) { |
| 2109 | | try init_list.append(next); |
| 2103 | try p.scratch.append(p.gpa, next); |
| 2110 | 2104 | if (p.eatToken(.comma) == null) { |
| 2111 | 2105 | trailing_comma = false; |
| 2112 | 2106 | break; |
| 2113 | 2107 | } |
| 2114 | 2108 | } |
| 2115 | 2109 | _ = try p.expectToken(.r_brace); |
| 2116 | | const span = try p.listToSpan(init_list.items); |
| 2110 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2117 | 2111 | return p.addNode(.{ |
| 2118 | 2112 | .tag = if (trailing_comma) .array_init_comma else .array_init, |
| 2119 | 2113 | .main_token = lbrace, |
| ... | ... | @@ -2188,18 +2182,18 @@ const Parser = struct { |
| 2188 | 2182 | try p.warnExpected(.comma); |
| 2189 | 2183 | } |
| 2190 | 2184 | |
| 2191 | | var param_list = std.ArrayList(Node.Index).init(p.gpa); |
| 2192 | | defer param_list.deinit(); |
| 2185 | const scratch_top = p.scratch.items.len; |
| 2186 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2193 | 2187 | |
| 2194 | | try param_list.append(param_one); |
| 2188 | try p.scratch.append(p.gpa, param_one); |
| 2195 | 2189 | |
| 2196 | 2190 | while (true) { |
| 2197 | 2191 | const next = try p.expectExpr(); |
| 2198 | | try param_list.append(next); |
| 2192 | try p.scratch.append(p.gpa, next); |
| 2199 | 2193 | switch (p.token_tags[p.nextToken()]) { |
| 2200 | 2194 | .comma => { |
| 2201 | 2195 | if (p.eatToken(.r_paren)) |_| { |
| 2202 | | const span = try p.listToSpan(param_list.items); |
| 2196 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2203 | 2197 | return p.addNode(.{ |
| 2204 | 2198 | .tag = .async_call_comma, |
| 2205 | 2199 | .main_token = lparen, |
| ... | ... | @@ -2216,7 +2210,7 @@ const Parser = struct { |
| 2216 | 2210 | } |
| 2217 | 2211 | }, |
| 2218 | 2212 | .r_paren => { |
| 2219 | | const span = try p.listToSpan(param_list.items); |
| 2213 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2220 | 2214 | return p.addNode(.{ |
| 2221 | 2215 | .tag = .async_call, |
| 2222 | 2216 | .main_token = lparen, |
| ... | ... | @@ -2277,18 +2271,18 @@ const Parser = struct { |
| 2277 | 2271 | try p.warnExpected(.comma); |
| 2278 | 2272 | } |
| 2279 | 2273 | |
| 2280 | | var param_list = std.ArrayList(Node.Index).init(p.gpa); |
| 2281 | | defer param_list.deinit(); |
| 2274 | const scratch_top = p.scratch.items.len; |
| 2275 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2282 | 2276 | |
| 2283 | | try param_list.append(param_one); |
| 2277 | try p.scratch.append(p.gpa, param_one); |
| 2284 | 2278 | |
| 2285 | 2279 | while (true) { |
| 2286 | 2280 | const next = try p.expectExpr(); |
| 2287 | | try param_list.append(next); |
| 2281 | try p.scratch.append(p.gpa, next); |
| 2288 | 2282 | switch (p.token_tags[p.nextToken()]) { |
| 2289 | 2283 | .comma => { |
| 2290 | 2284 | if (p.eatToken(.r_paren)) |_| { |
| 2291 | | const span = try p.listToSpan(param_list.items); |
| 2285 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2292 | 2286 | break :res try p.addNode(.{ |
| 2293 | 2287 | .tag = .call_comma, |
| 2294 | 2288 | .main_token = lparen, |
| ... | ... | @@ -2305,7 +2299,7 @@ const Parser = struct { |
| 2305 | 2299 | } |
| 2306 | 2300 | }, |
| 2307 | 2301 | .r_paren => { |
| 2308 | | const span = try p.listToSpan(param_list.items); |
| 2302 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2309 | 2303 | break :res try p.addNode(.{ |
| 2310 | 2304 | .tag = .call, |
| 2311 | 2305 | .main_token = lparen, |
| ... | ... | @@ -2602,15 +2596,15 @@ const Parser = struct { |
| 2602 | 2596 | if (comma_two == null) { |
| 2603 | 2597 | try p.warnExpected(.comma); |
| 2604 | 2598 | } |
| 2605 | | var init_list = std.ArrayList(Node.Index).init(p.gpa); |
| 2606 | | defer init_list.deinit(); |
| 2599 | const scratch_top = p.scratch.items.len; |
| 2600 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2607 | 2601 | |
| 2608 | | try init_list.appendSlice(&.{ field_init_one, field_init_two }); |
| 2602 | try p.scratch.appendSlice(p.gpa, &.{ field_init_one, field_init_two }); |
| 2609 | 2603 | |
| 2610 | 2604 | while (true) { |
| 2611 | 2605 | const next = try p.expectFieldInit(); |
| 2612 | 2606 | assert(next != 0); |
| 2613 | | try init_list.append(next); |
| 2607 | try p.scratch.append(p.gpa, next); |
| 2614 | 2608 | switch (p.token_tags[p.nextToken()]) { |
| 2615 | 2609 | .comma => { |
| 2616 | 2610 | if (p.eatToken(.r_brace)) |_| break; |
| ... | ... | @@ -2627,7 +2621,7 @@ const Parser = struct { |
| 2627 | 2621 | }, |
| 2628 | 2622 | } |
| 2629 | 2623 | } |
| 2630 | | const span = try p.listToSpan(init_list.items); |
| 2624 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2631 | 2625 | const trailing_comma = p.token_tags[p.tok_i - 2] == .comma; |
| 2632 | 2626 | return p.addNode(.{ |
| 2633 | 2627 | .tag = if (trailing_comma) .struct_init_dot_comma else .struct_init_dot, |
| ... | ... | @@ -2669,15 +2663,15 @@ const Parser = struct { |
| 2669 | 2663 | if (comma_two == null) { |
| 2670 | 2664 | try p.warnExpected(.comma); |
| 2671 | 2665 | } |
| 2672 | | var init_list = std.ArrayList(Node.Index).init(p.gpa); |
| 2673 | | defer init_list.deinit(); |
| 2666 | const scratch_top = p.scratch.items.len; |
| 2667 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2674 | 2668 | |
| 2675 | | try init_list.appendSlice(&.{ elem_init_one, elem_init_two }); |
| 2669 | try p.scratch.appendSlice(p.gpa, &.{ elem_init_one, elem_init_two }); |
| 2676 | 2670 | |
| 2677 | 2671 | while (true) { |
| 2678 | 2672 | const next = try p.expectExpr(); |
| 2679 | 2673 | if (next == 0) break; |
| 2680 | | try init_list.append(next); |
| 2674 | try p.scratch.append(p.gpa, next); |
| 2681 | 2675 | switch (p.token_tags[p.nextToken()]) { |
| 2682 | 2676 | .comma => { |
| 2683 | 2677 | if (p.eatToken(.r_brace)) |_| break; |
| ... | ... | @@ -2694,7 +2688,7 @@ const Parser = struct { |
| 2694 | 2688 | }, |
| 2695 | 2689 | } |
| 2696 | 2690 | } |
| 2697 | | const span = try p.listToSpan(init_list.items); |
| 2691 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2698 | 2692 | return p.addNode(.{ |
| 2699 | 2693 | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .array_init_dot_comma else .array_init_dot, |
| 2700 | 2694 | .main_token = lbrace, |
| ... | ... | @@ -2924,13 +2918,13 @@ const Parser = struct { |
| 2924 | 2918 | |
| 2925 | 2919 | _ = try p.expectToken(.colon); |
| 2926 | 2920 | |
| 2927 | | var list = std.ArrayList(Node.Index).init(p.gpa); |
| 2928 | | defer list.deinit(); |
| 2921 | const scratch_top = p.scratch.items.len; |
| 2922 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2929 | 2923 | |
| 2930 | 2924 | while (true) { |
| 2931 | 2925 | const output_item = try p.parseAsmOutputItem(); |
| 2932 | 2926 | if (output_item == 0) break; |
| 2933 | | try list.append(output_item); |
| 2927 | try p.scratch.append(p.gpa, output_item); |
| 2934 | 2928 | switch (p.token_tags[p.tok_i]) { |
| 2935 | 2929 | .comma => p.tok_i += 1, |
| 2936 | 2930 | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. |
| ... | ... | @@ -2945,7 +2939,7 @@ const Parser = struct { |
| 2945 | 2939 | while (true) { |
| 2946 | 2940 | const input_item = try p.parseAsmInputItem(); |
| 2947 | 2941 | if (input_item == 0) break; |
| 2948 | | try list.append(input_item); |
| 2942 | try p.scratch.append(p.gpa, input_item); |
| 2949 | 2943 | switch (p.token_tags[p.tok_i]) { |
| 2950 | 2944 | .comma => p.tok_i += 1, |
| 2951 | 2945 | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. |
| ... | ... | @@ -2971,7 +2965,7 @@ const Parser = struct { |
| 2971 | 2965 | } |
| 2972 | 2966 | } |
| 2973 | 2967 | const rparen = try p.expectToken(.r_paren); |
| 2974 | | const span = try p.listToSpan(list.items); |
| 2968 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2975 | 2969 | return p.addNode(.{ |
| 2976 | 2970 | .tag = .@"asm", |
| 2977 | 2971 | .main_token = asm_token, |
| ... | ... | @@ -3192,16 +3186,16 @@ const Parser = struct { |
| 3192 | 3186 | }); |
| 3193 | 3187 | } |
| 3194 | 3188 | |
| 3195 | | var list = std.ArrayList(Node.Index).init(p.gpa); |
| 3196 | | defer list.deinit(); |
| 3189 | const scratch_top = p.scratch.items.len; |
| 3190 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3197 | 3191 | |
| 3198 | | try list.append(first_item); |
| 3192 | try p.scratch.append(p.gpa, first_item); |
| 3199 | 3193 | while (p.eatToken(.comma)) |_| { |
| 3200 | 3194 | const next_item = try p.parseSwitchItem(); |
| 3201 | 3195 | if (next_item == 0) break; |
| 3202 | | try list.append(next_item); |
| 3196 | try p.scratch.append(p.gpa, next_item); |
| 3203 | 3197 | } |
| 3204 | | const span = try p.listToSpan(list.items); |
| 3198 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 3205 | 3199 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); |
| 3206 | 3200 | _ = try p.parsePtrPayload(); |
| 3207 | 3201 | return p.addNode(.{ |
| ... | ... | @@ -3556,10 +3550,13 @@ const Parser = struct { |
| 3556 | 3550 | } |
| 3557 | 3551 | |
| 3558 | 3552 | /// ParamDeclList <- (ParamDecl COMMA)* ParamDecl? |
| 3559 | | fn parseParamDeclList(p: *Parser) !SmallSpan { |
| 3553 | fn parseParamDeclList(p: *Parser) ![]Node.Index { |
| 3554 | const scratch_top = p.scratch.items.len; |
| 3555 | // don't defer p.scratch.shrinkRetainingCapacity because caller will do it |
| 3556 | |
| 3560 | 3557 | _ = try p.expectToken(.l_paren); |
| 3561 | 3558 | if (p.eatToken(.r_paren)) |_| { |
| 3562 | | return SmallSpan{ .zero_or_one = 0 }; |
| 3559 | return p.scratch.items[scratch_top..]; |
| 3563 | 3560 | } |
| 3564 | 3561 | const param_one = while (true) { |
| 3565 | 3562 | const param = try p.expectParamDecl(); |
| ... | ... | @@ -3567,10 +3564,10 @@ const Parser = struct { |
| 3567 | 3564 | switch (p.token_tags[p.nextToken()]) { |
| 3568 | 3565 | .comma => { |
| 3569 | 3566 | if (p.eatToken(.r_paren)) |_| { |
| 3570 | | return SmallSpan{ .zero_or_one = 0 }; |
| 3567 | return p.scratch.items[scratch_top..]; |
| 3571 | 3568 | } |
| 3572 | 3569 | }, |
| 3573 | | .r_paren => return SmallSpan{ .zero_or_one = 0 }, |
| 3570 | .r_paren => return p.scratch.items[scratch_top..], |
| 3574 | 3571 | else => { |
| 3575 | 3572 | // This is likely just a missing comma; |
| 3576 | 3573 | // give an error but continue parsing this list. |
| ... | ... | @@ -3579,11 +3576,12 @@ const Parser = struct { |
| 3579 | 3576 | }, |
| 3580 | 3577 | } |
| 3581 | 3578 | } else unreachable; |
| 3579 | try p.scratch.append(p.gpa, param_one); |
| 3582 | 3580 | |
| 3583 | 3581 | const param_two = while (true) { |
| 3584 | 3582 | switch (p.token_tags[p.nextToken()]) { |
| 3585 | 3583 | .comma => {}, |
| 3586 | | .r_paren => return SmallSpan{ .zero_or_one = param_one }, |
| 3584 | .r_paren => return p.scratch.items[scratch_top..], |
| 3587 | 3585 | .colon, .r_brace, .r_bracket => { |
| 3588 | 3586 | p.tok_i -= 1; |
| 3589 | 3587 | return p.failExpected(.r_paren); |
| ... | ... | @@ -3596,21 +3594,17 @@ const Parser = struct { |
| 3596 | 3594 | }, |
| 3597 | 3595 | } |
| 3598 | 3596 | if (p.eatToken(.r_paren)) |_| { |
| 3599 | | return SmallSpan{ .zero_or_one = param_one }; |
| 3597 | return p.scratch.items[scratch_top..]; |
| 3600 | 3598 | } |
| 3601 | 3599 | const param = try p.expectParamDecl(); |
| 3602 | 3600 | if (param != 0) break param; |
| 3603 | 3601 | } else unreachable; |
| 3604 | | |
| 3605 | | var list = std.ArrayList(Node.Index).init(p.gpa); |
| 3606 | | defer list.deinit(); |
| 3607 | | |
| 3608 | | try list.appendSlice(&.{ param_one, param_two }); |
| 3602 | try p.scratch.append(p.gpa, param_two); |
| 3609 | 3603 | |
| 3610 | 3604 | while (true) { |
| 3611 | 3605 | switch (p.token_tags[p.nextToken()]) { |
| 3612 | 3606 | .comma => {}, |
| 3613 | | .r_paren => return SmallSpan{ .multi = list.toOwnedSlice() }, |
| 3607 | .r_paren => return p.scratch.items[scratch_top..], |
| 3614 | 3608 | .colon, .r_brace, .r_bracket => { |
| 3615 | 3609 | p.tok_i -= 1; |
| 3616 | 3610 | return p.failExpected(.r_paren); |
| ... | ... | @@ -3623,10 +3617,10 @@ const Parser = struct { |
| 3623 | 3617 | }, |
| 3624 | 3618 | } |
| 3625 | 3619 | if (p.eatToken(.r_paren)) |_| { |
| 3626 | | return SmallSpan{ .multi = list.toOwnedSlice() }; |
| 3620 | return p.scratch.items[scratch_top..]; |
| 3627 | 3621 | } |
| 3628 | 3622 | const param = try p.expectParamDecl(); |
| 3629 | | if (param != 0) try list.append(param); |
| 3623 | if (param != 0) try p.scratch.append(p.gpa, param); |
| 3630 | 3624 | } |
| 3631 | 3625 | } |
| 3632 | 3626 | |
| ... | ... | @@ -3635,14 +3629,14 @@ const Parser = struct { |
| 3635 | 3629 | fn ListParseFn(comptime nodeParseFn: anytype) (fn (p: *Parser) Error!Node.SubRange) { |
| 3636 | 3630 | return struct { |
| 3637 | 3631 | pub fn parse(p: *Parser) Error!Node.SubRange { |
| 3638 | | var list = std.ArrayList(Node.Index).init(p.gpa); |
| 3639 | | defer list.deinit(); |
| 3632 | const scratch_top = p.scratch.items.len; |
| 3633 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3640 | 3634 | |
| 3641 | 3635 | while (true) { |
| 3642 | 3636 | const item = try nodeParseFn(p); |
| 3643 | 3637 | if (item == 0) break; |
| 3644 | 3638 | |
| 3645 | | try list.append(item); |
| 3639 | try p.scratch.append(p.gpa, item); |
| 3646 | 3640 | |
| 3647 | 3641 | switch (p.token_tags[p.tok_i]) { |
| 3648 | 3642 | .comma => p.tok_i += 1, |
| ... | ... | @@ -3655,7 +3649,7 @@ const Parser = struct { |
| 3655 | 3649 | }, |
| 3656 | 3650 | } |
| 3657 | 3651 | } |
| 3658 | | return p.listToSpan(list.items); |
| 3652 | return p.listToSpan(p.scratch.items[scratch_top..]); |
| 3659 | 3653 | } |
| 3660 | 3654 | }.parse; |
| 3661 | 3655 | } |
| ... | ... | @@ -3746,18 +3740,18 @@ const Parser = struct { |
| 3746 | 3740 | }, |
| 3747 | 3741 | } |
| 3748 | 3742 | |
| 3749 | | var list = std.ArrayList(Node.Index).init(p.gpa); |
| 3750 | | defer list.deinit(); |
| 3743 | const scratch_top = p.scratch.items.len; |
| 3744 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3751 | 3745 | |
| 3752 | | try list.appendSlice(&.{ param_one, param_two }); |
| 3746 | try p.scratch.appendSlice(p.gpa, &.{ param_one, param_two }); |
| 3753 | 3747 | |
| 3754 | 3748 | while (true) { |
| 3755 | 3749 | const param = try p.expectExpr(); |
| 3756 | | try list.append(param); |
| 3750 | try p.scratch.append(p.gpa, param); |
| 3757 | 3751 | switch (p.token_tags[p.nextToken()]) { |
| 3758 | 3752 | .comma => { |
| 3759 | 3753 | if (p.eatToken(.r_paren)) |_| { |
| 3760 | | const params = try p.listToSpan(list.items); |
| 3754 | const params = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 3761 | 3755 | return p.addNode(.{ |
| 3762 | 3756 | .tag = .builtin_call_comma, |
| 3763 | 3757 | .main_token = builtin_token, |
| ... | ... | @@ -3770,7 +3764,7 @@ const Parser = struct { |
| 3770 | 3764 | continue; |
| 3771 | 3765 | }, |
| 3772 | 3766 | .r_paren => { |
| 3773 | | const params = try p.listToSpan(list.items); |
| 3767 | const params = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 3774 | 3768 | return p.addNode(.{ |
| 3775 | 3769 | .tag = .builtin_call, |
| 3776 | 3770 | .main_token = builtin_token, |