| author | |
| committer | |
| log | 36eee7bc6cbe6fcc388ebdc38fd3c5f06c9e9043 |
| tree | f52add396d55777d2f2cb510e5f2cc22c61efc31 |
| parent | 25bcf4eb99d367965b0f699faff5d3fd1d991941 |
and extra newlines between top level declarations4 files changed, 404 insertions(+), 161 deletions(-)
lib/std/zig/ast.zig+100-24| ... | ... | @@ -196,6 +196,7 @@ pub const Tree = struct { |
| 196 | 196 | const datas = tree.nodes.items(.data); |
| 197 | 197 | const main_tokens = tree.nodes.items(.main_token); |
| 198 | 198 | const token_tags = tree.tokens.items(.tag); |
| 199 | var end_offset: TokenIndex = 0; | |
| 199 | 200 | var n = node; |
| 200 | 201 | while (true) switch (tags[n]) { |
| 201 | 202 | .Root => return 0, |
| ... | ... | @@ -251,7 +252,7 @@ pub const Tree = struct { |
| 251 | 252 | .ArrayType, |
| 252 | 253 | .ArrayTypeSentinel, |
| 253 | 254 | .ErrorValue, |
| 254 | => return main_tokens[n], | |
| 255 | => return main_tokens[n] - end_offset, | |
| 255 | 256 | |
| 256 | 257 | .ArrayInitDot, |
| 257 | 258 | .ArrayInitDotTwo, |
| ... | ... | @@ -260,7 +261,7 @@ pub const Tree = struct { |
| 260 | 261 | .StructInitDotTwo, |
| 261 | 262 | .StructInitDotTwoComma, |
| 262 | 263 | .EnumLiteral, |
| 263 | => return main_tokens[n] - 1, | |
| 264 | => return main_tokens[n] - 1 - end_offset, | |
| 264 | 265 | |
| 265 | 266 | .Catch, |
| 266 | 267 | .FieldAccess, |
| ... | ... | @@ -314,24 +315,32 @@ pub const Tree = struct { |
| 314 | 315 | .StructInitOne, |
| 315 | 316 | .StructInit, |
| 316 | 317 | .CallOne, |
| 318 | .CallOneComma, | |
| 317 | 319 | .Call, |
| 320 | .CallComma, | |
| 318 | 321 | .SwitchRange, |
| 319 | 322 | .FnDecl, |
| 320 | 323 | .ErrorUnion, |
| 321 | 324 | => n = datas[n].lhs, |
| 322 | 325 | |
| 326 | .AsyncCallOne, | |
| 327 | .AsyncCallOneComma, | |
| 328 | .AsyncCall, | |
| 329 | .AsyncCallComma, | |
| 330 | => { | |
| 331 | end_offset += 1; // async token | |
| 332 | n = datas[n].lhs; | |
| 333 | }, | |
| 334 | ||
| 323 | 335 | .ContainerFieldInit, |
| 324 | 336 | .ContainerFieldAlign, |
| 325 | 337 | .ContainerField, |
| 326 | 338 | => { |
| 327 | 339 | const name_token = main_tokens[n]; |
| 328 | if (name_token > 0 and | |
| 329 | token_tags[name_token - 1] == .Keyword_comptime) | |
| 330 | { | |
| 331 | return name_token - 1; | |
| 332 | } else { | |
| 333 | return name_token; | |
| 340 | if (name_token > 0 and token_tags[name_token - 1] == .Keyword_comptime) { | |
| 341 | end_offset += 1; | |
| 334 | 342 | } |
| 343 | return name_token - end_offset; | |
| 335 | 344 | }, |
| 336 | 345 | |
| 337 | 346 | .GlobalVarDecl, |
| ... | ... | @@ -351,10 +360,10 @@ pub const Tree = struct { |
| 351 | 360 | .StringLiteral, |
| 352 | 361 | => continue, |
| 353 | 362 | |
| 354 | else => return i + 1, | |
| 363 | else => return i + 1 - end_offset, | |
| 355 | 364 | } |
| 356 | 365 | } |
| 357 | return i; | |
| 366 | return i - end_offset; | |
| 358 | 367 | }, |
| 359 | 368 | |
| 360 | 369 | .Block, |
| ... | ... | @@ -365,10 +374,9 @@ pub const Tree = struct { |
| 365 | 374 | // Look for a label. |
| 366 | 375 | const lbrace = main_tokens[n]; |
| 367 | 376 | if (token_tags[lbrace - 1] == .Colon) { |
| 368 | return lbrace - 2; | |
| 369 | } else { | |
| 370 | return lbrace; | |
| 377 | end_offset += 2; | |
| 371 | 378 | } |
| 379 | return lbrace - end_offset; | |
| 372 | 380 | }, |
| 373 | 381 | |
| 374 | 382 | .ContainerDecl, |
| ... | ... | @@ -386,9 +394,10 @@ pub const Tree = struct { |
| 386 | 394 | => { |
| 387 | 395 | const main_token = main_tokens[n]; |
| 388 | 396 | switch (token_tags[main_token - 1]) { |
| 389 | .Keyword_packed, .Keyword_extern => return main_token - 1, | |
| 390 | else => return main_token, | |
| 397 | .Keyword_packed, .Keyword_extern => end_offset += 1, | |
| 398 | else => {}, | |
| 391 | 399 | } |
| 400 | return main_token - end_offset; | |
| 392 | 401 | }, |
| 393 | 402 | |
| 394 | 403 | .PtrTypeAligned, |
| ... | ... | @@ -404,12 +413,12 @@ pub const Tree = struct { |
| 404 | 413 | }, |
| 405 | 414 | .LBrace => main_token, |
| 406 | 415 | else => unreachable, |
| 407 | }; | |
| 416 | } - end_offset; | |
| 408 | 417 | }, |
| 409 | 418 | |
| 410 | 419 | .SwitchCaseOne => { |
| 411 | 420 | if (datas[n].lhs == 0) { |
| 412 | return main_tokens[n] - 1; // else token | |
| 421 | return main_tokens[n] - 1 - end_offset; // else token | |
| 413 | 422 | } else { |
| 414 | 423 | n = datas[n].lhs; |
| 415 | 424 | } |
| ... | ... | @@ -422,7 +431,7 @@ pub const Tree = struct { |
| 422 | 431 | |
| 423 | 432 | .AsmOutput, .AsmInput => { |
| 424 | 433 | assert(token_tags[main_tokens[n] - 1] == .LBracket); |
| 425 | return main_tokens[n] - 1; | |
| 434 | return main_tokens[n] - 1 - end_offset; | |
| 426 | 435 | }, |
| 427 | 436 | |
| 428 | 437 | .WhileSimple, |
| ... | ... | @@ -435,7 +444,7 @@ pub const Tree = struct { |
| 435 | 444 | return switch (token_tags[main_token - 1]) { |
| 436 | 445 | .Keyword_inline => main_token - 1, |
| 437 | 446 | else => main_token, |
| 438 | }; | |
| 447 | } - end_offset; | |
| 439 | 448 | }, |
| 440 | 449 | }; |
| 441 | 450 | } |
| ... | ... | @@ -555,7 +564,7 @@ pub const Tree = struct { |
| 555 | 564 | return main_tokens[n] + end_offset; |
| 556 | 565 | }, |
| 557 | 566 | |
| 558 | .Call => { | |
| 567 | .Call, .AsyncCall => { | |
| 559 | 568 | end_offset += 1; // for the rparen |
| 560 | 569 | const params = tree.extraData(datas[n].rhs, Node.SubRange); |
| 561 | 570 | if (params.end - params.start == 0) { |
| ... | ... | @@ -563,6 +572,12 @@ pub const Tree = struct { |
| 563 | 572 | } |
| 564 | 573 | n = tree.extra_data[params.end - 1]; // last parameter |
| 565 | 574 | }, |
| 575 | .CallComma, .AsyncCallComma => { | |
| 576 | end_offset += 2; // for the comma+rparen | |
| 577 | const params = tree.extraData(datas[n].rhs, Node.SubRange); | |
| 578 | assert(params.end > params.start); | |
| 579 | n = tree.extra_data[params.end - 1]; // last parameter | |
| 580 | }, | |
| 566 | 581 | .Switch => { |
| 567 | 582 | const cases = tree.extraData(datas[n].rhs, Node.SubRange); |
| 568 | 583 | if (cases.end - cases.start == 0) { |
| ... | ... | @@ -614,6 +629,7 @@ pub const Tree = struct { |
| 614 | 629 | n = tree.extra_data[datas[n].rhs - 1]; // last member |
| 615 | 630 | }, |
| 616 | 631 | .CallOne, |
| 632 | .AsyncCallOne, | |
| 617 | 633 | .ArrayAccess, |
| 618 | 634 | => { |
| 619 | 635 | end_offset += 1; // for the rparen/rbracket |
| ... | ... | @@ -622,7 +638,6 @@ pub const Tree = struct { |
| 622 | 638 | } |
| 623 | 639 | n = datas[n].rhs; |
| 624 | 640 | }, |
| 625 | ||
| 626 | 641 | .ArrayInitDotTwo, |
| 627 | 642 | .BlockTwo, |
| 628 | 643 | .StructInitDotTwo, |
| ... | ... | @@ -755,9 +770,10 @@ pub const Tree = struct { |
| 755 | 770 | } |
| 756 | 771 | }, |
| 757 | 772 | |
| 758 | .SliceOpen => { | |
| 759 | end_offset += 2; // ellipsis2 and rbracket | |
| 773 | .SliceOpen, .CallOneComma, .AsyncCallOneComma => { | |
| 774 | end_offset += 2; // ellipsis2 + rbracket, or comma + rparen | |
| 760 | 775 | n = datas[n].rhs; |
| 776 | assert(n != 0); | |
| 761 | 777 | }, |
| 762 | 778 | .Slice => { |
| 763 | 779 | const extra = tree.extraData(datas[n].rhs, Node.Slice); |
| ... | ... | @@ -1496,6 +1512,27 @@ pub const Tree = struct { |
| 1496 | 1512 | }); |
| 1497 | 1513 | } |
| 1498 | 1514 | |
| 1515 | pub fn callOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.Call { | |
| 1516 | const data = tree.nodes.items(.data)[node]; | |
| 1517 | buffer.* = .{data.rhs}; | |
| 1518 | const params = if (data.rhs != 0) buffer[0..1] else buffer[0..0]; | |
| 1519 | return tree.fullCall(.{ | |
| 1520 | .lparen = tree.nodes.items(.main_token)[node], | |
| 1521 | .fn_expr = data.lhs, | |
| 1522 | .params = params, | |
| 1523 | }); | |
| 1524 | } | |
| 1525 | ||
| 1526 | pub fn callFull(tree: Tree, node: Node.Index) full.Call { | |
| 1527 | const data = tree.nodes.items(.data)[node]; | |
| 1528 | const extra = tree.extraData(data.rhs, Node.SubRange); | |
| 1529 | return tree.fullCall(.{ | |
| 1530 | .lparen = tree.nodes.items(.main_token)[node], | |
| 1531 | .fn_expr = data.lhs, | |
| 1532 | .params = tree.extra_data[extra.start..extra.end], | |
| 1533 | }); | |
| 1534 | } | |
| 1535 | ||
| 1499 | 1536 | fn fullVarDecl(tree: Tree, info: full.VarDecl.Ast) full.VarDecl { |
| 1500 | 1537 | const token_tags = tree.tokens.items(.tag); |
| 1501 | 1538 | var result: full.VarDecl = .{ |
| ... | ... | @@ -1750,6 +1787,19 @@ pub const Tree = struct { |
| 1750 | 1787 | } |
| 1751 | 1788 | return result; |
| 1752 | 1789 | } |
| 1790 | ||
| 1791 | fn fullCall(tree: Tree, info: full.Call.Ast) full.Call { | |
| 1792 | const token_tags = tree.tokens.items(.tag); | |
| 1793 | var result: full.Call = .{ | |
| 1794 | .ast = info, | |
| 1795 | .async_token = null, | |
| 1796 | }; | |
| 1797 | const maybe_async_token = tree.firstToken(info.fn_expr) - 1; | |
| 1798 | if (token_tags[maybe_async_token] == .Keyword_async) { | |
| 1799 | result.async_token = maybe_async_token; | |
| 1800 | } | |
| 1801 | return result; | |
| 1802 | } | |
| 1753 | 1803 | }; |
| 1754 | 1804 | |
| 1755 | 1805 | /// Fully assembled AST node information. |
| ... | ... | @@ -1942,6 +1992,17 @@ pub const full = struct { |
| 1942 | 1992 | rparen: TokenIndex, |
| 1943 | 1993 | }; |
| 1944 | 1994 | }; |
| 1995 | ||
| 1996 | pub const Call = struct { | |
| 1997 | ast: Ast, | |
| 1998 | async_token: ?TokenIndex, | |
| 1999 | ||
| 2000 | pub const Ast = struct { | |
| 2001 | lparen: TokenIndex, | |
| 2002 | fn_expr: Node.Index, | |
| 2003 | params: []const Node.Index, | |
| 2004 | }; | |
| 2005 | }; | |
| 1945 | 2006 | }; |
| 1946 | 2007 | |
| 1947 | 2008 | pub const Error = union(enum) { |
| ... | ... | @@ -2383,9 +2444,24 @@ pub const Node = struct { |
| 2383 | 2444 | StructInit, |
| 2384 | 2445 | /// `lhs(rhs)`. rhs can be omitted. |
| 2385 | 2446 | CallOne, |
| 2386 | /// `lhs(a, b, c)`. `sub_range_list[rhs]`. | |
| 2447 | /// `lhs(rhs,)`. rhs can be omitted. | |
| 2448 | CallOneComma, | |
| 2449 | /// `async lhs(rhs)`. rhs can be omitted. | |
| 2450 | AsyncCallOne, | |
| 2451 | /// `async lhs(rhs,)`. | |
| 2452 | AsyncCallOneComma, | |
| 2453 | /// `lhs(a, b, c)`. `SubRange[rhs]`. | |
| 2387 | 2454 | /// main_token is the `(`. |
| 2388 | 2455 | Call, |
| 2456 | /// `lhs(a, b, c,)`. `SubRange[rhs]`. | |
| 2457 | /// main_token is the `(`. | |
| 2458 | CallComma, | |
| 2459 | /// `async lhs(a, b, c)`. `SubRange[rhs]`. | |
| 2460 | /// main_token is the `(`. | |
| 2461 | AsyncCall, | |
| 2462 | /// `async lhs(a, b, c,)`. `SubRange[rhs]`. | |
| 2463 | /// main_token is the `(`. | |
| 2464 | AsyncCallComma, | |
| 2389 | 2465 | /// `switch(lhs) {}`. `SubRange[rhs]`. |
| 2390 | 2466 | Switch, |
| 2391 | 2467 | /// Same as Switch except there is known to be a trailing comma |
lib/std/zig/parse.zig+180-30| ... | ... | @@ -2254,8 +2254,6 @@ const Parser = struct { |
| 2254 | 2254 | /// / PrimaryTypeExpr (SuffixOp / FnCallArguments)* |
| 2255 | 2255 | /// FnCallArguments <- LPAREN ExprList RPAREN |
| 2256 | 2256 | /// ExprList <- (Expr COMMA)* Expr? |
| 2257 | /// TODO detect when there is 1 or less parameter to the call and emit | |
| 2258 | /// CallOne instead of Call. | |
| 2259 | 2257 | fn parseSuffixExpr(p: *Parser) !Node.Index { |
| 2260 | 2258 | if (p.eatToken(.Keyword_async)) |async_token| { |
| 2261 | 2259 | var res = try p.expectPrimaryTypeExpr(); |
| ... | ... | @@ -2269,20 +2267,95 @@ const Parser = struct { |
| 2269 | 2267 | try p.warn(.{ .ExpectedParamList = .{ .token = p.tok_i } }); |
| 2270 | 2268 | return res; |
| 2271 | 2269 | }; |
| 2272 | const params = try ListParseFn(parseExpr)(p); | |
| 2273 | _ = try p.expectToken(.RParen); | |
| 2270 | if (p.eatToken(.RParen)) |_| { | |
| 2271 | return p.addNode(.{ | |
| 2272 | .tag = .AsyncCallOne, | |
| 2273 | .main_token = lparen, | |
| 2274 | .data = .{ | |
| 2275 | .lhs = res, | |
| 2276 | .rhs = 0, | |
| 2277 | }, | |
| 2278 | }); | |
| 2279 | } | |
| 2280 | const param_one = try p.expectExpr(); | |
| 2281 | const comma_one = p.eatToken(.Comma); | |
| 2282 | if (p.eatToken(.RParen)) |_| { | |
| 2283 | return p.addNode(.{ | |
| 2284 | .tag = if (comma_one == null) .AsyncCallOne else .AsyncCallOneComma, | |
| 2285 | .main_token = lparen, | |
| 2286 | .data = .{ | |
| 2287 | .lhs = res, | |
| 2288 | .rhs = param_one, | |
| 2289 | }, | |
| 2290 | }); | |
| 2291 | } | |
| 2292 | if (comma_one == null) { | |
| 2293 | try p.warn(.{ | |
| 2294 | .ExpectedToken = .{ .token = p.tok_i, .expected_id = .Comma }, | |
| 2295 | }); | |
| 2296 | } | |
| 2274 | 2297 | |
| 2275 | return p.addNode(.{ | |
| 2276 | .tag = .Call, | |
| 2277 | .main_token = lparen, | |
| 2278 | .data = .{ | |
| 2279 | .lhs = res, | |
| 2280 | .rhs = try p.addExtra(Node.SubRange{ | |
| 2281 | .start = params.start, | |
| 2282 | .end = params.end, | |
| 2283 | }), | |
| 2284 | }, | |
| 2285 | }); | |
| 2298 | var param_list = std.ArrayList(Node.Index).init(p.gpa); | |
| 2299 | defer param_list.deinit(); | |
| 2300 | ||
| 2301 | try param_list.append(param_one); | |
| 2302 | ||
| 2303 | while (true) { | |
| 2304 | const next = try p.expectExpr(); | |
| 2305 | try param_list.append(next); | |
| 2306 | switch (p.token_tags[p.nextToken()]) { | |
| 2307 | .Comma => { | |
| 2308 | if (p.eatToken(.RParen)) |_| { | |
| 2309 | const span = try p.listToSpan(param_list.items); | |
| 2310 | return p.addNode(.{ | |
| 2311 | .tag = .AsyncCallComma, | |
| 2312 | .main_token = lparen, | |
| 2313 | .data = .{ | |
| 2314 | .lhs = res, | |
| 2315 | .rhs = try p.addExtra(Node.SubRange{ | |
| 2316 | .start = span.start, | |
| 2317 | .end = span.end, | |
| 2318 | }), | |
| 2319 | }, | |
| 2320 | }); | |
| 2321 | } else { | |
| 2322 | continue; | |
| 2323 | } | |
| 2324 | }, | |
| 2325 | .RParen => { | |
| 2326 | const span = try p.listToSpan(param_list.items); | |
| 2327 | return p.addNode(.{ | |
| 2328 | .tag = .AsyncCall, | |
| 2329 | .main_token = lparen, | |
| 2330 | .data = .{ | |
| 2331 | .lhs = res, | |
| 2332 | .rhs = try p.addExtra(Node.SubRange{ | |
| 2333 | .start = span.start, | |
| 2334 | .end = span.end, | |
| 2335 | }), | |
| 2336 | }, | |
| 2337 | }); | |
| 2338 | }, | |
| 2339 | .Colon, .RBrace, .RBracket => { | |
| 2340 | p.tok_i -= 1; | |
| 2341 | return p.fail(.{ | |
| 2342 | .ExpectedToken = .{ | |
| 2343 | .token = p.tok_i, | |
| 2344 | .expected_id = .RParen, | |
| 2345 | }, | |
| 2346 | }); | |
| 2347 | }, | |
| 2348 | else => { | |
| 2349 | p.tok_i -= 1; | |
| 2350 | try p.warn(.{ | |
| 2351 | .ExpectedToken = .{ | |
| 2352 | .token = p.tok_i, | |
| 2353 | .expected_id = .Comma, | |
| 2354 | }, | |
| 2355 | }); | |
| 2356 | }, | |
| 2357 | } | |
| 2358 | } | |
| 2286 | 2359 | } |
| 2287 | 2360 | var res = try p.parsePrimaryTypeExpr(); |
| 2288 | 2361 | if (res == 0) return res; |
| ... | ... | @@ -2293,21 +2366,98 @@ const Parser = struct { |
| 2293 | 2366 | res = suffix_op; |
| 2294 | 2367 | continue; |
| 2295 | 2368 | } |
| 2296 | const lparen = p.eatToken(.LParen) orelse return res; | |
| 2297 | const params = try ListParseFn(parseExpr)(p); | |
| 2298 | _ = try p.expectToken(.RParen); | |
| 2369 | res = res: { | |
| 2370 | const lparen = p.eatToken(.LParen) orelse return res; | |
| 2371 | if (p.eatToken(.RParen)) |_| { | |
| 2372 | break :res try p.addNode(.{ | |
| 2373 | .tag = .CallOne, | |
| 2374 | .main_token = lparen, | |
| 2375 | .data = .{ | |
| 2376 | .lhs = res, | |
| 2377 | .rhs = 0, | |
| 2378 | }, | |
| 2379 | }); | |
| 2380 | } | |
| 2381 | const param_one = try p.expectExpr(); | |
| 2382 | const comma_one = p.eatToken(.Comma); | |
| 2383 | if (p.eatToken(.RParen)) |_| { | |
| 2384 | break :res try p.addNode(.{ | |
| 2385 | .tag = if (comma_one == null) .CallOne else .CallOneComma, | |
| 2386 | .main_token = lparen, | |
| 2387 | .data = .{ | |
| 2388 | .lhs = res, | |
| 2389 | .rhs = param_one, | |
| 2390 | }, | |
| 2391 | }); | |
| 2392 | } | |
| 2393 | if (comma_one == null) { | |
| 2394 | try p.warn(.{ | |
| 2395 | .ExpectedToken = .{ .token = p.tok_i, .expected_id = .Comma }, | |
| 2396 | }); | |
| 2397 | } | |
| 2299 | 2398 | |
| 2300 | res = try p.addNode(.{ | |
| 2301 | .tag = .Call, | |
| 2302 | .main_token = lparen, | |
| 2303 | .data = .{ | |
| 2304 | .lhs = res, | |
| 2305 | .rhs = try p.addExtra(Node.SubRange{ | |
| 2306 | .start = params.start, | |
| 2307 | .end = params.end, | |
| 2308 | }), | |
| 2309 | }, | |
| 2310 | }); | |
| 2399 | var param_list = std.ArrayList(Node.Index).init(p.gpa); | |
| 2400 | defer param_list.deinit(); | |
| 2401 | ||
| 2402 | try param_list.append(param_one); | |
| 2403 | ||
| 2404 | while (true) { | |
| 2405 | const next = try p.expectExpr(); | |
| 2406 | try param_list.append(next); | |
| 2407 | switch (p.token_tags[p.nextToken()]) { | |
| 2408 | .Comma => { | |
| 2409 | if (p.eatToken(.RParen)) |_| { | |
| 2410 | const span = try p.listToSpan(param_list.items); | |
| 2411 | break :res try p.addNode(.{ | |
| 2412 | .tag = .CallComma, | |
| 2413 | .main_token = lparen, | |
| 2414 | .data = .{ | |
| 2415 | .lhs = res, | |
| 2416 | .rhs = try p.addExtra(Node.SubRange{ | |
| 2417 | .start = span.start, | |
| 2418 | .end = span.end, | |
| 2419 | }), | |
| 2420 | }, | |
| 2421 | }); | |
| 2422 | } else { | |
| 2423 | continue; | |
| 2424 | } | |
| 2425 | }, | |
| 2426 | .RParen => { | |
| 2427 | const span = try p.listToSpan(param_list.items); | |
| 2428 | break :res try p.addNode(.{ | |
| 2429 | .tag = .Call, | |
| 2430 | .main_token = lparen, | |
| 2431 | .data = .{ | |
| 2432 | .lhs = res, | |
| 2433 | .rhs = try p.addExtra(Node.SubRange{ | |
| 2434 | .start = span.start, | |
| 2435 | .end = span.end, | |
| 2436 | }), | |
| 2437 | }, | |
| 2438 | }); | |
| 2439 | }, | |
| 2440 | .Colon, .RBrace, .RBracket => { | |
| 2441 | p.tok_i -= 1; | |
| 2442 | return p.fail(.{ | |
| 2443 | .ExpectedToken = .{ | |
| 2444 | .token = p.tok_i, | |
| 2445 | .expected_id = .RParen, | |
| 2446 | }, | |
| 2447 | }); | |
| 2448 | }, | |
| 2449 | else => { | |
| 2450 | p.tok_i -= 1; | |
| 2451 | try p.warn(.{ | |
| 2452 | .ExpectedToken = .{ | |
| 2453 | .token = p.tok_i, | |
| 2454 | .expected_id = .Comma, | |
| 2455 | }, | |
| 2456 | }); | |
| 2457 | }, | |
| 2458 | } | |
| 2459 | } | |
| 2460 | }; | |
| 2311 | 2461 | } |
| 2312 | 2462 | } |
| 2313 | 2463 | |
| ... | ... | @@ -2588,7 +2738,7 @@ const Parser = struct { |
| 2588 | 2738 | |
| 2589 | 2739 | while (true) { |
| 2590 | 2740 | const next = try p.expectFieldInit(); |
| 2591 | if (next == 0) break; | |
| 2741 | assert(next != 0); | |
| 2592 | 2742 | try init_list.append(next); |
| 2593 | 2743 | switch (p.token_tags[p.nextToken()]) { |
| 2594 | 2744 | .Comma => { |
lib/std/zig/parser_test.zig+29-29| ... | ... | @@ -3046,35 +3046,35 @@ test "zig fmt: for" { |
| 3046 | 3046 | // \\ |
| 3047 | 3047 | // ); |
| 3048 | 3048 | //} |
| 3049 | // | |
| 3050 | //test "zig fmt: async functions" { | |
| 3051 | // try testCanonical( | |
| 3052 | // \\fn simpleAsyncFn() void { | |
| 3053 | // \\ const a = async a.b(); | |
| 3054 | // \\ x += 1; | |
| 3055 | // \\ suspend; | |
| 3056 | // \\ x += 1; | |
| 3057 | // \\ suspend; | |
| 3058 | // \\ const p: anyframe->void = async simpleAsyncFn() catch unreachable; | |
| 3059 | // \\ await p; | |
| 3060 | // \\} | |
| 3061 | // \\ | |
| 3062 | // \\test "suspend, resume, await" { | |
| 3063 | // \\ const p: anyframe = async testAsyncSeq(); | |
| 3064 | // \\ resume p; | |
| 3065 | // \\ await p; | |
| 3066 | // \\} | |
| 3067 | // \\ | |
| 3068 | // ); | |
| 3069 | //} | |
| 3070 | // | |
| 3071 | //test "zig fmt: nosuspend" { | |
| 3072 | // try testCanonical( | |
| 3073 | // \\const a = nosuspend foo(); | |
| 3074 | // \\ | |
| 3075 | // ); | |
| 3076 | //} | |
| 3077 | // | |
| 3049 | ||
| 3050 | test "zig fmt: async functions" { | |
| 3051 | try testCanonical( | |
| 3052 | \\fn simpleAsyncFn() void { | |
| 3053 | \\ const a = async a.b(); | |
| 3054 | \\ x += 1; | |
| 3055 | \\ suspend; | |
| 3056 | \\ x += 1; | |
| 3057 | \\ suspend; | |
| 3058 | \\ const p: anyframe->void = async simpleAsyncFn() catch unreachable; | |
| 3059 | \\ await p; | |
| 3060 | \\} | |
| 3061 | \\ | |
| 3062 | \\test "suspend, resume, await" { | |
| 3063 | \\ const p: anyframe = async testAsyncSeq(); | |
| 3064 | \\ resume p; | |
| 3065 | \\ await p; | |
| 3066 | \\} | |
| 3067 | \\ | |
| 3068 | ); | |
| 3069 | } | |
| 3070 | ||
| 3071 | test "zig fmt: nosuspend" { | |
| 3072 | try testCanonical( | |
| 3073 | \\const a = nosuspend foo(); | |
| 3074 | \\ | |
| 3075 | ); | |
| 3076 | } | |
| 3077 | ||
| 3078 | 3078 | //test "zig fmt: Block after if" { |
| 3079 | 3079 | // try testCanonical( |
| 3080 | 3080 | // \\test "Block after if" { |
lib/std/zig/render.zig+95-78| ... | ... | @@ -73,8 +73,18 @@ fn renderRoot(ais: *Ais, tree: ast.Tree) Error!void { |
| 73 | 73 | const nodes_data = tree.nodes.items(.data); |
| 74 | 74 | const root_decls = tree.extra_data[nodes_data[0].lhs..nodes_data[0].rhs]; |
| 75 | 75 | |
| 76 | for (root_decls) |decl| { | |
| 77 | try renderMember(ais, tree, decl, .Newline); | |
| 76 | return renderAllMembers(ais, tree, root_decls); | |
| 77 | } | |
| 78 | ||
| 79 | fn renderAllMembers(ais: *Ais, tree: ast.Tree, members: []const ast.Node.Index) Error!void { | |
| 80 | if (members.len == 0) return; | |
| 81 | ||
| 82 | const first_member = members[0]; | |
| 83 | try renderMember(ais, tree, first_member, .Newline); | |
| 84 | ||
| 85 | for (members[1..]) |member| { | |
| 86 | try renderExtraNewline(ais, tree, member); | |
| 87 | try renderMember(ais, tree, member, .Newline); | |
| 78 | 88 | } |
| 79 | 89 | } |
| 80 | 90 | |
| ... | ... | @@ -391,65 +401,17 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 391 | 401 | .StructInitDot => return renderStructInit(ais, tree, tree.structInitDot(node), space), |
| 392 | 402 | .StructInit => return renderStructInit(ais, tree, tree.structInit(node), space), |
| 393 | 403 | |
| 394 | .CallOne => unreachable, // TODO | |
| 395 | .Call => { | |
| 396 | const call = datas[node]; | |
| 397 | const params_range = tree.extraData(call.rhs, ast.Node.SubRange); | |
| 398 | const params = tree.extra_data[params_range.start..params_range.end]; | |
| 399 | const async_token = tree.firstToken(call.lhs) - 1; | |
| 400 | if (token_tags[async_token] == .Keyword_async) { | |
| 401 | try renderToken(ais, tree, async_token, .Space); | |
| 402 | } | |
| 403 | try renderExpression(ais, tree, call.lhs, .None); | |
| 404 | ||
| 405 | const lparen = main_tokens[node]; | |
| 406 | ||
| 407 | if (params.len == 0) { | |
| 408 | try renderToken(ais, tree, lparen, .None); | |
| 409 | return renderToken(ais, tree, lparen + 1, space); // ) | |
| 410 | } | |
| 411 | ||
| 412 | const last_param = params[params.len - 1]; | |
| 413 | const after_last_param_tok = tree.lastToken(last_param) + 1; | |
| 414 | if (token_tags[after_last_param_tok] == .Comma) { | |
| 415 | ais.pushIndent(); | |
| 416 | try renderToken(ais, tree, lparen, Space.Newline); // ( | |
| 417 | for (params) |param_node, i| { | |
| 418 | if (i + 1 < params.len) { | |
| 419 | try renderExpression(ais, tree, param_node, Space.None); | |
| 420 | ||
| 421 | // Unindent the comma for multiline string literals | |
| 422 | const is_multiline_string = node_tags[param_node] == .StringLiteral and | |
| 423 | token_tags[main_tokens[param_node]] == .MultilineStringLiteralLine; | |
| 424 | if (is_multiline_string) ais.popIndent(); | |
| 425 | ||
| 426 | const comma = tree.lastToken(param_node) + 1; | |
| 427 | try renderToken(ais, tree, comma, Space.Newline); // , | |
| 428 | ||
| 429 | if (is_multiline_string) ais.pushIndent(); | |
| 430 | ||
| 431 | try renderExtraNewline(ais, tree, params[i + 1]); | |
| 432 | } else { | |
| 433 | try renderExpression(ais, tree, param_node, Space.Comma); | |
| 434 | } | |
| 435 | } | |
| 436 | ais.popIndent(); | |
| 437 | return renderToken(ais, tree, after_last_param_tok + 1, space); // ) | |
| 438 | } | |
| 439 | ||
| 440 | try renderToken(ais, tree, lparen, Space.None); // ( | |
| 441 | ||
| 442 | for (params) |param_node, i| { | |
| 443 | try renderExpression(ais, tree, param_node, Space.None); | |
| 444 | ||
| 445 | if (i + 1 < params.len) { | |
| 446 | const comma = tree.lastToken(param_node) + 1; | |
| 447 | try renderToken(ais, tree, comma, Space.Space); | |
| 448 | } | |
| 449 | } | |
| 450 | return renderToken(ais, tree, after_last_param_tok, space); // ) | |
| 404 | .CallOne, .CallOneComma, .AsyncCallOne, .AsyncCallOneComma => { | |
| 405 | var params: [1]ast.Node.Index = undefined; | |
| 406 | return renderCall(ais, tree, tree.callOne(&params, node), space); | |
| 451 | 407 | }, |
| 452 | 408 | |
| 409 | .Call, | |
| 410 | .CallComma, | |
| 411 | .AsyncCall, | |
| 412 | .AsyncCallComma, | |
| 413 | => return renderCall(ais, tree, tree.callFull(node), space), | |
| 414 | ||
| 453 | 415 | .ArrayAccess => { |
| 454 | 416 | const suffix = datas[node]; |
| 455 | 417 | const lbracket = tree.firstToken(suffix.rhs) - 1; |
| ... | ... | @@ -625,18 +587,16 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 625 | 587 | }, |
| 626 | 588 | .FnProto => return renderFnProto(ais, tree, tree.fnProto(node), space), |
| 627 | 589 | |
| 628 | .AnyFrameType => unreachable, // TODO | |
| 629 | //.AnyFrameType => { | |
| 630 | // const anyframe_type = @fieldParentPtr(ast.Node.AnyFrameType, "base", base); | |
| 631 | ||
| 632 | // if (anyframe_type.result) |result| { | |
| 633 | // try renderToken(ais, tree, anyframe_type.anyframe_token, Space.None); // anyframe | |
| 634 | // try renderToken(ais, tree, result.arrow_token, Space.None); // -> | |
| 635 | // return renderExpression(ais, tree, result.return_type, space); | |
| 636 | // } else { | |
| 637 | // return renderToken(ais, tree, anyframe_type.anyframe_token, space); // anyframe | |
| 638 | // } | |
| 639 | //}, | |
| 590 | .AnyFrameType => { | |
| 591 | const main_token = main_tokens[node]; | |
| 592 | if (datas[node].rhs != 0) { | |
| 593 | try renderToken(ais, tree, main_token, .None); // anyframe | |
| 594 | try renderToken(ais, tree, main_token + 1, .None); // -> | |
| 595 | return renderExpression(ais, tree, datas[node].rhs, space); | |
| 596 | } else { | |
| 597 | return renderToken(ais, tree, main_token, space); // anyframe | |
| 598 | } | |
| 599 | }, | |
| 640 | 600 | |
| 641 | 601 | .Switch, |
| 642 | 602 | .SwitchComma, |
| ... | ... | @@ -1730,13 +1690,7 @@ fn renderContainerDecl( |
| 1730 | 1690 | // One member per line. |
| 1731 | 1691 | ais.pushIndent(); |
| 1732 | 1692 | try renderToken(ais, tree, lbrace, .Newline); // lbrace |
| 1733 | for (container_decl.ast.members) |member, i| { | |
| 1734 | try renderMember(ais, tree, member, .Newline); | |
| 1735 | ||
| 1736 | if (i + 1 < container_decl.ast.members.len) { | |
| 1737 | try renderExtraNewline(ais, tree, container_decl.ast.members[i + 1]); | |
| 1738 | } | |
| 1739 | } | |
| 1693 | try renderAllMembers(ais, tree, container_decl.ast.members); | |
| 1740 | 1694 | ais.popIndent(); |
| 1741 | 1695 | |
| 1742 | 1696 | return renderToken(ais, tree, rbrace, space); // rbrace |
| ... | ... | @@ -1871,6 +1825,69 @@ fn renderAsm( |
| 1871 | 1825 | } else unreachable; // TODO shouldn't need this on while(true) |
| 1872 | 1826 | } |
| 1873 | 1827 | |
| 1828 | fn renderCall( | |
| 1829 | ais: *Ais, | |
| 1830 | tree: ast.Tree, | |
| 1831 | call: ast.full.Call, | |
| 1832 | space: Space, | |
| 1833 | ) Error!void { | |
| 1834 | const token_tags = tree.tokens.items(.tag); | |
| 1835 | const node_tags = tree.nodes.items(.tag); | |
| 1836 | const main_tokens = tree.nodes.items(.main_token); | |
| 1837 | ||
| 1838 | if (call.async_token) |async_token| { | |
| 1839 | try renderToken(ais, tree, async_token, .Space); | |
| 1840 | } | |
| 1841 | try renderExpression(ais, tree, call.ast.fn_expr, .None); | |
| 1842 | ||
| 1843 | const lparen = call.ast.lparen; | |
| 1844 | const params = call.ast.params; | |
| 1845 | if (params.len == 0) { | |
| 1846 | try renderToken(ais, tree, lparen, .None); | |
| 1847 | return renderToken(ais, tree, lparen + 1, space); // ) | |
| 1848 | } | |
| 1849 | ||
| 1850 | const last_param = params[params.len - 1]; | |
| 1851 | const after_last_param_tok = tree.lastToken(last_param) + 1; | |
| 1852 | if (token_tags[after_last_param_tok] == .Comma) { | |
| 1853 | ais.pushIndent(); | |
| 1854 | try renderToken(ais, tree, lparen, Space.Newline); // ( | |
| 1855 | for (params) |param_node, i| { | |
| 1856 | if (i + 1 < params.len) { | |
| 1857 | try renderExpression(ais, tree, param_node, Space.None); | |
| 1858 | ||
| 1859 | // Unindent the comma for multiline string literals | |
| 1860 | const is_multiline_string = node_tags[param_node] == .StringLiteral and | |
| 1861 | token_tags[main_tokens[param_node]] == .MultilineStringLiteralLine; | |
| 1862 | if (is_multiline_string) ais.popIndent(); | |
| 1863 | ||
| 1864 | const comma = tree.lastToken(param_node) + 1; | |
| 1865 | try renderToken(ais, tree, comma, Space.Newline); // , | |
| 1866 | ||
| 1867 | if (is_multiline_string) ais.pushIndent(); | |
| 1868 | ||
| 1869 | try renderExtraNewline(ais, tree, params[i + 1]); | |
| 1870 | } else { | |
| 1871 | try renderExpression(ais, tree, param_node, Space.Comma); | |
| 1872 | } | |
| 1873 | } | |
| 1874 | ais.popIndent(); | |
| 1875 | return renderToken(ais, tree, after_last_param_tok + 1, space); // ) | |
| 1876 | } | |
| 1877 | ||
| 1878 | try renderToken(ais, tree, lparen, Space.None); // ( | |
| 1879 | ||
| 1880 | for (params) |param_node, i| { | |
| 1881 | try renderExpression(ais, tree, param_node, Space.None); | |
| 1882 | ||
| 1883 | if (i + 1 < params.len) { | |
| 1884 | const comma = tree.lastToken(param_node) + 1; | |
| 1885 | try renderToken(ais, tree, comma, Space.Space); | |
| 1886 | } | |
| 1887 | } | |
| 1888 | return renderToken(ais, tree, after_last_param_tok, space); // ) | |
| 1889 | } | |
| 1890 | ||
| 1874 | 1891 | /// Render an expression, and the comma that follows it, if it is present in the source. |
| 1875 | 1892 | fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void { |
| 1876 | 1893 | const token_tags = tree.tokens.items(.tag); |