| ... | @@ -59,12 +59,26 @@ pub const Parser = struct { | ... | @@ -59,12 +59,26 @@ pub const Parser = struct { |
| 59 | lib_name: ?&ast.Node, | 59 | lib_name: ?&ast.Node, |
| 60 | }; | 60 | }; |
| 61 | | 61 | |
| | 62 | const VarDeclCtx = struct { |
| | 63 | mut_token: Token, |
| | 64 | visib_token: ?Token, |
| | 65 | comptime_token: ?Token, |
| | 66 | extern_export_token: ?Token, |
| | 67 | lib_name: ?&ast.Node, |
| | 68 | list: &ArrayList(&ast.Node), |
| | 69 | }; |
| | 70 | |
| 62 | const TopLevelExternOrFieldCtx = struct { | 71 | const TopLevelExternOrFieldCtx = struct { |
| 63 | visib_token: Token, | 72 | visib_token: Token, |
| 64 | container_decl: &ast.NodeContainerDecl, | 73 | container_decl: &ast.NodeContainerDecl, |
| 65 | }; | 74 | }; |
| 66 | | 75 | |
| 67 | const ContainerExternCtx = struct { | 76 | const ExternTypeCtx = struct { |
| | 77 | opt_ctx: OptionalCtx, |
| | 78 | extern_token: Token, |
| | 79 | }; |
| | 80 | |
| | 81 | const ContainerKindCtx = struct { |
| 68 | opt_ctx: OptionalCtx, | 82 | opt_ctx: OptionalCtx, |
| 69 | ltoken: Token, | 83 | ltoken: Token, |
| 70 | layout: ast.NodeContainerDecl.Layout, | 84 | layout: ast.NodeContainerDecl.Layout, |
| ... | @@ -80,15 +94,6 @@ pub const Parser = struct { | ... | @@ -80,15 +94,6 @@ pub const Parser = struct { |
| 80 | ptr: &?Token, | 94 | ptr: &?Token, |
| 81 | }; | 95 | }; |
| 82 | | 96 | |
| 83 | const RevertState = struct { | | |
| 84 | parser: Parser, | | |
| 85 | tokenizer: Tokenizer, | | |
| 86 | | | |
| 87 | // We expect, that if something is optional, then there is a field, | | |
| 88 | // that needs to be set to null, when we revert. | | |
| 89 | ptr: &?&ast.Node, | | |
| 90 | }; | | |
| 91 | | | |
| 92 | const ExprListCtx = struct { | 97 | const ExprListCtx = struct { |
| 93 | list: &ArrayList(&ast.Node), | 98 | list: &ArrayList(&ast.Node), |
| 94 | end: Token.Id, | 99 | end: Token.Id, |
| ... | @@ -102,6 +107,11 @@ pub const Parser = struct { | ... | @@ -102,6 +107,11 @@ pub const Parser = struct { |
| 102 | }; | 107 | }; |
| 103 | } | 108 | } |
| 104 | | 109 | |
| | 110 | const MaybeLabeledExpressionCtx = struct { |
| | 111 | label: Token, |
| | 112 | opt_ctx: OptionalCtx, |
| | 113 | }; |
| | 114 | |
| 105 | const LabelCtx = struct { | 115 | const LabelCtx = struct { |
| 106 | label: ?Token, | 116 | label: ?Token, |
| 107 | opt_ctx: OptionalCtx, | 117 | opt_ctx: OptionalCtx, |
| ... | @@ -179,12 +189,12 @@ pub const Parser = struct { | ... | @@ -179,12 +189,12 @@ pub const Parser = struct { |
| 179 | TopLevelDecl: TopLevelDeclCtx, | 189 | TopLevelDecl: TopLevelDeclCtx, |
| 180 | TopLevelExternOrField: TopLevelExternOrFieldCtx, | 190 | TopLevelExternOrField: TopLevelExternOrFieldCtx, |
| 181 | | 191 | |
| 182 | ContainerExtern: ContainerExternCtx, | 192 | ContainerKind: ContainerKindCtx, |
| 183 | ContainerInitArgStart: &ast.NodeContainerDecl, | 193 | ContainerInitArgStart: &ast.NodeContainerDecl, |
| 184 | ContainerInitArg: &ast.NodeContainerDecl, | 194 | ContainerInitArg: &ast.NodeContainerDecl, |
| 185 | ContainerDecl: &ast.NodeContainerDecl, | 195 | ContainerDecl: &ast.NodeContainerDecl, |
| 186 | | 196 | |
| 187 | VarDecl: &ast.NodeVarDecl, | 197 | VarDecl: VarDeclCtx, |
| 188 | VarDeclAlign: &ast.NodeVarDecl, | 198 | VarDeclAlign: &ast.NodeVarDecl, |
| 189 | VarDeclEq: &ast.NodeVarDecl, | 199 | VarDeclEq: &ast.NodeVarDecl, |
| 190 | | 200 | |
| ... | @@ -199,6 +209,7 @@ pub const Parser = struct { | ... | @@ -199,6 +209,7 @@ pub const Parser = struct { |
| 199 | ParamDeclEnd: ParamDeclEndCtx, | 209 | ParamDeclEnd: ParamDeclEndCtx, |
| 200 | ParamDeclComma: &ast.NodeFnProto, | 210 | ParamDeclComma: &ast.NodeFnProto, |
| 201 | | 211 | |
| | 212 | MaybeLabeledExpression: MaybeLabeledExpressionCtx, |
| 202 | LabeledExpression: LabelCtx, | 213 | LabeledExpression: LabelCtx, |
| 203 | Inline: InlineCtx, | 214 | Inline: InlineCtx, |
| 204 | While: LoopCtx, | 215 | While: LoopCtx, |
| ... | @@ -209,7 +220,7 @@ pub const Parser = struct { | ... | @@ -209,7 +220,7 @@ pub const Parser = struct { |
| 209 | Block: &ast.NodeBlock, | 220 | Block: &ast.NodeBlock, |
| 210 | Statement: &ast.NodeBlock, | 221 | Statement: &ast.NodeBlock, |
| 211 | ComptimeStatement: ComptimeStatementCtx, | 222 | ComptimeStatement: ComptimeStatementCtx, |
| 212 | Semicolon: &const &const ast.Node, | 223 | Semicolon: &&ast.Node, |
| 213 | | 224 | |
| 214 | AsmOutputItems: &ArrayList(&ast.NodeAsmOutput), | 225 | AsmOutputItems: &ArrayList(&ast.NodeAsmOutput), |
| 215 | AsmOutputReturnOrType: &ast.NodeAsmOutput, | 226 | AsmOutputReturnOrType: &ast.NodeAsmOutput, |
| ... | @@ -233,6 +244,7 @@ pub const Parser = struct { | ... | @@ -233,6 +244,7 @@ pub const Parser = struct { |
| 233 | AsyncAllocator: &ast.NodeAsyncAttribute, | 244 | AsyncAllocator: &ast.NodeAsyncAttribute, |
| 234 | AsyncEnd: AsyncEndCtx, | 245 | AsyncEnd: AsyncEndCtx, |
| 235 | | 246 | |
| | 247 | ExternType: ExternTypeCtx, |
| 236 | SliceOrArrayAccess: &ast.NodeSuffixOp, | 248 | SliceOrArrayAccess: &ast.NodeSuffixOp, |
| 237 | SliceOrArrayType: &ast.NodePrefixOp, | 249 | SliceOrArrayType: &ast.NodePrefixOp, |
| 238 | AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo, | 250 | AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo, |
| ... | @@ -491,6 +503,7 @@ pub const Parser = struct { | ... | @@ -491,6 +503,7 @@ pub const Parser = struct { |
| 491 | .lib_name = lib_name, | 503 | .lib_name = lib_name, |
| 492 | }, | 504 | }, |
| 493 | }) catch unreachable; | 505 | }) catch unreachable; |
| | 506 | continue; |
| 494 | }, | 507 | }, |
| 495 | State.TopLevelDecl => |ctx| { | 508 | State.TopLevelDecl => |ctx| { |
| 496 | const token = self.getNextToken(); | 509 | const token = self.getNextToken(); |
| ... | @@ -524,49 +537,20 @@ pub const Parser = struct { | ... | @@ -524,49 +537,20 @@ pub const Parser = struct { |
| 524 | } | 537 | } |
| 525 | } | 538 | } |
| 526 | | 539 | |
| 527 | const var_decl_node = try self.createAttachNode(arena, ctx.decls, ast.NodeVarDecl, | 540 | stack.append(State { |
| 528 | ast.NodeVarDecl { | 541 | .VarDecl = VarDeclCtx { |
| 529 | .base = undefined, | | |
| 530 | .visib_token = ctx.visib_token, | 542 | .visib_token = ctx.visib_token, |
| 531 | .mut_token = token, | 543 | .lib_name = ctx.lib_name, |
| 532 | .comptime_token = null, | 544 | .comptime_token = null, |
| 533 | .extern_export_token = ctx.extern_export_inline_token, | 545 | .extern_export_token = ctx.extern_export_inline_token, |
| 534 | .type_node = null, | 546 | .mut_token = token, |
| 535 | .align_node = null, | 547 | .list = ctx.decls |
| 536 | .init_node = null, | | |
| 537 | .lib_name = ctx.lib_name, | | |
| 538 | // initialized later | | |
| 539 | .name_token = undefined, | | |
| 540 | .eq_token = undefined, | | |
| 541 | .semicolon_token = undefined, | | |
| 542 | } | | |
| 543 | ); | | |
| 544 | stack.append(State { .VarDecl = var_decl_node }) catch unreachable; | | |
| 545 | continue; | | |
| 546 | }, | | |
| 547 | Token.Id.Keyword_fn => { | | |
| 548 | const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto, | | |
| 549 | ast.NodeFnProto { | | |
| 550 | .base = undefined, | | |
| 551 | .visib_token = ctx.visib_token, | | |
| 552 | .name_token = null, | | |
| 553 | .fn_token = token, | | |
| 554 | .params = ArrayList(&ast.Node).init(arena), | | |
| 555 | .return_type = undefined, | | |
| 556 | .var_args_token = null, | | |
| 557 | .extern_export_inline_token = ctx.extern_export_inline_token, | | |
| 558 | .cc_token = null, | | |
| 559 | .async_attr = null, | | |
| 560 | .body_node = null, | | |
| 561 | .lib_name = ctx.lib_name, | | |
| 562 | .align_expr = null, | | |
| 563 | } | 548 | } |
| 564 | ); | 549 | }) catch unreachable; |
| 565 | stack.append(State { .FnDef = fn_proto }) catch unreachable; | | |
| 566 | try stack.append(State { .FnProto = fn_proto }); | | |
| 567 | continue; | 550 | continue; |
| 568 | }, | 551 | }, |
| 569 | Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => { | 552 | Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc, |
| | 553 | Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => { |
| 570 | const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto, | 554 | const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto, |
| 571 | ast.NodeFnProto { | 555 | ast.NodeFnProto { |
| 572 | .base = undefined, | 556 | .base = undefined, |
| ... | @@ -577,7 +561,7 @@ pub const Parser = struct { | ... | @@ -577,7 +561,7 @@ pub const Parser = struct { |
| 577 | .return_type = undefined, | 561 | .return_type = undefined, |
| 578 | .var_args_token = null, | 562 | .var_args_token = null, |
| 579 | .extern_export_inline_token = ctx.extern_export_inline_token, | 563 | .extern_export_inline_token = ctx.extern_export_inline_token, |
| 580 | .cc_token = token, | 564 | .cc_token = null, |
| 581 | .async_attr = null, | 565 | .async_attr = null, |
| 582 | .body_node = null, | 566 | .body_node = null, |
| 583 | .lib_name = ctx.lib_name, | 567 | .lib_name = ctx.lib_name, |
| ... | @@ -586,52 +570,44 @@ pub const Parser = struct { | ... | @@ -586,52 +570,44 @@ pub const Parser = struct { |
| 586 | ); | 570 | ); |
| 587 | stack.append(State { .FnDef = fn_proto }) catch unreachable; | 571 | stack.append(State { .FnDef = fn_proto }) catch unreachable; |
| 588 | try stack.append(State { .FnProto = fn_proto }); | 572 | try stack.append(State { .FnProto = fn_proto }); |
| 589 | try stack.append(State { | | |
| 590 | .ExpectTokenSave = ExpectTokenSave { | | |
| 591 | .id = Token.Id.Keyword_fn, | | |
| 592 | .ptr = &fn_proto.fn_token, | | |
| 593 | } | | |
| 594 | }); | | |
| 595 | continue; | | |
| 596 | }, | | |
| 597 | Token.Id.Keyword_async => { | | |
| 598 | const async_node = try self.createNode(arena, ast.NodeAsyncAttribute, | | |
| 599 | ast.NodeAsyncAttribute { | | |
| 600 | .base = undefined, | | |
| 601 | .async_token = token, | | |
| 602 | .allocator_type = null, | | |
| 603 | .rangle_bracket = null, | | |
| 604 | } | | |
| 605 | ); | | |
| 606 | | 573 | |
| 607 | const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto, | 574 | switch (token.id) { |
| 608 | ast.NodeFnProto { | 575 | Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => { |
| 609 | .base = undefined, | 576 | fn_proto.cc_token = token; |
| 610 | .visib_token = ctx.visib_token, | 577 | try stack.append(State { |
| 611 | .name_token = null, | 578 | .ExpectTokenSave = ExpectTokenSave { |
| 612 | .fn_token = undefined, | 579 | .id = Token.Id.Keyword_fn, |
| 613 | .params = ArrayList(&ast.Node).init(arena), | 580 | .ptr = &fn_proto.fn_token, |
| 614 | .return_type = undefined, | 581 | } |
| 615 | .var_args_token = null, | 582 | }); |
| 616 | .extern_export_inline_token = ctx.extern_export_inline_token, | 583 | continue; |
| 617 | .cc_token = null, | 584 | }, |
| 618 | .async_attr = async_node, | 585 | Token.Id.Keyword_async => { |
| 619 | .body_node = null, | 586 | const async_node = try self.createNode(arena, ast.NodeAsyncAttribute, |
| 620 | .lib_name = ctx.lib_name, | 587 | ast.NodeAsyncAttribute { |
| 621 | .align_expr = null, | 588 | .base = undefined, |
| 622 | } | 589 | .async_token = token, |
| 623 | ); | 590 | .allocator_type = null, |
| 624 | stack.append(State { .FnDef = fn_proto }) catch unreachable; | 591 | .rangle_bracket = null, |
| 625 | try stack.append(State { .FnProto = fn_proto }); | 592 | } |
| 626 | try stack.append(State { | 593 | ); |
| 627 | .ExpectTokenSave = ExpectTokenSave { | 594 | fn_proto.async_attr = async_node; |
| 628 | .id = Token.Id.Keyword_fn, | | |
| 629 | .ptr = &fn_proto.fn_token, | | |
| 630 | } | | |
| 631 | }); | | |
| 632 | | 595 | |
| 633 | try stack.append(State { .AsyncAllocator = async_node }); | 596 | try stack.append(State { |
| 634 | continue; | 597 | .ExpectTokenSave = ExpectTokenSave { |
| | 598 | .id = Token.Id.Keyword_fn, |
| | 599 | .ptr = &fn_proto.fn_token, |
| | 600 | } |
| | 601 | }); |
| | 602 | try stack.append(State { .AsyncAllocator = async_node }); |
| | 603 | continue; |
| | 604 | }, |
| | 605 | Token.Id.Keyword_fn => { |
| | 606 | fn_proto.fn_token = token; |
| | 607 | continue; |
| | 608 | }, |
| | 609 | else => unreachable, |
| | 610 | } |
| 635 | }, | 611 | }, |
| 636 | else => { | 612 | else => { |
| 637 | return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)); | 613 | return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)); |
| ... | @@ -669,7 +645,7 @@ pub const Parser = struct { | ... | @@ -669,7 +645,7 @@ pub const Parser = struct { |
| 669 | }, | 645 | }, |
| 670 | | 646 | |
| 671 | | 647 | |
| 672 | State.ContainerExtern => |ctx| { | 648 | State.ContainerKind => |ctx| { |
| 673 | const token = self.getNextToken(); | 649 | const token = self.getNextToken(); |
| 674 | const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeContainerDecl, | 650 | const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeContainerDecl, |
| 675 | ast.NodeContainerDecl { | 651 | ast.NodeContainerDecl { |
| ... | @@ -697,6 +673,7 @@ pub const Parser = struct { | ... | @@ -697,6 +673,7 @@ pub const Parser = struct { |
| 697 | stack.append(State { .ContainerDecl = node }) catch unreachable; | 673 | stack.append(State { .ContainerDecl = node }) catch unreachable; |
| 698 | try stack.append(State { .ExpectToken = Token.Id.LBrace }); | 674 | try stack.append(State { .ExpectToken = Token.Id.LBrace }); |
| 699 | try stack.append(State { .ContainerInitArgStart = node }); | 675 | try stack.append(State { .ContainerInitArgStart = node }); |
| | 676 | continue; |
| 700 | }, | 677 | }, |
| 701 | | 678 | |
| 702 | State.ContainerInitArgStart => |container_decl| { | 679 | State.ContainerInitArgStart => |container_decl| { |
| ... | @@ -706,6 +683,7 @@ pub const Parser = struct { | ... | @@ -706,6 +683,7 @@ pub const Parser = struct { |
| 706 | | 683 | |
| 707 | stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable; | 684 | stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable; |
| 708 | try stack.append(State { .ContainerInitArg = container_decl }); | 685 | try stack.append(State { .ContainerInitArg = container_decl }); |
| | 686 | continue; |
| 709 | }, | 687 | }, |
| 710 | | 688 | |
| 711 | State.ContainerInitArg => |container_decl| { | 689 | State.ContainerInitArg => |container_decl| { |
| ... | @@ -781,6 +759,7 @@ pub const Parser = struct { | ... | @@ -781,6 +759,7 @@ pub const Parser = struct { |
| 781 | .container_decl = container_decl, | 759 | .container_decl = container_decl, |
| 782 | } | 760 | } |
| 783 | }); | 761 | }); |
| | 762 | continue; |
| 784 | }, | 763 | }, |
| 785 | else => { | 764 | else => { |
| 786 | stack.append(State{ .ContainerDecl = container_decl }) catch unreachable; | 765 | stack.append(State{ .ContainerDecl = container_decl }) catch unreachable; |
| ... | @@ -792,6 +771,7 @@ pub const Parser = struct { | ... | @@ -792,6 +771,7 @@ pub const Parser = struct { |
| 792 | .lib_name = null, | 771 | .lib_name = null, |
| 793 | } | 772 | } |
| 794 | }); | 773 | }); |
| | 774 | continue; |
| 795 | } | 775 | } |
| 796 | } | 776 | } |
| 797 | }, | 777 | }, |
| ... | @@ -828,7 +808,25 @@ pub const Parser = struct { | ... | @@ -828,7 +808,25 @@ pub const Parser = struct { |
| 828 | }, | 808 | }, |
| 829 | | 809 | |
| 830 | | 810 | |
| 831 | State.VarDecl => |var_decl| { | 811 | State.VarDecl => |ctx| { |
| | 812 | const var_decl = try self.createAttachNode(arena, ctx.list, ast.NodeVarDecl, |
| | 813 | ast.NodeVarDecl { |
| | 814 | .base = undefined, |
| | 815 | .visib_token = ctx.visib_token, |
| | 816 | .mut_token = ctx.mut_token, |
| | 817 | .comptime_token = ctx.comptime_token, |
| | 818 | .extern_export_token = ctx.extern_export_token, |
| | 819 | .type_node = null, |
| | 820 | .align_node = null, |
| | 821 | .init_node = null, |
| | 822 | .lib_name = ctx.lib_name, |
| | 823 | // initialized later |
| | 824 | .name_token = undefined, |
| | 825 | .eq_token = undefined, |
| | 826 | .semicolon_token = undefined, |
| | 827 | } |
| | 828 | ); |
| | 829 | |
| 832 | stack.append(State { .VarDeclAlign = var_decl }) catch unreachable; | 830 | stack.append(State { .VarDeclAlign = var_decl }) catch unreachable; |
| 833 | try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} }); | 831 | try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} }); |
| 834 | try stack.append(State { .IfToken = Token.Id.Colon }); | 832 | try stack.append(State { .IfToken = Token.Id.Colon }); |
| ... | @@ -907,12 +905,9 @@ pub const Parser = struct { | ... | @@ -907,12 +905,9 @@ pub const Parser = struct { |
| 907 | try stack.append(State { .ParamDecl = fn_proto }); | 905 | try stack.append(State { .ParamDecl = fn_proto }); |
| 908 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | 906 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 909 | | 907 | |
| 910 | const next_token = self.getNextToken(); | 908 | if (self.eatToken(Token.Id.Identifier)) |name_token| { |
| 911 | if (next_token.id == Token.Id.Identifier) { | 909 | fn_proto.name_token = name_token; |
| 912 | fn_proto.name_token = next_token; | | |
| 913 | continue; | | |
| 914 | } | 910 | } |
| 915 | self.putBackToken(next_token); | | |
| 916 | continue; | 911 | continue; |
| 917 | }, | 912 | }, |
| 918 | State.FnProtoAlign => |fn_proto| { | 913 | State.FnProtoAlign => |fn_proto| { |
| ... | @@ -923,7 +918,6 @@ pub const Parser = struct { | ... | @@ -923,7 +918,6 @@ pub const Parser = struct { |
| 923 | try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } }); | 918 | try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } }); |
| 924 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | 919 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 925 | } | 920 | } |
| 926 | | | |
| 927 | continue; | 921 | continue; |
| 928 | }, | 922 | }, |
| 929 | State.FnProtoReturnType => |fn_proto| { | 923 | State.FnProtoReturnType => |fn_proto| { |
| ... | @@ -987,6 +981,7 @@ pub const Parser = struct { | ... | @@ -987,6 +981,7 @@ pub const Parser = struct { |
| 987 | } else if (self.eatToken(Token.Id.Keyword_noalias)) |noalias_token| { | 981 | } else if (self.eatToken(Token.Id.Keyword_noalias)) |noalias_token| { |
| 988 | param_decl.noalias_token = noalias_token; | 982 | param_decl.noalias_token = noalias_token; |
| 989 | } | 983 | } |
| | 984 | continue; |
| 990 | }, | 985 | }, |
| 991 | State.ParamDeclName => |param_decl| { | 986 | State.ParamDeclName => |param_decl| { |
| 992 | // TODO: Here, we eat two tokens in one state. This means that we can't have | 987 | // TODO: Here, we eat two tokens in one state. This means that we can't have |
| ... | @@ -998,6 +993,7 @@ pub const Parser = struct { | ... | @@ -998,6 +993,7 @@ pub const Parser = struct { |
| 998 | self.putBackToken(ident_token); | 993 | self.putBackToken(ident_token); |
| 999 | } | 994 | } |
| 1000 | } | 995 | } |
| | 996 | continue; |
| 1001 | }, | 997 | }, |
| 1002 | State.ParamDeclEnd => |ctx| { | 998 | State.ParamDeclEnd => |ctx| { |
| 1003 | if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| { | 999 | if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| { |
| ... | @@ -1010,6 +1006,7 @@ pub const Parser = struct { | ... | @@ -1010,6 +1006,7 @@ pub const Parser = struct { |
| 1010 | try stack.append(State { | 1006 | try stack.append(State { |
| 1011 | .TypeExprBegin = OptionalCtx { .Required = &ctx.param_decl.type_node } | 1007 | .TypeExprBegin = OptionalCtx { .Required = &ctx.param_decl.type_node } |
| 1012 | }); | 1008 | }); |
| | 1009 | continue; |
| 1013 | }, | 1010 | }, |
| 1014 | State.ParamDeclComma => |fn_proto| { | 1011 | State.ParamDeclComma => |fn_proto| { |
| 1015 | if ((try self.expectCommaOrEnd(Token.Id.RParen)) == null) { | 1012 | if ((try self.expectCommaOrEnd(Token.Id.RParen)) == null) { |
| ... | @@ -1018,7 +1015,20 @@ pub const Parser = struct { | ... | @@ -1018,7 +1015,20 @@ pub const Parser = struct { |
| 1018 | continue; | 1015 | continue; |
| 1019 | }, | 1016 | }, |
| 1020 | | 1017 | |
| | 1018 | State.MaybeLabeledExpression => |ctx| { |
| | 1019 | if (self.eatToken(Token.Id.Colon)) |_| { |
| | 1020 | stack.append(State { |
| | 1021 | .LabeledExpression = LabelCtx { |
| | 1022 | .label = ctx.label, |
| | 1023 | .opt_ctx = ctx.opt_ctx, |
| | 1024 | } |
| | 1025 | }) catch unreachable; |
| | 1026 | continue; |
| | 1027 | } |
| 1021 | | 1028 | |
| | 1029 | _ = try self.createToCtxLiteral(arena, ctx.opt_ctx, ast.NodeIdentifier, ctx.label); |
| | 1030 | continue; |
| | 1031 | }, |
| 1022 | State.LabeledExpression => |ctx| { | 1032 | State.LabeledExpression => |ctx| { |
| 1023 | const token = self.getNextToken(); | 1033 | const token = self.getNextToken(); |
| 1024 | switch (token.id) { | 1034 | switch (token.id) { |
| ... | @@ -1134,11 +1144,13 @@ pub const Parser = struct { | ... | @@ -1134,11 +1144,13 @@ pub const Parser = struct { |
| 1134 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | 1144 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1135 | try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } }); | 1145 | try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } }); |
| 1136 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | 1146 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| | 1147 | continue; |
| 1137 | }, | 1148 | }, |
| 1138 | State.WhileContinueExpr => |dest| { | 1149 | State.WhileContinueExpr => |dest| { |
| 1139 | stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable; | 1150 | stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable; |
| 1140 | try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = dest } }); | 1151 | try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = dest } }); |
| 1141 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | 1152 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| | 1153 | continue; |
| 1142 | }, | 1154 | }, |
| 1143 | State.For => |ctx| { | 1155 | State.For => |ctx| { |
| 1144 | const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeFor, | 1156 | const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeFor, |
| ... | @@ -1159,26 +1171,26 @@ pub const Parser = struct { | ... | @@ -1159,26 +1171,26 @@ pub const Parser = struct { |
| 1159 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | 1171 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1160 | try stack.append(State { .Expression = OptionalCtx { .Required = &node.array_expr } }); | 1172 | try stack.append(State { .Expression = OptionalCtx { .Required = &node.array_expr } }); |
| 1161 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | 1173 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| | 1174 | continue; |
| 1162 | }, | 1175 | }, |
| 1163 | State.Else => |dest| { | 1176 | State.Else => |dest| { |
| 1164 | const else_token = self.getNextToken(); | 1177 | if (self.eatToken(Token.Id.Keyword_else)) |else_token| { |
| 1165 | if (else_token.id != Token.Id.Keyword_else) { | 1178 | const node = try self.createNode(arena, ast.NodeElse, |
| 1166 | self.putBackToken(else_token); | 1179 | ast.NodeElse { |
| | 1180 | .base = undefined, |
| | 1181 | .else_token = else_token, |
| | 1182 | .payload = null, |
| | 1183 | .body = undefined, |
| | 1184 | } |
| | 1185 | ); |
| | 1186 | *dest = node; |
| | 1187 | |
| | 1188 | stack.append(State { .Expression = OptionalCtx { .Required = &node.body } }) catch unreachable; |
| | 1189 | try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } }); |
| | 1190 | continue; |
| | 1191 | } else { |
| 1167 | continue; | 1192 | continue; |
| 1168 | } | 1193 | } |
| 1169 | | | |
| 1170 | const node = try self.createNode(arena, ast.NodeElse, | | |
| 1171 | ast.NodeElse { | | |
| 1172 | .base = undefined, | | |
| 1173 | .else_token = else_token, | | |
| 1174 | .payload = null, | | |
| 1175 | .body = undefined, | | |
| 1176 | } | | |
| 1177 | ); | | |
| 1178 | *dest = node; | | |
| 1179 | | | |
| 1180 | stack.append(State { .Expression = OptionalCtx { .Required = &node.body } }) catch unreachable; | | |
| 1181 | try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } }); | | |
| 1182 | }, | 1194 | }, |
| 1183 | | 1195 | |
| 1184 | | 1196 | |
| ... | @@ -1207,26 +1219,19 @@ pub const Parser = struct { | ... | @@ -1207,26 +1219,19 @@ pub const Parser = struct { |
| 1207 | .block = block, | 1219 | .block = block, |
| 1208 | } | 1220 | } |
| 1209 | }) catch unreachable; | 1221 | }) catch unreachable; |
| | 1222 | continue; |
| 1210 | }, | 1223 | }, |
| 1211 | Token.Id.Keyword_var, Token.Id.Keyword_const => { | 1224 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 1212 | const var_decl = try self.createAttachNode(arena, &block.statements, ast.NodeVarDecl, | 1225 | stack.append(State { |
| 1213 | ast.NodeVarDecl { | 1226 | .VarDecl = VarDeclCtx { |
| 1214 | .base = undefined, | | |
| 1215 | .visib_token = null, | 1227 | .visib_token = null, |
| 1216 | .mut_token = token, | | |
| 1217 | .comptime_token = null, | 1228 | .comptime_token = null, |
| 1218 | .extern_export_token = null, | 1229 | .extern_export_token = null, |
| 1219 | .type_node = null, | | |
| 1220 | .align_node = null, | | |
| 1221 | .init_node = null, | | |
| 1222 | .lib_name = null, | 1230 | .lib_name = null, |
| 1223 | // initialized later | 1231 | .mut_token = token, |
| 1224 | .name_token = undefined, | 1232 | .list = &block.statements, |
| 1225 | .eq_token = undefined, | | |
| 1226 | .semicolon_token = undefined, | | |
| 1227 | } | 1233 | } |
| 1228 | ); | 1234 | }) catch unreachable; |
| 1229 | stack.append(State { .VarDecl = var_decl }) catch unreachable; | | |
| 1230 | continue; | 1235 | continue; |
| 1231 | }, | 1236 | }, |
| 1232 | Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => { | 1237 | Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => { |
| ... | @@ -1242,7 +1247,7 @@ pub const Parser = struct { | ... | @@ -1242,7 +1247,7 @@ pub const Parser = struct { |
| 1242 | .expr = undefined, | 1247 | .expr = undefined, |
| 1243 | } | 1248 | } |
| 1244 | ); | 1249 | ); |
| 1245 | stack.append(State { .Semicolon = &node.base }) catch unreachable; | 1250 | stack.append(State { .Semicolon = &&node.base }) catch unreachable; |
| 1246 | try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } }); | 1251 | try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } }); |
| 1247 | continue; | 1252 | continue; |
| 1248 | }, | 1253 | }, |
| ... | @@ -1270,40 +1275,37 @@ pub const Parser = struct { | ... | @@ -1270,40 +1275,37 @@ pub const Parser = struct { |
| 1270 | }, | 1275 | }, |
| 1271 | State.ComptimeStatement => |ctx| { | 1276 | State.ComptimeStatement => |ctx| { |
| 1272 | const token = self.getNextToken(); | 1277 | const token = self.getNextToken(); |
| 1273 | if (token.id == Token.Id.Keyword_var or token.id == Token.Id.Keyword_const) { | 1278 | switch (token.id) { |
| 1274 | const var_decl = try self.createAttachNode(arena, &ctx.block.statements, ast.NodeVarDecl, | 1279 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 1275 | ast.NodeVarDecl { | 1280 | stack.append(State { |
| 1276 | .base = undefined, | 1281 | .VarDecl = VarDeclCtx { |
| 1277 | .visib_token = null, | 1282 | .visib_token = null, |
| 1278 | .mut_token = token, | 1283 | .comptime_token = ctx.comptime_token, |
| 1279 | .comptime_token = ctx.comptime_token, | 1284 | .extern_export_token = null, |
| 1280 | .extern_export_token = null, | 1285 | .lib_name = null, |
| 1281 | .type_node = null, | 1286 | .mut_token = token, |
| 1282 | .align_node = null, | 1287 | .list = &ctx.block.statements, |
| 1283 | .init_node = null, | 1288 | } |
| 1284 | .lib_name = null, | 1289 | }) catch unreachable; |
| 1285 | // initialized later | 1290 | continue; |
| 1286 | .name_token = undefined, | 1291 | }, |
| 1287 | .eq_token = undefined, | 1292 | else => { |
| 1288 | .semicolon_token = undefined, | 1293 | self.putBackToken(token); |
| 1289 | } | 1294 | self.putBackToken(ctx.comptime_token); |
| 1290 | ); | 1295 | const statememt = try ctx.block.statements.addOne(); |
| 1291 | stack.append(State { .VarDecl = var_decl }) catch unreachable; | 1296 | stack.append(State { .Semicolon = statememt }) catch unreachable; |
| 1292 | continue; | 1297 | try stack.append(State { .Expression = OptionalCtx { .Required = statememt } }); |
| 1293 | } else { | 1298 | continue; |
| 1294 | self.putBackToken(token); | 1299 | } |
| 1295 | self.putBackToken(ctx.comptime_token); | | |
| 1296 | const statememt = try ctx.block.statements.addOne(); | | |
| 1297 | stack.append(State { .Semicolon = statememt }) catch unreachable; | | |
| 1298 | try stack.append(State { .Expression = OptionalCtx { .Required = statememt } }); | | |
| 1299 | continue; | | |
| 1300 | } | 1300 | } |
| 1301 | }, | 1301 | }, |
| 1302 | State.Semicolon => |node_ptr| { | 1302 | State.Semicolon => |node_ptr| { |
| 1303 | const node = *node_ptr; | 1303 | const node = *node_ptr; |
| 1304 | if (requireSemiColon(node)) { | 1304 | if (requireSemiColon(node)) { |
| 1305 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; | 1305 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; |
| | 1306 | continue; |
| 1306 | } | 1307 | } |
| | 1308 | continue; |
| 1307 | }, | 1309 | }, |
| 1308 | | 1310 | |
| 1309 | | 1311 | |
| ... | @@ -1332,6 +1334,7 @@ pub const Parser = struct { | ... | @@ -1332,6 +1334,7 @@ pub const Parser = struct { |
| 1332 | try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } }); | 1334 | try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } }); |
| 1333 | try stack.append(State { .ExpectToken = Token.Id.RBracket }); | 1335 | try stack.append(State { .ExpectToken = Token.Id.RBracket }); |
| 1334 | try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } }); | 1336 | try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } }); |
| | 1337 | continue; |
| 1335 | }, | 1338 | }, |
| 1336 | State.AsmOutputReturnOrType => |node| { | 1339 | State.AsmOutputReturnOrType => |node| { |
| 1337 | const token = self.getNextToken(); | 1340 | const token = self.getNextToken(); |
| ... | @@ -1377,11 +1380,13 @@ pub const Parser = struct { | ... | @@ -1377,11 +1380,13 @@ pub const Parser = struct { |
| 1377 | try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } }); | 1380 | try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } }); |
| 1378 | try stack.append(State { .ExpectToken = Token.Id.RBracket }); | 1381 | try stack.append(State { .ExpectToken = Token.Id.RBracket }); |
| 1379 | try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } }); | 1382 | try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } }); |
| | 1383 | continue; |
| 1380 | }, | 1384 | }, |
| 1381 | State.AsmClopperItems => |items| { | 1385 | State.AsmClopperItems => |items| { |
| 1382 | stack.append(State { .AsmClopperItems = items }) catch unreachable; | 1386 | stack.append(State { .AsmClopperItems = items }) catch unreachable; |
| 1383 | try stack.append(State { .IfToken = Token.Id.Comma }); | 1387 | try stack.append(State { .IfToken = Token.Id.Comma }); |
| 1384 | try stack.append(State { .StringLiteral = OptionalCtx { .Required = try items.addOne() } }); | 1388 | try stack.append(State { .StringLiteral = OptionalCtx { .Required = try items.addOne() } }); |
| | 1389 | continue; |
| 1385 | }, | 1390 | }, |
| 1386 | | 1391 | |
| 1387 | | 1392 | |
| ... | @@ -1393,14 +1398,16 @@ pub const Parser = struct { | ... | @@ -1393,14 +1398,16 @@ pub const Parser = struct { |
| 1393 | | 1398 | |
| 1394 | stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable; | 1399 | stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable; |
| 1395 | try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } }); | 1400 | try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } }); |
| | 1401 | continue; |
| 1396 | }, | 1402 | }, |
| 1397 | State.ExprListCommaOrEnd => |list_state| { | 1403 | State.ExprListCommaOrEnd => |list_state| { |
| 1398 | if (try self.expectCommaOrEnd(list_state.end)) |end| { | 1404 | if (try self.expectCommaOrEnd(list_state.end)) |end| { |
| 1399 | *list_state.ptr = end; | 1405 | *list_state.ptr = end; |
| | 1406 | continue; |
| 1400 | } else { | 1407 | } else { |
| 1401 | stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable; | 1408 | stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable; |
| | 1409 | continue; |
| 1402 | } | 1410 | } |
| 1403 | continue; | | |
| 1404 | }, | 1411 | }, |
| 1405 | State.FieldInitListItemOrEnd => |list_state| { | 1412 | State.FieldInitListItemOrEnd => |list_state| { |
| 1406 | if (self.eatToken(Token.Id.RBrace)) |rbrace| { | 1413 | if (self.eatToken(Token.Id.RBrace)) |rbrace| { |
| ... | @@ -1433,22 +1440,25 @@ pub const Parser = struct { | ... | @@ -1433,22 +1440,25 @@ pub const Parser = struct { |
| 1433 | .ptr = &node.period_token, | 1440 | .ptr = &node.period_token, |
| 1434 | } | 1441 | } |
| 1435 | }); | 1442 | }); |
| | 1443 | continue; |
| 1436 | }, | 1444 | }, |
| 1437 | State.FieldInitListCommaOrEnd => |list_state| { | 1445 | State.FieldInitListCommaOrEnd => |list_state| { |
| 1438 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { | 1446 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| 1439 | *list_state.ptr = end; | 1447 | *list_state.ptr = end; |
| | 1448 | continue; |
| 1440 | } else { | 1449 | } else { |
| 1441 | stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable; | 1450 | stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable; |
| | 1451 | continue; |
| 1442 | } | 1452 | } |
| 1443 | continue; | | |
| 1444 | }, | 1453 | }, |
| 1445 | State.FieldListCommaOrEnd => |container_decl| { | 1454 | State.FieldListCommaOrEnd => |container_decl| { |
| 1446 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { | 1455 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| 1447 | container_decl.rbrace_token = end; | 1456 | container_decl.rbrace_token = end; |
| | 1457 | continue; |
| 1448 | } else { | 1458 | } else { |
| 1449 | stack.append(State { .ContainerDecl = container_decl }) catch unreachable; | 1459 | stack.append(State { .ContainerDecl = container_decl }) catch unreachable; |
| | 1460 | continue; |
| 1450 | } | 1461 | } |
| 1451 | continue; | | |
| 1452 | }, | 1462 | }, |
| 1453 | State.IdentifierListItemOrEnd => |list_state| { | 1463 | State.IdentifierListItemOrEnd => |list_state| { |
| 1454 | if (self.eatToken(Token.Id.RBrace)) |rbrace| { | 1464 | if (self.eatToken(Token.Id.RBrace)) |rbrace| { |
| ... | @@ -1458,14 +1468,16 @@ pub const Parser = struct { | ... | @@ -1458,14 +1468,16 @@ pub const Parser = struct { |
| 1458 | | 1468 | |
| 1459 | stack.append(State { .IdentifierListCommaOrEnd = list_state }) catch unreachable; | 1469 | stack.append(State { .IdentifierListCommaOrEnd = list_state }) catch unreachable; |
| 1460 | try stack.append(State { .Identifier = OptionalCtx { .Required = try list_state.list.addOne() } }); | 1470 | try stack.append(State { .Identifier = OptionalCtx { .Required = try list_state.list.addOne() } }); |
| | 1471 | continue; |
| 1461 | }, | 1472 | }, |
| 1462 | State.IdentifierListCommaOrEnd => |list_state| { | 1473 | State.IdentifierListCommaOrEnd => |list_state| { |
| 1463 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { | 1474 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| 1464 | *list_state.ptr = end; | 1475 | *list_state.ptr = end; |
| | 1476 | continue; |
| 1465 | } else { | 1477 | } else { |
| 1466 | stack.append(State { .IdentifierListItemOrEnd = list_state }) catch unreachable; | 1478 | stack.append(State { .IdentifierListItemOrEnd = list_state }) catch unreachable; |
| | 1479 | continue; |
| 1467 | } | 1480 | } |
| 1468 | continue; | | |
| 1469 | }, | 1481 | }, |
| 1470 | State.SwitchCaseOrEnd => |list_state| { | 1482 | State.SwitchCaseOrEnd => |list_state| { |
| 1471 | if (self.eatToken(Token.Id.RBrace)) |rbrace| { | 1483 | if (self.eatToken(Token.Id.RBrace)) |rbrace| { |
| ... | @@ -1486,15 +1498,16 @@ pub const Parser = struct { | ... | @@ -1486,15 +1498,16 @@ pub const Parser = struct { |
| 1486 | try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .Required = &node.expr } }); | 1498 | try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .Required = &node.expr } }); |
| 1487 | try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } }); | 1499 | try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } }); |
| 1488 | try stack.append(State { .SwitchCaseFirstItem = &node.items }); | 1500 | try stack.append(State { .SwitchCaseFirstItem = &node.items }); |
| 1489 | | 1501 | continue; |
| 1490 | }, | 1502 | }, |
| 1491 | State.SwitchCaseCommaOrEnd => |list_state| { | 1503 | State.SwitchCaseCommaOrEnd => |list_state| { |
| 1492 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { | 1504 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| 1493 | *list_state.ptr = end; | 1505 | *list_state.ptr = end; |
| | 1506 | continue; |
| 1494 | } else { | 1507 | } else { |
| 1495 | stack.append(State { .SwitchCaseOrEnd = list_state }) catch unreachable; | 1508 | stack.append(State { .SwitchCaseOrEnd = list_state }) catch unreachable; |
| | 1509 | continue; |
| 1496 | } | 1510 | } |
| 1497 | continue; | | |
| 1498 | }, | 1511 | }, |
| 1499 | State.SwitchCaseFirstItem => |case_items| { | 1512 | State.SwitchCaseFirstItem => |case_items| { |
| 1500 | const token = self.getNextToken(); | 1513 | const token = self.getNextToken(); |
| ... | @@ -1544,6 +1557,7 @@ pub const Parser = struct { | ... | @@ -1544,6 +1557,7 @@ pub const Parser = struct { |
| 1544 | } | 1557 | } |
| 1545 | }); | 1558 | }); |
| 1546 | try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &async_node.allocator_type } }); | 1559 | try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &async_node.allocator_type } }); |
| | 1560 | continue; |
| 1547 | }, | 1561 | }, |
| 1548 | State.AsyncEnd => |ctx| { | 1562 | State.AsyncEnd => |ctx| { |
| 1549 | const node = ctx.ctx.get() ?? continue; | 1563 | const node = ctx.ctx.get() ?? continue; |
| ... | @@ -1552,6 +1566,7 @@ pub const Parser = struct { | ... | @@ -1552,6 +1566,7 @@ pub const Parser = struct { |
| 1552 | ast.Node.Id.FnProto => { | 1566 | ast.Node.Id.FnProto => { |
| 1553 | const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node); | 1567 | const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node); |
| 1554 | fn_proto.async_attr = ctx.attribute; | 1568 | fn_proto.async_attr = ctx.attribute; |
| | 1569 | continue; |
| 1555 | }, | 1570 | }, |
| 1556 | ast.Node.Id.SuffixOp => { | 1571 | ast.Node.Id.SuffixOp => { |
| 1557 | const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node); | 1572 | const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node); |
| ... | @@ -1574,6 +1589,38 @@ pub const Parser = struct { | ... | @@ -1574,6 +1589,38 @@ pub const Parser = struct { |
| 1574 | }, | 1589 | }, |
| 1575 | | 1590 | |
| 1576 | | 1591 | |
| | 1592 | State.ExternType => |ctx| { |
| | 1593 | if (self.eatToken(Token.Id.Keyword_fn)) |fn_token| { |
| | 1594 | const fn_proto = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeFnProto, |
| | 1595 | ast.NodeFnProto { |
| | 1596 | .base = undefined, |
| | 1597 | .visib_token = null, |
| | 1598 | .name_token = null, |
| | 1599 | .fn_token = fn_token, |
| | 1600 | .params = ArrayList(&ast.Node).init(arena), |
| | 1601 | .return_type = undefined, |
| | 1602 | .var_args_token = null, |
| | 1603 | .extern_export_inline_token = ctx.extern_token, |
| | 1604 | .cc_token = null, |
| | 1605 | .async_attr = null, |
| | 1606 | .body_node = null, |
| | 1607 | .lib_name = null, |
| | 1608 | .align_expr = null, |
| | 1609 | } |
| | 1610 | ); |
| | 1611 | stack.append(State { .FnProto = fn_proto }) catch unreachable; |
| | 1612 | continue; |
| | 1613 | } |
| | 1614 | |
| | 1615 | stack.append(State { |
| | 1616 | .ContainerKind = ContainerKindCtx { |
| | 1617 | .opt_ctx = ctx.opt_ctx, |
| | 1618 | .ltoken = ctx.extern_token, |
| | 1619 | .layout = ast.NodeContainerDecl.Layout.Extern, |
| | 1620 | }, |
| | 1621 | }) catch unreachable; |
| | 1622 | continue; |
| | 1623 | }, |
| 1577 | State.SliceOrArrayAccess => |node| { | 1624 | State.SliceOrArrayAccess => |node| { |
| 1578 | var token = self.getNextToken(); | 1625 | var token = self.getNextToken(); |
| 1579 | switch (token.id) { | 1626 | switch (token.id) { |
| ... | @@ -1692,6 +1739,7 @@ pub const Parser = struct { | ... | @@ -1692,6 +1739,7 @@ pub const Parser = struct { |
| 1692 | } | 1739 | } |
| 1693 | }) catch unreachable; | 1740 | }) catch unreachable; |
| 1694 | try stack.append(State { .Identifier = OptionalCtx { .Required = &node.error_symbol } }); | 1741 | try stack.append(State { .Identifier = OptionalCtx { .Required = &node.error_symbol } }); |
| | 1742 | continue; |
| 1695 | }, | 1743 | }, |
| 1696 | State.PointerPayload => |opt_ctx| { | 1744 | State.PointerPayload => |opt_ctx| { |
| 1697 | const token = self.getNextToken(); | 1745 | const token = self.getNextToken(); |
| ... | @@ -1729,6 +1777,7 @@ pub const Parser = struct { | ... | @@ -1729,6 +1777,7 @@ pub const Parser = struct { |
| 1729 | .ptr = &node.ptr_token, | 1777 | .ptr = &node.ptr_token, |
| 1730 | } | 1778 | } |
| 1731 | }); | 1779 | }); |
| | 1780 | continue; |
| 1732 | }, | 1781 | }, |
| 1733 | State.PointerIndexPayload => |opt_ctx| { | 1782 | State.PointerIndexPayload => |opt_ctx| { |
| 1734 | const token = self.getNextToken(); | 1783 | const token = self.getNextToken(); |
| ... | @@ -1769,26 +1818,14 @@ pub const Parser = struct { | ... | @@ -1769,26 +1818,14 @@ pub const Parser = struct { |
| 1769 | .ptr = &node.ptr_token, | 1818 | .ptr = &node.ptr_token, |
| 1770 | } | 1819 | } |
| 1771 | }); | 1820 | }); |
| | 1821 | continue; |
| 1772 | }, | 1822 | }, |
| 1773 | | 1823 | |
| 1774 | | 1824 | |
| 1775 | State.Expression => |opt_ctx| { | 1825 | State.Expression => |opt_ctx| { |
| 1776 | const token = self.getNextToken(); | 1826 | const token = self.getNextToken(); |
| 1777 | switch (token.id) { | 1827 | switch (token.id) { |
| 1778 | Token.Id.Keyword_return => { | 1828 | Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => { |
| 1779 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeControlFlowExpression, | | |
| 1780 | ast.NodeControlFlowExpression { | | |
| 1781 | .base = undefined, | | |
| 1782 | .ltoken = token, | | |
| 1783 | .kind = ast.NodeControlFlowExpression.Kind.Return, | | |
| 1784 | .rhs = null, | | |
| 1785 | } | | |
| 1786 | ); | | |
| 1787 | | | |
| 1788 | stack.append(State { .Expression = OptionalCtx { .Optional = &node.rhs } }) catch unreachable; | | |
| 1789 | continue; | | |
| 1790 | }, | | |
| 1791 | Token.Id.Keyword_break, Token.Id.Keyword_continue => { | | |
| 1792 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeControlFlowExpression, | 1829 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeControlFlowExpression, |
| 1793 | ast.NodeControlFlowExpression { | 1830 | ast.NodeControlFlowExpression { |
| 1794 | .base = undefined, | 1831 | .base = undefined, |
| ... | @@ -1811,6 +1848,9 @@ pub const Parser = struct { | ... | @@ -1811,6 +1848,9 @@ pub const Parser = struct { |
| 1811 | try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } }); | 1848 | try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } }); |
| 1812 | try stack.append(State { .IfToken = Token.Id.Colon }); | 1849 | try stack.append(State { .IfToken = Token.Id.Colon }); |
| 1813 | }, | 1850 | }, |
| | 1851 | Token.Id.Keyword_return => { |
| | 1852 | node.kind = ast.NodeControlFlowExpression.Kind.Return; |
| | 1853 | }, |
| 1814 | else => unreachable, | 1854 | else => unreachable, |
| 1815 | } | 1855 | } |
| 1816 | continue; | 1856 | continue; |
| ... | @@ -1861,9 +1901,8 @@ pub const Parser = struct { | ... | @@ -1861,9 +1901,8 @@ pub const Parser = struct { |
| 1861 | } | 1901 | } |
| 1862 | ); | 1902 | ); |
| 1863 | stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable; | 1903 | stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable; |
| | 1904 | continue; |
| 1864 | } | 1905 | } |
| 1865 | | | |
| 1866 | continue; | | |
| 1867 | }, | 1906 | }, |
| 1868 | State.AssignmentExpressionBegin => |opt_ctx| { | 1907 | State.AssignmentExpressionBegin => |opt_ctx| { |
| 1869 | stack.append(State { .AssignmentExpressionEnd = opt_ctx }) catch unreachable; | 1908 | stack.append(State { .AssignmentExpressionEnd = opt_ctx }) catch unreachable; |
| ... | @@ -1904,34 +1943,27 @@ pub const Parser = struct { | ... | @@ -1904,34 +1943,27 @@ pub const Parser = struct { |
| 1904 | const lhs = opt_ctx.get() ?? continue; | 1943 | const lhs = opt_ctx.get() ?? continue; |
| 1905 | | 1944 | |
| 1906 | const token = self.getNextToken(); | 1945 | const token = self.getNextToken(); |
| 1907 | switch (token.id) { | 1946 | if (tokenIdToUnwrapExpr(token.id)) |unwrap_id| { |
| 1908 | Token.Id.Keyword_catch, Token.Id.QuestionMarkQuestionMark => { | 1947 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 1909 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, | 1948 | ast.NodeInfixOp { |
| 1910 | ast.NodeInfixOp { | 1949 | .base = undefined, |
| 1911 | .base = undefined, | 1950 | .lhs = lhs, |
| 1912 | .lhs = lhs, | 1951 | .op_token = token, |
| 1913 | .op_token = token, | 1952 | .op = unwrap_id, |
| 1914 | .op = switch (token.id) { | 1953 | .rhs = undefined, |
| 1915 | Token.Id.Keyword_catch => ast.NodeInfixOp.InfixOp { .Catch = null }, | 1954 | } |
| 1916 | Token.Id.QuestionMarkQuestionMark => ast.NodeInfixOp.InfixOp { .UnwrapMaybe = void{} }, | 1955 | ); |
| 1917 | else => unreachable, | | |
| 1918 | }, | | |
| 1919 | .rhs = undefined, | | |
| 1920 | } | | |
| 1921 | ); | | |
| 1922 | | 1956 | |
| 1923 | stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable; | 1957 | stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 1924 | try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }); | 1958 | try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }); |
| 1925 | | 1959 | |
| 1926 | if (node.op == ast.NodeInfixOp.InfixOp.Catch) { | 1960 | if (node.op == ast.NodeInfixOp.InfixOp.Catch) { |
| 1927 | try stack.append(State { .Payload = OptionalCtx { .Optional = &node.op.Catch } }); | 1961 | try stack.append(State { .Payload = OptionalCtx { .Optional = &node.op.Catch } }); |
| 1928 | } | 1962 | } |
| 1929 | continue; | 1963 | continue; |
| 1930 | }, | 1964 | } else { |
| 1931 | else => { | 1965 | self.putBackToken(token); |
| 1932 | self.putBackToken(token); | 1966 | continue; |
| 1933 | continue; | | |
| 1934 | }, | | |
| 1935 | } | 1967 | } |
| 1936 | }, | 1968 | }, |
| 1937 | | 1969 | |
| ... | @@ -1944,26 +1976,19 @@ pub const Parser = struct { | ... | @@ -1944,26 +1976,19 @@ pub const Parser = struct { |
| 1944 | State.BoolOrExpressionEnd => |opt_ctx| { | 1976 | State.BoolOrExpressionEnd => |opt_ctx| { |
| 1945 | const lhs = opt_ctx.get() ?? continue; | 1977 | const lhs = opt_ctx.get() ?? continue; |
| 1946 | | 1978 | |
| 1947 | const token = self.getNextToken(); | 1979 | if (self.eatToken(Token.Id.Keyword_or)) |or_token| { |
| 1948 | switch (token.id) { | 1980 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 1949 | Token.Id.Keyword_or => { | 1981 | ast.NodeInfixOp { |
| 1950 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, | 1982 | .base = undefined, |
| 1951 | ast.NodeInfixOp { | 1983 | .lhs = lhs, |
| 1952 | .base = undefined, | 1984 | .op_token = or_token, |
| 1953 | .lhs = lhs, | 1985 | .op = ast.NodeInfixOp.InfixOp.BoolOr, |
| 1954 | .op_token = token, | 1986 | .rhs = undefined, |
| 1955 | .op = ast.NodeInfixOp.InfixOp.BoolOr, | 1987 | } |
| 1956 | .rhs = undefined, | 1988 | ); |
| 1957 | } | 1989 | stack.append(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 1958 | ); | 1990 | try stack.append(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 1959 | stack.append(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable; | 1991 | continue; |
| 1960 | try stack.append(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } }); | | |
| 1961 | continue; | | |
| 1962 | }, | | |
| 1963 | else => { | | |
| 1964 | self.putBackToken(token); | | |
| 1965 | continue; | | |
| 1966 | }, | | |
| 1967 | } | 1992 | } |
| 1968 | }, | 1993 | }, |
| 1969 | | 1994 | |
| ... | @@ -1976,26 +2001,19 @@ pub const Parser = struct { | ... | @@ -1976,26 +2001,19 @@ pub const Parser = struct { |
| 1976 | State.BoolAndExpressionEnd => |opt_ctx| { | 2001 | State.BoolAndExpressionEnd => |opt_ctx| { |
| 1977 | const lhs = opt_ctx.get() ?? continue; | 2002 | const lhs = opt_ctx.get() ?? continue; |
| 1978 | | 2003 | |
| 1979 | const token = self.getNextToken(); | 2004 | if (self.eatToken(Token.Id.Keyword_and)) |and_token| { |
| 1980 | switch (token.id) { | 2005 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 1981 | Token.Id.Keyword_and => { | 2006 | ast.NodeInfixOp { |
| 1982 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, | 2007 | .base = undefined, |
| 1983 | ast.NodeInfixOp { | 2008 | .lhs = lhs, |
| 1984 | .base = undefined, | 2009 | .op_token = and_token, |
| 1985 | .lhs = lhs, | 2010 | .op = ast.NodeInfixOp.InfixOp.BoolAnd, |
| 1986 | .op_token = token, | 2011 | .rhs = undefined, |
| 1987 | .op = ast.NodeInfixOp.InfixOp.BoolAnd, | 2012 | } |
| 1988 | .rhs = undefined, | 2013 | ); |
| 1989 | } | 2014 | stack.append(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 1990 | ); | 2015 | try stack.append(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 1991 | stack.append(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable; | 2016 | continue; |
| 1992 | try stack.append(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } }); | | |
| 1993 | continue; | | |
| 1994 | }, | | |
| 1995 | else => { | | |
| 1996 | self.putBackToken(token); | | |
| 1997 | continue; | | |
| 1998 | }, | | |
| 1999 | } | 2017 | } |
| 2000 | }, | 2018 | }, |
| 2001 | | 2019 | |
| ... | @@ -2037,26 +2055,19 @@ pub const Parser = struct { | ... | @@ -2037,26 +2055,19 @@ pub const Parser = struct { |
| 2037 | State.BinaryOrExpressionEnd => |opt_ctx| { | 2055 | State.BinaryOrExpressionEnd => |opt_ctx| { |
| 2038 | const lhs = opt_ctx.get() ?? continue; | 2056 | const lhs = opt_ctx.get() ?? continue; |
| 2039 | | 2057 | |
| 2040 | const token = self.getNextToken(); | 2058 | if (self.eatToken(Token.Id.Pipe)) |pipe| { |
| 2041 | switch (token.id) { | 2059 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2042 | Token.Id.Pipe => { | 2060 | ast.NodeInfixOp { |
| 2043 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, | 2061 | .base = undefined, |
| 2044 | ast.NodeInfixOp { | 2062 | .lhs = lhs, |
| 2045 | .base = undefined, | 2063 | .op_token = pipe, |
| 2046 | .lhs = lhs, | 2064 | .op = ast.NodeInfixOp.InfixOp.BitOr, |
| 2047 | .op_token = token, | 2065 | .rhs = undefined, |
| 2048 | .op = ast.NodeInfixOp.InfixOp.BitOr, | 2066 | } |
| 2049 | .rhs = undefined, | 2067 | ); |
| 2050 | } | 2068 | stack.append(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2051 | ); | 2069 | try stack.append(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2052 | stack.append(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable; | 2070 | continue; |
| 2053 | try stack.append(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } }); | | |
| 2054 | continue; | | |
| 2055 | }, | | |
| 2056 | else => { | | |
| 2057 | self.putBackToken(token); | | |
| 2058 | continue; | | |
| 2059 | }, | | |
| 2060 | } | 2071 | } |
| 2061 | }, | 2072 | }, |
| 2062 | | 2073 | |
| ... | @@ -2069,26 +2080,19 @@ pub const Parser = struct { | ... | @@ -2069,26 +2080,19 @@ pub const Parser = struct { |
| 2069 | State.BinaryXorExpressionEnd => |opt_ctx| { | 2080 | State.BinaryXorExpressionEnd => |opt_ctx| { |
| 2070 | const lhs = opt_ctx.get() ?? continue; | 2081 | const lhs = opt_ctx.get() ?? continue; |
| 2071 | | 2082 | |
| 2072 | const token = self.getNextToken(); | 2083 | if (self.eatToken(Token.Id.Caret)) |caret| { |
| 2073 | switch (token.id) { | 2084 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2074 | Token.Id.Caret => { | 2085 | ast.NodeInfixOp { |
| 2075 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, | 2086 | .base = undefined, |
| 2076 | ast.NodeInfixOp { | 2087 | .lhs = lhs, |
| 2077 | .base = undefined, | 2088 | .op_token = caret, |
| 2078 | .lhs = lhs, | 2089 | .op = ast.NodeInfixOp.InfixOp.BitXor, |
| 2079 | .op_token = token, | 2090 | .rhs = undefined, |
| 2080 | .op = ast.NodeInfixOp.InfixOp.BitXor, | 2091 | } |
| 2081 | .rhs = undefined, | 2092 | ); |
| 2082 | } | 2093 | stack.append(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2083 | ); | 2094 | try stack.append(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2084 | stack.append(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable; | 2095 | continue; |
| 2085 | try stack.append(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } }); | | |
| 2086 | continue; | | |
| 2087 | }, | | |
| 2088 | else => { | | |
| 2089 | self.putBackToken(token); | | |
| 2090 | continue; | | |
| 2091 | }, | | |
| 2092 | } | 2096 | } |
| 2093 | }, | 2097 | }, |
| 2094 | | 2098 | |
| ... | @@ -2101,26 +2105,19 @@ pub const Parser = struct { | ... | @@ -2101,26 +2105,19 @@ pub const Parser = struct { |
| 2101 | State.BinaryAndExpressionEnd => |opt_ctx| { | 2105 | State.BinaryAndExpressionEnd => |opt_ctx| { |
| 2102 | const lhs = opt_ctx.get() ?? continue; | 2106 | const lhs = opt_ctx.get() ?? continue; |
| 2103 | | 2107 | |
| 2104 | const token = self.getNextToken(); | 2108 | if (self.eatToken(Token.Id.Ampersand)) |ampersand| { |
| 2105 | switch (token.id) { | 2109 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2106 | Token.Id.Ampersand => { | 2110 | ast.NodeInfixOp { |
| 2107 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, | 2111 | .base = undefined, |
| 2108 | ast.NodeInfixOp { | 2112 | .lhs = lhs, |
| 2109 | .base = undefined, | 2113 | .op_token = ampersand, |
| 2110 | .lhs = lhs, | 2114 | .op = ast.NodeInfixOp.InfixOp.BitAnd, |
| 2111 | .op_token = token, | 2115 | .rhs = undefined, |
| 2112 | .op = ast.NodeInfixOp.InfixOp.BitAnd, | 2116 | } |
| 2113 | .rhs = undefined, | 2117 | ); |
| 2114 | } | 2118 | stack.append(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2115 | ); | 2119 | try stack.append(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2116 | stack.append(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable; | 2120 | continue; |
| 2117 | try stack.append(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } }); | | |
| 2118 | continue; | | |
| 2119 | }, | | |
| 2120 | else => { | | |
| 2121 | self.putBackToken(token); | | |
| 2122 | continue; | | |
| 2123 | }, | | |
| 2124 | } | 2121 | } |
| 2125 | }, | 2122 | }, |
| 2126 | | 2123 | |
| ... | @@ -2241,28 +2238,28 @@ pub const Parser = struct { | ... | @@ -2241,28 +2238,28 @@ pub const Parser = struct { |
| 2241 | } | 2238 | } |
| 2242 | }); | 2239 | }); |
| 2243 | continue; | 2240 | continue; |
| 2244 | } else { | | |
| 2245 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp, | | |
| 2246 | ast.NodeSuffixOp { | | |
| 2247 | .base = undefined, | | |
| 2248 | .lhs = lhs, | | |
| 2249 | .op = ast.NodeSuffixOp.SuffixOp { | | |
| 2250 | .ArrayInitializer = ArrayList(&ast.Node).init(arena), | | |
| 2251 | }, | | |
| 2252 | .rtoken = undefined, | | |
| 2253 | } | | |
| 2254 | ); | | |
| 2255 | stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable; | | |
| 2256 | try stack.append(State { .IfToken = Token.Id.LBrace }); | | |
| 2257 | try stack.append(State { | | |
| 2258 | .ExprListItemOrEnd = ExprListCtx { | | |
| 2259 | .list = &node.op.ArrayInitializer, | | |
| 2260 | .end = Token.Id.RBrace, | | |
| 2261 | .ptr = &node.rtoken, | | |
| 2262 | } | | |
| 2263 | }); | | |
| 2264 | continue; | | |
| 2265 | } | 2241 | } |
| | 2242 | |
| | 2243 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp, |
| | 2244 | ast.NodeSuffixOp { |
| | 2245 | .base = undefined, |
| | 2246 | .lhs = lhs, |
| | 2247 | .op = ast.NodeSuffixOp.SuffixOp { |
| | 2248 | .ArrayInitializer = ArrayList(&ast.Node).init(arena), |
| | 2249 | }, |
| | 2250 | .rtoken = undefined, |
| | 2251 | } |
| | 2252 | ); |
| | 2253 | stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| | 2254 | try stack.append(State { .IfToken = Token.Id.LBrace }); |
| | 2255 | try stack.append(State { |
| | 2256 | .ExprListItemOrEnd = ExprListCtx { |
| | 2257 | .list = &node.op.ArrayInitializer, |
| | 2258 | .end = Token.Id.RBrace, |
| | 2259 | .ptr = &node.rtoken, |
| | 2260 | } |
| | 2261 | }); |
| | 2262 | continue; |
| 2266 | }, | 2263 | }, |
| 2267 | | 2264 | |
| 2268 | State.TypeExprBegin => |opt_ctx| { | 2265 | State.TypeExprBegin => |opt_ctx| { |
| ... | @@ -2274,26 +2271,19 @@ pub const Parser = struct { | ... | @@ -2274,26 +2271,19 @@ pub const Parser = struct { |
| 2274 | State.TypeExprEnd => |opt_ctx| { | 2271 | State.TypeExprEnd => |opt_ctx| { |
| 2275 | const lhs = opt_ctx.get() ?? continue; | 2272 | const lhs = opt_ctx.get() ?? continue; |
| 2276 | | 2273 | |
| 2277 | const token = self.getNextToken(); | 2274 | if (self.eatToken(Token.Id.Bang)) |bang| { |
| 2278 | switch (token.id) { | 2275 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2279 | Token.Id.Bang => { | 2276 | ast.NodeInfixOp { |
| 2280 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, | 2277 | .base = undefined, |
| 2281 | ast.NodeInfixOp { | 2278 | .lhs = lhs, |
| 2282 | .base = undefined, | 2279 | .op_token = bang, |
| 2283 | .lhs = lhs, | 2280 | .op = ast.NodeInfixOp.InfixOp.ErrorUnion, |
| 2284 | .op_token = token, | 2281 | .rhs = undefined, |
| 2285 | .op = ast.NodeInfixOp.InfixOp.ErrorUnion, | 2282 | } |
| 2286 | .rhs = undefined, | 2283 | ); |
| 2287 | } | 2284 | stack.append(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2288 | ); | 2285 | try stack.append(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } }); |
| 2289 | stack.append(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable; | 2286 | continue; |
| 2290 | try stack.append(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } }); | | |
| 2291 | continue; | | |
| 2292 | }, | | |
| 2293 | else => { | | |
| 2294 | self.putBackToken(token); | | |
| 2295 | continue; | | |
| 2296 | }, | | |
| 2297 | } | 2287 | } |
| 2298 | }, | 2288 | }, |
| 2299 | | 2289 | |
| ... | @@ -2309,6 +2299,7 @@ pub const Parser = struct { | ... | @@ -2309,6 +2299,7 @@ pub const Parser = struct { |
| 2309 | } | 2299 | } |
| 2310 | ); | 2300 | ); |
| 2311 | | 2301 | |
| | 2302 | // Treat '**' token as two derefs |
| 2312 | if (token.id == Token.Id.AsteriskAsterisk) { | 2303 | if (token.id == Token.Id.AsteriskAsterisk) { |
| 2313 | const child = try self.createNode(arena, ast.NodePrefixOp, | 2304 | const child = try self.createNode(arena, ast.NodePrefixOp, |
| 2314 | ast.NodePrefixOp { | 2305 | ast.NodePrefixOp { |
| ... | @@ -2335,35 +2326,30 @@ pub const Parser = struct { | ... | @@ -2335,35 +2326,30 @@ pub const Parser = struct { |
| 2335 | }, | 2326 | }, |
| 2336 | | 2327 | |
| 2337 | State.SuffixOpExpressionBegin => |opt_ctx| { | 2328 | State.SuffixOpExpressionBegin => |opt_ctx| { |
| 2338 | const token = self.getNextToken(); | 2329 | if (self.eatToken(Token.Id.Keyword_async)) |async_token| { |
| 2339 | switch (token.id) { | 2330 | const async_node = try self.createNode(arena, ast.NodeAsyncAttribute, |
| 2340 | Token.Id.Keyword_async => { | 2331 | ast.NodeAsyncAttribute { |
| 2341 | const async_node = try self.createNode(arena, ast.NodeAsyncAttribute, | 2332 | .base = undefined, |
| 2342 | ast.NodeAsyncAttribute { | 2333 | .async_token = async_token, |
| 2343 | .base = undefined, | 2334 | .allocator_type = null, |
| 2344 | .async_token = token, | 2335 | .rangle_bracket = null, |
| 2345 | .allocator_type = null, | 2336 | } |
| 2346 | .rangle_bracket = null, | 2337 | ); |
| 2347 | } | 2338 | stack.append(State { |
| 2348 | ); | 2339 | .AsyncEnd = AsyncEndCtx { |
| 2349 | stack.append(State { | 2340 | .ctx = opt_ctx, |
| 2350 | .AsyncEnd = AsyncEndCtx { | 2341 | .attribute = async_node, |
| 2351 | .ctx = opt_ctx, | 2342 | } |
| 2352 | .attribute = async_node, | 2343 | }) catch unreachable; |
| 2353 | } | 2344 | try stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }); |
| 2354 | }) catch unreachable; | 2345 | try stack.append(State { .PrimaryExpression = opt_ctx.toRequired() }); |
| 2355 | try stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }); | 2346 | try stack.append(State { .AsyncAllocator = async_node }); |
| 2356 | try stack.append(State { .PrimaryExpression = opt_ctx.toRequired() }); | 2347 | continue; |
| 2357 | try stack.append(State { .AsyncAllocator = async_node }); | | |
| 2358 | continue; | | |
| 2359 | }, | | |
| 2360 | else => { | | |
| 2361 | self.putBackToken(token); | | |
| 2362 | stack.append(State { .SuffixOpExpressionEnd = opt_ctx }) catch unreachable; | | |
| 2363 | try stack.append(State { .PrimaryExpression = opt_ctx }); | | |
| 2364 | continue; | | |
| 2365 | } | | |
| 2366 | } | 2348 | } |
| | 2349 | |
| | 2350 | stack.append(State { .SuffixOpExpressionEnd = opt_ctx }) catch unreachable; |
| | 2351 | try stack.append(State { .PrimaryExpression = opt_ctx }); |
| | 2352 | continue; |
| 2367 | }, | 2353 | }, |
| 2368 | | 2354 | |
| 2369 | State.SuffixOpExpressionEnd => |opt_ctx| { | 2355 | State.SuffixOpExpressionEnd => |opt_ctx| { |
| ... | @@ -2436,43 +2422,44 @@ pub const Parser = struct { | ... | @@ -2436,43 +2422,44 @@ pub const Parser = struct { |
| 2436 | const token = self.getNextToken(); | 2422 | const token = self.getNextToken(); |
| 2437 | switch (token.id) { | 2423 | switch (token.id) { |
| 2438 | Token.Id.IntegerLiteral => { | 2424 | Token.Id.IntegerLiteral => { |
| 2439 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base); | 2425 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeStringLiteral, token); |
| 2440 | continue; | 2426 | continue; |
| 2441 | }, | 2427 | }, |
| 2442 | Token.Id.FloatLiteral => { | 2428 | Token.Id.FloatLiteral => { |
| 2443 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeFloatLiteral, token)).base); | 2429 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeFloatLiteral, token); |
| 2444 | continue; | 2430 | continue; |
| 2445 | }, | 2431 | }, |
| 2446 | Token.Id.CharLiteral => { | 2432 | Token.Id.CharLiteral => { |
| 2447 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeCharLiteral, token)).base); | 2433 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeCharLiteral, token); |
| 2448 | continue; | 2434 | continue; |
| 2449 | }, | 2435 | }, |
| 2450 | Token.Id.Keyword_undefined => { | 2436 | Token.Id.Keyword_undefined => { |
| 2451 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeUndefinedLiteral, token)).base); | 2437 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeUndefinedLiteral, token); |
| 2452 | continue; | 2438 | continue; |
| 2453 | }, | 2439 | }, |
| 2454 | Token.Id.Keyword_true, Token.Id.Keyword_false => { | 2440 | Token.Id.Keyword_true, Token.Id.Keyword_false => { |
| 2455 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeBoolLiteral, token)).base); | 2441 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeBoolLiteral, token); |
| 2456 | continue; | 2442 | continue; |
| 2457 | }, | 2443 | }, |
| 2458 | Token.Id.Keyword_null => { | 2444 | Token.Id.Keyword_null => { |
| 2459 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeNullLiteral, token)).base); | 2445 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeNullLiteral, token); |
| 2460 | continue; | 2446 | continue; |
| 2461 | }, | 2447 | }, |
| 2462 | Token.Id.Keyword_this => { | 2448 | Token.Id.Keyword_this => { |
| 2463 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeThisLiteral, token)).base); | 2449 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeThisLiteral, token); |
| 2464 | continue; | 2450 | continue; |
| 2465 | }, | 2451 | }, |
| 2466 | Token.Id.Keyword_var => { | 2452 | Token.Id.Keyword_var => { |
| 2467 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeVarType, token)).base); | 2453 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeVarType, token); |
| 2468 | continue; | 2454 | continue; |
| 2469 | }, | 2455 | }, |
| 2470 | Token.Id.Keyword_unreachable => { | 2456 | Token.Id.Keyword_unreachable => { |
| 2471 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeUnreachable, token)).base); | 2457 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeUnreachable, token); |
| 2472 | continue; | 2458 | continue; |
| 2473 | }, | 2459 | }, |
| 2474 | Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => { | 2460 | Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => { |
| 2475 | opt_ctx.store((try self.parseStringLiteral(arena, token)) ?? unreachable); | 2461 | opt_ctx.store((try self.parseStringLiteral(arena, token)) ?? unreachable); |
| | 2462 | continue; |
| 2476 | }, | 2463 | }, |
| 2477 | Token.Id.LParen => { | 2464 | Token.Id.LParen => { |
| 2478 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeGroupedExpression, | 2465 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeGroupedExpression, |
| ... | @@ -2521,6 +2508,7 @@ pub const Parser = struct { | ... | @@ -2521,6 +2508,7 @@ pub const Parser = struct { |
| 2521 | } | 2508 | } |
| 2522 | ); | 2509 | ); |
| 2523 | stack.append(State { .SliceOrArrayType = node }) catch unreachable; | 2510 | stack.append(State { .SliceOrArrayType = node }) catch unreachable; |
| | 2511 | continue; |
| 2524 | }, | 2512 | }, |
| 2525 | Token.Id.Keyword_error => { | 2513 | Token.Id.Keyword_error => { |
| 2526 | stack.append(State { | 2514 | stack.append(State { |
| ... | @@ -2529,73 +2517,41 @@ pub const Parser = struct { | ... | @@ -2529,73 +2517,41 @@ pub const Parser = struct { |
| 2529 | .opt_ctx = opt_ctx | 2517 | .opt_ctx = opt_ctx |
| 2530 | } | 2518 | } |
| 2531 | }) catch unreachable; | 2519 | }) catch unreachable; |
| | 2520 | continue; |
| 2532 | }, | 2521 | }, |
| 2533 | Token.Id.Keyword_packed => { | 2522 | Token.Id.Keyword_packed => { |
| 2534 | stack.append(State { | 2523 | stack.append(State { |
| 2535 | .ContainerExtern = ContainerExternCtx { | 2524 | .ContainerKind = ContainerKindCtx { |
| 2536 | .opt_ctx = opt_ctx, | 2525 | .opt_ctx = opt_ctx, |
| 2537 | .ltoken = token, | 2526 | .ltoken = token, |
| 2538 | .layout = ast.NodeContainerDecl.Layout.Packed, | 2527 | .layout = ast.NodeContainerDecl.Layout.Packed, |
| 2539 | }, | 2528 | }, |
| 2540 | }) catch unreachable; | 2529 | }) catch unreachable; |
| | 2530 | continue; |
| 2541 | }, | 2531 | }, |
| 2542 | Token.Id.Keyword_extern => { | 2532 | Token.Id.Keyword_extern => { |
| 2543 | // TODO: Here, we eat two tokens in the same state. This prevents comments | | |
| 2544 | // from being between these two tokens. | | |
| 2545 | const next = self.getNextToken(); | | |
| 2546 | if (next.id == Token.Id.Keyword_fn) { | | |
| 2547 | const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.NodeFnProto, | | |
| 2548 | ast.NodeFnProto { | | |
| 2549 | .base = undefined, | | |
| 2550 | .visib_token = null, | | |
| 2551 | .name_token = null, | | |
| 2552 | .fn_token = next, | | |
| 2553 | .params = ArrayList(&ast.Node).init(arena), | | |
| 2554 | .return_type = undefined, | | |
| 2555 | .var_args_token = null, | | |
| 2556 | .extern_export_inline_token = token, | | |
| 2557 | .cc_token = null, | | |
| 2558 | .async_attr = null, | | |
| 2559 | .body_node = null, | | |
| 2560 | .lib_name = null, | | |
| 2561 | .align_expr = null, | | |
| 2562 | } | | |
| 2563 | ); | | |
| 2564 | stack.append(State { .FnProto = fn_proto }) catch unreachable; | | |
| 2565 | continue; | | |
| 2566 | } | | |
| 2567 | | | |
| 2568 | self.putBackToken(next); | | |
| 2569 | stack.append(State { | 2533 | stack.append(State { |
| 2570 | .ContainerExtern = ContainerExternCtx { | 2534 | .ExternType = ExternTypeCtx { |
| 2571 | .opt_ctx = opt_ctx, | 2535 | .opt_ctx = opt_ctx, |
| 2572 | .ltoken = token, | 2536 | .extern_token = token, |
| 2573 | .layout = ast.NodeContainerDecl.Layout.Extern, | | |
| 2574 | }, | 2537 | }, |
| 2575 | }) catch unreachable; | 2538 | }) catch unreachable; |
| | 2539 | continue; |
| 2576 | }, | 2540 | }, |
| 2577 | Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => { | 2541 | Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => { |
| 2578 | self.putBackToken(token); | 2542 | self.putBackToken(token); |
| 2579 | stack.append(State { | 2543 | stack.append(State { |
| 2580 | .ContainerExtern = ContainerExternCtx { | 2544 | .ContainerKind = ContainerKindCtx { |
| 2581 | .opt_ctx = opt_ctx, | 2545 | .opt_ctx = opt_ctx, |
| 2582 | .ltoken = token, | 2546 | .ltoken = token, |
| 2583 | .layout = ast.NodeContainerDecl.Layout.Auto, | 2547 | .layout = ast.NodeContainerDecl.Layout.Auto, |
| 2584 | }, | 2548 | }, |
| 2585 | }) catch unreachable; | 2549 | }) catch unreachable; |
| | 2550 | continue; |
| 2586 | }, | 2551 | }, |
| 2587 | Token.Id.Identifier => { | 2552 | Token.Id.Identifier => { |
| 2588 | // TODO: Here, we eat two tokens in the same state. This prevents comments | | |
| 2589 | // from being between these two tokens. | | |
| 2590 | const next = self.getNextToken(); | | |
| 2591 | if (next.id != Token.Id.Colon) { | | |
| 2592 | self.putBackToken(next); | | |
| 2593 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeIdentifier, token)).base); | | |
| 2594 | continue; | | |
| 2595 | } | | |
| 2596 | | | |
| 2597 | stack.append(State { | 2553 | stack.append(State { |
| 2598 | .LabeledExpression = LabelCtx { | 2554 | .MaybeLabeledExpression = MaybeLabeledExpressionCtx { |
| 2599 | .label = token, | 2555 | .label = token, |
| 2600 | .opt_ctx = opt_ctx | 2556 | .opt_ctx = opt_ctx |
| 2601 | } | 2557 | } |
| ... | @@ -2710,7 +2666,7 @@ pub const Parser = struct { | ... | @@ -2710,7 +2666,7 @@ pub const Parser = struct { |
| 2710 | | 2666 | |
| 2711 | State.ErrorTypeOrSetDecl => |ctx| { | 2667 | State.ErrorTypeOrSetDecl => |ctx| { |
| 2712 | if (self.eatToken(Token.Id.LBrace) == null) { | 2668 | if (self.eatToken(Token.Id.LBrace) == null) { |
| 2713 | ctx.opt_ctx.store(&(try self.createLiteral(arena, ast.NodeErrorType, ctx.error_token)).base); | 2669 | _ = try self.createToCtxLiteral(arena, ctx.opt_ctx, ast.NodeErrorType, ctx.error_token); |
| 2714 | continue; | 2670 | continue; |
| 2715 | } | 2671 | } |
| 2716 | | 2672 | |
| ... | @@ -2746,7 +2702,7 @@ pub const Parser = struct { | ... | @@ -2746,7 +2702,7 @@ pub const Parser = struct { |
| 2746 | }, | 2702 | }, |
| 2747 | State.Identifier => |opt_ctx| { | 2703 | State.Identifier => |opt_ctx| { |
| 2748 | if (self.eatToken(Token.Id.Identifier)) |ident_token| { | 2704 | if (self.eatToken(Token.Id.Identifier)) |ident_token| { |
| 2749 | opt_ctx.store(&(try self.createLiteral(arena, ast.NodeIdentifier, ident_token)).base); | 2705 | _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeIdentifier, ident_token); |
| 2750 | continue; | 2706 | continue; |
| 2751 | } | 2707 | } |
| 2752 | | 2708 | |
| ... | @@ -3044,8 +3000,16 @@ pub const Parser = struct { | ... | @@ -3044,8 +3000,16 @@ pub const Parser = struct { |
| 3044 | }; | 3000 | }; |
| 3045 | } | 3001 | } |
| 3046 | | 3002 | |
| 3047 | fn tokenIdToComparison(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp { | 3003 | fn tokenIdToUnwrapExpr(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp { |
| 3048 | return switch (*id) { | 3004 | return switch (id) { |
| | 3005 | Token.Id.Keyword_catch => ast.NodeInfixOp.InfixOp { .Catch = null }, |
| | 3006 | Token.Id.QuestionMarkQuestionMark => ast.NodeInfixOp.InfixOp { .UnwrapMaybe = void{} }, |
| | 3007 | else => null, |
| | 3008 | }; |
| | 3009 | } |
| | 3010 | |
| | 3011 | fn tokenIdToComparison(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp { |
| | 3012 | return switch (id) { |
| 3049 | Token.Id.BangEqual => ast.NodeInfixOp.InfixOp { .BangEqual = void{} }, | 3013 | Token.Id.BangEqual => ast.NodeInfixOp.InfixOp { .BangEqual = void{} }, |
| 3050 | Token.Id.EqualEqual => ast.NodeInfixOp.InfixOp { .EqualEqual = void{} }, | 3014 | Token.Id.EqualEqual => ast.NodeInfixOp.InfixOp { .EqualEqual = void{} }, |
| 3051 | Token.Id.AngleBracketLeft => ast.NodeInfixOp.InfixOp { .LessThan = void{} }, | 3015 | Token.Id.AngleBracketLeft => ast.NodeInfixOp.InfixOp { .LessThan = void{} }, |
| ... | @@ -3056,16 +3020,16 @@ pub const Parser = struct { | ... | @@ -3056,16 +3020,16 @@ pub const Parser = struct { |
| 3056 | }; | 3020 | }; |
| 3057 | } | 3021 | } |
| 3058 | | 3022 | |
| 3059 | fn tokenIdToBitShift(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp { | 3023 | fn tokenIdToBitShift(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp { |
| 3060 | return switch (*id) { | 3024 | return switch (id) { |
| 3061 | Token.Id.AngleBracketAngleBracketLeft => ast.NodeInfixOp.InfixOp { .BitShiftLeft = void{} }, | 3025 | Token.Id.AngleBracketAngleBracketLeft => ast.NodeInfixOp.InfixOp { .BitShiftLeft = void{} }, |
| 3062 | Token.Id.AngleBracketAngleBracketRight => ast.NodeInfixOp.InfixOp { .BitShiftRight = void{} }, | 3026 | Token.Id.AngleBracketAngleBracketRight => ast.NodeInfixOp.InfixOp { .BitShiftRight = void{} }, |
| 3063 | else => null, | 3027 | else => null, |
| 3064 | }; | 3028 | }; |
| 3065 | } | 3029 | } |
| 3066 | | 3030 | |
| 3067 | fn tokenIdToAddition(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp { | 3031 | fn tokenIdToAddition(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp { |
| 3068 | return switch (*id) { | 3032 | return switch (id) { |
| 3069 | Token.Id.Minus => ast.NodeInfixOp.InfixOp { .Sub = void{} }, | 3033 | Token.Id.Minus => ast.NodeInfixOp.InfixOp { .Sub = void{} }, |
| 3070 | Token.Id.MinusPercent => ast.NodeInfixOp.InfixOp { .SubWrap = void{} }, | 3034 | Token.Id.MinusPercent => ast.NodeInfixOp.InfixOp { .SubWrap = void{} }, |
| 3071 | Token.Id.Plus => ast.NodeInfixOp.InfixOp { .Add = void{} }, | 3035 | Token.Id.Plus => ast.NodeInfixOp.InfixOp { .Add = void{} }, |
| ... | @@ -3075,8 +3039,8 @@ pub const Parser = struct { | ... | @@ -3075,8 +3039,8 @@ pub const Parser = struct { |
| 3075 | }; | 3039 | }; |
| 3076 | } | 3040 | } |
| 3077 | | 3041 | |
| 3078 | fn tokenIdToMultiply(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp { | 3042 | fn tokenIdToMultiply(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp { |
| 3079 | return switch (*id) { | 3043 | return switch (id) { |
| 3080 | Token.Id.Slash => ast.NodeInfixOp.InfixOp { .Div = void{} }, | 3044 | Token.Id.Slash => ast.NodeInfixOp.InfixOp { .Div = void{} }, |
| 3081 | Token.Id.Asterisk => ast.NodeInfixOp.InfixOp { .Mult = void{} }, | 3045 | Token.Id.Asterisk => ast.NodeInfixOp.InfixOp { .Mult = void{} }, |
| 3082 | Token.Id.AsteriskAsterisk => ast.NodeInfixOp.InfixOp { .ArrayMult = void{} }, | 3046 | Token.Id.AsteriskAsterisk => ast.NodeInfixOp.InfixOp { .ArrayMult = void{} }, |
| ... | @@ -3087,8 +3051,8 @@ pub const Parser = struct { | ... | @@ -3087,8 +3051,8 @@ pub const Parser = struct { |
| 3087 | }; | 3051 | }; |
| 3088 | } | 3052 | } |
| 3089 | | 3053 | |
| 3090 | fn tokenIdToPrefixOp(id: &const Token.Id) ?ast.NodePrefixOp.PrefixOp { | 3054 | fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.NodePrefixOp.PrefixOp { |
| 3091 | return switch (*id) { | 3055 | return switch (id) { |
| 3092 | Token.Id.Bang => ast.NodePrefixOp.PrefixOp { .BoolNot = void{} }, | 3056 | Token.Id.Bang => ast.NodePrefixOp.PrefixOp { .BoolNot = void{} }, |
| 3093 | Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} }, | 3057 | Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} }, |
| 3094 | Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} }, | 3058 | Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} }, |
| ... | @@ -3149,6 +3113,13 @@ pub const Parser = struct { | ... | @@ -3149,6 +3113,13 @@ pub const Parser = struct { |
| 3149 | ); | 3113 | ); |
| 3150 | } | 3114 | } |
| 3151 | | 3115 | |
| | 3116 | fn createToCtxLiteral(self: &Parser, arena: &mem.Allocator, opt_ctx: &const OptionalCtx, comptime T: type, token: &const Token) !&T { |
| | 3117 | const node = try self.createLiteral(arena, T, token); |
| | 3118 | opt_ctx.store(&node.base); |
| | 3119 | |
| | 3120 | return node; |
| | 3121 | } |
| | 3122 | |
| 3152 | fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) (error{ParseError}) { | 3123 | fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) (error{ParseError}) { |
| 3153 | const loc = self.tokenizer.getTokenLocation(0, token); | 3124 | const loc = self.tokenizer.getTokenLocation(0, token); |
| 3154 | warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args); | 3125 | warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args); |