| ... | ... | @@ -59,12 +59,26 @@ pub const Parser = struct { |
| 59 | 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 | 71 | const TopLevelExternOrFieldCtx = struct { |
| 63 | 72 | visib_token: Token, |
| 64 | 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 | 82 | opt_ctx: OptionalCtx, |
| 69 | 83 | ltoken: Token, |
| 70 | 84 | layout: ast.NodeContainerDecl.Layout, |
| ... | ... | @@ -80,15 +94,6 @@ pub const Parser = struct { |
| 80 | 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 | 97 | const ExprListCtx = struct { |
| 93 | 98 | list: &ArrayList(&ast.Node), |
| 94 | 99 | end: Token.Id, |
| ... | ... | @@ -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 | 115 | const LabelCtx = struct { |
| 106 | 116 | label: ?Token, |
| 107 | 117 | opt_ctx: OptionalCtx, |
| ... | ... | @@ -179,12 +189,12 @@ pub const Parser = struct { |
| 179 | 189 | TopLevelDecl: TopLevelDeclCtx, |
| 180 | 190 | TopLevelExternOrField: TopLevelExternOrFieldCtx, |
| 181 | 191 | |
| 182 | | ContainerExtern: ContainerExternCtx, |
| 192 | ContainerKind: ContainerKindCtx, |
| 183 | 193 | ContainerInitArgStart: &ast.NodeContainerDecl, |
| 184 | 194 | ContainerInitArg: &ast.NodeContainerDecl, |
| 185 | 195 | ContainerDecl: &ast.NodeContainerDecl, |
| 186 | 196 | |
| 187 | | VarDecl: &ast.NodeVarDecl, |
| 197 | VarDecl: VarDeclCtx, |
| 188 | 198 | VarDeclAlign: &ast.NodeVarDecl, |
| 189 | 199 | VarDeclEq: &ast.NodeVarDecl, |
| 190 | 200 | |
| ... | ... | @@ -199,6 +209,7 @@ pub const Parser = struct { |
| 199 | 209 | ParamDeclEnd: ParamDeclEndCtx, |
| 200 | 210 | ParamDeclComma: &ast.NodeFnProto, |
| 201 | 211 | |
| 212 | MaybeLabeledExpression: MaybeLabeledExpressionCtx, |
| 202 | 213 | LabeledExpression: LabelCtx, |
| 203 | 214 | Inline: InlineCtx, |
| 204 | 215 | While: LoopCtx, |
| ... | ... | @@ -209,7 +220,7 @@ pub const Parser = struct { |
| 209 | 220 | Block: &ast.NodeBlock, |
| 210 | 221 | Statement: &ast.NodeBlock, |
| 211 | 222 | ComptimeStatement: ComptimeStatementCtx, |
| 212 | | Semicolon: &const &const ast.Node, |
| 223 | Semicolon: &&ast.Node, |
| 213 | 224 | |
| 214 | 225 | AsmOutputItems: &ArrayList(&ast.NodeAsmOutput), |
| 215 | 226 | AsmOutputReturnOrType: &ast.NodeAsmOutput, |
| ... | ... | @@ -233,6 +244,7 @@ pub const Parser = struct { |
| 233 | 244 | AsyncAllocator: &ast.NodeAsyncAttribute, |
| 234 | 245 | AsyncEnd: AsyncEndCtx, |
| 235 | 246 | |
| 247 | ExternType: ExternTypeCtx, |
| 236 | 248 | SliceOrArrayAccess: &ast.NodeSuffixOp, |
| 237 | 249 | SliceOrArrayType: &ast.NodePrefixOp, |
| 238 | 250 | AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo, |
| ... | ... | @@ -491,6 +503,7 @@ pub const Parser = struct { |
| 491 | 503 | .lib_name = lib_name, |
| 492 | 504 | }, |
| 493 | 505 | }) catch unreachable; |
| 506 | continue; |
| 494 | 507 | }, |
| 495 | 508 | State.TopLevelDecl => |ctx| { |
| 496 | 509 | const token = self.getNextToken(); |
| ... | ... | @@ -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, |
| 528 | | ast.NodeVarDecl { |
| 529 | | .base = undefined, |
| 540 | stack.append(State { |
| 541 | .VarDecl = VarDeclCtx { |
| 530 | 542 | .visib_token = ctx.visib_token, |
| 531 | | .mut_token = token, |
| 543 | .lib_name = ctx.lib_name, |
| 532 | 544 | .comptime_token = null, |
| 533 | 545 | .extern_export_token = ctx.extern_export_inline_token, |
| 534 | | .type_node = null, |
| 535 | | .align_node = null, |
| 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, |
| 546 | .mut_token = token, |
| 547 | .list = ctx.decls |
| 563 | 548 | } |
| 564 | | ); |
| 565 | | stack.append(State { .FnDef = fn_proto }) catch unreachable; |
| 566 | | try stack.append(State { .FnProto = fn_proto }); |
| 549 | }) catch unreachable; |
| 567 | 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 | 554 | const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto, |
| 571 | 555 | ast.NodeFnProto { |
| 572 | 556 | .base = undefined, |
| ... | ... | @@ -577,7 +561,7 @@ pub const Parser = struct { |
| 577 | 561 | .return_type = undefined, |
| 578 | 562 | .var_args_token = null, |
| 579 | 563 | .extern_export_inline_token = ctx.extern_export_inline_token, |
| 580 | | .cc_token = token, |
| 564 | .cc_token = null, |
| 581 | 565 | .async_attr = null, |
| 582 | 566 | .body_node = null, |
| 583 | 567 | .lib_name = ctx.lib_name, |
| ... | ... | @@ -586,52 +570,44 @@ pub const Parser = struct { |
| 586 | 570 | ); |
| 587 | 571 | stack.append(State { .FnDef = fn_proto }) catch unreachable; |
| 588 | 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, |
| 608 | | ast.NodeFnProto { |
| 609 | | .base = undefined, |
| 610 | | .visib_token = ctx.visib_token, |
| 611 | | .name_token = null, |
| 612 | | .fn_token = undefined, |
| 613 | | .params = ArrayList(&ast.Node).init(arena), |
| 614 | | .return_type = undefined, |
| 615 | | .var_args_token = null, |
| 616 | | .extern_export_inline_token = ctx.extern_export_inline_token, |
| 617 | | .cc_token = null, |
| 618 | | .async_attr = async_node, |
| 619 | | .body_node = null, |
| 620 | | .lib_name = ctx.lib_name, |
| 621 | | .align_expr = null, |
| 622 | | } |
| 623 | | ); |
| 624 | | stack.append(State { .FnDef = fn_proto }) catch unreachable; |
| 625 | | try stack.append(State { .FnProto = fn_proto }); |
| 626 | | try stack.append(State { |
| 627 | | .ExpectTokenSave = ExpectTokenSave { |
| 628 | | .id = Token.Id.Keyword_fn, |
| 629 | | .ptr = &fn_proto.fn_token, |
| 630 | | } |
| 631 | | }); |
| 574 | switch (token.id) { |
| 575 | Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => { |
| 576 | fn_proto.cc_token = token; |
| 577 | try stack.append(State { |
| 578 | .ExpectTokenSave = ExpectTokenSave { |
| 579 | .id = Token.Id.Keyword_fn, |
| 580 | .ptr = &fn_proto.fn_token, |
| 581 | } |
| 582 | }); |
| 583 | continue; |
| 584 | }, |
| 585 | Token.Id.Keyword_async => { |
| 586 | const async_node = try self.createNode(arena, ast.NodeAsyncAttribute, |
| 587 | ast.NodeAsyncAttribute { |
| 588 | .base = undefined, |
| 589 | .async_token = token, |
| 590 | .allocator_type = null, |
| 591 | .rangle_bracket = null, |
| 592 | } |
| 593 | ); |
| 594 | fn_proto.async_attr = async_node; |
| 632 | 595 | |
| 633 | | try stack.append(State { .AsyncAllocator = async_node }); |
| 634 | | continue; |
| 596 | try stack.append(State { |
| 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 | 612 | else => { |
| 637 | 613 | return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)); |
| ... | ... | @@ -669,7 +645,7 @@ pub const Parser = struct { |
| 669 | 645 | }, |
| 670 | 646 | |
| 671 | 647 | |
| 672 | | State.ContainerExtern => |ctx| { |
| 648 | State.ContainerKind => |ctx| { |
| 673 | 649 | const token = self.getNextToken(); |
| 674 | 650 | const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeContainerDecl, |
| 675 | 651 | ast.NodeContainerDecl { |
| ... | ... | @@ -697,6 +673,7 @@ pub const Parser = struct { |
| 697 | 673 | stack.append(State { .ContainerDecl = node }) catch unreachable; |
| 698 | 674 | try stack.append(State { .ExpectToken = Token.Id.LBrace }); |
| 699 | 675 | try stack.append(State { .ContainerInitArgStart = node }); |
| 676 | continue; |
| 700 | 677 | }, |
| 701 | 678 | |
| 702 | 679 | State.ContainerInitArgStart => |container_decl| { |
| ... | ... | @@ -706,6 +683,7 @@ pub const Parser = struct { |
| 706 | 683 | |
| 707 | 684 | stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable; |
| 708 | 685 | try stack.append(State { .ContainerInitArg = container_decl }); |
| 686 | continue; |
| 709 | 687 | }, |
| 710 | 688 | |
| 711 | 689 | State.ContainerInitArg => |container_decl| { |
| ... | ... | @@ -781,6 +759,7 @@ pub const Parser = struct { |
| 781 | 759 | .container_decl = container_decl, |
| 782 | 760 | } |
| 783 | 761 | }); |
| 762 | continue; |
| 784 | 763 | }, |
| 785 | 764 | else => { |
| 786 | 765 | stack.append(State{ .ContainerDecl = container_decl }) catch unreachable; |
| ... | ... | @@ -792,6 +771,7 @@ pub const Parser = struct { |
| 792 | 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 | 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 | 830 | stack.append(State { .VarDeclAlign = var_decl }) catch unreachable; |
| 833 | 831 | try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} }); |
| 834 | 832 | try stack.append(State { .IfToken = Token.Id.Colon }); |
| ... | ... | @@ -907,12 +905,9 @@ pub const Parser = struct { |
| 907 | 905 | try stack.append(State { .ParamDecl = fn_proto }); |
| 908 | 906 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 909 | 907 | |
| 910 | | const next_token = self.getNextToken(); |
| 911 | | if (next_token.id == Token.Id.Identifier) { |
| 912 | | fn_proto.name_token = next_token; |
| 913 | | continue; |
| 908 | if (self.eatToken(Token.Id.Identifier)) |name_token| { |
| 909 | fn_proto.name_token = name_token; |
| 914 | 910 | } |
| 915 | | self.putBackToken(next_token); |
| 916 | 911 | continue; |
| 917 | 912 | }, |
| 918 | 913 | State.FnProtoAlign => |fn_proto| { |
| ... | ... | @@ -923,7 +918,6 @@ pub const Parser = struct { |
| 923 | 918 | try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } }); |
| 924 | 919 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 925 | 920 | } |
| 926 | | |
| 927 | 921 | continue; |
| 928 | 922 | }, |
| 929 | 923 | State.FnProtoReturnType => |fn_proto| { |
| ... | ... | @@ -987,6 +981,7 @@ pub const Parser = struct { |
| 987 | 981 | } else if (self.eatToken(Token.Id.Keyword_noalias)) |noalias_token| { |
| 988 | 982 | param_decl.noalias_token = noalias_token; |
| 989 | 983 | } |
| 984 | continue; |
| 990 | 985 | }, |
| 991 | 986 | State.ParamDeclName => |param_decl| { |
| 992 | 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 | 993 | self.putBackToken(ident_token); |
| 999 | 994 | } |
| 1000 | 995 | } |
| 996 | continue; |
| 1001 | 997 | }, |
| 1002 | 998 | State.ParamDeclEnd => |ctx| { |
| 1003 | 999 | if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| { |
| ... | ... | @@ -1010,6 +1006,7 @@ pub const Parser = struct { |
| 1010 | 1006 | try stack.append(State { |
| 1011 | 1007 | .TypeExprBegin = OptionalCtx { .Required = &ctx.param_decl.type_node } |
| 1012 | 1008 | }); |
| 1009 | continue; |
| 1013 | 1010 | }, |
| 1014 | 1011 | State.ParamDeclComma => |fn_proto| { |
| 1015 | 1012 | if ((try self.expectCommaOrEnd(Token.Id.RParen)) == null) { |
| ... | ... | @@ -1018,7 +1015,20 @@ pub const Parser = struct { |
| 1018 | 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 | 1032 | State.LabeledExpression => |ctx| { |
| 1023 | 1033 | const token = self.getNextToken(); |
| 1024 | 1034 | switch (token.id) { |
| ... | ... | @@ -1134,11 +1144,13 @@ pub const Parser = struct { |
| 1134 | 1144 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1135 | 1145 | try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } }); |
| 1136 | 1146 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 1147 | continue; |
| 1137 | 1148 | }, |
| 1138 | 1149 | State.WhileContinueExpr => |dest| { |
| 1139 | 1150 | stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable; |
| 1140 | 1151 | try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = dest } }); |
| 1141 | 1152 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 1153 | continue; |
| 1142 | 1154 | }, |
| 1143 | 1155 | State.For => |ctx| { |
| 1144 | 1156 | const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeFor, |
| ... | ... | @@ -1159,26 +1171,26 @@ pub const Parser = struct { |
| 1159 | 1171 | try stack.append(State { .ExpectToken = Token.Id.RParen }); |
| 1160 | 1172 | try stack.append(State { .Expression = OptionalCtx { .Required = &node.array_expr } }); |
| 1161 | 1173 | try stack.append(State { .ExpectToken = Token.Id.LParen }); |
| 1174 | continue; |
| 1162 | 1175 | }, |
| 1163 | 1176 | State.Else => |dest| { |
| 1164 | | const else_token = self.getNextToken(); |
| 1165 | | if (else_token.id != Token.Id.Keyword_else) { |
| 1166 | | self.putBackToken(else_token); |
| 1177 | if (self.eatToken(Token.Id.Keyword_else)) |else_token| { |
| 1178 | const node = try self.createNode(arena, ast.NodeElse, |
| 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 | 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 | 1219 | .block = block, |
| 1208 | 1220 | } |
| 1209 | 1221 | }) catch unreachable; |
| 1222 | continue; |
| 1210 | 1223 | }, |
| 1211 | 1224 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 1212 | | const var_decl = try self.createAttachNode(arena, &block.statements, ast.NodeVarDecl, |
| 1213 | | ast.NodeVarDecl { |
| 1214 | | .base = undefined, |
| 1225 | stack.append(State { |
| 1226 | .VarDecl = VarDeclCtx { |
| 1215 | 1227 | .visib_token = null, |
| 1216 | | .mut_token = token, |
| 1217 | 1228 | .comptime_token = null, |
| 1218 | 1229 | .extern_export_token = null, |
| 1219 | | .type_node = null, |
| 1220 | | .align_node = null, |
| 1221 | | .init_node = null, |
| 1222 | 1230 | .lib_name = null, |
| 1223 | | // initialized later |
| 1224 | | .name_token = undefined, |
| 1225 | | .eq_token = undefined, |
| 1226 | | .semicolon_token = undefined, |
| 1231 | .mut_token = token, |
| 1232 | .list = &block.statements, |
| 1227 | 1233 | } |
| 1228 | | ); |
| 1229 | | stack.append(State { .VarDecl = var_decl }) catch unreachable; |
| 1234 | }) catch unreachable; |
| 1230 | 1235 | continue; |
| 1231 | 1236 | }, |
| 1232 | 1237 | Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => { |
| ... | ... | @@ -1242,7 +1247,7 @@ pub const Parser = struct { |
| 1242 | 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 | 1251 | try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } }); |
| 1247 | 1252 | continue; |
| 1248 | 1253 | }, |
| ... | ... | @@ -1270,40 +1275,37 @@ pub const Parser = struct { |
| 1270 | 1275 | }, |
| 1271 | 1276 | State.ComptimeStatement => |ctx| { |
| 1272 | 1277 | const token = self.getNextToken(); |
| 1273 | | if (token.id == Token.Id.Keyword_var or token.id == Token.Id.Keyword_const) { |
| 1274 | | const var_decl = try self.createAttachNode(arena, &ctx.block.statements, ast.NodeVarDecl, |
| 1275 | | ast.NodeVarDecl { |
| 1276 | | .base = undefined, |
| 1277 | | .visib_token = null, |
| 1278 | | .mut_token = token, |
| 1279 | | .comptime_token = ctx.comptime_token, |
| 1280 | | .extern_export_token = null, |
| 1281 | | .type_node = null, |
| 1282 | | .align_node = null, |
| 1283 | | .init_node = null, |
| 1284 | | .lib_name = null, |
| 1285 | | // initialized later |
| 1286 | | .name_token = undefined, |
| 1287 | | .eq_token = undefined, |
| 1288 | | .semicolon_token = undefined, |
| 1289 | | } |
| 1290 | | ); |
| 1291 | | stack.append(State { .VarDecl = var_decl }) catch unreachable; |
| 1292 | | continue; |
| 1293 | | } else { |
| 1294 | | self.putBackToken(token); |
| 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; |
| 1278 | switch (token.id) { |
| 1279 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 1280 | stack.append(State { |
| 1281 | .VarDecl = VarDeclCtx { |
| 1282 | .visib_token = null, |
| 1283 | .comptime_token = ctx.comptime_token, |
| 1284 | .extern_export_token = null, |
| 1285 | .lib_name = null, |
| 1286 | .mut_token = token, |
| 1287 | .list = &ctx.block.statements, |
| 1288 | } |
| 1289 | }) catch unreachable; |
| 1290 | continue; |
| 1291 | }, |
| 1292 | else => { |
| 1293 | self.putBackToken(token); |
| 1294 | self.putBackToken(ctx.comptime_token); |
| 1295 | const statememt = try ctx.block.statements.addOne(); |
| 1296 | stack.append(State { .Semicolon = statememt }) catch unreachable; |
| 1297 | try stack.append(State { .Expression = OptionalCtx { .Required = statememt } }); |
| 1298 | continue; |
| 1299 | } |
| 1300 | 1300 | } |
| 1301 | 1301 | }, |
| 1302 | 1302 | State.Semicolon => |node_ptr| { |
| 1303 | 1303 | const node = *node_ptr; |
| 1304 | 1304 | if (requireSemiColon(node)) { |
| 1305 | 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 | 1334 | try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } }); |
| 1333 | 1335 | try stack.append(State { .ExpectToken = Token.Id.RBracket }); |
| 1334 | 1336 | try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } }); |
| 1337 | continue; |
| 1335 | 1338 | }, |
| 1336 | 1339 | State.AsmOutputReturnOrType => |node| { |
| 1337 | 1340 | const token = self.getNextToken(); |
| ... | ... | @@ -1377,11 +1380,13 @@ pub const Parser = struct { |
| 1377 | 1380 | try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } }); |
| 1378 | 1381 | try stack.append(State { .ExpectToken = Token.Id.RBracket }); |
| 1379 | 1382 | try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } }); |
| 1383 | continue; |
| 1380 | 1384 | }, |
| 1381 | 1385 | State.AsmClopperItems => |items| { |
| 1382 | 1386 | stack.append(State { .AsmClopperItems = items }) catch unreachable; |
| 1383 | 1387 | try stack.append(State { .IfToken = Token.Id.Comma }); |
| 1384 | 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 | 1398 | |
| 1394 | 1399 | stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable; |
| 1395 | 1400 | try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } }); |
| 1401 | continue; |
| 1396 | 1402 | }, |
| 1397 | 1403 | State.ExprListCommaOrEnd => |list_state| { |
| 1398 | 1404 | if (try self.expectCommaOrEnd(list_state.end)) |end| { |
| 1399 | 1405 | *list_state.ptr = end; |
| 1406 | continue; |
| 1400 | 1407 | } else { |
| 1401 | 1408 | stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable; |
| 1409 | continue; |
| 1402 | 1410 | } |
| 1403 | | continue; |
| 1404 | 1411 | }, |
| 1405 | 1412 | State.FieldInitListItemOrEnd => |list_state| { |
| 1406 | 1413 | if (self.eatToken(Token.Id.RBrace)) |rbrace| { |
| ... | ... | @@ -1433,22 +1440,25 @@ pub const Parser = struct { |
| 1433 | 1440 | .ptr = &node.period_token, |
| 1434 | 1441 | } |
| 1435 | 1442 | }); |
| 1443 | continue; |
| 1436 | 1444 | }, |
| 1437 | 1445 | State.FieldInitListCommaOrEnd => |list_state| { |
| 1438 | 1446 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| 1439 | 1447 | *list_state.ptr = end; |
| 1448 | continue; |
| 1440 | 1449 | } else { |
| 1441 | 1450 | stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable; |
| 1451 | continue; |
| 1442 | 1452 | } |
| 1443 | | continue; |
| 1444 | 1453 | }, |
| 1445 | 1454 | State.FieldListCommaOrEnd => |container_decl| { |
| 1446 | 1455 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| 1447 | 1456 | container_decl.rbrace_token = end; |
| 1457 | continue; |
| 1448 | 1458 | } else { |
| 1449 | 1459 | stack.append(State { .ContainerDecl = container_decl }) catch unreachable; |
| 1460 | continue; |
| 1450 | 1461 | } |
| 1451 | | continue; |
| 1452 | 1462 | }, |
| 1453 | 1463 | State.IdentifierListItemOrEnd => |list_state| { |
| 1454 | 1464 | if (self.eatToken(Token.Id.RBrace)) |rbrace| { |
| ... | ... | @@ -1458,14 +1468,16 @@ pub const Parser = struct { |
| 1458 | 1468 | |
| 1459 | 1469 | stack.append(State { .IdentifierListCommaOrEnd = list_state }) catch unreachable; |
| 1460 | 1470 | try stack.append(State { .Identifier = OptionalCtx { .Required = try list_state.list.addOne() } }); |
| 1471 | continue; |
| 1461 | 1472 | }, |
| 1462 | 1473 | State.IdentifierListCommaOrEnd => |list_state| { |
| 1463 | 1474 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| 1464 | 1475 | *list_state.ptr = end; |
| 1476 | continue; |
| 1465 | 1477 | } else { |
| 1466 | 1478 | stack.append(State { .IdentifierListItemOrEnd = list_state }) catch unreachable; |
| 1479 | continue; |
| 1467 | 1480 | } |
| 1468 | | continue; |
| 1469 | 1481 | }, |
| 1470 | 1482 | State.SwitchCaseOrEnd => |list_state| { |
| 1471 | 1483 | if (self.eatToken(Token.Id.RBrace)) |rbrace| { |
| ... | ... | @@ -1486,15 +1498,16 @@ pub const Parser = struct { |
| 1486 | 1498 | try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .Required = &node.expr } }); |
| 1487 | 1499 | try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } }); |
| 1488 | 1500 | try stack.append(State { .SwitchCaseFirstItem = &node.items }); |
| 1489 | | |
| 1501 | continue; |
| 1490 | 1502 | }, |
| 1491 | 1503 | State.SwitchCaseCommaOrEnd => |list_state| { |
| 1492 | 1504 | if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| { |
| 1493 | 1505 | *list_state.ptr = end; |
| 1506 | continue; |
| 1494 | 1507 | } else { |
| 1495 | 1508 | stack.append(State { .SwitchCaseOrEnd = list_state }) catch unreachable; |
| 1509 | continue; |
| 1496 | 1510 | } |
| 1497 | | continue; |
| 1498 | 1511 | }, |
| 1499 | 1512 | State.SwitchCaseFirstItem => |case_items| { |
| 1500 | 1513 | const token = self.getNextToken(); |
| ... | ... | @@ -1544,6 +1557,7 @@ pub const Parser = struct { |
| 1544 | 1557 | } |
| 1545 | 1558 | }); |
| 1546 | 1559 | try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &async_node.allocator_type } }); |
| 1560 | continue; |
| 1547 | 1561 | }, |
| 1548 | 1562 | State.AsyncEnd => |ctx| { |
| 1549 | 1563 | const node = ctx.ctx.get() ?? continue; |
| ... | ... | @@ -1552,6 +1566,7 @@ pub const Parser = struct { |
| 1552 | 1566 | ast.Node.Id.FnProto => { |
| 1553 | 1567 | const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node); |
| 1554 | 1568 | fn_proto.async_attr = ctx.attribute; |
| 1569 | continue; |
| 1555 | 1570 | }, |
| 1556 | 1571 | ast.Node.Id.SuffixOp => { |
| 1557 | 1572 | const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node); |
| ... | ... | @@ -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 | 1624 | State.SliceOrArrayAccess => |node| { |
| 1578 | 1625 | var token = self.getNextToken(); |
| 1579 | 1626 | switch (token.id) { |
| ... | ... | @@ -1692,6 +1739,7 @@ pub const Parser = struct { |
| 1692 | 1739 | } |
| 1693 | 1740 | }) catch unreachable; |
| 1694 | 1741 | try stack.append(State { .Identifier = OptionalCtx { .Required = &node.error_symbol } }); |
| 1742 | continue; |
| 1695 | 1743 | }, |
| 1696 | 1744 | State.PointerPayload => |opt_ctx| { |
| 1697 | 1745 | const token = self.getNextToken(); |
| ... | ... | @@ -1729,6 +1777,7 @@ pub const Parser = struct { |
| 1729 | 1777 | .ptr = &node.ptr_token, |
| 1730 | 1778 | } |
| 1731 | 1779 | }); |
| 1780 | continue; |
| 1732 | 1781 | }, |
| 1733 | 1782 | State.PointerIndexPayload => |opt_ctx| { |
| 1734 | 1783 | const token = self.getNextToken(); |
| ... | ... | @@ -1769,26 +1818,14 @@ pub const Parser = struct { |
| 1769 | 1818 | .ptr = &node.ptr_token, |
| 1770 | 1819 | } |
| 1771 | 1820 | }); |
| 1821 | continue; |
| 1772 | 1822 | }, |
| 1773 | 1823 | |
| 1774 | 1824 | |
| 1775 | 1825 | State.Expression => |opt_ctx| { |
| 1776 | 1826 | const token = self.getNextToken(); |
| 1777 | 1827 | switch (token.id) { |
| 1778 | | Token.Id.Keyword_return => { |
| 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 => { |
| 1828 | Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => { |
| 1792 | 1829 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeControlFlowExpression, |
| 1793 | 1830 | ast.NodeControlFlowExpression { |
| 1794 | 1831 | .base = undefined, |
| ... | ... | @@ -1811,6 +1848,9 @@ pub const Parser = struct { |
| 1811 | 1848 | try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } }); |
| 1812 | 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 | 1854 | else => unreachable, |
| 1815 | 1855 | } |
| 1816 | 1856 | continue; |
| ... | ... | @@ -1861,9 +1901,8 @@ pub const Parser = struct { |
| 1861 | 1901 | } |
| 1862 | 1902 | ); |
| 1863 | 1903 | stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable; |
| 1904 | continue; |
| 1864 | 1905 | } |
| 1865 | | |
| 1866 | | continue; |
| 1867 | 1906 | }, |
| 1868 | 1907 | State.AssignmentExpressionBegin => |opt_ctx| { |
| 1869 | 1908 | stack.append(State { .AssignmentExpressionEnd = opt_ctx }) catch unreachable; |
| ... | ... | @@ -1904,34 +1943,27 @@ pub const Parser = struct { |
| 1904 | 1943 | const lhs = opt_ctx.get() ?? continue; |
| 1905 | 1944 | |
| 1906 | 1945 | const token = self.getNextToken(); |
| 1907 | | switch (token.id) { |
| 1908 | | Token.Id.Keyword_catch, Token.Id.QuestionMarkQuestionMark => { |
| 1909 | | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 1910 | | ast.NodeInfixOp { |
| 1911 | | .base = undefined, |
| 1912 | | .lhs = lhs, |
| 1913 | | .op_token = token, |
| 1914 | | .op = switch (token.id) { |
| 1915 | | Token.Id.Keyword_catch => ast.NodeInfixOp.InfixOp { .Catch = null }, |
| 1916 | | Token.Id.QuestionMarkQuestionMark => ast.NodeInfixOp.InfixOp { .UnwrapMaybe = void{} }, |
| 1917 | | else => unreachable, |
| 1918 | | }, |
| 1919 | | .rhs = undefined, |
| 1920 | | } |
| 1921 | | ); |
| 1946 | if (tokenIdToUnwrapExpr(token.id)) |unwrap_id| { |
| 1947 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 1948 | ast.NodeInfixOp { |
| 1949 | .base = undefined, |
| 1950 | .lhs = lhs, |
| 1951 | .op_token = token, |
| 1952 | .op = unwrap_id, |
| 1953 | .rhs = undefined, |
| 1954 | } |
| 1955 | ); |
| 1922 | 1956 | |
| 1923 | | stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 1924 | | try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }); |
| 1957 | stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 1958 | try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }); |
| 1925 | 1959 | |
| 1926 | | if (node.op == ast.NodeInfixOp.InfixOp.Catch) { |
| 1927 | | try stack.append(State { .Payload = OptionalCtx { .Optional = &node.op.Catch } }); |
| 1928 | | } |
| 1929 | | continue; |
| 1930 | | }, |
| 1931 | | else => { |
| 1932 | | self.putBackToken(token); |
| 1933 | | continue; |
| 1934 | | }, |
| 1960 | if (node.op == ast.NodeInfixOp.InfixOp.Catch) { |
| 1961 | try stack.append(State { .Payload = OptionalCtx { .Optional = &node.op.Catch } }); |
| 1962 | } |
| 1963 | continue; |
| 1964 | } else { |
| 1965 | self.putBackToken(token); |
| 1966 | continue; |
| 1935 | 1967 | } |
| 1936 | 1968 | }, |
| 1937 | 1969 | |
| ... | ... | @@ -1944,26 +1976,19 @@ pub const Parser = struct { |
| 1944 | 1976 | State.BoolOrExpressionEnd => |opt_ctx| { |
| 1945 | 1977 | const lhs = opt_ctx.get() ?? continue; |
| 1946 | 1978 | |
| 1947 | | const token = self.getNextToken(); |
| 1948 | | switch (token.id) { |
| 1949 | | Token.Id.Keyword_or => { |
| 1950 | | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 1951 | | ast.NodeInfixOp { |
| 1952 | | .base = undefined, |
| 1953 | | .lhs = lhs, |
| 1954 | | .op_token = token, |
| 1955 | | .op = ast.NodeInfixOp.InfixOp.BoolOr, |
| 1956 | | .rhs = undefined, |
| 1957 | | } |
| 1958 | | ); |
| 1959 | | stack.append(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 1960 | | try stack.append(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 1961 | | continue; |
| 1962 | | }, |
| 1963 | | else => { |
| 1964 | | self.putBackToken(token); |
| 1965 | | continue; |
| 1966 | | }, |
| 1979 | if (self.eatToken(Token.Id.Keyword_or)) |or_token| { |
| 1980 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 1981 | ast.NodeInfixOp { |
| 1982 | .base = undefined, |
| 1983 | .lhs = lhs, |
| 1984 | .op_token = or_token, |
| 1985 | .op = ast.NodeInfixOp.InfixOp.BoolOr, |
| 1986 | .rhs = undefined, |
| 1987 | } |
| 1988 | ); |
| 1989 | stack.append(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 1990 | try stack.append(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 1991 | continue; |
| 1967 | 1992 | } |
| 1968 | 1993 | }, |
| 1969 | 1994 | |
| ... | ... | @@ -1976,26 +2001,19 @@ pub const Parser = struct { |
| 1976 | 2001 | State.BoolAndExpressionEnd => |opt_ctx| { |
| 1977 | 2002 | const lhs = opt_ctx.get() ?? continue; |
| 1978 | 2003 | |
| 1979 | | const token = self.getNextToken(); |
| 1980 | | switch (token.id) { |
| 1981 | | Token.Id.Keyword_and => { |
| 1982 | | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 1983 | | ast.NodeInfixOp { |
| 1984 | | .base = undefined, |
| 1985 | | .lhs = lhs, |
| 1986 | | .op_token = token, |
| 1987 | | .op = ast.NodeInfixOp.InfixOp.BoolAnd, |
| 1988 | | .rhs = undefined, |
| 1989 | | } |
| 1990 | | ); |
| 1991 | | stack.append(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 1992 | | try stack.append(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 1993 | | continue; |
| 1994 | | }, |
| 1995 | | else => { |
| 1996 | | self.putBackToken(token); |
| 1997 | | continue; |
| 1998 | | }, |
| 2004 | if (self.eatToken(Token.Id.Keyword_and)) |and_token| { |
| 2005 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2006 | ast.NodeInfixOp { |
| 2007 | .base = undefined, |
| 2008 | .lhs = lhs, |
| 2009 | .op_token = and_token, |
| 2010 | .op = ast.NodeInfixOp.InfixOp.BoolAnd, |
| 2011 | .rhs = undefined, |
| 2012 | } |
| 2013 | ); |
| 2014 | stack.append(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2015 | try stack.append(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2016 | continue; |
| 1999 | 2017 | } |
| 2000 | 2018 | }, |
| 2001 | 2019 | |
| ... | ... | @@ -2037,26 +2055,19 @@ pub const Parser = struct { |
| 2037 | 2055 | State.BinaryOrExpressionEnd => |opt_ctx| { |
| 2038 | 2056 | const lhs = opt_ctx.get() ?? continue; |
| 2039 | 2057 | |
| 2040 | | const token = self.getNextToken(); |
| 2041 | | switch (token.id) { |
| 2042 | | Token.Id.Pipe => { |
| 2043 | | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2044 | | ast.NodeInfixOp { |
| 2045 | | .base = undefined, |
| 2046 | | .lhs = lhs, |
| 2047 | | .op_token = token, |
| 2048 | | .op = ast.NodeInfixOp.InfixOp.BitOr, |
| 2049 | | .rhs = undefined, |
| 2050 | | } |
| 2051 | | ); |
| 2052 | | stack.append(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2053 | | try stack.append(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2054 | | continue; |
| 2055 | | }, |
| 2056 | | else => { |
| 2057 | | self.putBackToken(token); |
| 2058 | | continue; |
| 2059 | | }, |
| 2058 | if (self.eatToken(Token.Id.Pipe)) |pipe| { |
| 2059 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2060 | ast.NodeInfixOp { |
| 2061 | .base = undefined, |
| 2062 | .lhs = lhs, |
| 2063 | .op_token = pipe, |
| 2064 | .op = ast.NodeInfixOp.InfixOp.BitOr, |
| 2065 | .rhs = undefined, |
| 2066 | } |
| 2067 | ); |
| 2068 | stack.append(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2069 | try stack.append(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2070 | continue; |
| 2060 | 2071 | } |
| 2061 | 2072 | }, |
| 2062 | 2073 | |
| ... | ... | @@ -2069,26 +2080,19 @@ pub const Parser = struct { |
| 2069 | 2080 | State.BinaryXorExpressionEnd => |opt_ctx| { |
| 2070 | 2081 | const lhs = opt_ctx.get() ?? continue; |
| 2071 | 2082 | |
| 2072 | | const token = self.getNextToken(); |
| 2073 | | switch (token.id) { |
| 2074 | | Token.Id.Caret => { |
| 2075 | | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2076 | | ast.NodeInfixOp { |
| 2077 | | .base = undefined, |
| 2078 | | .lhs = lhs, |
| 2079 | | .op_token = token, |
| 2080 | | .op = ast.NodeInfixOp.InfixOp.BitXor, |
| 2081 | | .rhs = undefined, |
| 2082 | | } |
| 2083 | | ); |
| 2084 | | stack.append(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2085 | | try stack.append(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2086 | | continue; |
| 2087 | | }, |
| 2088 | | else => { |
| 2089 | | self.putBackToken(token); |
| 2090 | | continue; |
| 2091 | | }, |
| 2083 | if (self.eatToken(Token.Id.Caret)) |caret| { |
| 2084 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2085 | ast.NodeInfixOp { |
| 2086 | .base = undefined, |
| 2087 | .lhs = lhs, |
| 2088 | .op_token = caret, |
| 2089 | .op = ast.NodeInfixOp.InfixOp.BitXor, |
| 2090 | .rhs = undefined, |
| 2091 | } |
| 2092 | ); |
| 2093 | stack.append(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2094 | try stack.append(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2095 | continue; |
| 2092 | 2096 | } |
| 2093 | 2097 | }, |
| 2094 | 2098 | |
| ... | ... | @@ -2101,26 +2105,19 @@ pub const Parser = struct { |
| 2101 | 2105 | State.BinaryAndExpressionEnd => |opt_ctx| { |
| 2102 | 2106 | const lhs = opt_ctx.get() ?? continue; |
| 2103 | 2107 | |
| 2104 | | const token = self.getNextToken(); |
| 2105 | | switch (token.id) { |
| 2106 | | Token.Id.Ampersand => { |
| 2107 | | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2108 | | ast.NodeInfixOp { |
| 2109 | | .base = undefined, |
| 2110 | | .lhs = lhs, |
| 2111 | | .op_token = token, |
| 2112 | | .op = ast.NodeInfixOp.InfixOp.BitAnd, |
| 2113 | | .rhs = undefined, |
| 2114 | | } |
| 2115 | | ); |
| 2116 | | stack.append(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2117 | | try stack.append(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2118 | | continue; |
| 2119 | | }, |
| 2120 | | else => { |
| 2121 | | self.putBackToken(token); |
| 2122 | | continue; |
| 2123 | | }, |
| 2108 | if (self.eatToken(Token.Id.Ampersand)) |ampersand| { |
| 2109 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2110 | ast.NodeInfixOp { |
| 2111 | .base = undefined, |
| 2112 | .lhs = lhs, |
| 2113 | .op_token = ampersand, |
| 2114 | .op = ast.NodeInfixOp.InfixOp.BitAnd, |
| 2115 | .rhs = undefined, |
| 2116 | } |
| 2117 | ); |
| 2118 | stack.append(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2119 | try stack.append(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } }); |
| 2120 | continue; |
| 2124 | 2121 | } |
| 2125 | 2122 | }, |
| 2126 | 2123 | |
| ... | ... | @@ -2241,28 +2238,28 @@ pub const Parser = struct { |
| 2241 | 2238 | } |
| 2242 | 2239 | }); |
| 2243 | 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 | 2265 | State.TypeExprBegin => |opt_ctx| { |
| ... | ... | @@ -2274,26 +2271,19 @@ pub const Parser = struct { |
| 2274 | 2271 | State.TypeExprEnd => |opt_ctx| { |
| 2275 | 2272 | const lhs = opt_ctx.get() ?? continue; |
| 2276 | 2273 | |
| 2277 | | const token = self.getNextToken(); |
| 2278 | | switch (token.id) { |
| 2279 | | Token.Id.Bang => { |
| 2280 | | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2281 | | ast.NodeInfixOp { |
| 2282 | | .base = undefined, |
| 2283 | | .lhs = lhs, |
| 2284 | | .op_token = token, |
| 2285 | | .op = ast.NodeInfixOp.InfixOp.ErrorUnion, |
| 2286 | | .rhs = undefined, |
| 2287 | | } |
| 2288 | | ); |
| 2289 | | stack.append(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2290 | | try stack.append(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } }); |
| 2291 | | continue; |
| 2292 | | }, |
| 2293 | | else => { |
| 2294 | | self.putBackToken(token); |
| 2295 | | continue; |
| 2296 | | }, |
| 2274 | if (self.eatToken(Token.Id.Bang)) |bang| { |
| 2275 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp, |
| 2276 | ast.NodeInfixOp { |
| 2277 | .base = undefined, |
| 2278 | .lhs = lhs, |
| 2279 | .op_token = bang, |
| 2280 | .op = ast.NodeInfixOp.InfixOp.ErrorUnion, |
| 2281 | .rhs = undefined, |
| 2282 | } |
| 2283 | ); |
| 2284 | stack.append(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable; |
| 2285 | try stack.append(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } }); |
| 2286 | continue; |
| 2297 | 2287 | } |
| 2298 | 2288 | }, |
| 2299 | 2289 | |
| ... | ... | @@ -2309,6 +2299,7 @@ pub const Parser = struct { |
| 2309 | 2299 | } |
| 2310 | 2300 | ); |
| 2311 | 2301 | |
| 2302 | // Treat '**' token as two derefs |
| 2312 | 2303 | if (token.id == Token.Id.AsteriskAsterisk) { |
| 2313 | 2304 | const child = try self.createNode(arena, ast.NodePrefixOp, |
| 2314 | 2305 | ast.NodePrefixOp { |
| ... | ... | @@ -2335,35 +2326,30 @@ pub const Parser = struct { |
| 2335 | 2326 | }, |
| 2336 | 2327 | |
| 2337 | 2328 | State.SuffixOpExpressionBegin => |opt_ctx| { |
| 2338 | | const token = self.getNextToken(); |
| 2339 | | switch (token.id) { |
| 2340 | | Token.Id.Keyword_async => { |
| 2341 | | const async_node = try self.createNode(arena, ast.NodeAsyncAttribute, |
| 2342 | | ast.NodeAsyncAttribute { |
| 2343 | | .base = undefined, |
| 2344 | | .async_token = token, |
| 2345 | | .allocator_type = null, |
| 2346 | | .rangle_bracket = null, |
| 2347 | | } |
| 2348 | | ); |
| 2349 | | stack.append(State { |
| 2350 | | .AsyncEnd = AsyncEndCtx { |
| 2351 | | .ctx = opt_ctx, |
| 2352 | | .attribute = async_node, |
| 2353 | | } |
| 2354 | | }) catch unreachable; |
| 2355 | | try stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }); |
| 2356 | | try stack.append(State { .PrimaryExpression = opt_ctx.toRequired() }); |
| 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 | | } |
| 2329 | if (self.eatToken(Token.Id.Keyword_async)) |async_token| { |
| 2330 | const async_node = try self.createNode(arena, ast.NodeAsyncAttribute, |
| 2331 | ast.NodeAsyncAttribute { |
| 2332 | .base = undefined, |
| 2333 | .async_token = async_token, |
| 2334 | .allocator_type = null, |
| 2335 | .rangle_bracket = null, |
| 2336 | } |
| 2337 | ); |
| 2338 | stack.append(State { |
| 2339 | .AsyncEnd = AsyncEndCtx { |
| 2340 | .ctx = opt_ctx, |
| 2341 | .attribute = async_node, |
| 2342 | } |
| 2343 | }) catch unreachable; |
| 2344 | try stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }); |
| 2345 | try stack.append(State { .PrimaryExpression = opt_ctx.toRequired() }); |
| 2346 | try stack.append(State { .AsyncAllocator = async_node }); |
| 2347 | continue; |
| 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 | 2355 | State.SuffixOpExpressionEnd => |opt_ctx| { |
| ... | ... | @@ -2436,43 +2422,44 @@ pub const Parser = struct { |
| 2436 | 2422 | const token = self.getNextToken(); |
| 2437 | 2423 | switch (token.id) { |
| 2438 | 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 | 2426 | continue; |
| 2441 | 2427 | }, |
| 2442 | 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 | 2430 | continue; |
| 2445 | 2431 | }, |
| 2446 | 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 | 2434 | continue; |
| 2449 | 2435 | }, |
| 2450 | 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 | 2438 | continue; |
| 2453 | 2439 | }, |
| 2454 | 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 | 2442 | continue; |
| 2457 | 2443 | }, |
| 2458 | 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 | 2446 | continue; |
| 2461 | 2447 | }, |
| 2462 | 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 | 2450 | continue; |
| 2465 | 2451 | }, |
| 2466 | 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 | 2454 | continue; |
| 2469 | 2455 | }, |
| 2470 | 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 | 2458 | continue; |
| 2473 | 2459 | }, |
| 2474 | 2460 | Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => { |
| 2475 | 2461 | opt_ctx.store((try self.parseStringLiteral(arena, token)) ?? unreachable); |
| 2462 | continue; |
| 2476 | 2463 | }, |
| 2477 | 2464 | Token.Id.LParen => { |
| 2478 | 2465 | const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeGroupedExpression, |
| ... | ... | @@ -2521,6 +2508,7 @@ pub const Parser = struct { |
| 2521 | 2508 | } |
| 2522 | 2509 | ); |
| 2523 | 2510 | stack.append(State { .SliceOrArrayType = node }) catch unreachable; |
| 2511 | continue; |
| 2524 | 2512 | }, |
| 2525 | 2513 | Token.Id.Keyword_error => { |
| 2526 | 2514 | stack.append(State { |
| ... | ... | @@ -2529,73 +2517,41 @@ pub const Parser = struct { |
| 2529 | 2517 | .opt_ctx = opt_ctx |
| 2530 | 2518 | } |
| 2531 | 2519 | }) catch unreachable; |
| 2520 | continue; |
| 2532 | 2521 | }, |
| 2533 | 2522 | Token.Id.Keyword_packed => { |
| 2534 | 2523 | stack.append(State { |
| 2535 | | .ContainerExtern = ContainerExternCtx { |
| 2524 | .ContainerKind = ContainerKindCtx { |
| 2536 | 2525 | .opt_ctx = opt_ctx, |
| 2537 | 2526 | .ltoken = token, |
| 2538 | 2527 | .layout = ast.NodeContainerDecl.Layout.Packed, |
| 2539 | 2528 | }, |
| 2540 | 2529 | }) catch unreachable; |
| 2530 | continue; |
| 2541 | 2531 | }, |
| 2542 | 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 | 2533 | stack.append(State { |
| 2570 | | .ContainerExtern = ContainerExternCtx { |
| 2534 | .ExternType = ExternTypeCtx { |
| 2571 | 2535 | .opt_ctx = opt_ctx, |
| 2572 | | .ltoken = token, |
| 2573 | | .layout = ast.NodeContainerDecl.Layout.Extern, |
| 2536 | .extern_token = token, |
| 2574 | 2537 | }, |
| 2575 | 2538 | }) catch unreachable; |
| 2539 | continue; |
| 2576 | 2540 | }, |
| 2577 | 2541 | Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => { |
| 2578 | 2542 | self.putBackToken(token); |
| 2579 | 2543 | stack.append(State { |
| 2580 | | .ContainerExtern = ContainerExternCtx { |
| 2544 | .ContainerKind = ContainerKindCtx { |
| 2581 | 2545 | .opt_ctx = opt_ctx, |
| 2582 | 2546 | .ltoken = token, |
| 2583 | 2547 | .layout = ast.NodeContainerDecl.Layout.Auto, |
| 2584 | 2548 | }, |
| 2585 | 2549 | }) catch unreachable; |
| 2550 | continue; |
| 2586 | 2551 | }, |
| 2587 | 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 | 2553 | stack.append(State { |
| 2598 | | .LabeledExpression = LabelCtx { |
| 2554 | .MaybeLabeledExpression = MaybeLabeledExpressionCtx { |
| 2599 | 2555 | .label = token, |
| 2600 | 2556 | .opt_ctx = opt_ctx |
| 2601 | 2557 | } |
| ... | ... | @@ -2710,7 +2666,7 @@ pub const Parser = struct { |
| 2710 | 2666 | |
| 2711 | 2667 | State.ErrorTypeOrSetDecl => |ctx| { |
| 2712 | 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 | 2670 | continue; |
| 2715 | 2671 | } |
| 2716 | 2672 | |
| ... | ... | @@ -2746,7 +2702,7 @@ pub const Parser = struct { |
| 2746 | 2702 | }, |
| 2747 | 2703 | State.Identifier => |opt_ctx| { |
| 2748 | 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 | 2706 | continue; |
| 2751 | 2707 | } |
| 2752 | 2708 | |
| ... | ... | @@ -3044,8 +3000,16 @@ pub const Parser = struct { |
| 3044 | 3000 | }; |
| 3045 | 3001 | } |
| 3046 | 3002 | |
| 3047 | | fn tokenIdToComparison(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp { |
| 3048 | | return switch (*id) { |
| 3003 | fn tokenIdToUnwrapExpr(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp { |
| 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 | 3013 | Token.Id.BangEqual => ast.NodeInfixOp.InfixOp { .BangEqual = void{} }, |
| 3050 | 3014 | Token.Id.EqualEqual => ast.NodeInfixOp.InfixOp { .EqualEqual = void{} }, |
| 3051 | 3015 | Token.Id.AngleBracketLeft => ast.NodeInfixOp.InfixOp { .LessThan = void{} }, |
| ... | ... | @@ -3056,16 +3020,16 @@ pub const Parser = struct { |
| 3056 | 3020 | }; |
| 3057 | 3021 | } |
| 3058 | 3022 | |
| 3059 | | fn tokenIdToBitShift(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp { |
| 3060 | | return switch (*id) { |
| 3023 | fn tokenIdToBitShift(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp { |
| 3024 | return switch (id) { |
| 3061 | 3025 | Token.Id.AngleBracketAngleBracketLeft => ast.NodeInfixOp.InfixOp { .BitShiftLeft = void{} }, |
| 3062 | 3026 | Token.Id.AngleBracketAngleBracketRight => ast.NodeInfixOp.InfixOp { .BitShiftRight = void{} }, |
| 3063 | 3027 | else => null, |
| 3064 | 3028 | }; |
| 3065 | 3029 | } |
| 3066 | 3030 | |
| 3067 | | fn tokenIdToAddition(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp { |
| 3068 | | return switch (*id) { |
| 3031 | fn tokenIdToAddition(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp { |
| 3032 | return switch (id) { |
| 3069 | 3033 | Token.Id.Minus => ast.NodeInfixOp.InfixOp { .Sub = void{} }, |
| 3070 | 3034 | Token.Id.MinusPercent => ast.NodeInfixOp.InfixOp { .SubWrap = void{} }, |
| 3071 | 3035 | Token.Id.Plus => ast.NodeInfixOp.InfixOp { .Add = void{} }, |
| ... | ... | @@ -3075,8 +3039,8 @@ pub const Parser = struct { |
| 3075 | 3039 | }; |
| 3076 | 3040 | } |
| 3077 | 3041 | |
| 3078 | | fn tokenIdToMultiply(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp { |
| 3079 | | return switch (*id) { |
| 3042 | fn tokenIdToMultiply(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp { |
| 3043 | return switch (id) { |
| 3080 | 3044 | Token.Id.Slash => ast.NodeInfixOp.InfixOp { .Div = void{} }, |
| 3081 | 3045 | Token.Id.Asterisk => ast.NodeInfixOp.InfixOp { .Mult = void{} }, |
| 3082 | 3046 | Token.Id.AsteriskAsterisk => ast.NodeInfixOp.InfixOp { .ArrayMult = void{} }, |
| ... | ... | @@ -3087,8 +3051,8 @@ pub const Parser = struct { |
| 3087 | 3051 | }; |
| 3088 | 3052 | } |
| 3089 | 3053 | |
| 3090 | | fn tokenIdToPrefixOp(id: &const Token.Id) ?ast.NodePrefixOp.PrefixOp { |
| 3091 | | return switch (*id) { |
| 3054 | fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.NodePrefixOp.PrefixOp { |
| 3055 | return switch (id) { |
| 3092 | 3056 | Token.Id.Bang => ast.NodePrefixOp.PrefixOp { .BoolNot = void{} }, |
| 3093 | 3057 | Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} }, |
| 3094 | 3058 | Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} }, |
| ... | ... | @@ -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 | 3123 | fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) (error{ParseError}) { |
| 3153 | 3124 | const loc = self.tokenizer.getTokenLocation(0, token); |
| 3154 | 3125 | warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args); |