authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-13 10:15:12+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-13 10:15:12+02:00
log44c53c9979e30653a109b07ee90ba57e3bc8a7df
tree8748ef5e8b26492c7bcb17ba2428a2a4e2f16768
parentfad54e62bb58937e82e5ca9c58b8b2066559e849

std.zig.parser: Refactor round 2

* More work on ensuring that each state only eat one token * VarDecl parsing now constructs its node * Handling all fn parsing in the same case * Using eatToken instead of getNextToken where possible * All tokenIdTo* now takes @TagType(Token.Id) * Added a createToCtxLiteral function

1 files changed, 410 insertions(+), 439 deletions(-)

std/zig/parser.zig+410-439
......@@ -59,12 +59,26 @@ pub const Parser = struct {
5959 lib_name: ?&ast.Node,
6060 };
6161
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
6271 const TopLevelExternOrFieldCtx = struct {
6372 visib_token: Token,
6473 container_decl: &ast.NodeContainerDecl,
6574 };
6675
67 const ContainerExternCtx = struct {
76 const ExternTypeCtx = struct {
77 opt_ctx: OptionalCtx,
78 extern_token: Token,
79 };
80
81 const ContainerKindCtx = struct {
6882 opt_ctx: OptionalCtx,
6983 ltoken: Token,
7084 layout: ast.NodeContainerDecl.Layout,
......@@ -80,15 +94,6 @@ pub const Parser = struct {
8094 ptr: &?Token,
8195 };
8296
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
9297 const ExprListCtx = struct {
9398 list: &ArrayList(&ast.Node),
9499 end: Token.Id,
......@@ -102,6 +107,11 @@ pub const Parser = struct {
102107 };
103108 }
104109
110 const MaybeLabeledExpressionCtx = struct {
111 label: Token,
112 opt_ctx: OptionalCtx,
113 };
114
105115 const LabelCtx = struct {
106116 label: ?Token,
107117 opt_ctx: OptionalCtx,
......@@ -179,12 +189,12 @@ pub const Parser = struct {
179189 TopLevelDecl: TopLevelDeclCtx,
180190 TopLevelExternOrField: TopLevelExternOrFieldCtx,
181191
182 ContainerExtern: ContainerExternCtx,
192 ContainerKind: ContainerKindCtx,
183193 ContainerInitArgStart: &ast.NodeContainerDecl,
184194 ContainerInitArg: &ast.NodeContainerDecl,
185195 ContainerDecl: &ast.NodeContainerDecl,
186196
187 VarDecl: &ast.NodeVarDecl,
197 VarDecl: VarDeclCtx,
188198 VarDeclAlign: &ast.NodeVarDecl,
189199 VarDeclEq: &ast.NodeVarDecl,
190200
......@@ -199,6 +209,7 @@ pub const Parser = struct {
199209 ParamDeclEnd: ParamDeclEndCtx,
200210 ParamDeclComma: &ast.NodeFnProto,
201211
212 MaybeLabeledExpression: MaybeLabeledExpressionCtx,
202213 LabeledExpression: LabelCtx,
203214 Inline: InlineCtx,
204215 While: LoopCtx,
......@@ -209,7 +220,7 @@ pub const Parser = struct {
209220 Block: &ast.NodeBlock,
210221 Statement: &ast.NodeBlock,
211222 ComptimeStatement: ComptimeStatementCtx,
212 Semicolon: &const &const ast.Node,
223 Semicolon: &&ast.Node,
213224
214225 AsmOutputItems: &ArrayList(&ast.NodeAsmOutput),
215226 AsmOutputReturnOrType: &ast.NodeAsmOutput,
......@@ -233,6 +244,7 @@ pub const Parser = struct {
233244 AsyncAllocator: &ast.NodeAsyncAttribute,
234245 AsyncEnd: AsyncEndCtx,
235246
247 ExternType: ExternTypeCtx,
236248 SliceOrArrayAccess: &ast.NodeSuffixOp,
237249 SliceOrArrayType: &ast.NodePrefixOp,
238250 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
......@@ -491,6 +503,7 @@ pub const Parser = struct {
491503 .lib_name = lib_name,
492504 },
493505 }) catch unreachable;
506 continue;
494507 },
495508 State.TopLevelDecl => |ctx| {
496509 const token = self.getNextToken();
......@@ -524,49 +537,20 @@ pub const Parser = struct {
524537 }
525538 }
526539
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 {
530542 .visib_token = ctx.visib_token,
531 .mut_token = token,
543 .lib_name = ctx.lib_name,
532544 .comptime_token = null,
533545 .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
563548 }
564 );
565 stack.append(State { .FnDef = fn_proto }) catch unreachable;
566 try stack.append(State { .FnProto = fn_proto });
549 }) catch unreachable;
567550 continue;
568551 },
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 => {
570554 const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto,
571555 ast.NodeFnProto {
572556 .base = undefined,
......@@ -577,7 +561,7 @@ pub const Parser = struct {
577561 .return_type = undefined,
578562 .var_args_token = null,
579563 .extern_export_inline_token = ctx.extern_export_inline_token,
580 .cc_token = token,
564 .cc_token = null,
581565 .async_attr = null,
582566 .body_node = null,
583567 .lib_name = ctx.lib_name,
......@@ -586,52 +570,44 @@ pub const Parser = struct {
586570 );
587571 stack.append(State { .FnDef = fn_proto }) catch unreachable;
588572 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 );
606573
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;
632595
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 }
635611 },
636612 else => {
637613 return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id));
......@@ -669,7 +645,7 @@ pub const Parser = struct {
669645 },
670646
671647
672 State.ContainerExtern => |ctx| {
648 State.ContainerKind => |ctx| {
673649 const token = self.getNextToken();
674650 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeContainerDecl,
675651 ast.NodeContainerDecl {
......@@ -697,6 +673,7 @@ pub const Parser = struct {
697673 stack.append(State { .ContainerDecl = node }) catch unreachable;
698674 try stack.append(State { .ExpectToken = Token.Id.LBrace });
699675 try stack.append(State { .ContainerInitArgStart = node });
676 continue;
700677 },
701678
702679 State.ContainerInitArgStart => |container_decl| {
......@@ -706,6 +683,7 @@ pub const Parser = struct {
706683
707684 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
708685 try stack.append(State { .ContainerInitArg = container_decl });
686 continue;
709687 },
710688
711689 State.ContainerInitArg => |container_decl| {
......@@ -781,6 +759,7 @@ pub const Parser = struct {
781759 .container_decl = container_decl,
782760 }
783761 });
762 continue;
784763 },
785764 else => {
786765 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
......@@ -792,6 +771,7 @@ pub const Parser = struct {
792771 .lib_name = null,
793772 }
794773 });
774 continue;
795775 }
796776 }
797777 },
......@@ -828,7 +808,25 @@ pub const Parser = struct {
828808 },
829809
830810
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
832830 stack.append(State { .VarDeclAlign = var_decl }) catch unreachable;
833831 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} });
834832 try stack.append(State { .IfToken = Token.Id.Colon });
......@@ -907,12 +905,9 @@ pub const Parser = struct {
907905 try stack.append(State { .ParamDecl = fn_proto });
908906 try stack.append(State { .ExpectToken = Token.Id.LParen });
909907
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;
914910 }
915 self.putBackToken(next_token);
916911 continue;
917912 },
918913 State.FnProtoAlign => |fn_proto| {
......@@ -923,7 +918,6 @@ pub const Parser = struct {
923918 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } });
924919 try stack.append(State { .ExpectToken = Token.Id.LParen });
925920 }
926
927921 continue;
928922 },
929923 State.FnProtoReturnType => |fn_proto| {
......@@ -987,6 +981,7 @@ pub const Parser = struct {
987981 } else if (self.eatToken(Token.Id.Keyword_noalias)) |noalias_token| {
988982 param_decl.noalias_token = noalias_token;
989983 }
984 continue;
990985 },
991986 State.ParamDeclName => |param_decl| {
992987 // TODO: Here, we eat two tokens in one state. This means that we can't have
......@@ -998,6 +993,7 @@ pub const Parser = struct {
998993 self.putBackToken(ident_token);
999994 }
1000995 }
996 continue;
1001997 },
1002998 State.ParamDeclEnd => |ctx| {
1003999 if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| {
......@@ -1010,6 +1006,7 @@ pub const Parser = struct {
10101006 try stack.append(State {
10111007 .TypeExprBegin = OptionalCtx { .Required = &ctx.param_decl.type_node }
10121008 });
1009 continue;
10131010 },
10141011 State.ParamDeclComma => |fn_proto| {
10151012 if ((try self.expectCommaOrEnd(Token.Id.RParen)) == null) {
......@@ -1018,7 +1015,20 @@ pub const Parser = struct {
10181015 continue;
10191016 },
10201017
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 }
10211028
1029 _ = try self.createToCtxLiteral(arena, ctx.opt_ctx, ast.NodeIdentifier, ctx.label);
1030 continue;
1031 },
10221032 State.LabeledExpression => |ctx| {
10231033 const token = self.getNextToken();
10241034 switch (token.id) {
......@@ -1134,11 +1144,13 @@ pub const Parser = struct {
11341144 try stack.append(State { .ExpectToken = Token.Id.RParen });
11351145 try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } });
11361146 try stack.append(State { .ExpectToken = Token.Id.LParen });
1147 continue;
11371148 },
11381149 State.WhileContinueExpr => |dest| {
11391150 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
11401151 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = dest } });
11411152 try stack.append(State { .ExpectToken = Token.Id.LParen });
1153 continue;
11421154 },
11431155 State.For => |ctx| {
11441156 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeFor,
......@@ -1159,26 +1171,26 @@ pub const Parser = struct {
11591171 try stack.append(State { .ExpectToken = Token.Id.RParen });
11601172 try stack.append(State { .Expression = OptionalCtx { .Required = &node.array_expr } });
11611173 try stack.append(State { .ExpectToken = Token.Id.LParen });
1174 continue;
11621175 },
11631176 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 {
11671192 continue;
11681193 }
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 } });
11821194 },
11831195
11841196
......@@ -1207,26 +1219,19 @@ pub const Parser = struct {
12071219 .block = block,
12081220 }
12091221 }) catch unreachable;
1222 continue;
12101223 },
12111224 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 {
12151227 .visib_token = null,
1216 .mut_token = token,
12171228 .comptime_token = null,
12181229 .extern_export_token = null,
1219 .type_node = null,
1220 .align_node = null,
1221 .init_node = null,
12221230 .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,
12271233 }
1228 );
1229 stack.append(State { .VarDecl = var_decl }) catch unreachable;
1234 }) catch unreachable;
12301235 continue;
12311236 },
12321237 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
......@@ -1242,7 +1247,7 @@ pub const Parser = struct {
12421247 .expr = undefined,
12431248 }
12441249 );
1245 stack.append(State { .Semicolon = &node.base }) catch unreachable;
1250 stack.append(State { .Semicolon = &&node.base }) catch unreachable;
12461251 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
12471252 continue;
12481253 },
......@@ -1270,40 +1275,37 @@ pub const Parser = struct {
12701275 },
12711276 State.ComptimeStatement => |ctx| {
12721277 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 }
13001300 }
13011301 },
13021302 State.Semicolon => |node_ptr| {
13031303 const node = *node_ptr;
13041304 if (requireSemiColon(node)) {
13051305 stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable;
1306 continue;
13061307 }
1308 continue;
13071309 },
13081310
13091311
......@@ -1332,6 +1334,7 @@ pub const Parser = struct {
13321334 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });
13331335 try stack.append(State { .ExpectToken = Token.Id.RBracket });
13341336 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });
1337 continue;
13351338 },
13361339 State.AsmOutputReturnOrType => |node| {
13371340 const token = self.getNextToken();
......@@ -1377,11 +1380,13 @@ pub const Parser = struct {
13771380 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });
13781381 try stack.append(State { .ExpectToken = Token.Id.RBracket });
13791382 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });
1383 continue;
13801384 },
13811385 State.AsmClopperItems => |items| {
13821386 stack.append(State { .AsmClopperItems = items }) catch unreachable;
13831387 try stack.append(State { .IfToken = Token.Id.Comma });
13841388 try stack.append(State { .StringLiteral = OptionalCtx { .Required = try items.addOne() } });
1389 continue;
13851390 },
13861391
13871392
......@@ -1393,14 +1398,16 @@ pub const Parser = struct {
13931398
13941399 stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable;
13951400 try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } });
1401 continue;
13961402 },
13971403 State.ExprListCommaOrEnd => |list_state| {
13981404 if (try self.expectCommaOrEnd(list_state.end)) |end| {
13991405 *list_state.ptr = end;
1406 continue;
14001407 } else {
14011408 stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable;
1409 continue;
14021410 }
1403 continue;
14041411 },
14051412 State.FieldInitListItemOrEnd => |list_state| {
14061413 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
......@@ -1433,22 +1440,25 @@ pub const Parser = struct {
14331440 .ptr = &node.period_token,
14341441 }
14351442 });
1443 continue;
14361444 },
14371445 State.FieldInitListCommaOrEnd => |list_state| {
14381446 if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| {
14391447 *list_state.ptr = end;
1448 continue;
14401449 } else {
14411450 stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable;
1451 continue;
14421452 }
1443 continue;
14441453 },
14451454 State.FieldListCommaOrEnd => |container_decl| {
14461455 if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| {
14471456 container_decl.rbrace_token = end;
1457 continue;
14481458 } else {
14491459 stack.append(State { .ContainerDecl = container_decl }) catch unreachable;
1460 continue;
14501461 }
1451 continue;
14521462 },
14531463 State.IdentifierListItemOrEnd => |list_state| {
14541464 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
......@@ -1458,14 +1468,16 @@ pub const Parser = struct {
14581468
14591469 stack.append(State { .IdentifierListCommaOrEnd = list_state }) catch unreachable;
14601470 try stack.append(State { .Identifier = OptionalCtx { .Required = try list_state.list.addOne() } });
1471 continue;
14611472 },
14621473 State.IdentifierListCommaOrEnd => |list_state| {
14631474 if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| {
14641475 *list_state.ptr = end;
1476 continue;
14651477 } else {
14661478 stack.append(State { .IdentifierListItemOrEnd = list_state }) catch unreachable;
1479 continue;
14671480 }
1468 continue;
14691481 },
14701482 State.SwitchCaseOrEnd => |list_state| {
14711483 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
......@@ -1486,15 +1498,16 @@ pub const Parser = struct {
14861498 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .Required = &node.expr } });
14871499 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
14881500 try stack.append(State { .SwitchCaseFirstItem = &node.items });
1489
1501 continue;
14901502 },
14911503 State.SwitchCaseCommaOrEnd => |list_state| {
14921504 if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| {
14931505 *list_state.ptr = end;
1506 continue;
14941507 } else {
14951508 stack.append(State { .SwitchCaseOrEnd = list_state }) catch unreachable;
1509 continue;
14961510 }
1497 continue;
14981511 },
14991512 State.SwitchCaseFirstItem => |case_items| {
15001513 const token = self.getNextToken();
......@@ -1544,6 +1557,7 @@ pub const Parser = struct {
15441557 }
15451558 });
15461559 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &async_node.allocator_type } });
1560 continue;
15471561 },
15481562 State.AsyncEnd => |ctx| {
15491563 const node = ctx.ctx.get() ?? continue;
......@@ -1552,6 +1566,7 @@ pub const Parser = struct {
15521566 ast.Node.Id.FnProto => {
15531567 const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node);
15541568 fn_proto.async_attr = ctx.attribute;
1569 continue;
15551570 },
15561571 ast.Node.Id.SuffixOp => {
15571572 const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node);
......@@ -1574,6 +1589,38 @@ pub const Parser = struct {
15741589 },
15751590
15761591
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 },
15771624 State.SliceOrArrayAccess => |node| {
15781625 var token = self.getNextToken();
15791626 switch (token.id) {
......@@ -1692,6 +1739,7 @@ pub const Parser = struct {
16921739 }
16931740 }) catch unreachable;
16941741 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.error_symbol } });
1742 continue;
16951743 },
16961744 State.PointerPayload => |opt_ctx| {
16971745 const token = self.getNextToken();
......@@ -1729,6 +1777,7 @@ pub const Parser = struct {
17291777 .ptr = &node.ptr_token,
17301778 }
17311779 });
1780 continue;
17321781 },
17331782 State.PointerIndexPayload => |opt_ctx| {
17341783 const token = self.getNextToken();
......@@ -1769,26 +1818,14 @@ pub const Parser = struct {
17691818 .ptr = &node.ptr_token,
17701819 }
17711820 });
1821 continue;
17721822 },
17731823
17741824
17751825 State.Expression => |opt_ctx| {
17761826 const token = self.getNextToken();
17771827 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 => {
17921829 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeControlFlowExpression,
17931830 ast.NodeControlFlowExpression {
17941831 .base = undefined,
......@@ -1811,6 +1848,9 @@ pub const Parser = struct {
18111848 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } });
18121849 try stack.append(State { .IfToken = Token.Id.Colon });
18131850 },
1851 Token.Id.Keyword_return => {
1852 node.kind = ast.NodeControlFlowExpression.Kind.Return;
1853 },
18141854 else => unreachable,
18151855 }
18161856 continue;
......@@ -1861,9 +1901,8 @@ pub const Parser = struct {
18611901 }
18621902 );
18631903 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1904 continue;
18641905 }
1865
1866 continue;
18671906 },
18681907 State.AssignmentExpressionBegin => |opt_ctx| {
18691908 stack.append(State { .AssignmentExpressionEnd = opt_ctx }) catch unreachable;
......@@ -1904,34 +1943,27 @@ pub const Parser = struct {
19041943 const lhs = opt_ctx.get() ?? continue;
19051944
19061945 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 );
19221956
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 } });
19251959
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;
19351967 }
19361968 },
19371969
......@@ -1944,26 +1976,19 @@ pub const Parser = struct {
19441976 State.BoolOrExpressionEnd => |opt_ctx| {
19451977 const lhs = opt_ctx.get() ?? continue;
19461978
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;
19671992 }
19681993 },
19691994
......@@ -1976,26 +2001,19 @@ pub const Parser = struct {
19762001 State.BoolAndExpressionEnd => |opt_ctx| {
19772002 const lhs = opt_ctx.get() ?? continue;
19782003
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;
19992017 }
20002018 },
20012019
......@@ -2037,26 +2055,19 @@ pub const Parser = struct {
20372055 State.BinaryOrExpressionEnd => |opt_ctx| {
20382056 const lhs = opt_ctx.get() ?? continue;
20392057
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;
20602071 }
20612072 },
20622073
......@@ -2069,26 +2080,19 @@ pub const Parser = struct {
20692080 State.BinaryXorExpressionEnd => |opt_ctx| {
20702081 const lhs = opt_ctx.get() ?? continue;
20712082
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;
20922096 }
20932097 },
20942098
......@@ -2101,26 +2105,19 @@ pub const Parser = struct {
21012105 State.BinaryAndExpressionEnd => |opt_ctx| {
21022106 const lhs = opt_ctx.get() ?? continue;
21032107
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;
21242121 }
21252122 },
21262123
......@@ -2241,28 +2238,28 @@ pub const Parser = struct {
22412238 }
22422239 });
22432240 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;
22652241 }
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;
22662263 },
22672264
22682265 State.TypeExprBegin => |opt_ctx| {
......@@ -2274,26 +2271,19 @@ pub const Parser = struct {
22742271 State.TypeExprEnd => |opt_ctx| {
22752272 const lhs = opt_ctx.get() ?? continue;
22762273
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;
22972287 }
22982288 },
22992289
......@@ -2309,6 +2299,7 @@ pub const Parser = struct {
23092299 }
23102300 );
23112301
2302 // Treat '**' token as two derefs
23122303 if (token.id == Token.Id.AsteriskAsterisk) {
23132304 const child = try self.createNode(arena, ast.NodePrefixOp,
23142305 ast.NodePrefixOp {
......@@ -2335,35 +2326,30 @@ pub const Parser = struct {
23352326 },
23362327
23372328 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;
23662348 }
2349
2350 stack.append(State { .SuffixOpExpressionEnd = opt_ctx }) catch unreachable;
2351 try stack.append(State { .PrimaryExpression = opt_ctx });
2352 continue;
23672353 },
23682354
23692355 State.SuffixOpExpressionEnd => |opt_ctx| {
......@@ -2436,43 +2422,44 @@ pub const Parser = struct {
24362422 const token = self.getNextToken();
24372423 switch (token.id) {
24382424 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);
24402426 continue;
24412427 },
24422428 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);
24442430 continue;
24452431 },
24462432 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);
24482434 continue;
24492435 },
24502436 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);
24522438 continue;
24532439 },
24542440 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);
24562442 continue;
24572443 },
24582444 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);
24602446 continue;
24612447 },
24622448 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);
24642450 continue;
24652451 },
24662452 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);
24682454 continue;
24692455 },
24702456 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);
24722458 continue;
24732459 },
24742460 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
24752461 opt_ctx.store((try self.parseStringLiteral(arena, token)) ?? unreachable);
2462 continue;
24762463 },
24772464 Token.Id.LParen => {
24782465 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeGroupedExpression,
......@@ -2521,6 +2508,7 @@ pub const Parser = struct {
25212508 }
25222509 );
25232510 stack.append(State { .SliceOrArrayType = node }) catch unreachable;
2511 continue;
25242512 },
25252513 Token.Id.Keyword_error => {
25262514 stack.append(State {
......@@ -2529,73 +2517,41 @@ pub const Parser = struct {
25292517 .opt_ctx = opt_ctx
25302518 }
25312519 }) catch unreachable;
2520 continue;
25322521 },
25332522 Token.Id.Keyword_packed => {
25342523 stack.append(State {
2535 .ContainerExtern = ContainerExternCtx {
2524 .ContainerKind = ContainerKindCtx {
25362525 .opt_ctx = opt_ctx,
25372526 .ltoken = token,
25382527 .layout = ast.NodeContainerDecl.Layout.Packed,
25392528 },
25402529 }) catch unreachable;
2530 continue;
25412531 },
25422532 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);
25692533 stack.append(State {
2570 .ContainerExtern = ContainerExternCtx {
2534 .ExternType = ExternTypeCtx {
25712535 .opt_ctx = opt_ctx,
2572 .ltoken = token,
2573 .layout = ast.NodeContainerDecl.Layout.Extern,
2536 .extern_token = token,
25742537 },
25752538 }) catch unreachable;
2539 continue;
25762540 },
25772541 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
25782542 self.putBackToken(token);
25792543 stack.append(State {
2580 .ContainerExtern = ContainerExternCtx {
2544 .ContainerKind = ContainerKindCtx {
25812545 .opt_ctx = opt_ctx,
25822546 .ltoken = token,
25832547 .layout = ast.NodeContainerDecl.Layout.Auto,
25842548 },
25852549 }) catch unreachable;
2550 continue;
25862551 },
25872552 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
25972553 stack.append(State {
2598 .LabeledExpression = LabelCtx {
2554 .MaybeLabeledExpression = MaybeLabeledExpressionCtx {
25992555 .label = token,
26002556 .opt_ctx = opt_ctx
26012557 }
......@@ -2710,7 +2666,7 @@ pub const Parser = struct {
27102666
27112667 State.ErrorTypeOrSetDecl => |ctx| {
27122668 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);
27142670 continue;
27152671 }
27162672
......@@ -2746,7 +2702,7 @@ pub const Parser = struct {
27462702 },
27472703 State.Identifier => |opt_ctx| {
27482704 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);
27502706 continue;
27512707 }
27522708
......@@ -3044,8 +3000,16 @@ pub const Parser = struct {
30443000 };
30453001 }
30463002
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) {
30493013 Token.Id.BangEqual => ast.NodeInfixOp.InfixOp { .BangEqual = void{} },
30503014 Token.Id.EqualEqual => ast.NodeInfixOp.InfixOp { .EqualEqual = void{} },
30513015 Token.Id.AngleBracketLeft => ast.NodeInfixOp.InfixOp { .LessThan = void{} },
......@@ -3056,16 +3020,16 @@ pub const Parser = struct {
30563020 };
30573021 }
30583022
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) {
30613025 Token.Id.AngleBracketAngleBracketLeft => ast.NodeInfixOp.InfixOp { .BitShiftLeft = void{} },
30623026 Token.Id.AngleBracketAngleBracketRight => ast.NodeInfixOp.InfixOp { .BitShiftRight = void{} },
30633027 else => null,
30643028 };
30653029 }
30663030
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) {
30693033 Token.Id.Minus => ast.NodeInfixOp.InfixOp { .Sub = void{} },
30703034 Token.Id.MinusPercent => ast.NodeInfixOp.InfixOp { .SubWrap = void{} },
30713035 Token.Id.Plus => ast.NodeInfixOp.InfixOp { .Add = void{} },
......@@ -3075,8 +3039,8 @@ pub const Parser = struct {
30753039 };
30763040 }
30773041
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) {
30803044 Token.Id.Slash => ast.NodeInfixOp.InfixOp { .Div = void{} },
30813045 Token.Id.Asterisk => ast.NodeInfixOp.InfixOp { .Mult = void{} },
30823046 Token.Id.AsteriskAsterisk => ast.NodeInfixOp.InfixOp { .ArrayMult = void{} },
......@@ -3087,8 +3051,8 @@ pub const Parser = struct {
30873051 };
30883052 }
30893053
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) {
30923056 Token.Id.Bang => ast.NodePrefixOp.PrefixOp { .BoolNot = void{} },
30933057 Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} },
30943058 Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} },
......@@ -3149,6 +3113,13 @@ pub const Parser = struct {
31493113 );
31503114 }
31513115
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
31523123 fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) (error{ParseError}) {
31533124 const loc = self.tokenizer.getTokenLocation(0, token);
31543125 warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);