| ... | ... | @@ -54,14 +54,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 54 | 54 | |
| 55 | 55 | switch (state) { |
| 56 | 56 | State.TopLevel => { |
| 57 | | while (try eatLineComment(arena, &tok_it)) |line_comment| { |
| 57 | while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| { |
| 58 | 58 | try root_node.decls.push(&line_comment.base); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | | const comments = try eatDocComments(arena, &tok_it); |
| 61 | const comments = try eatDocComments(arena, &tok_it, &tree); |
| 62 | 62 | |
| 63 | | const token_index = tok_it.index; |
| 64 | | const token_ptr = ??tok_it.next(); |
| 63 | const token = nextToken(&tok_it, &tree); |
| 64 | const token_index = token.index; |
| 65 | const token_ptr = token.ptr; |
| 65 | 66 | switch (token_ptr.id) { |
| 66 | 67 | Token.Id.Keyword_test => { |
| 67 | 68 | stack.push(State.TopLevel) catch unreachable; |
| ... | ... | @@ -144,7 +145,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 144 | 145 | continue; |
| 145 | 146 | }, |
| 146 | 147 | else => { |
| 147 | | _ = tok_it.prev(); |
| 148 | putBackToken(&tok_it, &tree); |
| 148 | 149 | stack.push(State.TopLevel) catch unreachable; |
| 149 | 150 | try stack.push(State { |
| 150 | 151 | .TopLevelExtern = TopLevelDeclCtx { |
| ... | ... | @@ -160,8 +161,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 160 | 161 | } |
| 161 | 162 | }, |
| 162 | 163 | State.TopLevelExtern => |ctx| { |
| 163 | | const token_index = tok_it.index; |
| 164 | | const token_ptr = ??tok_it.next(); |
| 164 | const token = nextToken(&tok_it, &tree); |
| 165 | const token_index = token.index; |
| 166 | const token_ptr = token.ptr; |
| 165 | 167 | switch (token_ptr.id) { |
| 166 | 168 | Token.Id.Keyword_export, Token.Id.Keyword_inline => { |
| 167 | 169 | stack.push(State { |
| ... | ... | @@ -194,7 +196,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 194 | 196 | continue; |
| 195 | 197 | }, |
| 196 | 198 | else => { |
| 197 | | _ = tok_it.prev(); |
| 199 | putBackToken(&tok_it, &tree); |
| 198 | 200 | stack.push(State { .TopLevelDecl = ctx }) catch unreachable; |
| 199 | 201 | continue; |
| 200 | 202 | } |
| ... | ... | @@ -202,10 +204,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 202 | 204 | }, |
| 203 | 205 | State.TopLevelLibname => |ctx| { |
| 204 | 206 | const lib_name = blk: { |
| 205 | | const lib_name_token_index = tok_it.index; |
| 206 | | const lib_name_token_ptr = ??tok_it.next(); |
| 207 | | break :blk (try parseStringLiteral(arena, &tok_it, lib_name_token_ptr, lib_name_token_index)) ?? { |
| 208 | | _ = tok_it.prev(); |
| 207 | const lib_name_token = nextToken(&tok_it, &tree); |
| 208 | const lib_name_token_index = lib_name_token.index; |
| 209 | const lib_name_token_ptr = lib_name_token.ptr; |
| 210 | break :blk (try parseStringLiteral(arena, &tok_it, lib_name_token_ptr, lib_name_token_index, &tree)) ?? { |
| 211 | putBackToken(&tok_it, &tree); |
| 209 | 212 | break :blk null; |
| 210 | 213 | }; |
| 211 | 214 | }; |
| ... | ... | @@ -222,8 +225,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 222 | 225 | continue; |
| 223 | 226 | }, |
| 224 | 227 | State.TopLevelDecl => |ctx| { |
| 225 | | const token_index = tok_it.index; |
| 226 | | const token_ptr = ??tok_it.next(); |
| 228 | const token = nextToken(&tok_it, &tree); |
| 229 | const token_index = token.index; |
| 230 | const token_ptr = token.ptr; |
| 227 | 231 | switch (token_ptr.id) { |
| 228 | 232 | Token.Id.Keyword_use => { |
| 229 | 233 | if (ctx.extern_export_inline_token) |annotated_token| { |
| ... | ... | @@ -345,7 +349,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 345 | 349 | } |
| 346 | 350 | }, |
| 347 | 351 | State.TopLevelExternOrField => |ctx| { |
| 348 | | if (eatToken(&tok_it, Token.Id.Identifier)) |identifier| { |
| 352 | if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |identifier| { |
| 349 | 353 | std.debug.assert(ctx.container_decl.kind == ast.Node.ContainerDecl.Kind.Struct); |
| 350 | 354 | const node = try arena.construct(ast.Node.StructField { |
| 351 | 355 | .base = ast.Node { |
| ... | ... | @@ -379,10 +383,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 379 | 383 | }, |
| 380 | 384 | |
| 381 | 385 | State.FieldInitValue => |ctx| { |
| 382 | | const eq_tok_index = tok_it.index; |
| 383 | | const eq_tok_ptr = ??tok_it.next(); |
| 386 | const eq_tok = nextToken(&tok_it, &tree); |
| 387 | const eq_tok_index = eq_tok.index; |
| 388 | const eq_tok_ptr = eq_tok.ptr; |
| 384 | 389 | if (eq_tok_ptr.id != Token.Id.Equal) { |
| 385 | | _ = tok_it.prev(); |
| 390 | putBackToken(&tok_it, &tree); |
| 386 | 391 | continue; |
| 387 | 392 | } |
| 388 | 393 | stack.push(State { .Expression = ctx }) catch unreachable; |
| ... | ... | @@ -390,8 +395,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 390 | 395 | }, |
| 391 | 396 | |
| 392 | 397 | State.ContainerKind => |ctx| { |
| 393 | | const token_index = tok_it.index; |
| 394 | | const token_ptr = ??tok_it.next(); |
| 398 | const token = nextToken(&tok_it, &tree); |
| 399 | const token_index = token.index; |
| 400 | const token_ptr = token.ptr; |
| 395 | 401 | const node = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.ContainerDecl, |
| 396 | 402 | ast.Node.ContainerDecl { |
| 397 | 403 | .base = undefined, |
| ... | ... | @@ -421,7 +427,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 421 | 427 | }, |
| 422 | 428 | |
| 423 | 429 | State.ContainerInitArgStart => |container_decl| { |
| 424 | | if (eatToken(&tok_it, Token.Id.LParen) == null) { |
| 430 | if (eatToken(&tok_it, &tree, Token.Id.LParen) == null) { |
| 425 | 431 | continue; |
| 426 | 432 | } |
| 427 | 433 | |
| ... | ... | @@ -431,24 +437,26 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 431 | 437 | }, |
| 432 | 438 | |
| 433 | 439 | State.ContainerInitArg => |container_decl| { |
| 434 | | const init_arg_token_index = tok_it.index; |
| 435 | | const init_arg_token_ptr = ??tok_it.next(); |
| 440 | const init_arg_token = nextToken(&tok_it, &tree); |
| 441 | const init_arg_token_index = init_arg_token.index; |
| 442 | const init_arg_token_ptr = init_arg_token.ptr; |
| 436 | 443 | switch (init_arg_token_ptr.id) { |
| 437 | 444 | Token.Id.Keyword_enum => { |
| 438 | 445 | container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg {.Enum = null}; |
| 439 | | const lparen_tok_index = tok_it.index; |
| 440 | | const lparen_tok_ptr = ??tok_it.next(); |
| 446 | const lparen_tok = nextToken(&tok_it, &tree); |
| 447 | const lparen_tok_index = lparen_tok.index; |
| 448 | const lparen_tok_ptr = lparen_tok.ptr; |
| 441 | 449 | if (lparen_tok_ptr.id == Token.Id.LParen) { |
| 442 | 450 | try stack.push(State { .ExpectToken = Token.Id.RParen } ); |
| 443 | 451 | try stack.push(State { .Expression = OptionalCtx { |
| 444 | 452 | .RequiredNull = &container_decl.init_arg_expr.Enum, |
| 445 | 453 | } }); |
| 446 | 454 | } else { |
| 447 | | _ = tok_it.prev(); |
| 455 | putBackToken(&tok_it, &tree); |
| 448 | 456 | } |
| 449 | 457 | }, |
| 450 | 458 | else => { |
| 451 | | _ = tok_it.prev(); |
| 459 | putBackToken(&tok_it, &tree); |
| 452 | 460 | container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg { .Type = undefined }; |
| 453 | 461 | stack.push(State { .Expression = OptionalCtx { .Required = &container_decl.init_arg_expr.Type } }) catch unreachable; |
| 454 | 462 | }, |
| ... | ... | @@ -457,13 +465,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 457 | 465 | }, |
| 458 | 466 | |
| 459 | 467 | State.ContainerDecl => |container_decl| { |
| 460 | | while (try eatLineComment(arena, &tok_it)) |line_comment| { |
| 468 | while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| { |
| 461 | 469 | try container_decl.fields_and_decls.push(&line_comment.base); |
| 462 | 470 | } |
| 463 | 471 | |
| 464 | | const comments = try eatDocComments(arena, &tok_it); |
| 465 | | const token_index = tok_it.index; |
| 466 | | const token_ptr = ??tok_it.next(); |
| 472 | const comments = try eatDocComments(arena, &tok_it, &tree); |
| 473 | const token = nextToken(&tok_it, &tree); |
| 474 | const token_index = token.index; |
| 475 | const token_ptr = token.ptr; |
| 467 | 476 | switch (token_ptr.id) { |
| 468 | 477 | Token.Id.Identifier => { |
| 469 | 478 | switch (container_decl.kind) { |
| ... | ... | @@ -568,7 +577,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 568 | 577 | continue; |
| 569 | 578 | }, |
| 570 | 579 | else => { |
| 571 | | _ = tok_it.prev(); |
| 580 | putBackToken(&tok_it, &tree); |
| 572 | 581 | stack.push(State{ .ContainerDecl = container_decl }) catch unreachable; |
| 573 | 582 | try stack.push(State { |
| 574 | 583 | .TopLevelExtern = TopLevelDeclCtx { |
| ... | ... | @@ -620,8 +629,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 620 | 629 | State.VarDeclAlign => |var_decl| { |
| 621 | 630 | try stack.push(State { .VarDeclEq = var_decl }); |
| 622 | 631 | |
| 623 | | const next_token_index = tok_it.index; |
| 624 | | const next_token_ptr = ??tok_it.next(); |
| 632 | const next_token = nextToken(&tok_it, &tree); |
| 633 | const next_token_index = next_token.index; |
| 634 | const next_token_ptr = next_token.ptr; |
| 625 | 635 | if (next_token_ptr.id == Token.Id.Keyword_align) { |
| 626 | 636 | try stack.push(State { .ExpectToken = Token.Id.RParen }); |
| 627 | 637 | try stack.push(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.align_node} }); |
| ... | ... | @@ -629,12 +639,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 629 | 639 | continue; |
| 630 | 640 | } |
| 631 | 641 | |
| 632 | | _ = tok_it.prev(); |
| 642 | putBackToken(&tok_it, &tree); |
| 633 | 643 | continue; |
| 634 | 644 | }, |
| 635 | 645 | State.VarDeclEq => |var_decl| { |
| 636 | | const token_index = tok_it.index; |
| 637 | | const token_ptr = ??tok_it.next(); |
| 646 | const token = nextToken(&tok_it, &tree); |
| 647 | const token_index = token.index; |
| 648 | const token_ptr = token.ptr; |
| 638 | 649 | switch (token_ptr.id) { |
| 639 | 650 | Token.Id.Equal => { |
| 640 | 651 | var_decl.eq_token = token_index; |
| ... | ... | @@ -662,8 +673,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 662 | 673 | |
| 663 | 674 | |
| 664 | 675 | State.FnDef => |fn_proto| { |
| 665 | | const token_index = tok_it.index; |
| 666 | | const token_ptr = ??tok_it.next(); |
| 676 | const token = nextToken(&tok_it, &tree); |
| 677 | const token_index = token.index; |
| 678 | const token_ptr = token.ptr; |
| 667 | 679 | switch(token_ptr.id) { |
| 668 | 680 | Token.Id.LBrace => { |
| 669 | 681 | const block = try arena.construct(ast.Node.Block { |
| ... | ... | @@ -691,7 +703,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 691 | 703 | try stack.push(State { .ParamDecl = fn_proto }); |
| 692 | 704 | try stack.push(State { .ExpectToken = Token.Id.LParen }); |
| 693 | 705 | |
| 694 | | if (eatToken(&tok_it, Token.Id.Identifier)) |name_token| { |
| 706 | if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |name_token| { |
| 695 | 707 | fn_proto.name_token = name_token; |
| 696 | 708 | } |
| 697 | 709 | continue; |
| ... | ... | @@ -699,7 +711,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 699 | 711 | State.FnProtoAlign => |fn_proto| { |
| 700 | 712 | stack.push(State { .FnProtoReturnType = fn_proto }) catch unreachable; |
| 701 | 713 | |
| 702 | | if (eatToken(&tok_it, Token.Id.Keyword_align)) |align_token| { |
| 714 | if (eatToken(&tok_it, &tree, Token.Id.Keyword_align)) |align_token| { |
| 703 | 715 | try stack.push(State { .ExpectToken = Token.Id.RParen }); |
| 704 | 716 | try stack.push(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } }); |
| 705 | 717 | try stack.push(State { .ExpectToken = Token.Id.LParen }); |
| ... | ... | @@ -707,8 +719,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 707 | 719 | continue; |
| 708 | 720 | }, |
| 709 | 721 | State.FnProtoReturnType => |fn_proto| { |
| 710 | | const token_index = tok_it.index; |
| 711 | | const token_ptr = ??tok_it.next(); |
| 722 | const token = nextToken(&tok_it, &tree); |
| 723 | const token_index = token.index; |
| 724 | const token_ptr = token.ptr; |
| 712 | 725 | switch (token_ptr.id) { |
| 713 | 726 | Token.Id.Bang => { |
| 714 | 727 | fn_proto.return_type = ast.Node.FnProto.ReturnType { .InferErrorSet = undefined }; |
| ... | ... | @@ -732,7 +745,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 732 | 745 | } |
| 733 | 746 | } |
| 734 | 747 | |
| 735 | | _ = tok_it.prev(); |
| 748 | putBackToken(&tok_it, &tree); |
| 736 | 749 | fn_proto.return_type = ast.Node.FnProto.ReturnType { .Explicit = undefined }; |
| 737 | 750 | stack.push(State { .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.Explicit }, }) catch unreachable; |
| 738 | 751 | continue; |
| ... | ... | @@ -742,7 +755,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 742 | 755 | |
| 743 | 756 | |
| 744 | 757 | State.ParamDecl => |fn_proto| { |
| 745 | | if (eatToken(&tok_it, Token.Id.RParen)) |_| { |
| 758 | if (eatToken(&tok_it, &tree, Token.Id.RParen)) |_| { |
| 746 | 759 | continue; |
| 747 | 760 | } |
| 748 | 761 | const param_decl = try arena.construct(ast.Node.ParamDecl { |
| ... | ... | @@ -766,9 +779,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 766 | 779 | continue; |
| 767 | 780 | }, |
| 768 | 781 | State.ParamDeclAliasOrComptime => |param_decl| { |
| 769 | | if (eatToken(&tok_it, Token.Id.Keyword_comptime)) |comptime_token| { |
| 782 | if (eatToken(&tok_it, &tree, Token.Id.Keyword_comptime)) |comptime_token| { |
| 770 | 783 | param_decl.comptime_token = comptime_token; |
| 771 | | } else if (eatToken(&tok_it, Token.Id.Keyword_noalias)) |noalias_token| { |
| 784 | } else if (eatToken(&tok_it, &tree, Token.Id.Keyword_noalias)) |noalias_token| { |
| 772 | 785 | param_decl.noalias_token = noalias_token; |
| 773 | 786 | } |
| 774 | 787 | continue; |
| ... | ... | @@ -776,17 +789,17 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 776 | 789 | State.ParamDeclName => |param_decl| { |
| 777 | 790 | // TODO: Here, we eat two tokens in one state. This means that we can't have |
| 778 | 791 | // comments between these two tokens. |
| 779 | | if (eatToken(&tok_it, Token.Id.Identifier)) |ident_token| { |
| 780 | | if (eatToken(&tok_it, Token.Id.Colon)) |_| { |
| 792 | if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |ident_token| { |
| 793 | if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| { |
| 781 | 794 | param_decl.name_token = ident_token; |
| 782 | 795 | } else { |
| 783 | | _ = tok_it.prev(); |
| 796 | putBackToken(&tok_it, &tree); |
| 784 | 797 | } |
| 785 | 798 | } |
| 786 | 799 | continue; |
| 787 | 800 | }, |
| 788 | 801 | State.ParamDeclEnd => |ctx| { |
| 789 | | if (eatToken(&tok_it, Token.Id.Ellipsis3)) |ellipsis3| { |
| 802 | if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| { |
| 790 | 803 | ctx.param_decl.var_args_token = ellipsis3; |
| 791 | 804 | stack.push(State { .ExpectToken = Token.Id.RParen }) catch unreachable; |
| 792 | 805 | continue; |
| ... | ... | @@ -799,7 +812,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 799 | 812 | continue; |
| 800 | 813 | }, |
| 801 | 814 | State.ParamDeclComma => |fn_proto| { |
| 802 | | switch (expectCommaOrEnd(&tok_it, Token.Id.RParen)) { |
| 815 | switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) { |
| 803 | 816 | ExpectCommaOrEndResult.end_token => |t| { |
| 804 | 817 | if (t == null) { |
| 805 | 818 | stack.push(State { .ParamDecl = fn_proto }) catch unreachable; |
| ... | ... | @@ -814,7 +827,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 814 | 827 | }, |
| 815 | 828 | |
| 816 | 829 | State.MaybeLabeledExpression => |ctx| { |
| 817 | | if (eatToken(&tok_it, Token.Id.Colon)) |_| { |
| 830 | if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| { |
| 818 | 831 | stack.push(State { |
| 819 | 832 | .LabeledExpression = LabelCtx { |
| 820 | 833 | .label = ctx.label, |
| ... | ... | @@ -828,8 +841,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 828 | 841 | continue; |
| 829 | 842 | }, |
| 830 | 843 | State.LabeledExpression => |ctx| { |
| 831 | | const token_index = tok_it.index; |
| 832 | | const token_ptr = ??tok_it.next(); |
| 844 | const token = nextToken(&tok_it, &tree); |
| 845 | const token_index = token.index; |
| 846 | const token_ptr = token.ptr; |
| 833 | 847 | switch (token_ptr.id) { |
| 834 | 848 | Token.Id.LBrace => { |
| 835 | 849 | const block = try createToCtxNode(arena, ctx.opt_ctx, ast.Node.Block, |
| ... | ... | @@ -899,14 +913,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 899 | 913 | return tree; |
| 900 | 914 | } |
| 901 | 915 | |
| 902 | | _ = tok_it.prev(); |
| 916 | putBackToken(&tok_it, &tree); |
| 903 | 917 | continue; |
| 904 | 918 | }, |
| 905 | 919 | } |
| 906 | 920 | }, |
| 907 | 921 | State.Inline => |ctx| { |
| 908 | | const token_index = tok_it.index; |
| 909 | | const token_ptr = ??tok_it.next(); |
| 922 | const token = nextToken(&tok_it, &tree); |
| 923 | const token_index = token.index; |
| 924 | const token_ptr = token.ptr; |
| 910 | 925 | switch (token_ptr.id) { |
| 911 | 926 | Token.Id.Keyword_while => { |
| 912 | 927 | stack.push(State { |
| ... | ... | @@ -938,7 +953,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 938 | 953 | return tree; |
| 939 | 954 | } |
| 940 | 955 | |
| 941 | | _ = tok_it.prev(); |
| 956 | putBackToken(&tok_it, &tree); |
| 942 | 957 | continue; |
| 943 | 958 | }, |
| 944 | 959 | } |
| ... | ... | @@ -995,7 +1010,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 995 | 1010 | continue; |
| 996 | 1011 | }, |
| 997 | 1012 | State.Else => |dest| { |
| 998 | | if (eatToken(&tok_it, Token.Id.Keyword_else)) |else_token| { |
| 1013 | if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| { |
| 999 | 1014 | const node = try createNode(arena, ast.Node.Else, |
| 1000 | 1015 | ast.Node.Else { |
| 1001 | 1016 | .base = undefined, |
| ... | ... | @@ -1016,19 +1031,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1016 | 1031 | |
| 1017 | 1032 | |
| 1018 | 1033 | State.Block => |block| { |
| 1019 | | const token_index = tok_it.index; |
| 1020 | | const token_ptr = ??tok_it.next(); |
| 1034 | const token = nextToken(&tok_it, &tree); |
| 1035 | const token_index = token.index; |
| 1036 | const token_ptr = token.ptr; |
| 1021 | 1037 | switch (token_ptr.id) { |
| 1022 | 1038 | Token.Id.RBrace => { |
| 1023 | 1039 | block.rbrace = token_index; |
| 1024 | 1040 | continue; |
| 1025 | 1041 | }, |
| 1026 | 1042 | else => { |
| 1027 | | _ = tok_it.prev(); |
| 1043 | putBackToken(&tok_it, &tree); |
| 1028 | 1044 | stack.push(State { .Block = block }) catch unreachable; |
| 1029 | 1045 | |
| 1030 | 1046 | var any_comments = false; |
| 1031 | | while (try eatLineComment(arena, &tok_it)) |line_comment| { |
| 1047 | while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| { |
| 1032 | 1048 | try block.statements.push(&line_comment.base); |
| 1033 | 1049 | any_comments = true; |
| 1034 | 1050 | } |
| ... | ... | @@ -1040,8 +1056,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1040 | 1056 | } |
| 1041 | 1057 | }, |
| 1042 | 1058 | State.Statement => |block| { |
| 1043 | | const token_index = tok_it.index; |
| 1044 | | const token_ptr = ??tok_it.next(); |
| 1059 | const token = nextToken(&tok_it, &tree); |
| 1060 | const token_index = token.index; |
| 1061 | const token_ptr = token.ptr; |
| 1045 | 1062 | switch (token_ptr.id) { |
| 1046 | 1063 | Token.Id.Keyword_comptime => { |
| 1047 | 1064 | stack.push(State { |
| ... | ... | @@ -1100,7 +1117,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1100 | 1117 | continue; |
| 1101 | 1118 | }, |
| 1102 | 1119 | else => { |
| 1103 | | _ = tok_it.prev(); |
| 1120 | putBackToken(&tok_it, &tree); |
| 1104 | 1121 | const statement = try block.statements.addOne(); |
| 1105 | 1122 | try stack.push(State { .Semicolon = statement }); |
| 1106 | 1123 | try stack.push(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } }); |
| ... | ... | @@ -1109,8 +1126,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1109 | 1126 | } |
| 1110 | 1127 | }, |
| 1111 | 1128 | State.ComptimeStatement => |ctx| { |
| 1112 | | const token_index = tok_it.index; |
| 1113 | | const token_ptr = ??tok_it.next(); |
| 1129 | const token = nextToken(&tok_it, &tree); |
| 1130 | const token_index = token.index; |
| 1131 | const token_ptr = token.ptr; |
| 1114 | 1132 | switch (token_ptr.id) { |
| 1115 | 1133 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 1116 | 1134 | stack.push(State { |
| ... | ... | @@ -1127,8 +1145,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1127 | 1145 | continue; |
| 1128 | 1146 | }, |
| 1129 | 1147 | else => { |
| 1130 | | _ = tok_it.prev(); |
| 1131 | | _ = tok_it.prev(); |
| 1148 | putBackToken(&tok_it, &tree); |
| 1149 | putBackToken(&tok_it, &tree); |
| 1132 | 1150 | const statement = try ctx.block.statements.addOne(); |
| 1133 | 1151 | try stack.push(State { .Semicolon = statement }); |
| 1134 | 1152 | try stack.push(State { .Expression = OptionalCtx { .Required = statement } }); |
| ... | ... | @@ -1146,10 +1164,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1146 | 1164 | }, |
| 1147 | 1165 | |
| 1148 | 1166 | State.AsmOutputItems => |items| { |
| 1149 | | const lbracket_index = tok_it.index; |
| 1150 | | const lbracket_ptr = ??tok_it.next(); |
| 1167 | const lbracket = nextToken(&tok_it, &tree); |
| 1168 | const lbracket_index = lbracket.index; |
| 1169 | const lbracket_ptr = lbracket.ptr; |
| 1151 | 1170 | if (lbracket_ptr.id != Token.Id.LBracket) { |
| 1152 | | _ = tok_it.prev(); |
| 1171 | putBackToken(&tok_it, &tree); |
| 1153 | 1172 | continue; |
| 1154 | 1173 | } |
| 1155 | 1174 | |
| ... | ... | @@ -1174,8 +1193,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1174 | 1193 | continue; |
| 1175 | 1194 | }, |
| 1176 | 1195 | State.AsmOutputReturnOrType => |node| { |
| 1177 | | const token_index = tok_it.index; |
| 1178 | | const token_ptr = ??tok_it.next(); |
| 1196 | const token = nextToken(&tok_it, &tree); |
| 1197 | const token_index = token.index; |
| 1198 | const token_ptr = token.ptr; |
| 1179 | 1199 | switch (token_ptr.id) { |
| 1180 | 1200 | Token.Id.Identifier => { |
| 1181 | 1201 | node.kind = ast.Node.AsmOutput.Kind { .Variable = try createLiteral(arena, ast.Node.Identifier, token_index) }; |
| ... | ... | @@ -1197,10 +1217,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1197 | 1217 | } |
| 1198 | 1218 | }, |
| 1199 | 1219 | State.AsmInputItems => |items| { |
| 1200 | | const lbracket_index = tok_it.index; |
| 1201 | | const lbracket_ptr = ??tok_it.next(); |
| 1220 | const lbracket = nextToken(&tok_it, &tree); |
| 1221 | const lbracket_index = lbracket.index; |
| 1222 | const lbracket_ptr = lbracket.ptr; |
| 1202 | 1223 | if (lbracket_ptr.id != Token.Id.LBracket) { |
| 1203 | | _ = tok_it.prev(); |
| 1224 | putBackToken(&tok_it, &tree); |
| 1204 | 1225 | continue; |
| 1205 | 1226 | } |
| 1206 | 1227 | |
| ... | ... | @@ -1233,7 +1254,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1233 | 1254 | |
| 1234 | 1255 | |
| 1235 | 1256 | State.ExprListItemOrEnd => |list_state| { |
| 1236 | | if (eatToken(&tok_it, list_state.end)) |token_index| { |
| 1257 | if (eatToken(&tok_it, &tree, list_state.end)) |token_index| { |
| 1237 | 1258 | *list_state.ptr = token_index; |
| 1238 | 1259 | continue; |
| 1239 | 1260 | } |
| ... | ... | @@ -1243,7 +1264,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1243 | 1264 | continue; |
| 1244 | 1265 | }, |
| 1245 | 1266 | State.ExprListCommaOrEnd => |list_state| { |
| 1246 | | switch (expectCommaOrEnd(&tok_it, list_state.end)) { |
| 1267 | switch (expectCommaOrEnd(&tok_it, &tree, list_state.end)) { |
| 1247 | 1268 | ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| { |
| 1248 | 1269 | *list_state.ptr = end; |
| 1249 | 1270 | continue; |
| ... | ... | @@ -1258,11 +1279,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1258 | 1279 | } |
| 1259 | 1280 | }, |
| 1260 | 1281 | State.FieldInitListItemOrEnd => |list_state| { |
| 1261 | | while (try eatLineComment(arena, &tok_it)) |line_comment| { |
| 1282 | while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| { |
| 1262 | 1283 | try list_state.list.push(&line_comment.base); |
| 1263 | 1284 | } |
| 1264 | 1285 | |
| 1265 | | if (eatToken(&tok_it, Token.Id.RBrace)) |rbrace| { |
| 1286 | if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| { |
| 1266 | 1287 | *list_state.ptr = rbrace; |
| 1267 | 1288 | continue; |
| 1268 | 1289 | } |
| ... | ... | @@ -1295,7 +1316,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1295 | 1316 | continue; |
| 1296 | 1317 | }, |
| 1297 | 1318 | State.FieldInitListCommaOrEnd => |list_state| { |
| 1298 | | switch (expectCommaOrEnd(&tok_it, Token.Id.RBrace)) { |
| 1319 | switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) { |
| 1299 | 1320 | ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| { |
| 1300 | 1321 | *list_state.ptr = end; |
| 1301 | 1322 | continue; |
| ... | ... | @@ -1310,7 +1331,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1310 | 1331 | } |
| 1311 | 1332 | }, |
| 1312 | 1333 | State.FieldListCommaOrEnd => |container_decl| { |
| 1313 | | switch (expectCommaOrEnd(&tok_it, Token.Id.RBrace)) { |
| 1334 | switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) { |
| 1314 | 1335 | ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| { |
| 1315 | 1336 | container_decl.rbrace_token = end; |
| 1316 | 1337 | continue; |
| ... | ... | @@ -1325,11 +1346,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1325 | 1346 | } |
| 1326 | 1347 | }, |
| 1327 | 1348 | State.ErrorTagListItemOrEnd => |list_state| { |
| 1328 | | while (try eatLineComment(arena, &tok_it)) |line_comment| { |
| 1349 | while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| { |
| 1329 | 1350 | try list_state.list.push(&line_comment.base); |
| 1330 | 1351 | } |
| 1331 | 1352 | |
| 1332 | | if (eatToken(&tok_it, Token.Id.RBrace)) |rbrace| { |
| 1353 | if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| { |
| 1333 | 1354 | *list_state.ptr = rbrace; |
| 1334 | 1355 | continue; |
| 1335 | 1356 | } |
| ... | ... | @@ -1341,7 +1362,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1341 | 1362 | continue; |
| 1342 | 1363 | }, |
| 1343 | 1364 | State.ErrorTagListCommaOrEnd => |list_state| { |
| 1344 | | switch (expectCommaOrEnd(&tok_it, Token.Id.RBrace)) { |
| 1365 | switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) { |
| 1345 | 1366 | ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| { |
| 1346 | 1367 | *list_state.ptr = end; |
| 1347 | 1368 | continue; |
| ... | ... | @@ -1356,16 +1377,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1356 | 1377 | } |
| 1357 | 1378 | }, |
| 1358 | 1379 | State.SwitchCaseOrEnd => |list_state| { |
| 1359 | | while (try eatLineComment(arena, &tok_it)) |line_comment| { |
| 1380 | while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| { |
| 1360 | 1381 | try list_state.list.push(&line_comment.base); |
| 1361 | 1382 | } |
| 1362 | 1383 | |
| 1363 | | if (eatToken(&tok_it, Token.Id.RBrace)) |rbrace| { |
| 1384 | if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| { |
| 1364 | 1385 | *list_state.ptr = rbrace; |
| 1365 | 1386 | continue; |
| 1366 | 1387 | } |
| 1367 | 1388 | |
| 1368 | | const comments = try eatDocComments(arena, &tok_it); |
| 1389 | const comments = try eatDocComments(arena, &tok_it, &tree); |
| 1369 | 1390 | const node = try arena.construct(ast.Node.SwitchCase { |
| 1370 | 1391 | .base = ast.Node { |
| 1371 | 1392 | .id = ast.Node.Id.SwitchCase, |
| ... | ... | @@ -1384,7 +1405,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1384 | 1405 | }, |
| 1385 | 1406 | |
| 1386 | 1407 | State.SwitchCaseCommaOrEnd => |list_state| { |
| 1387 | | switch (expectCommaOrEnd(&tok_it, Token.Id.RParen)) { |
| 1408 | switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) { |
| 1388 | 1409 | ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| { |
| 1389 | 1410 | *list_state.ptr = end; |
| 1390 | 1411 | continue; |
| ... | ... | @@ -1400,8 +1421,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1400 | 1421 | }, |
| 1401 | 1422 | |
| 1402 | 1423 | State.SwitchCaseFirstItem => |case_items| { |
| 1403 | | const token_index = tok_it.index; |
| 1404 | | const token_ptr = ??tok_it.next(); |
| 1424 | const token = nextToken(&tok_it, &tree); |
| 1425 | const token_index = token.index; |
| 1426 | const token_ptr = token.ptr; |
| 1405 | 1427 | if (token_ptr.id == Token.Id.Keyword_else) { |
| 1406 | 1428 | const else_node = try arena.construct(ast.Node.SwitchElse { |
| 1407 | 1429 | .base = ast.Node{ .id = ast.Node.Id.SwitchElse}, |
| ... | ... | @@ -1412,7 +1434,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1412 | 1434 | try stack.push(State { .ExpectToken = Token.Id.EqualAngleBracketRight }); |
| 1413 | 1435 | continue; |
| 1414 | 1436 | } else { |
| 1415 | | _ = tok_it.prev(); |
| 1437 | putBackToken(&tok_it, &tree); |
| 1416 | 1438 | try stack.push(State { .SwitchCaseItem = case_items }); |
| 1417 | 1439 | continue; |
| 1418 | 1440 | } |
| ... | ... | @@ -1422,7 +1444,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1422 | 1444 | try stack.push(State { .RangeExpressionBegin = OptionalCtx { .Required = try case_items.addOne() } }); |
| 1423 | 1445 | }, |
| 1424 | 1446 | State.SwitchCaseItemCommaOrEnd => |case_items| { |
| 1425 | | switch (expectCommaOrEnd(&tok_it, Token.Id.EqualAngleBracketRight)) { |
| 1447 | switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.EqualAngleBracketRight)) { |
| 1426 | 1448 | ExpectCommaOrEndResult.end_token => |t| { |
| 1427 | 1449 | if (t == null) { |
| 1428 | 1450 | stack.push(State { .SwitchCaseItem = case_items }) catch unreachable; |
| ... | ... | @@ -1445,7 +1467,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1445 | 1467 | continue; |
| 1446 | 1468 | }, |
| 1447 | 1469 | State.AsyncAllocator => |async_node| { |
| 1448 | | if (eatToken(&tok_it, Token.Id.AngleBracketLeft) == null) { |
| 1470 | if (eatToken(&tok_it, &tree, Token.Id.AngleBracketLeft) == null) { |
| 1449 | 1471 | continue; |
| 1450 | 1472 | } |
| 1451 | 1473 | |
| ... | ... | @@ -1491,7 +1513,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1491 | 1513 | |
| 1492 | 1514 | |
| 1493 | 1515 | State.ExternType => |ctx| { |
| 1494 | | if (eatToken(&tok_it, Token.Id.Keyword_fn)) |fn_token| { |
| 1516 | if (eatToken(&tok_it, &tree, Token.Id.Keyword_fn)) |fn_token| { |
| 1495 | 1517 | const fn_proto = try arena.construct(ast.Node.FnProto { |
| 1496 | 1518 | .base = ast.Node { |
| 1497 | 1519 | .id = ast.Node.Id.FnProto, |
| ... | ... | @@ -1525,8 +1547,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1525 | 1547 | continue; |
| 1526 | 1548 | }, |
| 1527 | 1549 | State.SliceOrArrayAccess => |node| { |
| 1528 | | const token_index = tok_it.index; |
| 1529 | | const token_ptr = ??tok_it.next(); |
| 1550 | const token = nextToken(&tok_it, &tree); |
| 1551 | const token_index = token.index; |
| 1552 | const token_ptr = token.ptr; |
| 1530 | 1553 | switch (token_ptr.id) { |
| 1531 | 1554 | Token.Id.Ellipsis2 => { |
| 1532 | 1555 | const start = node.op.ArrayAccess; |
| ... | ... | @@ -1559,7 +1582,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1559 | 1582 | } |
| 1560 | 1583 | }, |
| 1561 | 1584 | State.SliceOrArrayType => |node| { |
| 1562 | | if (eatToken(&tok_it, Token.Id.RBracket)) |_| { |
| 1585 | if (eatToken(&tok_it, &tree, Token.Id.RBracket)) |_| { |
| 1563 | 1586 | node.op = ast.Node.PrefixOp.Op { |
| 1564 | 1587 | .SliceType = ast.Node.PrefixOp.AddrOfInfo { |
| 1565 | 1588 | .align_expr = null, |
| ... | ... | @@ -1581,8 +1604,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1581 | 1604 | continue; |
| 1582 | 1605 | }, |
| 1583 | 1606 | State.AddrOfModifiers => |addr_of_info| { |
| 1584 | | const token_index = tok_it.index; |
| 1585 | | const token_ptr = ??tok_it.next(); |
| 1607 | const token = nextToken(&tok_it, &tree); |
| 1608 | const token_index = token.index; |
| 1609 | const token_ptr = token.ptr; |
| 1586 | 1610 | switch (token_ptr.id) { |
| 1587 | 1611 | Token.Id.Keyword_align => { |
| 1588 | 1612 | stack.push(state) catch unreachable; |
| ... | ... | @@ -1620,7 +1644,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1620 | 1644 | continue; |
| 1621 | 1645 | }, |
| 1622 | 1646 | else => { |
| 1623 | | _ = tok_it.prev(); |
| 1647 | putBackToken(&tok_it, &tree); |
| 1624 | 1648 | continue; |
| 1625 | 1649 | }, |
| 1626 | 1650 | } |
| ... | ... | @@ -1628,8 +1652,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1628 | 1652 | |
| 1629 | 1653 | |
| 1630 | 1654 | State.Payload => |opt_ctx| { |
| 1631 | | const token_index = tok_it.index; |
| 1632 | | const token_ptr = ??tok_it.next(); |
| 1655 | const token = nextToken(&tok_it, &tree); |
| 1656 | const token_index = token.index; |
| 1657 | const token_ptr = token.ptr; |
| 1633 | 1658 | if (token_ptr.id != Token.Id.Pipe) { |
| 1634 | 1659 | if (opt_ctx != OptionalCtx.Optional) { |
| 1635 | 1660 | *(try tree.errors.addOne()) = Error { |
| ... | ... | @@ -1641,7 +1666,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1641 | 1666 | return tree; |
| 1642 | 1667 | } |
| 1643 | 1668 | |
| 1644 | | _ = tok_it.prev(); |
| 1669 | putBackToken(&tok_it, &tree); |
| 1645 | 1670 | continue; |
| 1646 | 1671 | } |
| 1647 | 1672 | |
| ... | ... | @@ -1664,8 +1689,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1664 | 1689 | continue; |
| 1665 | 1690 | }, |
| 1666 | 1691 | State.PointerPayload => |opt_ctx| { |
| 1667 | | const token_index = tok_it.index; |
| 1668 | | const token_ptr = ??tok_it.next(); |
| 1692 | const token = nextToken(&tok_it, &tree); |
| 1693 | const token_index = token.index; |
| 1694 | const token_ptr = token.ptr; |
| 1669 | 1695 | if (token_ptr.id != Token.Id.Pipe) { |
| 1670 | 1696 | if (opt_ctx != OptionalCtx.Optional) { |
| 1671 | 1697 | *(try tree.errors.addOne()) = Error { |
| ... | ... | @@ -1677,7 +1703,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1677 | 1703 | return tree; |
| 1678 | 1704 | } |
| 1679 | 1705 | |
| 1680 | | _ = tok_it.prev(); |
| 1706 | putBackToken(&tok_it, &tree); |
| 1681 | 1707 | continue; |
| 1682 | 1708 | } |
| 1683 | 1709 | |
| ... | ... | @@ -1707,8 +1733,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1707 | 1733 | continue; |
| 1708 | 1734 | }, |
| 1709 | 1735 | State.PointerIndexPayload => |opt_ctx| { |
| 1710 | | const token_index = tok_it.index; |
| 1711 | | const token_ptr = ??tok_it.next(); |
| 1736 | const token = nextToken(&tok_it, &tree); |
| 1737 | const token_index = token.index; |
| 1738 | const token_ptr = token.ptr; |
| 1712 | 1739 | if (token_ptr.id != Token.Id.Pipe) { |
| 1713 | 1740 | if (opt_ctx != OptionalCtx.Optional) { |
| 1714 | 1741 | *(try tree.errors.addOne()) = Error { |
| ... | ... | @@ -1720,7 +1747,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1720 | 1747 | return tree; |
| 1721 | 1748 | } |
| 1722 | 1749 | |
| 1723 | | _ = tok_it.prev(); |
| 1750 | putBackToken(&tok_it, &tree); |
| 1724 | 1751 | continue; |
| 1725 | 1752 | } |
| 1726 | 1753 | |
| ... | ... | @@ -1755,8 +1782,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1755 | 1782 | |
| 1756 | 1783 | |
| 1757 | 1784 | State.Expression => |opt_ctx| { |
| 1758 | | const token_index = tok_it.index; |
| 1759 | | const token_ptr = ??tok_it.next(); |
| 1785 | const token = nextToken(&tok_it, &tree); |
| 1786 | const token_index = token.index; |
| 1787 | const token_ptr = token.ptr; |
| 1760 | 1788 | switch (token_ptr.id) { |
| 1761 | 1789 | Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => { |
| 1762 | 1790 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.ControlFlowExpression, |
| ... | ... | @@ -1808,7 +1836,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1808 | 1836 | }, |
| 1809 | 1837 | else => { |
| 1810 | 1838 | if (!try parseBlockExpr(&stack, arena, opt_ctx, token_ptr, token_index)) { |
| 1811 | | _ = tok_it.prev(); |
| 1839 | putBackToken(&tok_it, &tree); |
| 1812 | 1840 | stack.push(State { .UnwrapExpressionBegin = opt_ctx }) catch unreachable; |
| 1813 | 1841 | } |
| 1814 | 1842 | continue; |
| ... | ... | @@ -1823,7 +1851,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1823 | 1851 | State.RangeExpressionEnd => |opt_ctx| { |
| 1824 | 1852 | const lhs = opt_ctx.get() ?? continue; |
| 1825 | 1853 | |
| 1826 | | if (eatToken(&tok_it, Token.Id.Ellipsis3)) |ellipsis3| { |
| 1854 | if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| { |
| 1827 | 1855 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 1828 | 1856 | ast.Node.InfixOp { |
| 1829 | 1857 | .base = undefined, |
| ... | ... | @@ -1846,8 +1874,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1846 | 1874 | State.AssignmentExpressionEnd => |opt_ctx| { |
| 1847 | 1875 | const lhs = opt_ctx.get() ?? continue; |
| 1848 | 1876 | |
| 1849 | | const token_index = tok_it.index; |
| 1850 | | const token_ptr = ??tok_it.next(); |
| 1877 | const token = nextToken(&tok_it, &tree); |
| 1878 | const token_index = token.index; |
| 1879 | const token_ptr = token.ptr; |
| 1851 | 1880 | if (tokenIdToAssignment(token_ptr.id)) |ass_id| { |
| 1852 | 1881 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 1853 | 1882 | ast.Node.InfixOp { |
| ... | ... | @@ -1862,7 +1891,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1862 | 1891 | try stack.push(State { .Expression = OptionalCtx { .Required = &node.rhs } }); |
| 1863 | 1892 | continue; |
| 1864 | 1893 | } else { |
| 1865 | | _ = tok_it.prev(); |
| 1894 | putBackToken(&tok_it, &tree); |
| 1866 | 1895 | continue; |
| 1867 | 1896 | } |
| 1868 | 1897 | }, |
| ... | ... | @@ -1876,8 +1905,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1876 | 1905 | State.UnwrapExpressionEnd => |opt_ctx| { |
| 1877 | 1906 | const lhs = opt_ctx.get() ?? continue; |
| 1878 | 1907 | |
| 1879 | | const token_index = tok_it.index; |
| 1880 | | const token_ptr = ??tok_it.next(); |
| 1908 | const token = nextToken(&tok_it, &tree); |
| 1909 | const token_index = token.index; |
| 1910 | const token_ptr = token.ptr; |
| 1881 | 1911 | if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| { |
| 1882 | 1912 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 1883 | 1913 | ast.Node.InfixOp { |
| ... | ... | @@ -1897,7 +1927,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1897 | 1927 | } |
| 1898 | 1928 | continue; |
| 1899 | 1929 | } else { |
| 1900 | | _ = tok_it.prev(); |
| 1930 | putBackToken(&tok_it, &tree); |
| 1901 | 1931 | continue; |
| 1902 | 1932 | } |
| 1903 | 1933 | }, |
| ... | ... | @@ -1911,7 +1941,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1911 | 1941 | State.BoolOrExpressionEnd => |opt_ctx| { |
| 1912 | 1942 | const lhs = opt_ctx.get() ?? continue; |
| 1913 | 1943 | |
| 1914 | | if (eatToken(&tok_it, Token.Id.Keyword_or)) |or_token| { |
| 1944 | if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| { |
| 1915 | 1945 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 1916 | 1946 | ast.Node.InfixOp { |
| 1917 | 1947 | .base = undefined, |
| ... | ... | @@ -1936,7 +1966,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1936 | 1966 | State.BoolAndExpressionEnd => |opt_ctx| { |
| 1937 | 1967 | const lhs = opt_ctx.get() ?? continue; |
| 1938 | 1968 | |
| 1939 | | if (eatToken(&tok_it, Token.Id.Keyword_and)) |and_token| { |
| 1969 | if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| { |
| 1940 | 1970 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 1941 | 1971 | ast.Node.InfixOp { |
| 1942 | 1972 | .base = undefined, |
| ... | ... | @@ -1961,8 +1991,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1961 | 1991 | State.ComparisonExpressionEnd => |opt_ctx| { |
| 1962 | 1992 | const lhs = opt_ctx.get() ?? continue; |
| 1963 | 1993 | |
| 1964 | | const token_index = tok_it.index; |
| 1965 | | const token_ptr = ??tok_it.next(); |
| 1994 | const token = nextToken(&tok_it, &tree); |
| 1995 | const token_index = token.index; |
| 1996 | const token_ptr = token.ptr; |
| 1966 | 1997 | if (tokenIdToComparison(token_ptr.id)) |comp_id| { |
| 1967 | 1998 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 1968 | 1999 | ast.Node.InfixOp { |
| ... | ... | @@ -1977,7 +2008,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1977 | 2008 | try stack.push(State { .BinaryOrExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 1978 | 2009 | continue; |
| 1979 | 2010 | } else { |
| 1980 | | _ = tok_it.prev(); |
| 2011 | putBackToken(&tok_it, &tree); |
| 1981 | 2012 | continue; |
| 1982 | 2013 | } |
| 1983 | 2014 | }, |
| ... | ... | @@ -1991,7 +2022,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 1991 | 2022 | State.BinaryOrExpressionEnd => |opt_ctx| { |
| 1992 | 2023 | const lhs = opt_ctx.get() ?? continue; |
| 1993 | 2024 | |
| 1994 | | if (eatToken(&tok_it, Token.Id.Pipe)) |pipe| { |
| 2025 | if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| { |
| 1995 | 2026 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 1996 | 2027 | ast.Node.InfixOp { |
| 1997 | 2028 | .base = undefined, |
| ... | ... | @@ -2016,7 +2047,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2016 | 2047 | State.BinaryXorExpressionEnd => |opt_ctx| { |
| 2017 | 2048 | const lhs = opt_ctx.get() ?? continue; |
| 2018 | 2049 | |
| 2019 | | if (eatToken(&tok_it, Token.Id.Caret)) |caret| { |
| 2050 | if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| { |
| 2020 | 2051 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 2021 | 2052 | ast.Node.InfixOp { |
| 2022 | 2053 | .base = undefined, |
| ... | ... | @@ -2041,7 +2072,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2041 | 2072 | State.BinaryAndExpressionEnd => |opt_ctx| { |
| 2042 | 2073 | const lhs = opt_ctx.get() ?? continue; |
| 2043 | 2074 | |
| 2044 | | if (eatToken(&tok_it, Token.Id.Ampersand)) |ampersand| { |
| 2075 | if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| { |
| 2045 | 2076 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 2046 | 2077 | ast.Node.InfixOp { |
| 2047 | 2078 | .base = undefined, |
| ... | ... | @@ -2066,8 +2097,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2066 | 2097 | State.BitShiftExpressionEnd => |opt_ctx| { |
| 2067 | 2098 | const lhs = opt_ctx.get() ?? continue; |
| 2068 | 2099 | |
| 2069 | | const token_index = tok_it.index; |
| 2070 | | const token_ptr = ??tok_it.next(); |
| 2100 | const token = nextToken(&tok_it, &tree); |
| 2101 | const token_index = token.index; |
| 2102 | const token_ptr = token.ptr; |
| 2071 | 2103 | if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| { |
| 2072 | 2104 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 2073 | 2105 | ast.Node.InfixOp { |
| ... | ... | @@ -2082,7 +2114,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2082 | 2114 | try stack.push(State { .AdditionExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2083 | 2115 | continue; |
| 2084 | 2116 | } else { |
| 2085 | | _ = tok_it.prev(); |
| 2117 | putBackToken(&tok_it, &tree); |
| 2086 | 2118 | continue; |
| 2087 | 2119 | } |
| 2088 | 2120 | }, |
| ... | ... | @@ -2096,8 +2128,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2096 | 2128 | State.AdditionExpressionEnd => |opt_ctx| { |
| 2097 | 2129 | const lhs = opt_ctx.get() ?? continue; |
| 2098 | 2130 | |
| 2099 | | const token_index = tok_it.index; |
| 2100 | | const token_ptr = ??tok_it.next(); |
| 2131 | const token = nextToken(&tok_it, &tree); |
| 2132 | const token_index = token.index; |
| 2133 | const token_ptr = token.ptr; |
| 2101 | 2134 | if (tokenIdToAddition(token_ptr.id)) |add_id| { |
| 2102 | 2135 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 2103 | 2136 | ast.Node.InfixOp { |
| ... | ... | @@ -2112,7 +2145,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2112 | 2145 | try stack.push(State { .MultiplyExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2113 | 2146 | continue; |
| 2114 | 2147 | } else { |
| 2115 | | _ = tok_it.prev(); |
| 2148 | putBackToken(&tok_it, &tree); |
| 2116 | 2149 | continue; |
| 2117 | 2150 | } |
| 2118 | 2151 | }, |
| ... | ... | @@ -2126,8 +2159,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2126 | 2159 | State.MultiplyExpressionEnd => |opt_ctx| { |
| 2127 | 2160 | const lhs = opt_ctx.get() ?? continue; |
| 2128 | 2161 | |
| 2129 | | const token_index = tok_it.index; |
| 2130 | | const token_ptr = ??tok_it.next(); |
| 2162 | const token = nextToken(&tok_it, &tree); |
| 2163 | const token_index = token.index; |
| 2164 | const token_ptr = token.ptr; |
| 2131 | 2165 | if (tokenIdToMultiply(token_ptr.id)) |mult_id| { |
| 2132 | 2166 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 2133 | 2167 | ast.Node.InfixOp { |
| ... | ... | @@ -2142,7 +2176,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2142 | 2176 | try stack.push(State { .CurlySuffixExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2143 | 2177 | continue; |
| 2144 | 2178 | } else { |
| 2145 | | _ = tok_it.prev(); |
| 2179 | putBackToken(&tok_it, &tree); |
| 2146 | 2180 | continue; |
| 2147 | 2181 | } |
| 2148 | 2182 | }, |
| ... | ... | @@ -2210,7 +2244,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2210 | 2244 | State.TypeExprEnd => |opt_ctx| { |
| 2211 | 2245 | const lhs = opt_ctx.get() ?? continue; |
| 2212 | 2246 | |
| 2213 | | if (eatToken(&tok_it, Token.Id.Bang)) |bang| { |
| 2247 | if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| { |
| 2214 | 2248 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.InfixOp, |
| 2215 | 2249 | ast.Node.InfixOp { |
| 2216 | 2250 | .base = undefined, |
| ... | ... | @@ -2227,8 +2261,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2227 | 2261 | }, |
| 2228 | 2262 | |
| 2229 | 2263 | State.PrefixOpExpression => |opt_ctx| { |
| 2230 | | const token_index = tok_it.index; |
| 2231 | | const token_ptr = ??tok_it.next(); |
| 2264 | const token = nextToken(&tok_it, &tree); |
| 2265 | const token_index = token.index; |
| 2266 | const token_ptr = token.ptr; |
| 2232 | 2267 | if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| { |
| 2233 | 2268 | var node = try createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp, |
| 2234 | 2269 | ast.Node.PrefixOp { |
| ... | ... | @@ -2259,14 +2294,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2259 | 2294 | } |
| 2260 | 2295 | continue; |
| 2261 | 2296 | } else { |
| 2262 | | _ = tok_it.prev(); |
| 2297 | putBackToken(&tok_it, &tree); |
| 2263 | 2298 | stack.push(State { .SuffixOpExpressionBegin = opt_ctx }) catch unreachable; |
| 2264 | 2299 | continue; |
| 2265 | 2300 | } |
| 2266 | 2301 | }, |
| 2267 | 2302 | |
| 2268 | 2303 | State.SuffixOpExpressionBegin => |opt_ctx| { |
| 2269 | | if (eatToken(&tok_it, Token.Id.Keyword_async)) |async_token| { |
| 2304 | if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| { |
| 2270 | 2305 | const async_node = try createNode(arena, ast.Node.AsyncAttribute, |
| 2271 | 2306 | ast.Node.AsyncAttribute { |
| 2272 | 2307 | .base = undefined, |
| ... | ... | @@ -2295,8 +2330,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2295 | 2330 | State.SuffixOpExpressionEnd => |opt_ctx| { |
| 2296 | 2331 | const lhs = opt_ctx.get() ?? continue; |
| 2297 | 2332 | |
| 2298 | | const token_index = tok_it.index; |
| 2299 | | const token_ptr = ??tok_it.next(); |
| 2333 | const token = nextToken(&tok_it, &tree); |
| 2334 | const token_index = token.index; |
| 2335 | const token_ptr = token.ptr; |
| 2300 | 2336 | switch (token_ptr.id) { |
| 2301 | 2337 | Token.Id.LParen => { |
| 2302 | 2338 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp, |
| ... | ... | @@ -2353,50 +2389,49 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2353 | 2389 | continue; |
| 2354 | 2390 | }, |
| 2355 | 2391 | else => { |
| 2356 | | _ = tok_it.prev(); |
| 2392 | putBackToken(&tok_it, &tree); |
| 2357 | 2393 | continue; |
| 2358 | 2394 | }, |
| 2359 | 2395 | } |
| 2360 | 2396 | }, |
| 2361 | 2397 | |
| 2362 | 2398 | State.PrimaryExpression => |opt_ctx| { |
| 2363 | | const token_index = tok_it.index; |
| 2364 | | const token_ptr = ??tok_it.next(); |
| 2365 | | switch (token_ptr.id) { |
| 2399 | const token = nextToken(&tok_it, &tree); |
| 2400 | switch (token.ptr.id) { |
| 2366 | 2401 | Token.Id.IntegerLiteral => { |
| 2367 | | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.StringLiteral, token_index); |
| 2402 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.StringLiteral, token.index); |
| 2368 | 2403 | continue; |
| 2369 | 2404 | }, |
| 2370 | 2405 | Token.Id.FloatLiteral => { |
| 2371 | | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.FloatLiteral, token_index); |
| 2406 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.FloatLiteral, token.index); |
| 2372 | 2407 | continue; |
| 2373 | 2408 | }, |
| 2374 | 2409 | Token.Id.CharLiteral => { |
| 2375 | | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.CharLiteral, token_index); |
| 2410 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.CharLiteral, token.index); |
| 2376 | 2411 | continue; |
| 2377 | 2412 | }, |
| 2378 | 2413 | Token.Id.Keyword_undefined => { |
| 2379 | | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.UndefinedLiteral, token_index); |
| 2414 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.UndefinedLiteral, token.index); |
| 2380 | 2415 | continue; |
| 2381 | 2416 | }, |
| 2382 | 2417 | Token.Id.Keyword_true, Token.Id.Keyword_false => { |
| 2383 | | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.BoolLiteral, token_index); |
| 2418 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.BoolLiteral, token.index); |
| 2384 | 2419 | continue; |
| 2385 | 2420 | }, |
| 2386 | 2421 | Token.Id.Keyword_null => { |
| 2387 | | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.NullLiteral, token_index); |
| 2422 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.NullLiteral, token.index); |
| 2388 | 2423 | continue; |
| 2389 | 2424 | }, |
| 2390 | 2425 | Token.Id.Keyword_this => { |
| 2391 | | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.ThisLiteral, token_index); |
| 2426 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.ThisLiteral, token.index); |
| 2392 | 2427 | continue; |
| 2393 | 2428 | }, |
| 2394 | 2429 | Token.Id.Keyword_var => { |
| 2395 | | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.VarType, token_index); |
| 2430 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.VarType, token.index); |
| 2396 | 2431 | continue; |
| 2397 | 2432 | }, |
| 2398 | 2433 | Token.Id.Keyword_unreachable => { |
| 2399 | | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.Unreachable, token_index); |
| 2434 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.Unreachable, token.index); |
| 2400 | 2435 | continue; |
| 2401 | 2436 | }, |
| 2402 | 2437 | Token.Id.Keyword_promise => { |
| ... | ... | @@ -2404,14 +2439,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2404 | 2439 | .base = ast.Node { |
| 2405 | 2440 | .id = ast.Node.Id.PromiseType, |
| 2406 | 2441 | }, |
| 2407 | | .promise_token = token_index, |
| 2442 | .promise_token = token.index, |
| 2408 | 2443 | .result = null, |
| 2409 | 2444 | }); |
| 2410 | 2445 | opt_ctx.store(&node.base); |
| 2411 | | const next_token_index = tok_it.index; |
| 2412 | | const next_token_ptr = ??tok_it.next(); |
| 2446 | const next_token = nextToken(&tok_it, &tree); |
| 2447 | const next_token_index = next_token.index; |
| 2448 | const next_token_ptr = next_token.ptr; |
| 2413 | 2449 | if (next_token_ptr.id != Token.Id.Arrow) { |
| 2414 | | _ = tok_it.prev(); |
| 2450 | putBackToken(&tok_it, &tree); |
| 2415 | 2451 | continue; |
| 2416 | 2452 | } |
| 2417 | 2453 | node.result = ast.Node.PromiseType.Result { |
| ... | ... | @@ -2423,14 +2459,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2423 | 2459 | continue; |
| 2424 | 2460 | }, |
| 2425 | 2461 | Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => { |
| 2426 | | opt_ctx.store((try parseStringLiteral(arena, &tok_it, token_ptr, token_index)) ?? unreachable); |
| 2462 | opt_ctx.store((try parseStringLiteral(arena, &tok_it, token.ptr, token.index, &tree)) ?? unreachable); |
| 2427 | 2463 | continue; |
| 2428 | 2464 | }, |
| 2429 | 2465 | Token.Id.LParen => { |
| 2430 | 2466 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.GroupedExpression, |
| 2431 | 2467 | ast.Node.GroupedExpression { |
| 2432 | 2468 | .base = undefined, |
| 2433 | | .lparen = token_index, |
| 2469 | .lparen = token.index, |
| 2434 | 2470 | .expr = undefined, |
| 2435 | 2471 | .rparen = undefined, |
| 2436 | 2472 | } |
| ... | ... | @@ -2448,7 +2484,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2448 | 2484 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.BuiltinCall, |
| 2449 | 2485 | ast.Node.BuiltinCall { |
| 2450 | 2486 | .base = undefined, |
| 2451 | | .builtin_token = token_index, |
| 2487 | .builtin_token = token.index, |
| 2452 | 2488 | .params = ast.Node.BuiltinCall.ParamList.init(arena), |
| 2453 | 2489 | .rparen_token = undefined, |
| 2454 | 2490 | } |
| ... | ... | @@ -2467,7 +2503,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2467 | 2503 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp, |
| 2468 | 2504 | ast.Node.PrefixOp { |
| 2469 | 2505 | .base = undefined, |
| 2470 | | .op_token = token_index, |
| 2506 | .op_token = token.index, |
| 2471 | 2507 | .op = undefined, |
| 2472 | 2508 | .rhs = undefined, |
| 2473 | 2509 | } |
| ... | ... | @@ -2478,7 +2514,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2478 | 2514 | Token.Id.Keyword_error => { |
| 2479 | 2515 | stack.push(State { |
| 2480 | 2516 | .ErrorTypeOrSetDecl = ErrorTypeOrSetDeclCtx { |
| 2481 | | .error_token = token_index, |
| 2517 | .error_token = token.index, |
| 2482 | 2518 | .opt_ctx = opt_ctx |
| 2483 | 2519 | } |
| 2484 | 2520 | }) catch unreachable; |
| ... | ... | @@ -2488,7 +2524,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2488 | 2524 | stack.push(State { |
| 2489 | 2525 | .ContainerKind = ContainerKindCtx { |
| 2490 | 2526 | .opt_ctx = opt_ctx, |
| 2491 | | .ltoken = token_index, |
| 2527 | .ltoken = token.index, |
| 2492 | 2528 | .layout = ast.Node.ContainerDecl.Layout.Packed, |
| 2493 | 2529 | }, |
| 2494 | 2530 | }) catch unreachable; |
| ... | ... | @@ -2498,18 +2534,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2498 | 2534 | stack.push(State { |
| 2499 | 2535 | .ExternType = ExternTypeCtx { |
| 2500 | 2536 | .opt_ctx = opt_ctx, |
| 2501 | | .extern_token = token_index, |
| 2537 | .extern_token = token.index, |
| 2502 | 2538 | .comments = null, |
| 2503 | 2539 | }, |
| 2504 | 2540 | }) catch unreachable; |
| 2505 | 2541 | continue; |
| 2506 | 2542 | }, |
| 2507 | 2543 | Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => { |
| 2508 | | _ = tok_it.prev(); |
| 2544 | putBackToken(&tok_it, &tree); |
| 2509 | 2545 | stack.push(State { |
| 2510 | 2546 | .ContainerKind = ContainerKindCtx { |
| 2511 | 2547 | .opt_ctx = opt_ctx, |
| 2512 | | .ltoken = token_index, |
| 2548 | .ltoken = token.index, |
| 2513 | 2549 | .layout = ast.Node.ContainerDecl.Layout.Auto, |
| 2514 | 2550 | }, |
| 2515 | 2551 | }) catch unreachable; |
| ... | ... | @@ -2518,7 +2554,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2518 | 2554 | Token.Id.Identifier => { |
| 2519 | 2555 | stack.push(State { |
| 2520 | 2556 | .MaybeLabeledExpression = MaybeLabeledExpressionCtx { |
| 2521 | | .label = token_index, |
| 2557 | .label = token.index, |
| 2522 | 2558 | .opt_ctx = opt_ctx |
| 2523 | 2559 | } |
| 2524 | 2560 | }) catch unreachable; |
| ... | ... | @@ -2532,7 +2568,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2532 | 2568 | .doc_comments = null, |
| 2533 | 2569 | .visib_token = null, |
| 2534 | 2570 | .name_token = null, |
| 2535 | | .fn_token = token_index, |
| 2571 | .fn_token = token.index, |
| 2536 | 2572 | .params = ast.Node.FnProto.ParamList.init(arena), |
| 2537 | 2573 | .return_type = undefined, |
| 2538 | 2574 | .var_args_token = null, |
| ... | ... | @@ -2560,7 +2596,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2560 | 2596 | .return_type = undefined, |
| 2561 | 2597 | .var_args_token = null, |
| 2562 | 2598 | .extern_export_inline_token = null, |
| 2563 | | .cc_token = token_index, |
| 2599 | .cc_token = token.index, |
| 2564 | 2600 | .async_attr = null, |
| 2565 | 2601 | .body_node = null, |
| 2566 | 2602 | .lib_name = null, |
| ... | ... | @@ -2580,7 +2616,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2580 | 2616 | const node = try createToCtxNode(arena, opt_ctx, ast.Node.Asm, |
| 2581 | 2617 | ast.Node.Asm { |
| 2582 | 2618 | .base = undefined, |
| 2583 | | .asm_token = token_index, |
| 2619 | .asm_token = token.index, |
| 2584 | 2620 | .volatile_token = null, |
| 2585 | 2621 | .template = undefined, |
| 2586 | 2622 | .outputs = ast.Node.Asm.OutputList.init(arena), |
| ... | ... | @@ -2614,18 +2650,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2614 | 2650 | stack.push(State { |
| 2615 | 2651 | .Inline = InlineCtx { |
| 2616 | 2652 | .label = null, |
| 2617 | | .inline_token = token_index, |
| 2653 | .inline_token = token.index, |
| 2618 | 2654 | .opt_ctx = opt_ctx, |
| 2619 | 2655 | } |
| 2620 | 2656 | }) catch unreachable; |
| 2621 | 2657 | continue; |
| 2622 | 2658 | }, |
| 2623 | 2659 | else => { |
| 2624 | | if (!try parseBlockExpr(&stack, arena, opt_ctx, token_ptr, token_index)) { |
| 2625 | | _ = tok_it.prev(); |
| 2660 | if (!try parseBlockExpr(&stack, arena, opt_ctx, token.ptr, token.index)) { |
| 2661 | putBackToken(&tok_it, &tree); |
| 2626 | 2662 | if (opt_ctx != OptionalCtx.Optional) { |
| 2627 | 2663 | *(try tree.errors.addOne()) = Error { |
| 2628 | | .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr { .token = token_index }, |
| 2664 | .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr { .token = token.index }, |
| 2629 | 2665 | }; |
| 2630 | 2666 | return tree; |
| 2631 | 2667 | } |
| ... | ... | @@ -2637,7 +2673,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2637 | 2673 | |
| 2638 | 2674 | |
| 2639 | 2675 | State.ErrorTypeOrSetDecl => |ctx| { |
| 2640 | | if (eatToken(&tok_it, Token.Id.LBrace) == null) { |
| 2676 | if (eatToken(&tok_it, &tree, Token.Id.LBrace) == null) { |
| 2641 | 2677 | _ = try createToCtxLiteral(arena, ctx.opt_ctx, ast.Node.ErrorType, ctx.error_token); |
| 2642 | 2678 | continue; |
| 2643 | 2679 | } |
| ... | ... | @@ -2661,11 +2697,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2661 | 2697 | continue; |
| 2662 | 2698 | }, |
| 2663 | 2699 | State.StringLiteral => |opt_ctx| { |
| 2664 | | const token_index = tok_it.index; |
| 2665 | | const token_ptr = ??tok_it.next(); |
| 2700 | const token = nextToken(&tok_it, &tree); |
| 2701 | const token_index = token.index; |
| 2702 | const token_ptr = token.ptr; |
| 2666 | 2703 | opt_ctx.store( |
| 2667 | | (try parseStringLiteral(arena, &tok_it, token_ptr, token_index)) ?? { |
| 2668 | | _ = tok_it.prev(); |
| 2704 | (try parseStringLiteral(arena, &tok_it, token_ptr, token_index, &tree)) ?? { |
| 2705 | putBackToken(&tok_it, &tree); |
| 2669 | 2706 | if (opt_ctx != OptionalCtx.Optional) { |
| 2670 | 2707 | *(try tree.errors.addOne()) = Error { |
| 2671 | 2708 | .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr { .token = token_index }, |
| ... | ... | @@ -2679,14 +2716,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2679 | 2716 | }, |
| 2680 | 2717 | |
| 2681 | 2718 | State.Identifier => |opt_ctx| { |
| 2682 | | if (eatToken(&tok_it, Token.Id.Identifier)) |ident_token| { |
| 2719 | if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |ident_token| { |
| 2683 | 2720 | _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.Identifier, ident_token); |
| 2684 | 2721 | continue; |
| 2685 | 2722 | } |
| 2686 | 2723 | |
| 2687 | 2724 | if (opt_ctx != OptionalCtx.Optional) { |
| 2688 | | const token_index = tok_it.index; |
| 2689 | | const token_ptr = ??tok_it.next(); |
| 2725 | const token = nextToken(&tok_it, &tree); |
| 2726 | const token_index = token.index; |
| 2727 | const token_ptr = token.ptr; |
| 2690 | 2728 | *(try tree.errors.addOne()) = Error { |
| 2691 | 2729 | .ExpectedToken = Error.ExpectedToken { |
| 2692 | 2730 | .token = token_index, |
| ... | ... | @@ -2698,9 +2736,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2698 | 2736 | }, |
| 2699 | 2737 | |
| 2700 | 2738 | State.ErrorTag => |node_ptr| { |
| 2701 | | const comments = try eatDocComments(arena, &tok_it); |
| 2702 | | const ident_token_index = tok_it.index; |
| 2703 | | const ident_token_ptr = ??tok_it.next(); |
| 2739 | const comments = try eatDocComments(arena, &tok_it, &tree); |
| 2740 | const ident_token = nextToken(&tok_it, &tree); |
| 2741 | const ident_token_index = ident_token.index; |
| 2742 | const ident_token_ptr = ident_token.ptr; |
| 2704 | 2743 | if (ident_token_ptr.id != Token.Id.Identifier) { |
| 2705 | 2744 | *(try tree.errors.addOne()) = Error { |
| 2706 | 2745 | .ExpectedToken = Error.ExpectedToken { |
| ... | ... | @@ -2723,8 +2762,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2723 | 2762 | }, |
| 2724 | 2763 | |
| 2725 | 2764 | State.ExpectToken => |token_id| { |
| 2726 | | const token_index = tok_it.index; |
| 2727 | | const token_ptr = ??tok_it.next(); |
| 2765 | const token = nextToken(&tok_it, &tree); |
| 2766 | const token_index = token.index; |
| 2767 | const token_ptr = token.ptr; |
| 2728 | 2768 | if (token_ptr.id != token_id) { |
| 2729 | 2769 | *(try tree.errors.addOne()) = Error { |
| 2730 | 2770 | .ExpectedToken = Error.ExpectedToken { |
| ... | ... | @@ -2737,8 +2777,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2737 | 2777 | continue; |
| 2738 | 2778 | }, |
| 2739 | 2779 | State.ExpectTokenSave => |expect_token_save| { |
| 2740 | | const token_index = tok_it.index; |
| 2741 | | const token_ptr = ??tok_it.next(); |
| 2780 | const token = nextToken(&tok_it, &tree); |
| 2781 | const token_index = token.index; |
| 2782 | const token_ptr = token.ptr; |
| 2742 | 2783 | if (token_ptr.id != expect_token_save.id) { |
| 2743 | 2784 | *(try tree.errors.addOne()) = Error { |
| 2744 | 2785 | .ExpectedToken = Error.ExpectedToken { |
| ... | ... | @@ -2752,7 +2793,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2752 | 2793 | continue; |
| 2753 | 2794 | }, |
| 2754 | 2795 | State.IfToken => |token_id| { |
| 2755 | | if (eatToken(&tok_it, token_id)) |_| { |
| 2796 | if (eatToken(&tok_it, &tree, token_id)) |_| { |
| 2756 | 2797 | continue; |
| 2757 | 2798 | } |
| 2758 | 2799 | |
| ... | ... | @@ -2760,7 +2801,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2760 | 2801 | continue; |
| 2761 | 2802 | }, |
| 2762 | 2803 | State.IfTokenSave => |if_token_save| { |
| 2763 | | if (eatToken(&tok_it, if_token_save.id)) |token_index| { |
| 2804 | if (eatToken(&tok_it, &tree, if_token_save.id)) |token_index| { |
| 2764 | 2805 | *if_token_save.ptr = token_index; |
| 2765 | 2806 | continue; |
| 2766 | 2807 | } |
| ... | ... | @@ -2769,7 +2810,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree { |
| 2769 | 2810 | continue; |
| 2770 | 2811 | }, |
| 2771 | 2812 | State.OptionalTokenSave => |optional_token_save| { |
| 2772 | | if (eatToken(&tok_it, optional_token_save.id)) |token_index| { |
| 2813 | if (eatToken(&tok_it, &tree, optional_token_save.id)) |token_index| { |
| 2773 | 2814 | *optional_token_save.ptr = token_index; |
| 2774 | 2815 | continue; |
| 2775 | 2816 | } |
| ... | ... | @@ -3043,10 +3084,10 @@ const State = union(enum) { |
| 3043 | 3084 | OptionalTokenSave: OptionalTokenSave, |
| 3044 | 3085 | }; |
| 3045 | 3086 | |
| 3046 | | fn eatDocComments(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator) !?&ast.Node.DocComment { |
| 3087 | fn eatDocComments(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) !?&ast.Node.DocComment { |
| 3047 | 3088 | var result: ?&ast.Node.DocComment = null; |
| 3048 | 3089 | while (true) { |
| 3049 | | if (eatToken(tok_it, Token.Id.DocComment)) |line_comment| { |
| 3090 | if (eatToken(tok_it, tree, Token.Id.DocComment)) |line_comment| { |
| 3050 | 3091 | const node = blk: { |
| 3051 | 3092 | if (result) |comment_node| { |
| 3052 | 3093 | break :blk comment_node; |
| ... | ... | @@ -3069,8 +3110,8 @@ fn eatDocComments(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator) ! |
| 3069 | 3110 | return result; |
| 3070 | 3111 | } |
| 3071 | 3112 | |
| 3072 | | fn eatLineComment(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator) !?&ast.Node.LineComment { |
| 3073 | | const token = eatToken(tok_it, Token.Id.LineComment) ?? return null; |
| 3113 | fn eatLineComment(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) !?&ast.Node.LineComment { |
| 3114 | const token = eatToken(tok_it, tree, Token.Id.LineComment) ?? return null; |
| 3074 | 3115 | return try arena.construct(ast.Node.LineComment { |
| 3075 | 3116 | .base = ast.Node { |
| 3076 | 3117 | .id = ast.Node.Id.LineComment, |
| ... | ... | @@ -3080,7 +3121,7 @@ fn eatLineComment(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator) ! |
| 3080 | 3121 | } |
| 3081 | 3122 | |
| 3082 | 3123 | fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterator, |
| 3083 | | token_ptr: &const Token, token_index: TokenIndex) !?&ast.Node |
| 3124 | token_ptr: &const Token, token_index: TokenIndex, tree: &ast.Tree) !?&ast.Node |
| 3084 | 3125 | { |
| 3085 | 3126 | switch (token_ptr.id) { |
| 3086 | 3127 | Token.Id.StringLiteral => { |
| ... | ... | @@ -3093,10 +3134,11 @@ fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterato |
| 3093 | 3134 | }); |
| 3094 | 3135 | try node.lines.push(token_index); |
| 3095 | 3136 | while (true) { |
| 3096 | | const multiline_str_index = tok_it.index; |
| 3097 | | const multiline_str_ptr = ??tok_it.next(); |
| 3137 | const multiline_str = nextToken(tok_it, tree); |
| 3138 | const multiline_str_index = multiline_str.index; |
| 3139 | const multiline_str_ptr = multiline_str.ptr; |
| 3098 | 3140 | if (multiline_str_ptr.id != Token.Id.MultilineStringLiteralLine) { |
| 3099 | | _ = tok_it.prev(); |
| 3141 | putBackToken(tok_it, tree); |
| 3100 | 3142 | break; |
| 3101 | 3143 | } |
| 3102 | 3144 | |
| ... | ... | @@ -3230,9 +3272,10 @@ const ExpectCommaOrEndResult = union(enum) { |
| 3230 | 3272 | parse_error: Error, |
| 3231 | 3273 | }; |
| 3232 | 3274 | |
| 3233 | | fn expectCommaOrEnd(tok_it: &ast.Tree.TokenList.Iterator, end: @TagType(Token.Id)) ExpectCommaOrEndResult { |
| 3234 | | const token_index = tok_it.index; |
| 3235 | | const token_ptr = ??tok_it.next(); |
| 3275 | fn expectCommaOrEnd(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree, end: @TagType(Token.Id)) ExpectCommaOrEndResult { |
| 3276 | const token = nextToken(tok_it, tree); |
| 3277 | const token_index = token.index; |
| 3278 | const token_ptr = token.ptr; |
| 3236 | 3279 | switch (token_ptr.id) { |
| 3237 | 3280 | Token.Id.Comma => return ExpectCommaOrEndResult { .end_token = null}, |
| 3238 | 3281 | else => { |
| ... | ... | @@ -3385,16 +3428,45 @@ fn createToCtxLiteral(arena: &mem.Allocator, opt_ctx: &const OptionalCtx, compti |
| 3385 | 3428 | return node; |
| 3386 | 3429 | } |
| 3387 | 3430 | |
| 3388 | | fn eatToken(tok_it: &ast.Tree.TokenList.Iterator, id: @TagType(Token.Id)) ?TokenIndex { |
| 3389 | | const token_index = tok_it.index; |
| 3390 | | const token_ptr = ??tok_it.next(); |
| 3391 | | if (token_ptr.id == id) |
| 3392 | | return token_index; |
| 3431 | fn eatToken(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree, id: @TagType(Token.Id)) ?TokenIndex { |
| 3432 | const token = nextToken(tok_it, tree); |
| 3433 | |
| 3434 | if (token.ptr.id == id) |
| 3435 | return token.index; |
| 3393 | 3436 | |
| 3394 | | _ = tok_it.prev(); |
| 3437 | putBackToken(tok_it, tree); |
| 3395 | 3438 | return null; |
| 3396 | 3439 | } |
| 3397 | 3440 | |
| 3441 | fn nextToken(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) AnnotatedToken { |
| 3442 | const result = AnnotatedToken { |
| 3443 | .index = tok_it.index, |
| 3444 | .ptr = ??tok_it.next(), |
| 3445 | }; |
| 3446 | // possibly skip a following same line token |
| 3447 | const token = tok_it.next() ?? return result; |
| 3448 | if (token.id != Token.Id.LineComment) { |
| 3449 | putBackToken(tok_it, tree); |
| 3450 | return result; |
| 3451 | } |
| 3452 | const loc = tree.tokenLocationPtr(result.ptr.end, token); |
| 3453 | if (loc.line != 0) { |
| 3454 | putBackToken(tok_it, tree); |
| 3455 | } |
| 3456 | return result; |
| 3457 | } |
| 3458 | |
| 3459 | fn putBackToken(tok_it: &ast.Tree.TokenList.Iterator, tree: &ast.Tree) void { |
| 3460 | const prev_tok = ??tok_it.prev(); |
| 3461 | if (prev_tok.id == Token.Id.LineComment) { |
| 3462 | const minus2_tok = tok_it.prev() ?? return; |
| 3463 | const loc = tree.tokenLocationPtr(minus2_tok.end, prev_tok); |
| 3464 | if (loc.line != 0) { |
| 3465 | _ = tok_it.next(); |
| 3466 | } |
| 3467 | } |
| 3468 | } |
| 3469 | |
| 3398 | 3470 | const RenderAstFrame = struct { |
| 3399 | 3471 | node: &ast.Node, |
| 3400 | 3472 | indent: usize, |