| ... | @@ -43,11 +43,13 @@ pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!Tree { | ... | @@ -43,11 +43,13 @@ pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!Tree { |
| 43 | .errors = .{}, | 43 | .errors = .{}, |
| 44 | .nodes = .{}, | 44 | .nodes = .{}, |
| 45 | .extra_data = .{}, | 45 | .extra_data = .{}, |
| | 46 | .scratch = .{}, |
| 46 | .tok_i = 0, | 47 | .tok_i = 0, |
| 47 | }; | 48 | }; |
| 48 | defer parser.errors.deinit(gpa); | 49 | defer parser.errors.deinit(gpa); |
| 49 | defer parser.nodes.deinit(gpa); | 50 | defer parser.nodes.deinit(gpa); |
| 50 | defer parser.extra_data.deinit(gpa); | 51 | defer parser.extra_data.deinit(gpa); |
| | 52 | defer parser.scratch.deinit(gpa); |
| 51 | | 53 | |
| 52 | // Empirically, Zig source code has a 2:1 ratio of tokens to AST nodes. | 54 | // Empirically, Zig source code has a 2:1 ratio of tokens to AST nodes. |
| 53 | // Make sure at least 1 so we can use appendAssumeCapacity on the root node below. | 55 | // Make sure at least 1 so we can use appendAssumeCapacity on the root node below. |
| ... | @@ -93,17 +95,11 @@ const Parser = struct { | ... | @@ -93,17 +95,11 @@ const Parser = struct { |
| 93 | errors: std.ArrayListUnmanaged(AstError), | 95 | errors: std.ArrayListUnmanaged(AstError), |
| 94 | nodes: ast.NodeList, | 96 | nodes: ast.NodeList, |
| 95 | extra_data: std.ArrayListUnmanaged(Node.Index), | 97 | extra_data: std.ArrayListUnmanaged(Node.Index), |
| | 98 | scratch: std.ArrayListUnmanaged(Node.Index), |
| 96 | | 99 | |
| 97 | const SmallSpan = union(enum) { | 100 | const SmallSpan = union(enum) { |
| 98 | zero_or_one: Node.Index, | 101 | zero_or_one: Node.Index, |
| 99 | multi: []Node.Index, | 102 | multi: Node.SubRange, |
| 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 | }; | 103 | }; |
| 108 | | 104 | |
| 109 | const Members = struct { | 105 | const Members = struct { |
| ... | @@ -204,8 +200,8 @@ const Parser = struct { | ... | @@ -204,8 +200,8 @@ const Parser = struct { |
| 204 | /// / | 200 | /// / |
| 205 | /// TopLevelComptime <- KEYWORD_comptime BlockExpr | 201 | /// TopLevelComptime <- KEYWORD_comptime BlockExpr |
| 206 | fn parseContainerMembers(p: *Parser) !Members { | 202 | fn parseContainerMembers(p: *Parser) !Members { |
| 207 | var list = std.ArrayList(Node.Index).init(p.gpa); | 203 | const scratch_top = p.scratch.items.len; |
| 208 | defer list.deinit(); | 204 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 209 | | 205 | |
| 210 | var field_state: union(enum) { | 206 | var field_state: union(enum) { |
| 211 | /// No fields have been seen. | 207 | /// No fields have been seen. |
| ... | @@ -233,7 +229,7 @@ const Parser = struct { | ... | @@ -233,7 +229,7 @@ const Parser = struct { |
| 233 | if (field_state == .seen) { | 229 | if (field_state == .seen) { |
| 234 | field_state = .{ .end = test_decl_node }; | 230 | field_state = .{ .end = test_decl_node }; |
| 235 | } | 231 | } |
| 236 | try list.append(test_decl_node); | 232 | try p.scratch.append(p.gpa, test_decl_node); |
| 237 | } | 233 | } |
| 238 | trailing = false; | 234 | trailing = false; |
| 239 | }, | 235 | }, |
| ... | @@ -254,7 +250,7 @@ const Parser = struct { | ... | @@ -254,7 +250,7 @@ const Parser = struct { |
| 254 | field_state = .err; | 250 | field_state = .err; |
| 255 | }, | 251 | }, |
| 256 | } | 252 | } |
| 257 | try list.append(container_field); | 253 | try p.scratch.append(p.gpa, container_field); |
| 258 | switch (p.token_tags[p.tok_i]) { | 254 | switch (p.token_tags[p.tok_i]) { |
| 259 | .comma => { | 255 | .comma => { |
| 260 | p.tok_i += 1; | 256 | p.tok_i += 1; |
| ... | @@ -294,7 +290,7 @@ const Parser = struct { | ... | @@ -294,7 +290,7 @@ const Parser = struct { |
| 294 | if (field_state == .seen) { | 290 | if (field_state == .seen) { |
| 295 | field_state = .{ .end = comptime_node }; | 291 | field_state = .{ .end = comptime_node }; |
| 296 | } | 292 | } |
| 297 | try list.append(comptime_node); | 293 | try p.scratch.append(p.gpa, comptime_node); |
| 298 | } | 294 | } |
| 299 | trailing = false; | 295 | trailing = false; |
| 300 | }, | 296 | }, |
| ... | @@ -310,7 +306,7 @@ const Parser = struct { | ... | @@ -310,7 +306,7 @@ const Parser = struct { |
| 310 | if (field_state == .seen) { | 306 | if (field_state == .seen) { |
| 311 | field_state = .{ .end = top_level_decl }; | 307 | field_state = .{ .end = top_level_decl }; |
| 312 | } | 308 | } |
| 313 | try list.append(top_level_decl); | 309 | try p.scratch.append(p.gpa, top_level_decl); |
| 314 | } | 310 | } |
| 315 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; | 311 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; |
| 316 | }, | 312 | }, |
| ... | @@ -320,7 +316,7 @@ const Parser = struct { | ... | @@ -320,7 +316,7 @@ const Parser = struct { |
| 320 | if (field_state == .seen) { | 316 | if (field_state == .seen) { |
| 321 | field_state = .{ .end = node }; | 317 | field_state = .{ .end = node }; |
| 322 | } | 318 | } |
| 323 | try list.append(node); | 319 | try p.scratch.append(p.gpa, node); |
| 324 | } | 320 | } |
| 325 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; | 321 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; |
| 326 | }, | 322 | }, |
| ... | @@ -338,7 +334,7 @@ const Parser = struct { | ... | @@ -338,7 +334,7 @@ const Parser = struct { |
| 338 | if (field_state == .seen) { | 334 | if (field_state == .seen) { |
| 339 | field_state = .{ .end = top_level_decl }; | 335 | field_state = .{ .end = top_level_decl }; |
| 340 | } | 336 | } |
| 341 | try list.append(top_level_decl); | 337 | try p.scratch.append(p.gpa, top_level_decl); |
| 342 | } | 338 | } |
| 343 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; | 339 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; |
| 344 | }, | 340 | }, |
| ... | @@ -357,7 +353,7 @@ const Parser = struct { | ... | @@ -357,7 +353,7 @@ const Parser = struct { |
| 357 | field_state = .err; | 353 | field_state = .err; |
| 358 | }, | 354 | }, |
| 359 | } | 355 | } |
| 360 | try list.append(container_field); | 356 | try p.scratch.append(p.gpa, container_field); |
| 361 | switch (p.token_tags[p.tok_i]) { | 357 | switch (p.token_tags[p.tok_i]) { |
| 362 | .comma => { | 358 | .comma => { |
| 363 | p.tok_i += 1; | 359 | p.tok_i += 1; |
| ... | @@ -393,7 +389,8 @@ const Parser = struct { | ... | @@ -393,7 +389,8 @@ const Parser = struct { |
| 393 | } | 389 | } |
| 394 | } | 390 | } |
| 395 | | 391 | |
| 396 | switch (list.items.len) { | 392 | const items = p.scratch.items[scratch_top..]; |
| | 393 | switch (items.len) { |
| 397 | 0 => return Members{ | 394 | 0 => return Members{ |
| 398 | .len = 0, | 395 | .len = 0, |
| 399 | .lhs = 0, | 396 | .lhs = 0, |
| ... | @@ -402,20 +399,20 @@ const Parser = struct { | ... | @@ -402,20 +399,20 @@ const Parser = struct { |
| 402 | }, | 399 | }, |
| 403 | 1 => return Members{ | 400 | 1 => return Members{ |
| 404 | .len = 1, | 401 | .len = 1, |
| 405 | .lhs = list.items[0], | 402 | .lhs = items[0], |
| 406 | .rhs = 0, | 403 | .rhs = 0, |
| 407 | .trailing = trailing, | 404 | .trailing = trailing, |
| 408 | }, | 405 | }, |
| 409 | 2 => return Members{ | 406 | 2 => return Members{ |
| 410 | .len = 2, | 407 | .len = 2, |
| 411 | .lhs = list.items[0], | 408 | .lhs = items[0], |
| 412 | .rhs = list.items[1], | 409 | .rhs = items[1], |
| 413 | .trailing = trailing, | 410 | .trailing = trailing, |
| 414 | }, | 411 | }, |
| 415 | else => { | 412 | else => { |
| 416 | const span = try p.listToSpan(list.items); | 413 | const span = try p.listToSpan(items); |
| 417 | return Members{ | 414 | return Members{ |
| 418 | .len = list.items.len, | 415 | .len = items.len, |
| 419 | .lhs = span.start, | 416 | .lhs = span.start, |
| 420 | .rhs = span.end, | 417 | .rhs = span.end, |
| 421 | .trailing = trailing, | 418 | .trailing = trailing, |
| ... | @@ -648,7 +645,6 @@ const Parser = struct { | ... | @@ -648,7 +645,6 @@ const Parser = struct { |
| 648 | | 645 | |
| 649 | _ = p.eatToken(.identifier); | 646 | _ = p.eatToken(.identifier); |
| 650 | const params = try p.parseParamDeclList(); | 647 | const params = try p.parseParamDeclList(); |
| 651 | defer params.deinit(p.gpa); | | |
| 652 | const align_expr = try p.parseByteAlign(); | 648 | const align_expr = try p.parseByteAlign(); |
| 653 | const section_expr = try p.parseLinkSection(); | 649 | const section_expr = try p.parseLinkSection(); |
| 654 | const callconv_expr = try p.parseCallconv(); | 650 | const callconv_expr = try p.parseCallconv(); |
| ... | @@ -671,8 +667,7 @@ const Parser = struct { | ... | @@ -671,8 +667,7 @@ const Parser = struct { |
| 671 | .rhs = return_type_expr, | 667 | .rhs = return_type_expr, |
| 672 | }, | 668 | }, |
| 673 | }), | 669 | }), |
| 674 | .multi => |list| { | 670 | .multi => |span| { |
| 675 | const span = try p.listToSpan(list); | | |
| 676 | return p.setNode(fn_proto_index, .{ | 671 | return p.setNode(fn_proto_index, .{ |
| 677 | .tag = .fn_proto_multi, | 672 | .tag = .fn_proto_multi, |
| 678 | .main_token = fn_token, | 673 | .main_token = fn_token, |
| ... | @@ -701,8 +696,7 @@ const Parser = struct { | ... | @@ -701,8 +696,7 @@ const Parser = struct { |
| 701 | .rhs = return_type_expr, | 696 | .rhs = return_type_expr, |
| 702 | }, | 697 | }, |
| 703 | }), | 698 | }), |
| 704 | .multi => |list| { | 699 | .multi => |span| { |
| 705 | const span = try p.listToSpan(list); | | |
| 706 | return p.setNode(fn_proto_index, .{ | 700 | return p.setNode(fn_proto_index, .{ |
| 707 | .tag = .fn_proto, | 701 | .tag = .fn_proto, |
| 708 | .main_token = fn_token, | 702 | .main_token = fn_token, |
| ... | @@ -1894,20 +1888,20 @@ const Parser = struct { | ... | @@ -1894,20 +1888,20 @@ const Parser = struct { |
| 1894 | }); | 1888 | }); |
| 1895 | } | 1889 | } |
| 1896 | | 1890 | |
| 1897 | var statements = std.ArrayList(Node.Index).init(p.gpa); | 1891 | const scratch_top = p.scratch.items.len; |
| 1898 | defer statements.deinit(); | 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 | while (true) { | 1896 | while (true) { |
| 1903 | const statement = try p.expectStatementRecoverable(); | 1897 | const statement = try p.expectStatementRecoverable(); |
| 1904 | if (statement == 0) break; | 1898 | if (statement == 0) break; |
| 1905 | try statements.append(statement); | 1899 | try p.scratch.append(p.gpa, statement); |
| 1906 | if (p.token_tags[p.tok_i] == .r_brace) break; | 1900 | if (p.token_tags[p.tok_i] == .r_brace) break; |
| 1907 | } | 1901 | } |
| 1908 | _ = try p.expectToken(.r_brace); | 1902 | _ = try p.expectToken(.r_brace); |
| 1909 | const semicolon = p.token_tags[p.tok_i - 2] == .semicolon; | 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 | return p.addNode(.{ | 1905 | return p.addNode(.{ |
| 1912 | .tag = if (semicolon) .block_semicolon else .block, | 1906 | .tag = if (semicolon) .block_semicolon else .block, |
| 1913 | .main_token = lbrace, | 1907 | .main_token = lbrace, |
| ... | @@ -2041,14 +2035,14 @@ const Parser = struct { | ... | @@ -2041,14 +2035,14 @@ const Parser = struct { |
| 2041 | }); | 2035 | }); |
| 2042 | } | 2036 | } |
| 2043 | | 2037 | |
| 2044 | var init_list = std.ArrayList(Node.Index).init(p.gpa); | 2038 | const scratch_top = p.scratch.items.len; |
| 2045 | defer init_list.deinit(); | 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 | while (true) { | 2043 | while (true) { |
| 2050 | const next = try p.expectFieldInit(); | 2044 | const next = try p.expectFieldInit(); |
| 2051 | try init_list.append(next); | 2045 | try p.scratch.append(p.gpa, next); |
| 2052 | | 2046 | |
| 2053 | switch (p.token_tags[p.nextToken()]) { | 2047 | switch (p.token_tags[p.nextToken()]) { |
| 2054 | .comma => { | 2048 | .comma => { |
| ... | @@ -2068,7 +2062,7 @@ const Parser = struct { | ... | @@ -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 | return p.addNode(.{ | 2066 | return p.addNode(.{ |
| 2073 | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .struct_init_comma else .struct_init, | 2067 | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .struct_init_comma else .struct_init, |
| 2074 | .main_token = lbrace, | 2068 | .main_token = lbrace, |
| ... | @@ -2098,22 +2092,22 @@ const Parser = struct { | ... | @@ -2098,22 +2092,22 @@ const Parser = struct { |
| 2098 | try p.warnExpected(.comma); | 2092 | try p.warnExpected(.comma); |
| 2099 | } | 2093 | } |
| 2100 | | 2094 | |
| 2101 | var init_list = std.ArrayList(Node.Index).init(p.gpa); | 2095 | const scratch_top = p.scratch.items.len; |
| 2102 | defer init_list.deinit(); | 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 | var trailing_comma = true; | 2100 | var trailing_comma = true; |
| 2107 | var next = try p.parseExpr(); | 2101 | var next = try p.parseExpr(); |
| 2108 | while (next != 0) : (next = try p.parseExpr()) { | 2102 | while (next != 0) : (next = try p.parseExpr()) { |
| 2109 | try init_list.append(next); | 2103 | try p.scratch.append(p.gpa, next); |
| 2110 | if (p.eatToken(.comma) == null) { | 2104 | if (p.eatToken(.comma) == null) { |
| 2111 | trailing_comma = false; | 2105 | trailing_comma = false; |
| 2112 | break; | 2106 | break; |
| 2113 | } | 2107 | } |
| 2114 | } | 2108 | } |
| 2115 | _ = try p.expectToken(.r_brace); | 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 | return p.addNode(.{ | 2111 | return p.addNode(.{ |
| 2118 | .tag = if (trailing_comma) .array_init_comma else .array_init, | 2112 | .tag = if (trailing_comma) .array_init_comma else .array_init, |
| 2119 | .main_token = lbrace, | 2113 | .main_token = lbrace, |
| ... | @@ -2188,18 +2182,18 @@ const Parser = struct { | ... | @@ -2188,18 +2182,18 @@ const Parser = struct { |
| 2188 | try p.warnExpected(.comma); | 2182 | try p.warnExpected(.comma); |
| 2189 | } | 2183 | } |
| 2190 | | 2184 | |
| 2191 | var param_list = std.ArrayList(Node.Index).init(p.gpa); | 2185 | const scratch_top = p.scratch.items.len; |
| 2192 | defer param_list.deinit(); | 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 | while (true) { | 2190 | while (true) { |
| 2197 | const next = try p.expectExpr(); | 2191 | const next = try p.expectExpr(); |
| 2198 | try param_list.append(next); | 2192 | try p.scratch.append(p.gpa, next); |
| 2199 | switch (p.token_tags[p.nextToken()]) { | 2193 | switch (p.token_tags[p.nextToken()]) { |
| 2200 | .comma => { | 2194 | .comma => { |
| 2201 | if (p.eatToken(.r_paren)) |_| { | 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 | return p.addNode(.{ | 2197 | return p.addNode(.{ |
| 2204 | .tag = .async_call_comma, | 2198 | .tag = .async_call_comma, |
| 2205 | .main_token = lparen, | 2199 | .main_token = lparen, |
| ... | @@ -2216,7 +2210,7 @@ const Parser = struct { | ... | @@ -2216,7 +2210,7 @@ const Parser = struct { |
| 2216 | } | 2210 | } |
| 2217 | }, | 2211 | }, |
| 2218 | .r_paren => { | 2212 | .r_paren => { |
| 2219 | const span = try p.listToSpan(param_list.items); | 2213 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2220 | return p.addNode(.{ | 2214 | return p.addNode(.{ |
| 2221 | .tag = .async_call, | 2215 | .tag = .async_call, |
| 2222 | .main_token = lparen, | 2216 | .main_token = lparen, |
| ... | @@ -2277,18 +2271,18 @@ const Parser = struct { | ... | @@ -2277,18 +2271,18 @@ const Parser = struct { |
| 2277 | try p.warnExpected(.comma); | 2271 | try p.warnExpected(.comma); |
| 2278 | } | 2272 | } |
| 2279 | | 2273 | |
| 2280 | var param_list = std.ArrayList(Node.Index).init(p.gpa); | 2274 | const scratch_top = p.scratch.items.len; |
| 2281 | defer param_list.deinit(); | 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 | while (true) { | 2279 | while (true) { |
| 2286 | const next = try p.expectExpr(); | 2280 | const next = try p.expectExpr(); |
| 2287 | try param_list.append(next); | 2281 | try p.scratch.append(p.gpa, next); |
| 2288 | switch (p.token_tags[p.nextToken()]) { | 2282 | switch (p.token_tags[p.nextToken()]) { |
| 2289 | .comma => { | 2283 | .comma => { |
| 2290 | if (p.eatToken(.r_paren)) |_| { | 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 | break :res try p.addNode(.{ | 2286 | break :res try p.addNode(.{ |
| 2293 | .tag = .call_comma, | 2287 | .tag = .call_comma, |
| 2294 | .main_token = lparen, | 2288 | .main_token = lparen, |
| ... | @@ -2305,7 +2299,7 @@ const Parser = struct { | ... | @@ -2305,7 +2299,7 @@ const Parser = struct { |
| 2305 | } | 2299 | } |
| 2306 | }, | 2300 | }, |
| 2307 | .r_paren => { | 2301 | .r_paren => { |
| 2308 | const span = try p.listToSpan(param_list.items); | 2302 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2309 | break :res try p.addNode(.{ | 2303 | break :res try p.addNode(.{ |
| 2310 | .tag = .call, | 2304 | .tag = .call, |
| 2311 | .main_token = lparen, | 2305 | .main_token = lparen, |
| ... | @@ -2602,15 +2596,15 @@ const Parser = struct { | ... | @@ -2602,15 +2596,15 @@ const Parser = struct { |
| 2602 | if (comma_two == null) { | 2596 | if (comma_two == null) { |
| 2603 | try p.warnExpected(.comma); | 2597 | try p.warnExpected(.comma); |
| 2604 | } | 2598 | } |
| 2605 | var init_list = std.ArrayList(Node.Index).init(p.gpa); | 2599 | const scratch_top = p.scratch.items.len; |
| 2606 | defer init_list.deinit(); | 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 | while (true) { | 2604 | while (true) { |
| 2611 | const next = try p.expectFieldInit(); | 2605 | const next = try p.expectFieldInit(); |
| 2612 | assert(next != 0); | 2606 | assert(next != 0); |
| 2613 | try init_list.append(next); | 2607 | try p.scratch.append(p.gpa, next); |
| 2614 | switch (p.token_tags[p.nextToken()]) { | 2608 | switch (p.token_tags[p.nextToken()]) { |
| 2615 | .comma => { | 2609 | .comma => { |
| 2616 | if (p.eatToken(.r_brace)) |_| break; | 2610 | if (p.eatToken(.r_brace)) |_| break; |
| ... | @@ -2627,7 +2621,7 @@ const Parser = struct { | ... | @@ -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 | const trailing_comma = p.token_tags[p.tok_i - 2] == .comma; | 2625 | const trailing_comma = p.token_tags[p.tok_i - 2] == .comma; |
| 2632 | return p.addNode(.{ | 2626 | return p.addNode(.{ |
| 2633 | .tag = if (trailing_comma) .struct_init_dot_comma else .struct_init_dot, | 2627 | .tag = if (trailing_comma) .struct_init_dot_comma else .struct_init_dot, |
| ... | @@ -2669,15 +2663,15 @@ const Parser = struct { | ... | @@ -2669,15 +2663,15 @@ const Parser = struct { |
| 2669 | if (comma_two == null) { | 2663 | if (comma_two == null) { |
| 2670 | try p.warnExpected(.comma); | 2664 | try p.warnExpected(.comma); |
| 2671 | } | 2665 | } |
| 2672 | var init_list = std.ArrayList(Node.Index).init(p.gpa); | 2666 | const scratch_top = p.scratch.items.len; |
| 2673 | defer init_list.deinit(); | 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 | while (true) { | 2671 | while (true) { |
| 2678 | const next = try p.expectExpr(); | 2672 | const next = try p.expectExpr(); |
| 2679 | if (next == 0) break; | 2673 | if (next == 0) break; |
| 2680 | try init_list.append(next); | 2674 | try p.scratch.append(p.gpa, next); |
| 2681 | switch (p.token_tags[p.nextToken()]) { | 2675 | switch (p.token_tags[p.nextToken()]) { |
| 2682 | .comma => { | 2676 | .comma => { |
| 2683 | if (p.eatToken(.r_brace)) |_| break; | 2677 | if (p.eatToken(.r_brace)) |_| break; |
| ... | @@ -2694,7 +2688,7 @@ const Parser = struct { | ... | @@ -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 | return p.addNode(.{ | 2692 | return p.addNode(.{ |
| 2699 | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .array_init_dot_comma else .array_init_dot, | 2693 | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .array_init_dot_comma else .array_init_dot, |
| 2700 | .main_token = lbrace, | 2694 | .main_token = lbrace, |
| ... | @@ -2924,13 +2918,13 @@ const Parser = struct { | ... | @@ -2924,13 +2918,13 @@ const Parser = struct { |
| 2924 | | 2918 | |
| 2925 | _ = try p.expectToken(.colon); | 2919 | _ = try p.expectToken(.colon); |
| 2926 | | 2920 | |
| 2927 | var list = std.ArrayList(Node.Index).init(p.gpa); | 2921 | const scratch_top = p.scratch.items.len; |
| 2928 | defer list.deinit(); | 2922 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2929 | | 2923 | |
| 2930 | while (true) { | 2924 | while (true) { |
| 2931 | const output_item = try p.parseAsmOutputItem(); | 2925 | const output_item = try p.parseAsmOutputItem(); |
| 2932 | if (output_item == 0) break; | 2926 | if (output_item == 0) break; |
| 2933 | try list.append(output_item); | 2927 | try p.scratch.append(p.gpa, output_item); |
| 2934 | switch (p.token_tags[p.tok_i]) { | 2928 | switch (p.token_tags[p.tok_i]) { |
| 2935 | .comma => p.tok_i += 1, | 2929 | .comma => p.tok_i += 1, |
| 2936 | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. | 2930 | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. |
| ... | @@ -2945,7 +2939,7 @@ const Parser = struct { | ... | @@ -2945,7 +2939,7 @@ const Parser = struct { |
| 2945 | while (true) { | 2939 | while (true) { |
| 2946 | const input_item = try p.parseAsmInputItem(); | 2940 | const input_item = try p.parseAsmInputItem(); |
| 2947 | if (input_item == 0) break; | 2941 | if (input_item == 0) break; |
| 2948 | try list.append(input_item); | 2942 | try p.scratch.append(p.gpa, input_item); |
| 2949 | switch (p.token_tags[p.tok_i]) { | 2943 | switch (p.token_tags[p.tok_i]) { |
| 2950 | .comma => p.tok_i += 1, | 2944 | .comma => p.tok_i += 1, |
| 2951 | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. | 2945 | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. |
| ... | @@ -2971,7 +2965,7 @@ const Parser = struct { | ... | @@ -2971,7 +2965,7 @@ const Parser = struct { |
| 2971 | } | 2965 | } |
| 2972 | } | 2966 | } |
| 2973 | const rparen = try p.expectToken(.r_paren); | 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 | return p.addNode(.{ | 2969 | return p.addNode(.{ |
| 2976 | .tag = .@"asm", | 2970 | .tag = .@"asm", |
| 2977 | .main_token = asm_token, | 2971 | .main_token = asm_token, |
| ... | @@ -3192,16 +3186,16 @@ const Parser = struct { | ... | @@ -3192,16 +3186,16 @@ const Parser = struct { |
| 3192 | }); | 3186 | }); |
| 3193 | } | 3187 | } |
| 3194 | | 3188 | |
| 3195 | var list = std.ArrayList(Node.Index).init(p.gpa); | 3189 | const scratch_top = p.scratch.items.len; |
| 3196 | defer list.deinit(); | 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 | while (p.eatToken(.comma)) |_| { | 3193 | while (p.eatToken(.comma)) |_| { |
| 3200 | const next_item = try p.parseSwitchItem(); | 3194 | const next_item = try p.parseSwitchItem(); |
| 3201 | if (next_item == 0) break; | 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 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); | 3199 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); |
| 3206 | _ = try p.parsePtrPayload(); | 3200 | _ = try p.parsePtrPayload(); |
| 3207 | return p.addNode(.{ | 3201 | return p.addNode(.{ |
| ... | @@ -3602,15 +3596,14 @@ const Parser = struct { | ... | @@ -3602,15 +3596,14 @@ const Parser = struct { |
| 3602 | if (param != 0) break param; | 3596 | if (param != 0) break param; |
| 3603 | } else unreachable; | 3597 | } else unreachable; |
| 3604 | | 3598 | |
| 3605 | var list = std.ArrayList(Node.Index).init(p.gpa); | 3599 | const scratch_top = p.scratch.items.len; |
| 3606 | defer list.deinit(); | 3600 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3607 | | 3601 | try p.scratch.appendSlice(p.gpa, &.{ param_one, param_two }); |
| 3608 | try list.appendSlice(&.{ param_one, param_two }); | | |
| 3609 | | 3602 | |
| 3610 | while (true) { | 3603 | while (true) { |
| 3611 | switch (p.token_tags[p.nextToken()]) { | 3604 | switch (p.token_tags[p.nextToken()]) { |
| 3612 | .comma => {}, | 3605 | .comma => {}, |
| 3613 | .r_paren => return SmallSpan{ .multi = list.toOwnedSlice() }, | 3606 | .r_paren => return SmallSpan{ .multi = try p.listToSpan(p.scratch.items[scratch_top..]) }, |
| 3614 | .colon, .r_brace, .r_bracket => { | 3607 | .colon, .r_brace, .r_bracket => { |
| 3615 | p.tok_i -= 1; | 3608 | p.tok_i -= 1; |
| 3616 | return p.failExpected(.r_paren); | 3609 | return p.failExpected(.r_paren); |
| ... | @@ -3623,10 +3616,10 @@ const Parser = struct { | ... | @@ -3623,10 +3616,10 @@ const Parser = struct { |
| 3623 | }, | 3616 | }, |
| 3624 | } | 3617 | } |
| 3625 | if (p.eatToken(.r_paren)) |_| { | 3618 | if (p.eatToken(.r_paren)) |_| { |
| 3626 | return SmallSpan{ .multi = list.toOwnedSlice() }; | 3619 | return SmallSpan{ .multi = try p.listToSpan(p.scratch.items[scratch_top..]) }; |
| 3627 | } | 3620 | } |
| 3628 | const param = try p.expectParamDecl(); | 3621 | const param = try p.expectParamDecl(); |
| 3629 | if (param != 0) try list.append(param); | 3622 | if (param != 0) try p.scratch.append(p.gpa, param); |
| 3630 | } | 3623 | } |
| 3631 | } | 3624 | } |
| 3632 | | 3625 | |
| ... | @@ -3635,14 +3628,14 @@ const Parser = struct { | ... | @@ -3635,14 +3628,14 @@ const Parser = struct { |
| 3635 | fn ListParseFn(comptime nodeParseFn: anytype) (fn (p: *Parser) Error!Node.SubRange) { | 3628 | fn ListParseFn(comptime nodeParseFn: anytype) (fn (p: *Parser) Error!Node.SubRange) { |
| 3636 | return struct { | 3629 | return struct { |
| 3637 | pub fn parse(p: *Parser) Error!Node.SubRange { | 3630 | pub fn parse(p: *Parser) Error!Node.SubRange { |
| 3638 | var list = std.ArrayList(Node.Index).init(p.gpa); | 3631 | const scratch_top = p.scratch.items.len; |
| 3639 | defer list.deinit(); | 3632 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3640 | | 3633 | |
| 3641 | while (true) { | 3634 | while (true) { |
| 3642 | const item = try nodeParseFn(p); | 3635 | const item = try nodeParseFn(p); |
| 3643 | if (item == 0) break; | 3636 | if (item == 0) break; |
| 3644 | | 3637 | |
| 3645 | try list.append(item); | 3638 | try p.scratch.append(p.gpa, item); |
| 3646 | | 3639 | |
| 3647 | switch (p.token_tags[p.tok_i]) { | 3640 | switch (p.token_tags[p.tok_i]) { |
| 3648 | .comma => p.tok_i += 1, | 3641 | .comma => p.tok_i += 1, |
| ... | @@ -3655,7 +3648,7 @@ const Parser = struct { | ... | @@ -3655,7 +3648,7 @@ const Parser = struct { |
| 3655 | }, | 3648 | }, |
| 3656 | } | 3649 | } |
| 3657 | } | 3650 | } |
| 3658 | return p.listToSpan(list.items); | 3651 | return p.listToSpan(p.scratch.items[scratch_top..]); |
| 3659 | } | 3652 | } |
| 3660 | }.parse; | 3653 | }.parse; |
| 3661 | } | 3654 | } |
| ... | @@ -3746,18 +3739,18 @@ const Parser = struct { | ... | @@ -3746,18 +3739,18 @@ const Parser = struct { |
| 3746 | }, | 3739 | }, |
| 3747 | } | 3740 | } |
| 3748 | | 3741 | |
| 3749 | var list = std.ArrayList(Node.Index).init(p.gpa); | 3742 | const scratch_top = p.scratch.items.len; |
| 3750 | defer list.deinit(); | 3743 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3751 | | 3744 | |
| 3752 | try list.appendSlice(&.{ param_one, param_two }); | 3745 | try p.scratch.appendSlice(p.gpa, &.{ param_one, param_two }); |
| 3753 | | 3746 | |
| 3754 | while (true) { | 3747 | while (true) { |
| 3755 | const param = try p.expectExpr(); | 3748 | const param = try p.expectExpr(); |
| 3756 | try list.append(param); | 3749 | try p.scratch.append(p.gpa, param); |
| 3757 | switch (p.token_tags[p.nextToken()]) { | 3750 | switch (p.token_tags[p.nextToken()]) { |
| 3758 | .comma => { | 3751 | .comma => { |
| 3759 | if (p.eatToken(.r_paren)) |_| { | 3752 | if (p.eatToken(.r_paren)) |_| { |
| 3760 | const params = try p.listToSpan(list.items); | 3753 | const params = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 3761 | return p.addNode(.{ | 3754 | return p.addNode(.{ |
| 3762 | .tag = .builtin_call_comma, | 3755 | .tag = .builtin_call_comma, |
| 3763 | .main_token = builtin_token, | 3756 | .main_token = builtin_token, |
| ... | @@ -3770,7 +3763,7 @@ const Parser = struct { | ... | @@ -3770,7 +3763,7 @@ const Parser = struct { |
| 3770 | continue; | 3763 | continue; |
| 3771 | }, | 3764 | }, |
| 3772 | .r_paren => { | 3765 | .r_paren => { |
| 3773 | const params = try p.listToSpan(list.items); | 3766 | const params = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 3774 | return p.addNode(.{ | 3767 | return p.addNode(.{ |
| 3775 | .tag = .builtin_call, | 3768 | .tag = .builtin_call, |
| 3776 | .main_token = builtin_token, | 3769 | .main_token = builtin_token, |