authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-13 11:17:09-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2018-04-13 11:17:09-04:00
log4662fd4d92b216708390a2056a201c91773b9bc6
tree15edb79059e5a4695287a78a6293c0b015dc0727
parent30c5f3c441e6090f29c0540b1fa8a20d6bd2fc0d
parenta498993fd102c649c3d24f73f064c5bbafb9b3ec
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #919 from zig-lang/self-hosted-parser-refactor

Self-hosted parser refactor

2 files changed, 1996 insertions(+), 1942 deletions(-)

std/zig/ast.zig+55-39
......@@ -283,13 +283,13 @@ pub const NodeUse = struct {
283283pub const NodeErrorSetDecl = struct {
284284 base: Node,
285285 error_token: Token,
286 decls: ArrayList(&NodeIdentifier),
286 decls: ArrayList(&Node),
287287 rbrace_token: Token,
288288
289289 pub fn iterate(self: &NodeErrorSetDecl, index: usize) ?&Node {
290290 var i = index;
291291
292 if (i < self.decls.len) return &self.decls.at(i).base;
292 if (i < self.decls.len) return self.decls.at(i);
293293 i -= self.decls.len;
294294
295295 return null;
......@@ -676,13 +676,13 @@ pub const NodeComptime = struct {
676676pub const NodePayload = struct {
677677 base: Node,
678678 lpipe: Token,
679 error_symbol: &NodeIdentifier,
679 error_symbol: &Node,
680680 rpipe: Token,
681681
682682 pub fn iterate(self: &NodePayload, index: usize) ?&Node {
683683 var i = index;
684684
685 if (i < 1) return &self.error_symbol.base;
685 if (i < 1) return self.error_symbol;
686686 i -= 1;
687687
688688 return null;
......@@ -700,14 +700,14 @@ pub const NodePayload = struct {
700700pub const NodePointerPayload = struct {
701701 base: Node,
702702 lpipe: Token,
703 is_ptr: bool,
704 value_symbol: &NodeIdentifier,
703 ptr_token: ?Token,
704 value_symbol: &Node,
705705 rpipe: Token,
706706
707707 pub fn iterate(self: &NodePointerPayload, index: usize) ?&Node {
708708 var i = index;
709709
710 if (i < 1) return &self.value_symbol.base;
710 if (i < 1) return self.value_symbol;
711711 i -= 1;
712712
713713 return null;
......@@ -725,19 +725,19 @@ pub const NodePointerPayload = struct {
725725pub const NodePointerIndexPayload = struct {
726726 base: Node,
727727 lpipe: Token,
728 is_ptr: bool,
729 value_symbol: &NodeIdentifier,
730 index_symbol: ?&NodeIdentifier,
728 ptr_token: ?Token,
729 value_symbol: &Node,
730 index_symbol: ?&Node,
731731 rpipe: Token,
732732
733733 pub fn iterate(self: &NodePointerIndexPayload, index: usize) ?&Node {
734734 var i = index;
735735
736 if (i < 1) return &self.value_symbol.base;
736 if (i < 1) return self.value_symbol;
737737 i -= 1;
738738
739739 if (self.index_symbol) |index_symbol| {
740 if (i < 1) return &index_symbol.base;
740 if (i < 1) return index_symbol;
741741 i -= 1;
742742 }
743743
......@@ -756,14 +756,14 @@ pub const NodePointerIndexPayload = struct {
756756pub const NodeElse = struct {
757757 base: Node,
758758 else_token: Token,
759 payload: ?&NodePayload,
759 payload: ?&Node,
760760 body: &Node,
761761
762762 pub fn iterate(self: &NodeElse, index: usize) ?&Node {
763763 var i = index;
764764
765765 if (self.payload) |payload| {
766 if (i < 1) return &payload.base;
766 if (i < 1) return payload;
767767 i -= 1;
768768 }
769769
......@@ -813,7 +813,7 @@ pub const NodeSwitch = struct {
813813pub const NodeSwitchCase = struct {
814814 base: Node,
815815 items: ArrayList(&Node),
816 payload: ?&NodePointerPayload,
816 payload: ?&Node,
817817 expr: &Node,
818818
819819 pub fn iterate(self: &NodeSwitchCase, index: usize) ?&Node {
......@@ -823,7 +823,7 @@ pub const NodeSwitchCase = struct {
823823 i -= self.items.len;
824824
825825 if (self.payload) |payload| {
826 if (i < 1) return &payload.base;
826 if (i < 1) return payload;
827827 i -= 1;
828828 }
829829
......@@ -865,7 +865,7 @@ pub const NodeWhile = struct {
865865 inline_token: ?Token,
866866 while_token: Token,
867867 condition: &Node,
868 payload: ?&NodePointerPayload,
868 payload: ?&Node,
869869 continue_expr: ?&Node,
870870 body: &Node,
871871 @"else": ?&NodeElse,
......@@ -877,7 +877,7 @@ pub const NodeWhile = struct {
877877 i -= 1;
878878
879879 if (self.payload) |payload| {
880 if (i < 1) return &payload.base;
880 if (i < 1) return payload;
881881 i -= 1;
882882 }
883883
......@@ -924,7 +924,7 @@ pub const NodeFor = struct {
924924 inline_token: ?Token,
925925 for_token: Token,
926926 array_expr: &Node,
927 payload: ?&NodePointerIndexPayload,
927 payload: ?&Node,
928928 body: &Node,
929929 @"else": ?&NodeElse,
930930
......@@ -935,7 +935,7 @@ pub const NodeFor = struct {
935935 i -= 1;
936936
937937 if (self.payload) |payload| {
938 if (i < 1) return &payload.base;
938 if (i < 1) return payload;
939939 i -= 1;
940940 }
941941
......@@ -975,7 +975,7 @@ pub const NodeIf = struct {
975975 base: Node,
976976 if_token: Token,
977977 condition: &Node,
978 payload: ?&NodePointerPayload,
978 payload: ?&Node,
979979 body: &Node,
980980 @"else": ?&NodeElse,
981981
......@@ -986,7 +986,7 @@ pub const NodeIf = struct {
986986 i -= 1;
987987
988988 if (self.payload) |payload| {
989 if (i < 1) return &payload.base;
989 if (i < 1) return payload;
990990 i -= 1;
991991 }
992992
......@@ -1048,7 +1048,7 @@ pub const NodeInfixOp = struct {
10481048 BitXor,
10491049 BoolAnd,
10501050 BoolOr,
1051 Catch: ?&NodePayload,
1051 Catch: ?&Node,
10521052 Div,
10531053 EqualEqual,
10541054 ErrorUnion,
......@@ -1076,7 +1076,7 @@ pub const NodeInfixOp = struct {
10761076 switch (self.op) {
10771077 InfixOp.Catch => |maybe_payload| {
10781078 if (maybe_payload) |payload| {
1079 if (i < 1) return &payload.base;
1079 if (i < 1) return payload;
10801080 i -= 1;
10811081 }
10821082 },
......@@ -1344,14 +1344,30 @@ pub const NodeControlFlowExpression = struct {
13441344 rhs: ?&Node,
13451345
13461346 const Kind = union(enum) {
1347 Break: ?Token,
1348 Continue: ?Token,
1347 Break: ?&Node,
1348 Continue: ?&Node,
13491349 Return,
13501350 };
13511351
13521352 pub fn iterate(self: &NodeControlFlowExpression, index: usize) ?&Node {
13531353 var i = index;
13541354
1355 switch (self.kind) {
1356 Kind.Break => |maybe_label| {
1357 if (maybe_label) |label| {
1358 if (i < 1) return label;
1359 i -= 1;
1360 }
1361 },
1362 Kind.Continue => |maybe_label| {
1363 if (maybe_label) |label| {
1364 if (i < 1) return label;
1365 i -= 1;
1366 }
1367 },
1368 Kind.Return => {},
1369 }
1370
13551371 if (self.rhs) |rhs| {
13561372 if (i < 1) return rhs;
13571373 i -= 1;
......@@ -1370,14 +1386,14 @@ pub const NodeControlFlowExpression = struct {
13701386 }
13711387
13721388 switch (self.kind) {
1373 Kind.Break => |maybe_blk_token| {
1374 if (maybe_blk_token) |blk_token| {
1375 return blk_token;
1389 Kind.Break => |maybe_label| {
1390 if (maybe_label) |label| {
1391 return label.lastToken();
13761392 }
13771393 },
1378 Kind.Continue => |maybe_blk_token| {
1379 if (maybe_blk_token) |blk_token| {
1380 return blk_token;
1394 Kind.Continue => |maybe_label| {
1395 if (maybe_label) |label| {
1396 return label.lastToken();
13811397 }
13821398 },
13831399 Kind.Return => return self.ltoken,
......@@ -1390,14 +1406,14 @@ pub const NodeControlFlowExpression = struct {
13901406pub const NodeSuspend = struct {
13911407 base: Node,
13921408 suspend_token: Token,
1393 payload: ?&NodePayload,
1409 payload: ?&Node,
13941410 body: ?&Node,
13951411
13961412 pub fn iterate(self: &NodeSuspend, index: usize) ?&Node {
13971413 var i = index;
13981414
13991415 if (self.payload) |payload| {
1400 if (i < 1) return &payload.base;
1416 if (i < 1) return payload;
14011417 i -= 1;
14021418 }
14031419
......@@ -1605,7 +1621,7 @@ pub const NodeThisLiteral = struct {
16051621
16061622pub const NodeAsmOutput = struct {
16071623 base: Node,
1608 symbolic_name: &NodeIdentifier,
1624 symbolic_name: &Node,
16091625 constraint: &Node,
16101626 kind: Kind,
16111627
......@@ -1617,7 +1633,7 @@ pub const NodeAsmOutput = struct {
16171633 pub fn iterate(self: &NodeAsmOutput, index: usize) ?&Node {
16181634 var i = index;
16191635
1620 if (i < 1) return &self.symbolic_name.base;
1636 if (i < 1) return self.symbolic_name;
16211637 i -= 1;
16221638
16231639 if (i < 1) return self.constraint;
......@@ -1651,14 +1667,14 @@ pub const NodeAsmOutput = struct {
16511667
16521668pub const NodeAsmInput = struct {
16531669 base: Node,
1654 symbolic_name: &NodeIdentifier,
1670 symbolic_name: &Node,
16551671 constraint: &Node,
16561672 expr: &Node,
16571673
16581674 pub fn iterate(self: &NodeAsmInput, index: usize) ?&Node {
16591675 var i = index;
16601676
1661 if (i < 1) return &self.symbolic_name.base;
1677 if (i < 1) return self.symbolic_name;
16621678 i -= 1;
16631679
16641680 if (i < 1) return self.constraint;
......@@ -1682,7 +1698,7 @@ pub const NodeAsmInput = struct {
16821698pub const NodeAsm = struct {
16831699 base: Node,
16841700 asm_token: Token,
1685 is_volatile: bool,
1701 volatile_token: ?Token,
16861702 template: &Node,
16871703 //tokens: ArrayList(AsmToken),
16881704 outputs: ArrayList(&NodeAsmOutput),
std/zig/parser.zig+1941-1903
......@@ -59,29 +59,29 @@ pub const Parser = struct {
5959 lib_name: ?&ast.Node,
6060 };
6161
62 const ContainerExternCtx = struct {
63 dest_ptr: DestPtr,
64 ltoken: Token,
65 layout: ast.NodeContainerDecl.Layout,
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),
6669 };
6770
68 const DestPtr = union(enum) {
69 Field: &&ast.Node,
70 NullableField: &?&ast.Node,
71 const TopLevelExternOrFieldCtx = struct {
72 visib_token: Token,
73 container_decl: &ast.NodeContainerDecl,
74 };
7175
72 pub fn store(self: &const DestPtr, value: &ast.Node) void {
73 switch (*self) {
74 DestPtr.Field => |ptr| *ptr = value,
75 DestPtr.NullableField => |ptr| *ptr = value,
76 }
77 }
76 const ExternTypeCtx = struct {
77 opt_ctx: OptionalCtx,
78 extern_token: Token,
79 };
7880
79 pub fn get(self: &const DestPtr) &ast.Node {
80 switch (*self) {
81 DestPtr.Field => |ptr| return *ptr,
82 DestPtr.NullableField => |ptr| return ??*ptr,
83 }
84 }
81 const ContainerKindCtx = struct {
82 opt_ctx: OptionalCtx,
83 ltoken: Token,
84 layout: ast.NodeContainerDecl.Layout,
8585 };
8686
8787 const ExpectTokenSave = struct {
......@@ -89,13 +89,9 @@ pub const Parser = struct {
8989 ptr: &Token,
9090 };
9191
92 const RevertState = struct {
93 parser: Parser,
94 tokenizer: Tokenizer,
95
96 // We expect, that if something is optional, then there is a field,
97 // that needs to be set to null, when we revert.
98 ptr: &?&ast.Node,
92 const OptionalTokenSave = struct {
93 id: Token.Id,
94 ptr: &?Token,
9995 };
10096
10197 const ExprListCtx = struct {
......@@ -104,11 +100,6 @@ pub const Parser = struct {
104100 ptr: &Token,
105101 };
106102
107 const ElseCtx = struct {
108 payload: ?DestPtr,
109 body: DestPtr,
110 };
111
112103 fn ListSave(comptime T: type) type {
113104 return struct {
114105 list: &ArrayList(T),
......@@ -116,120 +107,196 @@ pub const Parser = struct {
116107 };
117108 }
118109
110 const MaybeLabeledExpressionCtx = struct {
111 label: Token,
112 opt_ctx: OptionalCtx,
113 };
114
119115 const LabelCtx = struct {
120116 label: ?Token,
121 dest_ptr: DestPtr,
117 opt_ctx: OptionalCtx,
122118 };
123119
124120 const InlineCtx = struct {
125121 label: ?Token,
126122 inline_token: ?Token,
127 dest_ptr: DestPtr,
123 opt_ctx: OptionalCtx,
128124 };
129125
130126 const LoopCtx = struct {
131127 label: ?Token,
132128 inline_token: ?Token,
133129 loop_token: Token,
134 dest_ptr: DestPtr,
130 opt_ctx: OptionalCtx,
135131 };
136132
137133 const AsyncEndCtx = struct {
138 dest_ptr: DestPtr,
134 ctx: OptionalCtx,
139135 attribute: &ast.NodeAsyncAttribute,
140136 };
141137
138 const ErrorTypeOrSetDeclCtx = struct {
139 opt_ctx: OptionalCtx,
140 error_token: Token,
141 };
142
143 const ParamDeclEndCtx = struct {
144 fn_proto: &ast.NodeFnProto,
145 param_decl: &ast.NodeParamDecl,
146 };
147
148 const ComptimeStatementCtx = struct {
149 comptime_token: Token,
150 block: &ast.NodeBlock,
151 };
152
153 const OptionalCtx = union(enum) {
154 Optional: &?&ast.Node,
155 RequiredNull: &?&ast.Node,
156 Required: &&ast.Node,
157
158 pub fn store(self: &const OptionalCtx, value: &ast.Node) void {
159 switch (*self) {
160 OptionalCtx.Optional => |ptr| *ptr = value,
161 OptionalCtx.RequiredNull => |ptr| *ptr = value,
162 OptionalCtx.Required => |ptr| *ptr = value,
163 }
164 }
165
166 pub fn get(self: &const OptionalCtx) ?&ast.Node {
167 switch (*self) {
168 OptionalCtx.Optional => |ptr| return *ptr,
169 OptionalCtx.RequiredNull => |ptr| return ??*ptr,
170 OptionalCtx.Required => |ptr| return *ptr,
171 }
172 }
173
174 pub fn toRequired(self: &const OptionalCtx) OptionalCtx {
175 switch (*self) {
176 OptionalCtx.Optional => |ptr| {
177 return OptionalCtx { .RequiredNull = ptr };
178 },
179 OptionalCtx.RequiredNull => |ptr| return *self,
180 OptionalCtx.Required => |ptr| return *self,
181 }
182 }
183 };
184
142185 const State = union(enum) {
143186 TopLevel,
144187 TopLevelExtern: TopLevelDeclCtx,
145188 TopLevelLibname: TopLevelDeclCtx,
146189 TopLevelDecl: TopLevelDeclCtx,
147 ContainerExtern: ContainerExternCtx,
190 TopLevelExternOrField: TopLevelExternOrFieldCtx,
191
192 ContainerKind: ContainerKindCtx,
193 ContainerInitArgStart: &ast.NodeContainerDecl,
194 ContainerInitArg: &ast.NodeContainerDecl,
148195 ContainerDecl: &ast.NodeContainerDecl,
149 SliceOrArrayAccess: &ast.NodeSuffixOp,
150 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
151 VarDecl: &ast.NodeVarDecl,
196
197 VarDecl: VarDeclCtx,
152198 VarDeclAlign: &ast.NodeVarDecl,
153199 VarDeclEq: &ast.NodeVarDecl,
154 IfToken: @TagType(Token.Id),
155 IfTokenSave: ExpectTokenSave,
156 ExpectToken: @TagType(Token.Id),
157 ExpectTokenSave: ExpectTokenSave,
200
201 FnDef: &ast.NodeFnProto,
158202 FnProto: &ast.NodeFnProto,
159203 FnProtoAlign: &ast.NodeFnProto,
160204 FnProtoReturnType: &ast.NodeFnProto,
205
161206 ParamDecl: &ast.NodeFnProto,
162 ParamDeclComma,
163 FnDef: &ast.NodeFnProto,
207 ParamDeclAliasOrComptime: &ast.NodeParamDecl,
208 ParamDeclName: &ast.NodeParamDecl,
209 ParamDeclEnd: ParamDeclEndCtx,
210 ParamDeclComma: &ast.NodeFnProto,
211
212 MaybeLabeledExpression: MaybeLabeledExpressionCtx,
164213 LabeledExpression: LabelCtx,
165214 Inline: InlineCtx,
166215 While: LoopCtx,
216 WhileContinueExpr: &?&ast.Node,
167217 For: LoopCtx,
168 Block: &ast.NodeBlock,
169218 Else: &?&ast.NodeElse,
170 WhileContinueExpr: &?&ast.Node,
219
220 Block: &ast.NodeBlock,
171221 Statement: &ast.NodeBlock,
172 Semicolon: &const &const ast.Node,
222 ComptimeStatement: ComptimeStatementCtx,
223 Semicolon: &&ast.Node,
224
173225 AsmOutputItems: &ArrayList(&ast.NodeAsmOutput),
226 AsmOutputReturnOrType: &ast.NodeAsmOutput,
174227 AsmInputItems: &ArrayList(&ast.NodeAsmInput),
175228 AsmClopperItems: &ArrayList(&ast.Node),
229
176230 ExprListItemOrEnd: ExprListCtx,
177231 ExprListCommaOrEnd: ExprListCtx,
178232 FieldInitListItemOrEnd: ListSave(&ast.NodeFieldInitializer),
179233 FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),
180234 FieldListCommaOrEnd: &ast.NodeContainerDecl,
181 IdentifierListItemOrEnd: ListSave(&ast.NodeIdentifier),
182 IdentifierListCommaOrEnd: ListSave(&ast.NodeIdentifier),
235 IdentifierListItemOrEnd: ListSave(&ast.Node),
236 IdentifierListCommaOrEnd: ListSave(&ast.Node),
183237 SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),
184 SuspendBody: &ast.NodeSuspend,
185 AsyncEnd: AsyncEndCtx,
186 Payload: &?&ast.NodePayload,
187 PointerPayload: &?&ast.NodePointerPayload,
188 PointerIndexPayload: &?&ast.NodePointerIndexPayload,
189238 SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase),
239 SwitchCaseFirstItem: &ArrayList(&ast.Node),
190240 SwitchCaseItem: &ArrayList(&ast.Node),
191241 SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node),
192242
193 /// A state that can be appended before any other State. If an error occures,
194 /// the parser will first try looking for the closest optional state. If an
195 /// optional state is found, the parser will revert to the state it was in
196 /// when the optional was added. This will polute the arena allocator with
197 /// "leaked" nodes. TODO: Figure out if it's nessesary to handle leaked nodes.
198 Optional: RevertState,
199
200 Expression: DestPtr,
201 RangeExpressionBegin: DestPtr,
202 RangeExpressionEnd: DestPtr,
203 AssignmentExpressionBegin: DestPtr,
204 AssignmentExpressionEnd: DestPtr,
205 UnwrapExpressionBegin: DestPtr,
206 UnwrapExpressionEnd: DestPtr,
207 BoolOrExpressionBegin: DestPtr,
208 BoolOrExpressionEnd: DestPtr,
209 BoolAndExpressionBegin: DestPtr,
210 BoolAndExpressionEnd: DestPtr,
211 ComparisonExpressionBegin: DestPtr,
212 ComparisonExpressionEnd: DestPtr,
213 BinaryOrExpressionBegin: DestPtr,
214 BinaryOrExpressionEnd: DestPtr,
215 BinaryXorExpressionBegin: DestPtr,
216 BinaryXorExpressionEnd: DestPtr,
217 BinaryAndExpressionBegin: DestPtr,
218 BinaryAndExpressionEnd: DestPtr,
219 BitShiftExpressionBegin: DestPtr,
220 BitShiftExpressionEnd: DestPtr,
221 AdditionExpressionBegin: DestPtr,
222 AdditionExpressionEnd: DestPtr,
223 MultiplyExpressionBegin: DestPtr,
224 MultiplyExpressionEnd: DestPtr,
225 CurlySuffixExpressionBegin: DestPtr,
226 CurlySuffixExpressionEnd: DestPtr,
227 TypeExprBegin: DestPtr,
228 TypeExprEnd: DestPtr,
229 PrefixOpExpression: DestPtr,
230 SuffixOpExpressionBegin: DestPtr,
231 SuffixOpExpressionEnd: DestPtr,
232 PrimaryExpression: DestPtr,
243 SuspendBody: &ast.NodeSuspend,
244 AsyncAllocator: &ast.NodeAsyncAttribute,
245 AsyncEnd: AsyncEndCtx,
246
247 ExternType: ExternTypeCtx,
248 SliceOrArrayAccess: &ast.NodeSuffixOp,
249 SliceOrArrayType: &ast.NodePrefixOp,
250 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
251
252 Payload: OptionalCtx,
253 PointerPayload: OptionalCtx,
254 PointerIndexPayload: OptionalCtx,
255
256 Expression: OptionalCtx,
257 RangeExpressionBegin: OptionalCtx,
258 RangeExpressionEnd: OptionalCtx,
259 AssignmentExpressionBegin: OptionalCtx,
260 AssignmentExpressionEnd: OptionalCtx,
261 UnwrapExpressionBegin: OptionalCtx,
262 UnwrapExpressionEnd: OptionalCtx,
263 BoolOrExpressionBegin: OptionalCtx,
264 BoolOrExpressionEnd: OptionalCtx,
265 BoolAndExpressionBegin: OptionalCtx,
266 BoolAndExpressionEnd: OptionalCtx,
267 ComparisonExpressionBegin: OptionalCtx,
268 ComparisonExpressionEnd: OptionalCtx,
269 BinaryOrExpressionBegin: OptionalCtx,
270 BinaryOrExpressionEnd: OptionalCtx,
271 BinaryXorExpressionBegin: OptionalCtx,
272 BinaryXorExpressionEnd: OptionalCtx,
273 BinaryAndExpressionBegin: OptionalCtx,
274 BinaryAndExpressionEnd: OptionalCtx,
275 BitShiftExpressionBegin: OptionalCtx,
276 BitShiftExpressionEnd: OptionalCtx,
277 AdditionExpressionBegin: OptionalCtx,
278 AdditionExpressionEnd: OptionalCtx,
279 MultiplyExpressionBegin: OptionalCtx,
280 MultiplyExpressionEnd: OptionalCtx,
281 CurlySuffixExpressionBegin: OptionalCtx,
282 CurlySuffixExpressionEnd: OptionalCtx,
283 TypeExprBegin: OptionalCtx,
284 TypeExprEnd: OptionalCtx,
285 PrefixOpExpression: OptionalCtx,
286 SuffixOpExpressionBegin: OptionalCtx,
287 SuffixOpExpressionEnd: OptionalCtx,
288 PrimaryExpression: OptionalCtx,
289
290 ErrorTypeOrSetDecl: ErrorTypeOrSetDeclCtx,
291 StringLiteral: OptionalCtx,
292 Identifier: OptionalCtx,
293
294
295 IfToken: @TagType(Token.Id),
296 IfTokenSave: ExpectTokenSave,
297 ExpectToken: @TagType(Token.Id),
298 ExpectTokenSave: ExpectTokenSave,
299 OptionalTokenSave: OptionalTokenSave,
233300 };
234301
235302 /// Returns an AST tree, allocated with the parser's allocator.
......@@ -302,31 +369,31 @@ pub const Parser = struct {
302369 Token.Id.Keyword_test => {
303370 stack.append(State.TopLevel) catch unreachable;
304371
305 const name_token = self.getNextToken();
306 const name = (try self.parseStringLiteral(arena, name_token)) ?? {
307 try self.parseError(&stack, name_token, "expected string literal, found {}", @tagName(name_token.id));
308 continue;
309 };
310 const lbrace = (try self.expectToken(&stack, Token.Id.LBrace)) ?? continue;
311
312372 const block = try self.createNode(arena, ast.NodeBlock,
313373 ast.NodeBlock {
314374 .base = undefined,
315375 .label = null,
316 .lbrace = lbrace,
376 .lbrace = undefined,
317377 .statements = ArrayList(&ast.Node).init(arena),
318378 .rbrace = undefined,
319379 }
320380 );
321 _ = try self.createAttachNode(arena, &root_node.decls, ast.NodeTestDecl,
381 const test_node = try self.createAttachNode(arena, &root_node.decls, ast.NodeTestDecl,
322382 ast.NodeTestDecl {
323383 .base = undefined,
324384 .test_token = token,
325 .name = name,
385 .name = undefined,
326386 .body_node = &block.base,
327387 }
328388 );
329389 stack.append(State { .Block = block }) catch unreachable;
390 try stack.append(State {
391 .ExpectTokenSave = ExpectTokenSave {
392 .id = Token.Id.LBrace,
393 .ptr = &block.rbrace,
394 }
395 });
396 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &test_node.name } });
330397 continue;
331398 },
332399 Token.Id.Eof => {
......@@ -346,15 +413,30 @@ pub const Parser = struct {
346413 continue;
347414 },
348415 Token.Id.Keyword_comptime => {
416 const block = try self.createNode(arena, ast.NodeBlock,
417 ast.NodeBlock {
418 .base = undefined,
419 .label = null,
420 .lbrace = undefined,
421 .statements = ArrayList(&ast.Node).init(arena),
422 .rbrace = undefined,
423 }
424 );
349425 const node = try self.createAttachNode(arena, &root_node.decls, ast.NodeComptime,
350426 ast.NodeComptime {
351427 .base = undefined,
352428 .comptime_token = token,
353 .expr = undefined,
429 .expr = &block.base,
354430 }
355431 );
356432 stack.append(State.TopLevel) catch unreachable;
357 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
433 try stack.append(State { .Block = block });
434 try stack.append(State {
435 .ExpectTokenSave = ExpectTokenSave {
436 .id = Token.Id.LBrace,
437 .ptr = &block.rbrace,
438 }
439 });
358440 continue;
359441 },
360442 else => {
......@@ -404,7 +486,6 @@ pub const Parser = struct {
404486 }
405487 }
406488 },
407
408489 State.TopLevelLibname => |ctx| {
409490 const lib_name = blk: {
410491 const lib_name_token = self.getNextToken();
......@@ -422,15 +503,14 @@ pub const Parser = struct {
422503 .lib_name = lib_name,
423504 },
424505 }) catch unreachable;
506 continue;
425507 },
426
427508 State.TopLevelDecl => |ctx| {
428509 const token = self.getNextToken();
429510 switch (token.id) {
430511 Token.Id.Keyword_use => {
431512 if (ctx.extern_export_inline_token != null) {
432 try self.parseError(&stack, token, "Invalid token {}", @tagName((??ctx.extern_export_inline_token).id));
433 continue;
513 return self.parseError(token, "Invalid token {}", @tagName((??ctx.extern_export_inline_token).id));
434514 }
435515
436516 const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse,
......@@ -447,60 +527,30 @@ pub const Parser = struct {
447527 .ptr = &node.semicolon_token,
448528 }
449529 }) catch unreachable;
450 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
530 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
451531 continue;
452532 },
453533 Token.Id.Keyword_var, Token.Id.Keyword_const => {
454534 if (ctx.extern_export_inline_token) |extern_export_inline_token| {
455535 if (extern_export_inline_token.id == Token.Id.Keyword_inline) {
456 try self.parseError(&stack, token, "Invalid token {}", @tagName(extern_export_inline_token.id));
457 continue;
536 return self.parseError(token, "Invalid token {}", @tagName(extern_export_inline_token.id));
458537 }
459538 }
460539
461 const var_decl_node = try self.createAttachNode(arena, ctx.decls, ast.NodeVarDecl,
462 ast.NodeVarDecl {
463 .base = undefined,
540 stack.append(State {
541 .VarDecl = VarDeclCtx {
464542 .visib_token = ctx.visib_token,
465 .mut_token = token,
543 .lib_name = ctx.lib_name,
466544 .comptime_token = null,
467545 .extern_export_token = ctx.extern_export_inline_token,
468 .type_node = null,
469 .align_node = null,
470 .init_node = null,
471 .lib_name = ctx.lib_name,
472 // initialized later
473 .name_token = undefined,
474 .eq_token = undefined,
475 .semicolon_token = undefined,
476 }
477 );
478 stack.append(State { .VarDecl = var_decl_node }) catch unreachable;
479 continue;
480 },
481 Token.Id.Keyword_fn => {
482 const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto,
483 ast.NodeFnProto {
484 .base = undefined,
485 .visib_token = ctx.visib_token,
486 .name_token = null,
487 .fn_token = token,
488 .params = ArrayList(&ast.Node).init(arena),
489 .return_type = undefined,
490 .var_args_token = null,
491 .extern_export_inline_token = ctx.extern_export_inline_token,
492 .cc_token = null,
493 .async_attr = null,
494 .body_node = null,
495 .lib_name = ctx.lib_name,
496 .align_expr = null,
546 .mut_token = token,
547 .list = ctx.decls
497548 }
498 );
499 stack.append(State { .FnDef = fn_proto }) catch unreachable;
500 try stack.append(State { .FnProto = fn_proto });
549 }) catch unreachable;
501550 continue;
502551 },
503 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 => {
504554 const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto,
505555 ast.NodeFnProto {
506556 .base = undefined,
......@@ -511,7 +561,7 @@ pub const Parser = struct {
511561 .return_type = undefined,
512562 .var_args_token = null,
513563 .extern_export_inline_token = ctx.extern_export_inline_token,
514 .cc_token = token,
564 .cc_token = null,
515565 .async_attr = null,
516566 .body_node = null,
517567 .lib_name = ctx.lib_name,
......@@ -520,126 +570,84 @@ pub const Parser = struct {
520570 );
521571 stack.append(State { .FnDef = fn_proto }) catch unreachable;
522572 try stack.append(State { .FnProto = fn_proto });
523 try stack.append(State {
524 .ExpectTokenSave = ExpectTokenSave {
525 .id = Token.Id.Keyword_fn,
526 .ptr = &fn_proto.fn_token,
527 }
528 });
529 continue;
530 },
531 Token.Id.Keyword_async => {
532 const async_node = try self.createNode(arena, ast.NodeAsyncAttribute,
533 ast.NodeAsyncAttribute {
534 .base = undefined,
535 .async_token = token,
536 .allocator_type = null,
537 .rangle_bracket = null,
538 }
539 );
540573
541 const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto,
542 ast.NodeFnProto {
543 .base = undefined,
544 .visib_token = ctx.visib_token,
545 .name_token = null,
546 .fn_token = undefined,
547 .params = ArrayList(&ast.Node).init(arena),
548 .return_type = undefined,
549 .var_args_token = null,
550 .extern_export_inline_token = ctx.extern_export_inline_token,
551 .cc_token = null,
552 .async_attr = async_node,
553 .body_node = null,
554 .lib_name = ctx.lib_name,
555 .align_expr = null,
556 }
557 );
558 stack.append(State { .FnDef = fn_proto }) catch unreachable;
559 try stack.append(State { .FnProto = fn_proto });
560 try stack.append(State {
561 .ExpectTokenSave = ExpectTokenSave {
562 .id = Token.Id.Keyword_fn,
563 .ptr = &fn_proto.fn_token,
564 }
565 });
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;
566595
567 const langle_bracket = self.getNextToken();
568 if (langle_bracket.id != Token.Id.AngleBracketLeft) {
569 self.putBackToken(langle_bracket);
570 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,
571610 }
572
573 async_node.rangle_bracket = Token(undefined);
574 try stack.append(State {
575 .ExpectTokenSave = ExpectTokenSave {
576 .id = Token.Id.AngleBracketRight,
577 .ptr = &??async_node.rangle_bracket,
578 }
579 });
580 try stack.append(State { .TypeExprBegin = DestPtr { .NullableField = &async_node.allocator_type } });
581 continue;
582611 },
583612 else => {
584 try self.parseError(&stack, token, "expected variable declaration or function, found {}", @tagName(token.id));
585 continue;
613 return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id));
586614 },
587615 }
588616 },
589 State.VarDecl => |var_decl| {
590 stack.append(State { .VarDeclAlign = var_decl }) catch unreachable;
591 try stack.append(State { .TypeExprBegin = DestPtr {.NullableField = &var_decl.type_node} });
592 try stack.append(State { .IfToken = Token.Id.Colon });
593 try stack.append(State {
594 .ExpectTokenSave = ExpectTokenSave {
595 .id = Token.Id.Identifier,
596 .ptr = &var_decl.name_token,
597 }
598 });
599 continue;
600 },
601 State.VarDeclAlign => |var_decl| {
602 stack.append(State { .VarDeclEq = var_decl }) catch unreachable;
617 State.TopLevelExternOrField => |ctx| {
618 if (self.eatToken(Token.Id.Identifier)) |identifier| {
619 std.debug.assert(ctx.container_decl.kind == ast.NodeContainerDecl.Kind.Struct);
620 const node = try self.createAttachNode(arena, &ctx.container_decl.fields_and_decls, ast.NodeStructField,
621 ast.NodeStructField {
622 .base = undefined,
623 .visib_token = ctx.visib_token,
624 .name_token = identifier,
625 .type_expr = undefined,
626 }
627 );
603628
604 const next_token = self.getNextToken();
605 if (next_token.id == Token.Id.Keyword_align) {
606 try stack.append(State { .ExpectToken = Token.Id.RParen });
607 try stack.append(State { .Expression = DestPtr{.NullableField = &var_decl.align_node} });
608 try stack.append(State { .ExpectToken = Token.Id.LParen });
629 stack.append(State { .FieldListCommaOrEnd = ctx.container_decl }) catch unreachable;
630 try stack.append(State { .Expression = OptionalCtx { .Required = &node.type_expr } });
631 try stack.append(State { .ExpectToken = Token.Id.Colon });
609632 continue;
610633 }
611634
612 self.putBackToken(next_token);
613 continue;
614 },
615 State.VarDeclEq => |var_decl| {
616 const token = self.getNextToken();
617 switch (token.id) {
618 Token.Id.Equal => {
619 var_decl.eq_token = token;
620 stack.append(State {
621 .ExpectTokenSave = ExpectTokenSave {
622 .id = Token.Id.Semicolon,
623 .ptr = &var_decl.semicolon_token,
624 },
625 }) catch unreachable;
626 try stack.append(State { .Expression = DestPtr {.NullableField = &var_decl.init_node} });
627 continue;
628 },
629 Token.Id.Semicolon => {
630 var_decl.semicolon_token = token;
631 continue;
632 },
633 else => {
634 try self.parseError(&stack, token, "expected '=' or ';', found {}", @tagName(token.id));
635 continue;
635 stack.append(State{ .ContainerDecl = ctx.container_decl }) catch unreachable;
636 try stack.append(State {
637 .TopLevelExtern = TopLevelDeclCtx {
638 .decls = &ctx.container_decl.fields_and_decls,
639 .visib_token = ctx.visib_token,
640 .extern_export_inline_token = null,
641 .lib_name = null,
636642 }
637 }
643 });
644 continue;
638645 },
639646
640 State.ContainerExtern => |ctx| {
647
648 State.ContainerKind => |ctx| {
641649 const token = self.getNextToken();
642 const node = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeContainerDecl,
650 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeContainerDecl,
643651 ast.NodeContainerDecl {
644652 .base = undefined,
645653 .ltoken = ctx.ltoken,
......@@ -649,15 +657,14 @@ pub const Parser = struct {
649657 Token.Id.Keyword_union => ast.NodeContainerDecl.Kind.Union,
650658 Token.Id.Keyword_enum => ast.NodeContainerDecl.Kind.Enum,
651659 else => {
652 try self.parseError(&stack, token, "expected {}, {} or {}, found {}",
660 return self.parseError(token, "expected {}, {} or {}, found {}",
653661 @tagName(Token.Id.Keyword_struct),
654662 @tagName(Token.Id.Keyword_union),
655663 @tagName(Token.Id.Keyword_enum),
656664 @tagName(token.id));
657 continue;
658665 },
659666 },
660 .init_arg_expr = undefined,
667 .init_arg_expr = ast.NodeContainerDecl.InitArg.None,
661668 .fields_and_decls = ArrayList(&ast.Node).init(arena),
662669 .rbrace_token = undefined,
663670 }
......@@ -665,37 +672,36 @@ pub const Parser = struct {
665672
666673 stack.append(State { .ContainerDecl = node }) catch unreachable;
667674 try stack.append(State { .ExpectToken = Token.Id.LBrace });
675 try stack.append(State { .ContainerInitArgStart = node });
676 continue;
677 },
668678
669 const lparen = self.getNextToken();
670 if (lparen.id != Token.Id.LParen) {
671 self.putBackToken(lparen);
672 node.init_arg_expr = ast.NodeContainerDecl.InitArg.None;
679 State.ContainerInitArgStart => |container_decl| {
680 if (self.eatToken(Token.Id.LParen) == null) {
673681 continue;
674682 }
675683
676 try stack.append(State { .ExpectToken = Token.Id.RParen });
684 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
685 try stack.append(State { .ContainerInitArg = container_decl });
686 continue;
687 },
677688
689 State.ContainerInitArg => |container_decl| {
678690 const init_arg_token = self.getNextToken();
679691 switch (init_arg_token.id) {
680692 Token.Id.Keyword_enum => {
681 node.init_arg_expr = ast.NodeContainerDecl.InitArg.Enum;
693 container_decl.init_arg_expr = ast.NodeContainerDecl.InitArg.Enum;
682694 },
683695 else => {
684696 self.putBackToken(init_arg_token);
685 node.init_arg_expr = ast.NodeContainerDecl.InitArg { .Type = undefined };
686 try stack.append(State {
687 .Expression = DestPtr {
688 .Field = &node.init_arg_expr.Type
689 }
690 });
697 container_decl.init_arg_expr = ast.NodeContainerDecl.InitArg { .Type = undefined };
698 stack.append(State { .Expression = OptionalCtx { .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;
691699 },
692700 }
693701 continue;
694702 },
695
696703 State.ContainerDecl => |container_decl| {
697704 const token = self.getNextToken();
698
699705 switch (token.id) {
700706 Token.Id.Identifier => {
701707 switch (container_decl.kind) {
......@@ -710,7 +716,7 @@ pub const Parser = struct {
710716 );
711717
712718 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
713 try stack.append(State { .Expression = DestPtr { .Field = &node.type_expr } });
719 try stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.type_expr } });
714720 try stack.append(State { .ExpectToken = Token.Id.Colon });
715721 continue;
716722 },
......@@ -724,14 +730,8 @@ pub const Parser = struct {
724730 );
725731
726732 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
727
728 const next = self.getNextToken();
729 if (next.id != Token.Id.Colon) {
730 self.putBackToken(next);
731 continue;
732 }
733
734 try stack.append(State { .Expression = DestPtr { .NullableField = &node.type_expr } });
733 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &node.type_expr } });
734 try stack.append(State { .IfToken = Token.Id.Colon });
735735 continue;
736736 },
737737 ast.NodeContainerDecl.Kind.Enum => {
......@@ -744,52 +744,36 @@ pub const Parser = struct {
744744 );
745745
746746 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
747
748 const next = self.getNextToken();
749 if (next.id != Token.Id.Equal) {
750 self.putBackToken(next);
751 continue;
752 }
753
754 try stack.append(State { .Expression = DestPtr { .NullableField = &node.value } });
747 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &node.value } });
748 try stack.append(State { .IfToken = Token.Id.Equal });
755749 continue;
756750 },
757751 }
758752 },
759753 Token.Id.Keyword_pub => {
760 if (self.eatToken(Token.Id.Identifier)) |identifier| {
761 switch (container_decl.kind) {
762 ast.NodeContainerDecl.Kind.Struct => {
763 const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeStructField,
764 ast.NodeStructField {
765 .base = undefined,
766 .visib_token = token,
767 .name_token = identifier,
768 .type_expr = undefined,
769 }
770 );
771
772 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
773 try stack.append(State { .Expression = DestPtr { .Field = &node.type_expr } });
774 try stack.append(State { .ExpectToken = Token.Id.Colon });
775 continue;
776 },
777 else => {
778 self.putBackToken(identifier);
779 }
754 switch (container_decl.kind) {
755 ast.NodeContainerDecl.Kind.Struct => {
756 try stack.append(State {
757 .TopLevelExternOrField = TopLevelExternOrFieldCtx {
758 .visib_token = token,
759 .container_decl = container_decl,
760 }
761 });
762 continue;
763 },
764 else => {
765 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
766 try stack.append(State {
767 .TopLevelExtern = TopLevelDeclCtx {
768 .decls = &container_decl.fields_and_decls,
769 .visib_token = token,
770 .extern_export_inline_token = null,
771 .lib_name = null,
772 }
773 });
774 continue;
780775 }
781776 }
782
783 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
784 try stack.append(State {
785 .TopLevelExtern = TopLevelDeclCtx {
786 .decls = &container_decl.fields_and_decls,
787 .visib_token = token,
788 .extern_export_inline_token = null,
789 .lib_name = null,
790 }
791 });
792 continue;
793777 },
794778 Token.Id.Keyword_export => {
795779 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
......@@ -823,1118 +807,554 @@ pub const Parser = struct {
823807 }
824808 },
825809
826 State.ExpectToken => |token_id| {
827 _ = (try self.expectToken(&stack, token_id)) ?? continue;
828 continue;
829 },
830810
831 State.ExpectTokenSave => |expect_token_save| {
832 *expect_token_save.ptr = (try self.expectToken(&stack, expect_token_save.id)) ?? continue;
833 continue;
834 },
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 );
835829
836 State.IfToken => |token_id| {
837 const token = self.getNextToken();
838 if (@TagType(Token.Id)(token.id) != token_id) {
839 self.putBackToken(token);
840 _ = stack.pop();
841 continue;
842 }
830 stack.append(State { .VarDeclAlign = var_decl }) catch unreachable;
831 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} });
832 try stack.append(State { .IfToken = Token.Id.Colon });
833 try stack.append(State {
834 .ExpectTokenSave = ExpectTokenSave {
835 .id = Token.Id.Identifier,
836 .ptr = &var_decl.name_token,
837 }
838 });
843839 continue;
844840 },
841 State.VarDeclAlign => |var_decl| {
842 stack.append(State { .VarDeclEq = var_decl }) catch unreachable;
845843
846 State.IfTokenSave => |if_token_save| {
847 const token = self.getNextToken();
848 if (@TagType(Token.Id)(token.id) != if_token_save.id) {
849 self.putBackToken(token);
850 _ = stack.pop();
844 const next_token = self.getNextToken();
845 if (next_token.id == Token.Id.Keyword_align) {
846 try stack.append(State { .ExpectToken = Token.Id.RParen });
847 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.align_node} });
848 try stack.append(State { .ExpectToken = Token.Id.LParen });
851849 continue;
852850 }
853851
854 *if_token_save.ptr = token;
852 self.putBackToken(next_token);
855853 continue;
856854 },
857
858 State.Optional => { },
859
860 State.Expression => |dest_ptr| {
855 State.VarDeclEq => |var_decl| {
861856 const token = self.getNextToken();
862857 switch (token.id) {
863 Token.Id.Keyword_return => {
864 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeControlFlowExpression,
865 ast.NodeControlFlowExpression {
866 .base = undefined,
867 .ltoken = token,
868 .kind = ast.NodeControlFlowExpression.Kind.Return,
869 .rhs = undefined,
870 }
871 );
872
873 // TODO: Find another way to do optional expressions
874 stack.append(State {
875 .Optional = RevertState {
876 .parser = *self,
877 .tokenizer = *self.tokenizer,
878 .ptr = &node.rhs,
879 }
880 }) catch unreachable;
881 try stack.append(State { .Expression = DestPtr { .NullableField = &node.rhs } });
882 continue;
883 },
884 Token.Id.Keyword_break, Token.Id.Keyword_continue => {
885 const label = blk: {
886 const colon = self.getNextToken();
887 if (colon.id != Token.Id.Colon) {
888 self.putBackToken(colon);
889 break :blk null;
890 }
891
892 break :blk (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
893 };
894
895 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeControlFlowExpression,
896 ast.NodeControlFlowExpression {
897 .base = undefined,
898 .ltoken = token,
899 .kind = switch (token.id) {
900 Token.Id.Keyword_break => ast.NodeControlFlowExpression.Kind { .Break = label },
901 Token.Id.Keyword_continue => ast.NodeControlFlowExpression.Kind { .Continue = label },
902 else => unreachable,
903 },
904 .rhs = undefined,
905 }
906 );
907
908 // TODO: Find another way to do optional expressions
858 Token.Id.Equal => {
859 var_decl.eq_token = token;
909860 stack.append(State {
910 .Optional = RevertState {
911 .parser = *self,
912 .tokenizer = *self.tokenizer,
913 .ptr = &node.rhs,
914 }
861 .ExpectTokenSave = ExpectTokenSave {
862 .id = Token.Id.Semicolon,
863 .ptr = &var_decl.semicolon_token,
864 },
915865 }) catch unreachable;
916 try stack.append(State { .Expression = DestPtr { .NullableField = &node.rhs } });
866 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.init_node } });
917867 continue;
918868 },
919 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
920 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
921 ast.NodePrefixOp {
922 .base = undefined,
923 .op_token = token,
924 .op = switch (token.id) {
925 Token.Id.Keyword_try => ast.NodePrefixOp.PrefixOp { .Try = void{} },
926 Token.Id.Keyword_cancel => ast.NodePrefixOp.PrefixOp { .Cancel = void{} },
927 Token.Id.Keyword_resume => ast.NodePrefixOp.PrefixOp { .Resume = void{} },
928 else => unreachable,
929 },
930 .rhs = undefined,
931 }
932 );
933
934 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;
869 Token.Id.Semicolon => {
870 var_decl.semicolon_token = token;
935871 continue;
936872 },
937873 else => {
938 if (!try self.parseBlockExpr(&stack, arena, dest_ptr, token)) {
939 self.putBackToken(token);
940 stack.append(State { .UnwrapExpressionBegin = dest_ptr }) catch unreachable;
941 }
942 continue;
874 return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id));
943875 }
944876 }
945877 },
946878
947 State.RangeExpressionBegin => |dest_ptr| {
948 stack.append(State { .RangeExpressionEnd = dest_ptr }) catch unreachable;
949 try stack.append(State { .Expression = dest_ptr });
950 continue;
951 },
952
953 State.RangeExpressionEnd => |dest_ptr| {
954 if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| {
955 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
956 ast.NodeInfixOp {
957 .base = undefined,
958 .lhs = dest_ptr.get(),
959 .op_token = ellipsis3,
960 .op = ast.NodeInfixOp.InfixOp.Range,
961 .rhs = undefined,
962 }
963 );
964 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;
965 }
966
967 continue;
968 },
969
970 State.AssignmentExpressionBegin => |dest_ptr| {
971 stack.append(State { .AssignmentExpressionEnd = dest_ptr }) catch unreachable;
972 try stack.append(State { .Expression = dest_ptr });
973 continue;
974 },
975
976 State.AssignmentExpressionEnd => |dest_ptr| {
977 const token = self.getNextToken();
978 if (tokenIdToAssignment(token.id)) |ass_id| {
979 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
980 ast.NodeInfixOp {
981 .base = undefined,
982 .lhs = dest_ptr.get(),
983 .op_token = token,
984 .op = ass_id,
985 .rhs = undefined,
986 }
987 );
988 stack.append(State { .AssignmentExpressionEnd = dest_ptr }) catch unreachable;
989 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });
990 continue;
991 } else {
992 self.putBackToken(token);
993 continue;
994 }
995 },
996
997 State.UnwrapExpressionBegin => |dest_ptr| {
998 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
999 try stack.append(State { .BoolOrExpressionBegin = dest_ptr });
1000 continue;
1001 },
1002879
1003 State.UnwrapExpressionEnd => |dest_ptr| {
880 State.FnDef => |fn_proto| {
1004881 const token = self.getNextToken();
1005 switch (token.id) {
1006 Token.Id.Keyword_catch, Token.Id.QuestionMarkQuestionMark => {
1007 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1008 ast.NodeInfixOp {
882 switch(token.id) {
883 Token.Id.LBrace => {
884 const block = try self.createNode(arena, ast.NodeBlock,
885 ast.NodeBlock {
1009886 .base = undefined,
1010 .lhs = dest_ptr.get(),
1011 .op_token = token,
1012 .op = switch (token.id) {
1013 Token.Id.Keyword_catch => ast.NodeInfixOp.InfixOp { .Catch = null },
1014 Token.Id.QuestionMarkQuestionMark => ast.NodeInfixOp.InfixOp { .UnwrapMaybe = void{} },
1015 else => unreachable,
1016 },
1017 .rhs = undefined,
887 .label = null,
888 .lbrace = token,
889 .statements = ArrayList(&ast.Node).init(arena),
890 .rbrace = undefined,
1018891 }
1019892 );
1020
1021 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
1022 try stack.append(State { .Expression = DestPtr { .Field = &node.rhs } });
1023
1024 if (node.op == ast.NodeInfixOp.InfixOp.Catch) {
1025 try stack.append(State { .Payload = &node.op.Catch });
1026 }
893 fn_proto.body_node = &block.base;
894 stack.append(State { .Block = block }) catch unreachable;
1027895 continue;
1028896 },
897 Token.Id.Semicolon => continue,
1029898 else => {
1030 self.putBackToken(token);
1031 continue;
899 return self.parseError(token, "expected ';' or '{{', found {}", @tagName(token.id));
1032900 },
1033901 }
1034902 },
903 State.FnProto => |fn_proto| {
904 stack.append(State { .FnProtoAlign = fn_proto }) catch unreachable;
905 try stack.append(State { .ParamDecl = fn_proto });
906 try stack.append(State { .ExpectToken = Token.Id.LParen });
1035907
1036 State.BoolOrExpressionBegin => |dest_ptr| {
1037 stack.append(State { .BoolOrExpressionEnd = dest_ptr }) catch unreachable;
1038 try stack.append(State { .BoolAndExpressionBegin = dest_ptr });
908 if (self.eatToken(Token.Id.Identifier)) |name_token| {
909 fn_proto.name_token = name_token;
910 }
1039911 continue;
1040912 },
913 State.FnProtoAlign => |fn_proto| {
914 stack.append(State { .FnProtoReturnType = fn_proto }) catch unreachable;
1041915
1042 State.BoolOrExpressionEnd => |dest_ptr| {
1043 const token = self.getNextToken();
1044 switch (token.id) {
1045 Token.Id.Keyword_or => {
1046 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1047 ast.NodeInfixOp {
1048 .base = undefined,
1049 .lhs = dest_ptr.get(),
1050 .op_token = token,
1051 .op = ast.NodeInfixOp.InfixOp.BoolOr,
1052 .rhs = undefined,
1053 }
1054 );
1055 stack.append(State { .BoolOrExpressionEnd = dest_ptr }) catch unreachable;
1056 try stack.append(State { .BoolAndExpressionBegin = DestPtr { .Field = &node.rhs } });
1057 continue;
1058 },
1059 else => {
1060 self.putBackToken(token);
1061 continue;
1062 },
916 if (self.eatToken(Token.Id.Keyword_align)) |align_token| {
917 try stack.append(State { .ExpectToken = Token.Id.RParen });
918 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } });
919 try stack.append(State { .ExpectToken = Token.Id.LParen });
1063920 }
1064 },
1065
1066 State.BoolAndExpressionBegin => |dest_ptr| {
1067 stack.append(State { .BoolAndExpressionEnd = dest_ptr }) catch unreachable;
1068 try stack.append(State { .ComparisonExpressionBegin = dest_ptr });
1069921 continue;
1070922 },
1071
1072 State.BoolAndExpressionEnd => |dest_ptr| {
923 State.FnProtoReturnType => |fn_proto| {
1073924 const token = self.getNextToken();
1074925 switch (token.id) {
1075 Token.Id.Keyword_and => {
1076 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1077 ast.NodeInfixOp {
1078 .base = undefined,
1079 .lhs = dest_ptr.get(),
1080 .op_token = token,
1081 .op = ast.NodeInfixOp.InfixOp.BoolAnd,
1082 .rhs = undefined,
1083 }
1084 );
1085 stack.append(State { .BoolAndExpressionEnd = dest_ptr }) catch unreachable;
1086 try stack.append(State { .ComparisonExpressionBegin = DestPtr { .Field = &node.rhs } });
926 Token.Id.Bang => {
927 fn_proto.return_type = ast.NodeFnProto.ReturnType { .InferErrorSet = undefined };
928 stack.append(State {
929 .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.InferErrorSet },
930 }) catch unreachable;
1087931 continue;
1088932 },
1089933 else => {
934 // TODO: this is a special case. Remove this when #760 is fixed
935 if (token.id == Token.Id.Keyword_error) {
936 if (self.isPeekToken(Token.Id.LBrace)) {
937 fn_proto.return_type = ast.NodeFnProto.ReturnType {
938 .Explicit = &(try self.createLiteral(arena, ast.NodeErrorType, token)).base
939 };
940 continue;
941 }
942 }
943
1090944 self.putBackToken(token);
945 fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined };
946 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.Explicit }, }) catch unreachable;
1091947 continue;
1092948 },
1093949 }
1094950 },
1095951
1096 State.ComparisonExpressionBegin => |dest_ptr| {
1097 stack.append(State { .ComparisonExpressionEnd = dest_ptr }) catch unreachable;
1098 try stack.append(State { .BinaryOrExpressionBegin = dest_ptr });
1099 continue;
1100 },
1101952
1102 State.ComparisonExpressionEnd => |dest_ptr| {
1103 const token = self.getNextToken();
1104 if (tokenIdToComparison(token.id)) |comp_id| {
1105 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1106 ast.NodeInfixOp {
1107 .base = undefined,
1108 .lhs = dest_ptr.get(),
1109 .op_token = token,
1110 .op = comp_id,
1111 .rhs = undefined,
1112 }
1113 );
1114 stack.append(State { .ComparisonExpressionEnd = dest_ptr }) catch unreachable;
1115 try stack.append(State { .BinaryOrExpressionBegin = DestPtr { .Field = &node.rhs } });
1116 continue;
1117 } else {
1118 self.putBackToken(token);
953 State.ParamDecl => |fn_proto| {
954 if (self.eatToken(Token.Id.RParen)) |_| {
1119955 continue;
1120956 }
1121 },
957 const param_decl = try self.createAttachNode(arena, &fn_proto.params, ast.NodeParamDecl,
958 ast.NodeParamDecl {
959 .base = undefined,
960 .comptime_token = null,
961 .noalias_token = null,
962 .name_token = null,
963 .type_node = undefined,
964 .var_args_token = null,
965 },
966 );
1122967
1123 State.BinaryOrExpressionBegin => |dest_ptr| {
1124 stack.append(State { .BinaryOrExpressionEnd = dest_ptr }) catch unreachable;
1125 try stack.append(State { .BinaryXorExpressionBegin = dest_ptr });
968 stack.append(State {
969 .ParamDeclEnd = ParamDeclEndCtx {
970 .param_decl = param_decl,
971 .fn_proto = fn_proto,
972 }
973 }) catch unreachable;
974 try stack.append(State { .ParamDeclName = param_decl });
975 try stack.append(State { .ParamDeclAliasOrComptime = param_decl });
1126976 continue;
1127977 },
1128
1129 State.BinaryOrExpressionEnd => |dest_ptr| {
1130 const token = self.getNextToken();
1131 switch (token.id) {
1132 Token.Id.Pipe => {
1133 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1134 ast.NodeInfixOp {
1135 .base = undefined,
1136 .lhs = dest_ptr.get(),
1137 .op_token = token,
1138 .op = ast.NodeInfixOp.InfixOp.BitOr,
1139 .rhs = undefined,
1140 }
1141 );
1142 stack.append(State { .BinaryOrExpressionEnd = dest_ptr }) catch unreachable;
1143 try stack.append(State { .BinaryXorExpressionBegin = DestPtr { .Field = &node.rhs } });
1144 continue;
1145 },
1146 else => {
1147 self.putBackToken(token);
1148 continue;
1149 },
978 State.ParamDeclAliasOrComptime => |param_decl| {
979 if (self.eatToken(Token.Id.Keyword_comptime)) |comptime_token| {
980 param_decl.comptime_token = comptime_token;
981 } else if (self.eatToken(Token.Id.Keyword_noalias)) |noalias_token| {
982 param_decl.noalias_token = noalias_token;
983 }
984 continue;
985 },
986 State.ParamDeclName => |param_decl| {
987 // TODO: Here, we eat two tokens in one state. This means that we can't have
988 // comments between these two tokens.
989 if (self.eatToken(Token.Id.Identifier)) |ident_token| {
990 if (self.eatToken(Token.Id.Colon)) |_| {
991 param_decl.name_token = ident_token;
992 } else {
993 self.putBackToken(ident_token);
994 }
1150995 }
996 continue;
1151997 },
998 State.ParamDeclEnd => |ctx| {
999 if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| {
1000 ctx.param_decl.var_args_token = ellipsis3;
1001 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
1002 continue;
1003 }
11521004
1153 State.BinaryXorExpressionBegin => |dest_ptr| {
1154 stack.append(State { .BinaryXorExpressionEnd = dest_ptr }) catch unreachable;
1155 try stack.append(State { .BinaryAndExpressionBegin = dest_ptr });
1005 try stack.append(State { .ParamDeclComma = ctx.fn_proto });
1006 try stack.append(State {
1007 .TypeExprBegin = OptionalCtx { .Required = &ctx.param_decl.type_node }
1008 });
1009 continue;
1010 },
1011 State.ParamDeclComma => |fn_proto| {
1012 if ((try self.expectCommaOrEnd(Token.Id.RParen)) == null) {
1013 stack.append(State { .ParamDecl = fn_proto }) catch unreachable;
1014 }
11561015 continue;
11571016 },
11581017
1159 State.BinaryXorExpressionEnd => |dest_ptr| {
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 }
1028
1029 _ = try self.createToCtxLiteral(arena, ctx.opt_ctx, ast.NodeIdentifier, ctx.label);
1030 continue;
1031 },
1032 State.LabeledExpression => |ctx| {
11601033 const token = self.getNextToken();
11611034 switch (token.id) {
1162 Token.Id.Caret => {
1163 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1164 ast.NodeInfixOp {
1035 Token.Id.LBrace => {
1036 const block = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeBlock,
1037 ast.NodeBlock {
11651038 .base = undefined,
1166 .lhs = dest_ptr.get(),
1167 .op_token = token,
1168 .op = ast.NodeInfixOp.InfixOp.BitXor,
1169 .rhs = undefined,
1039 .label = ctx.label,
1040 .lbrace = token,
1041 .statements = ArrayList(&ast.Node).init(arena),
1042 .rbrace = undefined,
11701043 }
11711044 );
1172 stack.append(State { .BinaryXorExpressionEnd = dest_ptr }) catch unreachable;
1173 try stack.append(State { .BinaryAndExpressionBegin = DestPtr { .Field = &node.rhs } });
1045 stack.append(State { .Block = block }) catch unreachable;
1046 continue;
1047 },
1048 Token.Id.Keyword_while => {
1049 stack.append(State {
1050 .While = LoopCtx {
1051 .label = ctx.label,
1052 .inline_token = null,
1053 .loop_token = token,
1054 .opt_ctx = ctx.opt_ctx.toRequired(),
1055 }
1056 }) catch unreachable;
1057 continue;
1058 },
1059 Token.Id.Keyword_for => {
1060 stack.append(State {
1061 .For = LoopCtx {
1062 .label = ctx.label,
1063 .inline_token = null,
1064 .loop_token = token,
1065 .opt_ctx = ctx.opt_ctx.toRequired(),
1066 }
1067 }) catch unreachable;
1068 continue;
1069 },
1070 Token.Id.Keyword_inline => {
1071 stack.append(State {
1072 .Inline = InlineCtx {
1073 .label = ctx.label,
1074 .inline_token = token,
1075 .opt_ctx = ctx.opt_ctx.toRequired(),
1076 }
1077 }) catch unreachable;
11741078 continue;
11751079 },
11761080 else => {
1081 if (ctx.opt_ctx != OptionalCtx.Optional) {
1082 return self.parseError(token, "expected 'while', 'for', 'inline' or '{{', found {}", @tagName(token.id));
1083 }
1084
11771085 self.putBackToken(token);
11781086 continue;
11791087 },
11801088 }
11811089 },
1182
1183 State.BinaryAndExpressionBegin => |dest_ptr| {
1184 stack.append(State { .BinaryAndExpressionEnd = dest_ptr }) catch unreachable;
1185 try stack.append(State { .BitShiftExpressionBegin = dest_ptr });
1186 continue;
1187 },
1188
1189 State.BinaryAndExpressionEnd => |dest_ptr| {
1090 State.Inline => |ctx| {
11901091 const token = self.getNextToken();
11911092 switch (token.id) {
1192 Token.Id.Ampersand => {
1193 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1194 ast.NodeInfixOp {
1195 .base = undefined,
1196 .lhs = dest_ptr.get(),
1197 .op_token = token,
1198 .op = ast.NodeInfixOp.InfixOp.BitAnd,
1199 .rhs = undefined,
1093 Token.Id.Keyword_while => {
1094 stack.append(State {
1095 .While = LoopCtx {
1096 .inline_token = ctx.inline_token,
1097 .label = ctx.label,
1098 .loop_token = token,
1099 .opt_ctx = ctx.opt_ctx.toRequired(),
12001100 }
1201 );
1202 stack.append(State { .BinaryAndExpressionEnd = dest_ptr }) catch unreachable;
1203 try stack.append(State { .BitShiftExpressionBegin = DestPtr { .Field = &node.rhs } });
1101 }) catch unreachable;
1102 continue;
1103 },
1104 Token.Id.Keyword_for => {
1105 stack.append(State {
1106 .For = LoopCtx {
1107 .inline_token = ctx.inline_token,
1108 .label = ctx.label,
1109 .loop_token = token,
1110 .opt_ctx = ctx.opt_ctx.toRequired(),
1111 }
1112 }) catch unreachable;
12041113 continue;
12051114 },
12061115 else => {
1116 if (ctx.opt_ctx != OptionalCtx.Optional) {
1117 return self.parseError(token, "expected 'while' or 'for', found {}", @tagName(token.id));
1118 }
1119
12071120 self.putBackToken(token);
12081121 continue;
12091122 },
12101123 }
12111124 },
1212
1213 State.BitShiftExpressionBegin => |dest_ptr| {
1214 stack.append(State { .BitShiftExpressionEnd = dest_ptr }) catch unreachable;
1215 try stack.append(State { .AdditionExpressionBegin = dest_ptr });
1125 State.While => |ctx| {
1126 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeWhile,
1127 ast.NodeWhile {
1128 .base = undefined,
1129 .label = ctx.label,
1130 .inline_token = ctx.inline_token,
1131 .while_token = ctx.loop_token,
1132 .condition = undefined,
1133 .payload = null,
1134 .continue_expr = null,
1135 .body = undefined,
1136 .@"else" = null,
1137 }
1138 );
1139 stack.append(State { .Else = &node.@"else" }) catch unreachable;
1140 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
1141 try stack.append(State { .WhileContinueExpr = &node.continue_expr });
1142 try stack.append(State { .IfToken = Token.Id.Colon });
1143 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
1144 try stack.append(State { .ExpectToken = Token.Id.RParen });
1145 try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } });
1146 try stack.append(State { .ExpectToken = Token.Id.LParen });
12161147 continue;
12171148 },
1218
1219 State.BitShiftExpressionEnd => |dest_ptr| {
1220 const token = self.getNextToken();
1221 if (tokenIdToBitShift(token.id)) |bitshift_id| {
1222 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1223 ast.NodeInfixOp {
1224 .base = undefined,
1225 .lhs = dest_ptr.get(),
1226 .op_token = token,
1227 .op = bitshift_id,
1228 .rhs = undefined,
1229 }
1230 );
1231 stack.append(State { .BitShiftExpressionEnd = dest_ptr }) catch unreachable;
1232 try stack.append(State { .AdditionExpressionBegin = DestPtr { .Field = &node.rhs } });
1233 continue;
1234 } else {
1235 self.putBackToken(token);
1236 continue;
1237 }
1238 },
1239
1240 State.AdditionExpressionBegin => |dest_ptr| {
1241 stack.append(State { .AdditionExpressionEnd = dest_ptr }) catch unreachable;
1242 try stack.append(State { .MultiplyExpressionBegin = dest_ptr });
1149 State.WhileContinueExpr => |dest| {
1150 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
1151 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = dest } });
1152 try stack.append(State { .ExpectToken = Token.Id.LParen });
12431153 continue;
12441154 },
1245
1246 State.AdditionExpressionEnd => |dest_ptr| {
1247 const token = self.getNextToken();
1248 if (tokenIdToAddition(token.id)) |add_id| {
1249 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1250 ast.NodeInfixOp {
1251 .base = undefined,
1252 .lhs = dest_ptr.get(),
1253 .op_token = token,
1254 .op = add_id,
1255 .rhs = undefined,
1256 }
1257 );
1258 stack.append(State { .AdditionExpressionEnd = dest_ptr }) catch unreachable;
1259 try stack.append(State { .MultiplyExpressionBegin = DestPtr { .Field = &node.rhs } });
1260 continue;
1261 } else {
1262 self.putBackToken(token);
1263 continue;
1264 }
1265 },
1266
1267 State.MultiplyExpressionBegin => |dest_ptr| {
1268 stack.append(State { .MultiplyExpressionEnd = dest_ptr }) catch unreachable;
1269 try stack.append(State { .CurlySuffixExpressionBegin = dest_ptr });
1155 State.For => |ctx| {
1156 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeFor,
1157 ast.NodeFor {
1158 .base = undefined,
1159 .label = ctx.label,
1160 .inline_token = ctx.inline_token,
1161 .for_token = ctx.loop_token,
1162 .array_expr = undefined,
1163 .payload = null,
1164 .body = undefined,
1165 .@"else" = null,
1166 }
1167 );
1168 stack.append(State { .Else = &node.@"else" }) catch unreachable;
1169 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
1170 try stack.append(State { .PointerIndexPayload = OptionalCtx { .Optional = &node.payload } });
1171 try stack.append(State { .ExpectToken = Token.Id.RParen });
1172 try stack.append(State { .Expression = OptionalCtx { .Required = &node.array_expr } });
1173 try stack.append(State { .ExpectToken = Token.Id.LParen });
12701174 continue;
12711175 },
1272
1273 State.MultiplyExpressionEnd => |dest_ptr| {
1274 const token = self.getNextToken();
1275 if (tokenIdToMultiply(token.id)) |mult_id| {
1276 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1277 ast.NodeInfixOp {
1176 State.Else => |dest| {
1177 if (self.eatToken(Token.Id.Keyword_else)) |else_token| {
1178 const node = try self.createNode(arena, ast.NodeElse,
1179 ast.NodeElse {
12781180 .base = undefined,
1279 .lhs = dest_ptr.get(),
1280 .op_token = token,
1281 .op = mult_id,
1282 .rhs = undefined,
1181 .else_token = else_token,
1182 .payload = null,
1183 .body = undefined,
12831184 }
12841185 );
1285 stack.append(State { .MultiplyExpressionEnd = dest_ptr }) catch unreachable;
1286 try stack.append(State { .CurlySuffixExpressionBegin = DestPtr { .Field = &node.rhs } });
1287 continue;
1288 } else {
1289 self.putBackToken(token);
1290 continue;
1291 }
1292 },
1293
1294 State.CurlySuffixExpressionBegin => |dest_ptr| {
1295 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;
1296 try stack.append(State { .TypeExprBegin = dest_ptr });
1297 continue;
1298 },
1299
1300 State.CurlySuffixExpressionEnd => |dest_ptr| {
1301 if (self.eatToken(Token.Id.LBrace) == null) {
1302 continue;
1303 }
1186 *dest = node;
13041187
1305 if (self.isPeekToken(Token.Id.Period)) {
1306 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuffixOp,
1307 ast.NodeSuffixOp {
1308 .base = undefined,
1309 .lhs = dest_ptr.get(),
1310 .op = ast.NodeSuffixOp.SuffixOp {
1311 .StructInitializer = ArrayList(&ast.NodeFieldInitializer).init(arena),
1312 },
1313 .rtoken = undefined,
1314 }
1315 );
1316 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;
1317 try stack.append(State {
1318 .FieldInitListItemOrEnd = ListSave(&ast.NodeFieldInitializer) {
1319 .list = &node.op.StructInitializer,
1320 .ptr = &node.rtoken,
1321 }
1322 });
1188 stack.append(State { .Expression = OptionalCtx { .Required = &node.body } }) catch unreachable;
1189 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });
13231190 continue;
13241191 } else {
1325 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuffixOp,
1326 ast.NodeSuffixOp {
1327 .base = undefined,
1328 .lhs = dest_ptr.get(),
1329 .op = ast.NodeSuffixOp.SuffixOp {
1330 .ArrayInitializer = ArrayList(&ast.Node).init(arena),
1331 },
1332 .rtoken = undefined,
1333 }
1334 );
1335 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;
1336 try stack.append(State {
1337 .ExprListItemOrEnd = ExprListCtx {
1338 .list = &node.op.ArrayInitializer,
1339 .end = Token.Id.RBrace,
1340 .ptr = &node.rtoken,
1341 }
1342 });
13431192 continue;
13441193 }
13451194 },
13461195
1347 State.TypeExprBegin => |dest_ptr| {
1348 stack.append(State { .TypeExprEnd = dest_ptr }) catch unreachable;
1349 try stack.append(State { .PrefixOpExpression = dest_ptr });
1350 continue;
1351 },
13521196
1353 State.TypeExprEnd => |dest_ptr| {
1197 State.Block => |block| {
13541198 const token = self.getNextToken();
13551199 switch (token.id) {
1356 Token.Id.Bang => {
1357 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1358 ast.NodeInfixOp {
1359 .base = undefined,
1360 .lhs = dest_ptr.get(),
1361 .op_token = token,
1362 .op = ast.NodeInfixOp.InfixOp.ErrorUnion,
1363 .rhs = undefined,
1364 }
1365 );
1366 stack.append(State { .TypeExprEnd = dest_ptr }) catch unreachable;
1367 try stack.append(State { .PrefixOpExpression = DestPtr { .Field = &node.rhs } });
1200 Token.Id.RBrace => {
1201 block.rbrace = token;
13681202 continue;
13691203 },
13701204 else => {
13711205 self.putBackToken(token);
1206 stack.append(State { .Block = block }) catch unreachable;
1207 try stack.append(State { .Statement = block });
13721208 continue;
13731209 },
13741210 }
13751211 },
1376
1377 State.PrefixOpExpression => |dest_ptr| {
1378 const token = self.getNextToken();
1379 if (tokenIdToPrefixOp(token.id)) |prefix_id| {
1380 var node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
1381 ast.NodePrefixOp {
1382 .base = undefined,
1383 .op_token = token,
1384 .op = prefix_id,
1385 .rhs = undefined,
1386 }
1387 );
1388
1389 if (token.id == Token.Id.AsteriskAsterisk) {
1390 const child = try self.createNode(arena, ast.NodePrefixOp,
1391 ast.NodePrefixOp {
1392 .base = undefined,
1393 .op_token = token,
1394 .op = prefix_id,
1395 .rhs = undefined,
1396 }
1397 );
1398 node.rhs = &child.base;
1399 node = child;
1400 }
1401
1402 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;
1403 if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {
1404 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
1405 }
1406 continue;
1407 } else {
1408 self.putBackToken(token);
1409 stack.append(State { .SuffixOpExpressionBegin = dest_ptr }) catch unreachable;
1410 continue;
1411 }
1412 },
1413
1414 State.SuffixOpExpressionBegin => |dest_ptr| {
1212 State.Statement => |block| {
14151213 const token = self.getNextToken();
14161214 switch (token.id) {
1417 Token.Id.Keyword_async => {
1418 const async_node = try self.createNode(arena, ast.NodeAsyncAttribute,
1419 ast.NodeAsyncAttribute {
1420 .base = undefined,
1421 .async_token = token,
1422 .allocator_type = null,
1423 .rangle_bracket = null,
1424 }
1425 );
1215 Token.Id.Keyword_comptime => {
14261216 stack.append(State {
1427 .AsyncEnd = AsyncEndCtx {
1428 .dest_ptr = dest_ptr,
1429 .attribute = async_node,
1217 .ComptimeStatement = ComptimeStatementCtx {
1218 .comptime_token = token,
1219 .block = block,
14301220 }
14311221 }) catch unreachable;
1432 try stack.append(State { .SuffixOpExpressionEnd = dest_ptr });
1433 try stack.append(State { .PrimaryExpression = dest_ptr });
1434
1435 const langle_bracket = self.getNextToken();
1436 if (langle_bracket.id != Token.Id.AngleBracketLeft) {
1437 self.putBackToken(langle_bracket);
1438 continue;
1439 }
1440
1441 async_node.rangle_bracket = Token(undefined);
1442 try stack.append(State {
1443 .ExpectTokenSave = ExpectTokenSave {
1444 .id = Token.Id.AngleBracketRight,
1445 .ptr = &??async_node.rangle_bracket,
1446 }
1447 });
1448 try stack.append(State { .TypeExprBegin = DestPtr { .NullableField = &async_node.allocator_type } });
14491222 continue;
14501223 },
1451 else => {
1452 self.putBackToken(token);
1453 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1454 try stack.append(State { .PrimaryExpression = dest_ptr });
1455 continue;
1456 }
1457 }
1458 },
1459
1460 State.SuffixOpExpressionEnd => |dest_ptr| {
1461 const token = self.getNextToken();
1462 switch (token.id) {
1463 Token.Id.LParen => {
1464 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuffixOp,
1465 ast.NodeSuffixOp {
1466 .base = undefined,
1467 .lhs = dest_ptr.get(),
1468 .op = ast.NodeSuffixOp.SuffixOp {
1469 .Call = ast.NodeSuffixOp.CallInfo {
1470 .params = ArrayList(&ast.Node).init(arena),
1471 .async_attr = null,
1472 }
1473 },
1474 .rtoken = undefined,
1475 }
1476 );
1477 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1478 try stack.append(State {
1479 .ExprListItemOrEnd = ExprListCtx {
1480 .list = &node.op.Call.params,
1481 .end = Token.Id.RParen,
1482 .ptr = &node.rtoken,
1224 Token.Id.Keyword_var, Token.Id.Keyword_const => {
1225 stack.append(State {
1226 .VarDecl = VarDeclCtx {
1227 .visib_token = null,
1228 .comptime_token = null,
1229 .extern_export_token = null,
1230 .lib_name = null,
1231 .mut_token = token,
1232 .list = &block.statements,
14831233 }
1484 });
1234 }) catch unreachable;
14851235 continue;
14861236 },
1487 Token.Id.LBracket => {
1488 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuffixOp,
1489 ast.NodeSuffixOp {
1237 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
1238 const node = try self.createAttachNode(arena, &block.statements, ast.NodeDefer,
1239 ast.NodeDefer {
14901240 .base = undefined,
1491 .lhs = dest_ptr.get(),
1492 .op = ast.NodeSuffixOp.SuffixOp {
1493 .ArrayAccess = undefined,
1241 .defer_token = token,
1242 .kind = switch (token.id) {
1243 Token.Id.Keyword_defer => ast.NodeDefer.Kind.Unconditional,
1244 Token.Id.Keyword_errdefer => ast.NodeDefer.Kind.Error,
1245 else => unreachable,
14941246 },
1495 .rtoken = undefined
1247 .expr = undefined,
14961248 }
14971249 );
1498 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1499 try stack.append(State { .SliceOrArrayAccess = node });
1500 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayAccess }});
1250 stack.append(State { .Semicolon = &&node.base }) catch unreachable;
1251 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
15011252 continue;
15021253 },
1503 Token.Id.Period => {
1504 const identifier = try self.createLiteral(arena, ast.NodeIdentifier, Token(undefined));
1505 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1506 ast.NodeInfixOp {
1254 Token.Id.LBrace => {
1255 const inner_block = try self.createAttachNode(arena, &block.statements, ast.NodeBlock,
1256 ast.NodeBlock {
15071257 .base = undefined,
1508 .lhs = dest_ptr.get(),
1509 .op_token = token,
1510 .op = ast.NodeInfixOp.InfixOp.Period,
1511 .rhs = &identifier.base,
1258 .label = null,
1259 .lbrace = token,
1260 .statements = ArrayList(&ast.Node).init(arena),
1261 .rbrace = undefined,
15121262 }
15131263 );
1514 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1515 try stack.append(State {
1516 .ExpectTokenSave = ExpectTokenSave {
1517 .id = Token.Id.Identifier,
1518 .ptr = &identifier.token
1519 }
1520 });
1264 stack.append(State { .Block = inner_block }) catch unreachable;
15211265 continue;
15221266 },
15231267 else => {
15241268 self.putBackToken(token);
1269 const statememt = try block.statements.addOne();
1270 stack.append(State { .Semicolon = statememt }) catch unreachable;
1271 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statememt } });
15251272 continue;
1526 },
1273 }
15271274 }
15281275 },
1529
1530 State.PrimaryExpression => |dest_ptr| {
1276 State.ComptimeStatement => |ctx| {
15311277 const token = self.getNextToken();
15321278 switch (token.id) {
1533 Token.Id.IntegerLiteral => {
1534 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base);
1535 continue;
1536 },
1537 Token.Id.FloatLiteral => {
1538 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeFloatLiteral, token)).base);
1539 continue;
1540 },
1541 Token.Id.CharLiteral => {
1542 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeCharLiteral, token)).base);
1543 continue;
1544 },
1545 Token.Id.Keyword_undefined => {
1546 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeUndefinedLiteral, token)).base);
1547 continue;
1548 },
1549 Token.Id.Keyword_true, Token.Id.Keyword_false => {
1550 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeBoolLiteral, token)).base);
1551 continue;
1552 },
1553 Token.Id.Keyword_null => {
1554 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeNullLiteral, token)).base);
1555 continue;
1556 },
1557 Token.Id.Keyword_this => {
1558 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeThisLiteral, token)).base);
1559 continue;
1560 },
1561 Token.Id.Keyword_var => {
1562 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeVarType, token)).base);
1563 continue;
1564 },
1565 Token.Id.Keyword_unreachable => {
1566 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeUnreachable, token)).base);
1567 continue;
1568 },
1569 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
1570 dest_ptr.store((try self.parseStringLiteral(arena, token)) ?? unreachable);
1571 },
1572 Token.Id.LParen => {
1573 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeGroupedExpression,
1574 ast.NodeGroupedExpression {
1575 .base = undefined,
1576 .lparen = token,
1577 .expr = undefined,
1578 .rparen = undefined,
1579 }
1580 );
1279 Token.Id.Keyword_var, Token.Id.Keyword_const => {
15811280 stack.append(State {
1582 .ExpectTokenSave = ExpectTokenSave {
1583 .id = Token.Id.RParen,
1584 .ptr = &node.rparen,
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,
15851288 }
15861289 }) catch unreachable;
1587 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
15881290 continue;
15891291 },
1590 Token.Id.Builtin => {
1591 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeBuiltinCall,
1592 ast.NodeBuiltinCall {
1593 .base = undefined,
1594 .builtin_token = token,
1595 .params = ArrayList(&ast.Node).init(arena),
1596 .rparen_token = undefined,
1597 }
1598 );
1599 stack.append(State {
1600 .ExprListItemOrEnd = ExprListCtx {
1601 .list = &node.params,
1602 .end = Token.Id.RParen,
1603 .ptr = &node.rparen_token,
1604 }
1605 }) catch unreachable;
1606 try stack.append(State { .ExpectToken = Token.Id.LParen, });
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 } });
16071298 continue;
1608 },
1609 Token.Id.LBracket => {
1610 const rbracket_token = self.getNextToken();
1611 if (rbracket_token.id == Token.Id.RBracket) {
1612 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
1613 ast.NodePrefixOp {
1614 .base = undefined,
1615 .op_token = token,
1616 .op = ast.NodePrefixOp.PrefixOp{
1617 .SliceType = ast.NodePrefixOp.AddrOfInfo {
1618 .align_expr = null,
1619 .bit_offset_start_token = null,
1620 .bit_offset_end_token = null,
1621 .const_token = null,
1622 .volatile_token = null,
1623 }
1624 },
1625 .rhs = undefined,
1626 }
1627 );
1628 dest_ptr.store(&node.base);
1629 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;
1630 try stack.append(State { .AddrOfModifiers = &node.op.SliceType });
1631 continue;
1632 }
1633
1634 self.putBackToken(rbracket_token);
1299 }
1300 }
1301 },
1302 State.Semicolon => |node_ptr| {
1303 const node = *node_ptr;
1304 if (requireSemiColon(node)) {
1305 stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable;
1306 continue;
1307 }
1308 continue;
1309 },
16351310
1636 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
1637 ast.NodePrefixOp {
1638 .base = undefined,
1639 .op_token = token,
1640 .op = ast.NodePrefixOp.PrefixOp{
1641 .ArrayType = undefined,
1642 },
1643 .rhs = undefined,
1644 }
1645 );
1646 stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.rhs } }) catch unreachable;
1647 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1648 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayType } });
16491311
1650 },
1651 Token.Id.Keyword_error => {
1652 if (self.eatToken(Token.Id.LBrace) == null) {
1653 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeErrorType, token)).base);
1654 continue;
1655 }
1312 State.AsmOutputItems => |items| {
1313 const lbracket = self.getNextToken();
1314 if (lbracket.id != Token.Id.LBracket) {
1315 self.putBackToken(lbracket);
1316 continue;
1317 }
16561318
1657 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeErrorSetDecl,
1658 ast.NodeErrorSetDecl {
1659 .base = undefined,
1660 .error_token = token,
1661 .decls = ArrayList(&ast.NodeIdentifier).init(arena),
1662 .rbrace_token = undefined,
1663 }
1664 );
1319 const node = try self.createNode(arena, ast.NodeAsmOutput,
1320 ast.NodeAsmOutput {
1321 .base = undefined,
1322 .symbolic_name = undefined,
1323 .constraint = undefined,
1324 .kind = undefined,
1325 }
1326 );
1327 try items.append(node);
16651328
1666 stack.append(State {
1667 .IdentifierListItemOrEnd = ListSave(&ast.NodeIdentifier) {
1668 .list = &node.decls,
1669 .ptr = &node.rbrace_token,
1670 }
1671 }) catch unreachable;
1329 stack.append(State { .AsmOutputItems = items }) catch unreachable;
1330 try stack.append(State { .IfToken = Token.Id.Comma });
1331 try stack.append(State { .ExpectToken = Token.Id.RParen });
1332 try stack.append(State { .AsmOutputReturnOrType = node });
1333 try stack.append(State { .ExpectToken = Token.Id.LParen });
1334 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });
1335 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1336 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });
1337 continue;
1338 },
1339 State.AsmOutputReturnOrType => |node| {
1340 const token = self.getNextToken();
1341 switch (token.id) {
1342 Token.Id.Identifier => {
1343 node.kind = ast.NodeAsmOutput.Kind { .Variable = try self.createLiteral(arena, ast.NodeIdentifier, token) };
16721344 continue;
16731345 },
1674 Token.Id.Keyword_packed => {
1675 stack.append(State {
1676 .ContainerExtern = ContainerExternCtx {
1677 .dest_ptr = dest_ptr,
1678 .ltoken = token,
1679 .layout = ast.NodeContainerDecl.Layout.Packed,
1680 },
1681 }) catch unreachable;
1682 },
1683 Token.Id.Keyword_extern => {
1684 const next = self.getNextToken();
1685 if (next.id == Token.Id.Keyword_fn) {
1686 const fn_proto = try self.createToDestNode(arena, dest_ptr, ast.NodeFnProto,
1687 ast.NodeFnProto {
1688 .base = undefined,
1689 .visib_token = null,
1690 .name_token = null,
1691 .fn_token = next,
1692 .params = ArrayList(&ast.Node).init(arena),
1693 .return_type = undefined,
1694 .var_args_token = null,
1695 .extern_export_inline_token = token,
1696 .cc_token = null,
1697 .async_attr = null,
1698 .body_node = null,
1699 .lib_name = null,
1700 .align_expr = null,
1701 }
1702 );
1703 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1704 continue;
1705 }
1706
1707 self.putBackToken(next);
1708 stack.append(State {
1709 .ContainerExtern = ContainerExternCtx {
1710 .dest_ptr = dest_ptr,
1711 .ltoken = token,
1712 .layout = ast.NodeContainerDecl.Layout.Extern,
1713 },
1714 }) catch unreachable;
1346 Token.Id.Arrow => {
1347 node.kind = ast.NodeAsmOutput.Kind { .Return = undefined };
1348 try stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.kind.Return } });
1349 continue;
17151350 },
1716 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
1717 self.putBackToken(token);
1718 stack.append(State {
1719 .ContainerExtern = ContainerExternCtx {
1720 .dest_ptr = dest_ptr,
1721 .ltoken = token,
1722 .layout = ast.NodeContainerDecl.Layout.Auto,
1723 },
1724 }) catch unreachable;
1725 },
1726 Token.Id.Identifier => {
1727 const next = self.getNextToken();
1728 if (next.id != Token.Id.Colon) {
1729 self.putBackToken(next);
1730 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeIdentifier, token)).base);
1731 continue;
1732 }
1733
1734 stack.append(State {
1735 .LabeledExpression = LabelCtx {
1736 .label = token,
1737 .dest_ptr = dest_ptr
1738 }
1739 }) catch unreachable;
1740 continue;
1741 },
1742 Token.Id.Keyword_fn => {
1743 const fn_proto = try self.createToDestNode(arena, dest_ptr, ast.NodeFnProto,
1744 ast.NodeFnProto {
1745 .base = undefined,
1746 .visib_token = null,
1747 .name_token = null,
1748 .fn_token = token,
1749 .params = ArrayList(&ast.Node).init(arena),
1750 .return_type = undefined,
1751 .var_args_token = null,
1752 .extern_export_inline_token = null,
1753 .cc_token = null,
1754 .async_attr = null,
1755 .body_node = null,
1756 .lib_name = null,
1757 .align_expr = null,
1758 }
1759 );
1760 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1761 continue;
1762 },
1763 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
1764 const fn_token = (try self.expectToken(&stack, Token.Id.Keyword_fn)) ?? continue;
1765 const fn_proto = try self.createToDestNode(arena, dest_ptr, ast.NodeFnProto,
1766 ast.NodeFnProto {
1767 .base = undefined,
1768 .visib_token = null,
1769 .name_token = null,
1770 .fn_token = fn_token,
1771 .params = ArrayList(&ast.Node).init(arena),
1772 .return_type = undefined,
1773 .var_args_token = null,
1774 .extern_export_inline_token = null,
1775 .cc_token = token,
1776 .async_attr = null,
1777 .body_node = null,
1778 .lib_name = null,
1779 .align_expr = null,
1780 }
1781 );
1782 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1783 continue;
1784 },
1785 Token.Id.Keyword_asm => {
1786 const is_volatile = blk: {
1787 const volatile_token = self.getNextToken();
1788 if (volatile_token.id != Token.Id.Keyword_volatile) {
1789 self.putBackToken(volatile_token);
1790 break :blk false;
1791 }
1792 break :blk true;
1793 };
1794 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
1795
1796 const template_token = self.getNextToken();
1797 const template = (try self.parseStringLiteral(arena, template_token)) ?? {
1798 try self.parseError(&stack, template_token, "expected string literal, found {}", @tagName(template_token.id));
1799 continue;
1800 };
1801 // TODO parse template
1802
1803 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeAsm,
1804 ast.NodeAsm {
1805 .base = undefined,
1806 .asm_token = token,
1807 .is_volatile = is_volatile,
1808 .template = template,
1809 //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),
1810 .outputs = ArrayList(&ast.NodeAsmOutput).init(arena),
1811 .inputs = ArrayList(&ast.NodeAsmInput).init(arena),
1812 .cloppers = ArrayList(&ast.Node).init(arena),
1813 .rparen = undefined,
1814 }
1815 );
1816 stack.append(State {
1817 .ExpectTokenSave = ExpectTokenSave {
1818 .id = Token.Id.RParen,
1819 .ptr = &node.rparen,
1820 }
1821 }) catch unreachable;
1822 try stack.append(State { .AsmClopperItems = &node.cloppers });
1823 try stack.append(State { .IfToken = Token.Id.Colon });
1824 try stack.append(State { .AsmInputItems = &node.inputs });
1825 try stack.append(State { .IfToken = Token.Id.Colon });
1826 try stack.append(State { .AsmOutputItems = &node.outputs });
1827 try stack.append(State { .IfToken = Token.Id.Colon });
1828 },
1829 Token.Id.Keyword_inline => {
1830 stack.append(State {
1831 .Inline = InlineCtx {
1832 .label = null,
1833 .inline_token = token,
1834 .dest_ptr = dest_ptr,
1835 }
1836 }) catch unreachable;
1837 continue;
1838 },
1839 else => {
1840 if (!try self.parseBlockExpr(&stack, arena, dest_ptr, token)) {
1841 try self.parseError(&stack, token, "expected primary expression, found {}", @tagName(token.id));
1842 }
1843 continue;
1844 }
1845 }
1846 },
1847
1848 State.SliceOrArrayAccess => |node| {
1849 var token = self.getNextToken();
1850
1851 switch (token.id) {
1852 Token.Id.Ellipsis2 => {
1853 const start = node.op.ArrayAccess;
1854 node.op = ast.NodeSuffixOp.SuffixOp {
1855 .Slice = ast.NodeSuffixOp.SliceRange {
1856 .start = start,
1857 .end = undefined,
1858 }
1859 };
1860
1861 const rbracket_token = self.getNextToken();
1862 if (rbracket_token.id != Token.Id.RBracket) {
1863 self.putBackToken(rbracket_token);
1864 stack.append(State {
1865 .ExpectTokenSave = ExpectTokenSave {
1866 .id = Token.Id.RBracket,
1867 .ptr = &node.rtoken,
1868 }
1869 }) catch unreachable;
1870 try stack.append(State { .Expression = DestPtr { .NullableField = &node.op.Slice.end } });
1871 } else {
1872 node.rtoken = rbracket_token;
1873 }
1874 continue;
1875 },
1876 Token.Id.RBracket => {
1877 node.rtoken = token;
1878 continue;
1879 },
1880 else => {
1881 try self.parseError(&stack, token, "expected ']' or '..', found {}", @tagName(token.id));
1882 continue;
1883 }
1884 }
1885 },
1886
1887
1888 State.AsmOutputItems => |items| {
1889 const lbracket = self.getNextToken();
1890 if (lbracket.id != Token.Id.LBracket) {
1891 self.putBackToken(lbracket);
1892 continue;
1893 }
1894
1895 stack.append(State { .AsmOutputItems = items }) catch unreachable;
1896 try stack.append(State { .IfToken = Token.Id.Comma });
1897
1898 const symbolic_name = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
1899 _ = (try self.expectToken(&stack, Token.Id.RBracket)) ?? continue;
1900
1901 const constraint_token = self.getNextToken();
1902 const constraint = (try self.parseStringLiteral(arena, constraint_token)) ?? {
1903 try self.parseError(&stack, constraint_token, "expected string literal, found {}", @tagName(constraint_token.id));
1904 continue;
1905 };
1906
1907 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
1908 try stack.append(State { .ExpectToken = Token.Id.RParen });
1909
1910 const node = try self.createNode(arena, ast.NodeAsmOutput,
1911 ast.NodeAsmOutput {
1912 .base = undefined,
1913 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),
1914 .constraint = constraint,
1915 .kind = undefined,
1916 }
1917 );
1918 try items.append(node);
1919
1920 const symbol_or_arrow = self.getNextToken();
1921 switch (symbol_or_arrow.id) {
1922 Token.Id.Identifier => {
1923 node.kind = ast.NodeAsmOutput.Kind { .Variable = try self.createLiteral(arena, ast.NodeIdentifier, symbol_or_arrow) };
1924 },
1925 Token.Id.Arrow => {
1926 node.kind = ast.NodeAsmOutput.Kind { .Return = undefined };
1927 try stack.append(State { .TypeExprBegin = DestPtr { .Field = &node.kind.Return } });
1928 },
1929 else => {
1930 try self.parseError(&stack, symbol_or_arrow, "expected '->' or {}, found {}",
1931 @tagName(Token.Id.Identifier),
1932 @tagName(symbol_or_arrow.id));
1933 continue;
1351 else => {
1352 return self.parseError(token, "expected '->' or {}, found {}",
1353 @tagName(Token.Id.Identifier),
1354 @tagName(token.id));
19341355 },
19351356 }
19361357 },
1937
19381358 State.AsmInputItems => |items| {
19391359 const lbracket = self.getNextToken();
19401360 if (lbracket.id != Token.Id.LBracket) {
......@@ -1942,59 +1362,53 @@ pub const Parser = struct {
19421362 continue;
19431363 }
19441364
1945 stack.append(State { .AsmInputItems = items }) catch unreachable;
1946 try stack.append(State { .IfToken = Token.Id.Comma });
1947
1948 const symbolic_name = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
1949 _ = (try self.expectToken(&stack, Token.Id.RBracket)) ?? continue;
1950
1951 const constraint_token = self.getNextToken();
1952 const constraint = (try self.parseStringLiteral(arena, constraint_token)) ?? {
1953 try self.parseError(&stack, constraint_token, "expected string literal, found {}", @tagName(constraint_token.id));
1954 continue;
1955 };
1956
1957 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
1958 try stack.append(State { .ExpectToken = Token.Id.RParen });
1959
19601365 const node = try self.createNode(arena, ast.NodeAsmInput,
19611366 ast.NodeAsmInput {
19621367 .base = undefined,
1963 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),
1964 .constraint = constraint,
1368 .symbolic_name = undefined,
1369 .constraint = undefined,
19651370 .expr = undefined,
19661371 }
19671372 );
19681373 try items.append(node);
1969 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
1970 },
19711374
1375 stack.append(State { .AsmInputItems = items }) catch unreachable;
1376 try stack.append(State { .IfToken = Token.Id.Comma });
1377 try stack.append(State { .ExpectToken = Token.Id.RParen });
1378 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
1379 try stack.append(State { .ExpectToken = Token.Id.LParen });
1380 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });
1381 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1382 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });
1383 continue;
1384 },
19721385 State.AsmClopperItems => |items| {
1973 const string_token = self.getNextToken();
1974 const string = (try self.parseStringLiteral(arena, string_token)) ?? {
1975 self.putBackToken(string_token);
1976 continue;
1977 };
1978 try items.append(string);
1979
19801386 stack.append(State { .AsmClopperItems = items }) catch unreachable;
19811387 try stack.append(State { .IfToken = Token.Id.Comma });
1388 try stack.append(State { .StringLiteral = OptionalCtx { .Required = try items.addOne() } });
1389 continue;
19821390 },
19831391
1984 State.ExprListItemOrEnd => |list_state| {
1985 var token = self.getNextToken();
19861392
1987 const IdTag = @TagType(Token.Id);
1988 if (IdTag(list_state.end) == token.id) {
1393 State.ExprListItemOrEnd => |list_state| {
1394 if (self.eatToken(list_state.end)) |token| {
19891395 *list_state.ptr = token;
19901396 continue;
19911397 }
19921398
1993 self.putBackToken(token);
19941399 stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable;
1995 try stack.append(State { .Expression = DestPtr{ .Field = try list_state.list.addOne() } });
1400 try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } });
1401 continue;
1402 },
1403 State.ExprListCommaOrEnd => |list_state| {
1404 if (try self.expectCommaOrEnd(list_state.end)) |end| {
1405 *list_state.ptr = end;
1406 continue;
1407 } else {
1408 stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable;
1409 continue;
1410 }
19961411 },
1997
19981412 State.FieldInitListItemOrEnd => |list_state| {
19991413 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
20001414 *list_state.ptr = rbrace;
......@@ -2012,7 +1426,7 @@ pub const Parser = struct {
20121426 try list_state.list.append(node);
20131427
20141428 stack.append(State { .FieldInitListCommaOrEnd = list_state }) catch unreachable;
2015 try stack.append(State { .Expression = DestPtr{.Field = &node.expr} });
1429 try stack.append(State { .Expression = OptionalCtx{ .Required = &node.expr } });
20161430 try stack.append(State { .ExpectToken = Token.Id.Equal });
20171431 try stack.append(State {
20181432 .ExpectTokenSave = ExpectTokenSave {
......@@ -2026,26 +1440,45 @@ pub const Parser = struct {
20261440 .ptr = &node.period_token,
20271441 }
20281442 });
1443 continue;
1444 },
1445 State.FieldInitListCommaOrEnd => |list_state| {
1446 if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| {
1447 *list_state.ptr = end;
1448 continue;
1449 } else {
1450 stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable;
1451 continue;
1452 }
1453 },
1454 State.FieldListCommaOrEnd => |container_decl| {
1455 if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| {
1456 container_decl.rbrace_token = end;
1457 continue;
1458 } else {
1459 stack.append(State { .ContainerDecl = container_decl }) catch unreachable;
1460 continue;
1461 }
20291462 },
2030
20311463 State.IdentifierListItemOrEnd => |list_state| {
20321464 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
20331465 *list_state.ptr = rbrace;
20341466 continue;
20351467 }
20361468
2037 const node = try self.createLiteral(arena, ast.NodeIdentifier, Token(undefined));
2038 try list_state.list.append(node);
2039
20401469 stack.append(State { .IdentifierListCommaOrEnd = list_state }) catch unreachable;
2041 try stack.append(State {
2042 .ExpectTokenSave = ExpectTokenSave {
2043 .id = Token.Id.Identifier,
2044 .ptr = &node.token,
2045 }
2046 });
1470 try stack.append(State { .Identifier = OptionalCtx { .Required = try list_state.list.addOne() } });
1471 continue;
1472 },
1473 State.IdentifierListCommaOrEnd => |list_state| {
1474 if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| {
1475 *list_state.ptr = end;
1476 continue;
1477 } else {
1478 stack.append(State { .IdentifierListItemOrEnd = list_state }) catch unreachable;
1479 continue;
1480 }
20471481 },
2048
20491482 State.SwitchCaseOrEnd => |list_state| {
20501483 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
20511484 *list_state.ptr = rbrace;
......@@ -2062,109 +1495,78 @@ pub const Parser = struct {
20621495 );
20631496 try list_state.list.append(node);
20641497 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;
2065 try stack.append(State { .AssignmentExpressionBegin = DestPtr{ .Field = &node.expr } });
2066 try stack.append(State { .PointerPayload = &node.payload });
2067
2068 const maybe_else = self.getNextToken();
2069 if (maybe_else.id == Token.Id.Keyword_else) {
2070 const else_node = try self.createAttachNode(arena, &node.items, ast.NodeSwitchElse,
1498 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .Required = &node.expr } });
1499 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
1500 try stack.append(State { .SwitchCaseFirstItem = &node.items });
1501 continue;
1502 },
1503 State.SwitchCaseCommaOrEnd => |list_state| {
1504 if (try self.expectCommaOrEnd(Token.Id.RBrace)) |end| {
1505 *list_state.ptr = end;
1506 continue;
1507 } else {
1508 stack.append(State { .SwitchCaseOrEnd = list_state }) catch unreachable;
1509 continue;
1510 }
1511 },
1512 State.SwitchCaseFirstItem => |case_items| {
1513 const token = self.getNextToken();
1514 if (token.id == Token.Id.Keyword_else) {
1515 const else_node = try self.createAttachNode(arena, case_items, ast.NodeSwitchElse,
20711516 ast.NodeSwitchElse {
20721517 .base = undefined,
2073 .token = maybe_else,
1518 .token = token,
20741519 }
20751520 );
20761521 try stack.append(State { .ExpectToken = Token.Id.EqualAngleBracketRight });
20771522 continue;
20781523 } else {
2079 self.putBackToken(maybe_else);
2080 try stack.append(State { .SwitchCaseItem = &node.items });
1524 self.putBackToken(token);
1525 try stack.append(State { .SwitchCaseItem = case_items });
20811526 continue;
20821527 }
20831528 },
2084
20851529 State.SwitchCaseItem => |case_items| {
20861530 stack.append(State { .SwitchCaseItemCommaOrEnd = case_items }) catch unreachable;
2087 try stack.append(State { .RangeExpressionBegin = DestPtr{ .Field = try case_items.addOne() } });
2088 },
2089
2090 State.ExprListCommaOrEnd => |list_state| {
2091 try self.commaOrEnd(&stack, list_state.end, list_state.ptr, State { .ExprListItemOrEnd = list_state });
2092 continue;
2093 },
2094
2095 State.FieldInitListCommaOrEnd => |list_state| {
2096 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .FieldInitListItemOrEnd = list_state });
2097 continue;
1531 try stack.append(State { .RangeExpressionBegin = OptionalCtx { .Required = try case_items.addOne() } });
20981532 },
2099
2100 State.FieldListCommaOrEnd => |container_decl| {
2101 try self.commaOrEnd(&stack, Token.Id.RBrace, &container_decl.rbrace_token,
2102 State { .ContainerDecl = container_decl });
1533 State.SwitchCaseItemCommaOrEnd => |case_items| {
1534 if ((try self.expectCommaOrEnd(Token.Id.EqualAngleBracketRight)) == null) {
1535 stack.append(State { .SwitchCaseItem = case_items }) catch unreachable;
1536 }
21031537 continue;
21041538 },
21051539
2106 State.IdentifierListCommaOrEnd => |list_state| {
2107 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .IdentifierListItemOrEnd = list_state });
2108 continue;
2109 },
21101540
2111 State.SwitchCaseCommaOrEnd => |list_state| {
2112 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .SwitchCaseOrEnd = list_state });
1541 State.SuspendBody => |suspend_node| {
1542 if (suspend_node.payload != null) {
1543 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = &suspend_node.body } });
1544 }
21131545 continue;
21141546 },
1547 State.AsyncAllocator => |async_node| {
1548 if (self.eatToken(Token.Id.AngleBracketLeft) == null) {
1549 continue;
1550 }
21151551
2116 State.SwitchCaseItemCommaOrEnd => |case_items| {
2117 try self.commaOrEnd(&stack, Token.Id.EqualAngleBracketRight, null, State { .SwitchCaseItem = case_items });
1552 async_node.rangle_bracket = Token(undefined);
1553 try stack.append(State {
1554 .ExpectTokenSave = ExpectTokenSave {
1555 .id = Token.Id.AngleBracketRight,
1556 .ptr = &??async_node.rangle_bracket,
1557 }
1558 });
1559 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &async_node.allocator_type } });
21181560 continue;
21191561 },
2120
2121 State.Else => |dest| {
2122 const else_token = self.getNextToken();
2123 if (else_token.id != Token.Id.Keyword_else) {
2124 self.putBackToken(else_token);
2125 continue;
2126 }
2127
2128 const node = try self.createNode(arena, ast.NodeElse,
2129 ast.NodeElse {
2130 .base = undefined,
2131 .else_token = else_token,
2132 .payload = null,
2133 .body = undefined,
2134 }
2135 );
2136 *dest = node;
2137
2138 stack.append(State { .Expression = DestPtr { .Field = &node.body } }) catch unreachable;
2139 try stack.append(State { .Payload = &node.payload });
2140 },
2141
2142 State.WhileContinueExpr => |dest| {
2143 const colon = self.getNextToken();
2144 if (colon.id != Token.Id.Colon) {
2145 self.putBackToken(colon);
2146 continue;
2147 }
2148
2149 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
2150 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
2151 try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = dest } });
2152 },
2153
2154 State.SuspendBody => |suspend_node| {
2155 if (suspend_node.payload != null) {
2156 try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = &suspend_node.body } });
2157 }
2158 continue;
2159 },
2160
2161 State.AsyncEnd => |ctx| {
2162 const node = ctx.dest_ptr.get();
1562 State.AsyncEnd => |ctx| {
1563 const node = ctx.ctx.get() ?? continue;
21631564
21641565 switch (node.id) {
21651566 ast.Node.Id.FnProto => {
21661567 const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node);
21671568 fn_proto.async_attr = ctx.attribute;
1569 continue;
21681570 },
21691571 ast.Node.Id.SuffixOp => {
21701572 const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node);
......@@ -2173,128 +1575,121 @@ pub const Parser = struct {
21731575 continue;
21741576 }
21751577
2176 try self.parseError(&stack, node.firstToken(), "expected call or fn proto, found {}.",
1578 return self.parseError(node.firstToken(), "expected {}, found {}.",
1579 @tagName(ast.NodeSuffixOp.SuffixOp.Call),
21771580 @tagName(suffix_op.op));
2178 continue;
21791581 },
21801582 else => {
2181 try self.parseError(&stack, node.firstToken(), "expected call or fn proto, found {}.",
1583 return self.parseError(node.firstToken(), "expected {} or {}, found {}.",
1584 @tagName(ast.NodeSuffixOp.SuffixOp.Call),
1585 @tagName(ast.Node.Id.FnProto),
21821586 @tagName(node.id));
2183 continue;
21841587 }
21851588 }
21861589 },
21871590
2188 State.Payload => |dest| {
2189 const lpipe = self.getNextToken();
2190 if (lpipe.id != Token.Id.Pipe) {
2191 self.putBackToken(lpipe);
2192 continue;
2193 }
2194
2195 const error_symbol = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
2196 const rpipe = (try self.expectToken(&stack, Token.Id.Pipe)) ?? continue;
2197 *dest = try self.createNode(arena, ast.NodePayload,
2198 ast.NodePayload {
2199 .base = undefined,
2200 .lpipe = lpipe,
2201 .error_symbol = try self.createLiteral(arena, ast.NodeIdentifier, error_symbol),
2202 .rpipe = rpipe
2203 }
2204 );
2205 },
22061591
2207 State.PointerPayload => |dest| {
2208 const lpipe = self.getNextToken();
2209 if (lpipe.id != Token.Id.Pipe) {
2210 self.putBackToken(lpipe);
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;
22111612 continue;
22121613 }
22131614
2214 const is_ptr = blk: {
2215 const asterik = self.getNextToken();
2216 if (asterik.id == Token.Id.Asterisk) {
2217 break :blk true;
2218 } else {
2219 self.putBackToken(asterik);
2220 break :blk false;
2221 }
2222 };
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 },
1624 State.SliceOrArrayAccess => |node| {
1625 var token = self.getNextToken();
1626 switch (token.id) {
1627 Token.Id.Ellipsis2 => {
1628 const start = node.op.ArrayAccess;
1629 node.op = ast.NodeSuffixOp.SuffixOp {
1630 .Slice = ast.NodeSuffixOp.SliceRange {
1631 .start = start,
1632 .end = null,
1633 }
1634 };
22231635
2224 const value_symbol = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
2225 const rpipe = (try self.expectToken(&stack, Token.Id.Pipe)) ?? continue;
2226 *dest = try self.createNode(arena, ast.NodePointerPayload,
2227 ast.NodePointerPayload {
2228 .base = undefined,
2229 .lpipe = lpipe,
2230 .is_ptr = is_ptr,
2231 .value_symbol = try self.createLiteral(arena, ast.NodeIdentifier, value_symbol),
2232 .rpipe = rpipe
1636 stack.append(State {
1637 .ExpectTokenSave = ExpectTokenSave {
1638 .id = Token.Id.RBracket,
1639 .ptr = &node.rtoken,
1640 }
1641 }) catch unreachable;
1642 try stack.append(State { .Expression = OptionalCtx { .Optional = &node.op.Slice.end } });
1643 continue;
1644 },
1645 Token.Id.RBracket => {
1646 node.rtoken = token;
1647 continue;
1648 },
1649 else => {
1650 return self.parseError(token, "expected ']' or '..', found {}", @tagName(token.id));
22331651 }
2234 );
1652 }
22351653 },
2236
2237 State.PointerIndexPayload => |dest| {
2238 const lpipe = self.getNextToken();
2239 if (lpipe.id != Token.Id.Pipe) {
2240 self.putBackToken(lpipe);
1654 State.SliceOrArrayType => |node| {
1655 if (self.eatToken(Token.Id.RBracket)) |_| {
1656 node.op = ast.NodePrefixOp.PrefixOp {
1657 .SliceType = ast.NodePrefixOp.AddrOfInfo {
1658 .align_expr = null,
1659 .bit_offset_start_token = null,
1660 .bit_offset_end_token = null,
1661 .const_token = null,
1662 .volatile_token = null,
1663 }
1664 };
1665 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1666 try stack.append(State { .AddrOfModifiers = &node.op.SliceType });
22411667 continue;
22421668 }
22431669
2244 const is_ptr = blk: {
2245 const asterik = self.getNextToken();
2246 if (asterik.id == Token.Id.Asterisk) {
2247 break :blk true;
2248 } else {
2249 self.putBackToken(asterik);
2250 break :blk false;
2251 }
2252 };
2253
2254 const value_symbol = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
2255 const index_symbol = blk: {
2256 const comma = self.getNextToken();
2257 if (comma.id != Token.Id.Comma) {
2258 self.putBackToken(comma);
2259 break :blk null;
2260 }
2261
2262 const symbol = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
2263 break :blk try self.createLiteral(arena, ast.NodeIdentifier, symbol);
2264 };
2265
2266 const rpipe = (try self.expectToken(&stack, Token.Id.Pipe)) ?? continue;
2267 *dest = try self.createNode(arena, ast.NodePointerIndexPayload,
2268 ast.NodePointerIndexPayload {
2269 .base = undefined,
2270 .lpipe = lpipe,
2271 .is_ptr = is_ptr,
2272 .value_symbol = try self.createLiteral(arena, ast.NodeIdentifier, value_symbol),
2273 .index_symbol = index_symbol,
2274 .rpipe = rpipe
2275 }
2276 );
1670 node.op = ast.NodePrefixOp.PrefixOp { .ArrayType = undefined };
1671 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1672 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1673 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayType } });
1674 continue;
22771675 },
2278
22791676 State.AddrOfModifiers => |addr_of_info| {
22801677 var token = self.getNextToken();
22811678 switch (token.id) {
22821679 Token.Id.Keyword_align => {
22831680 stack.append(state) catch unreachable;
22841681 if (addr_of_info.align_expr != null) {
2285 try self.parseError(&stack, token, "multiple align qualifiers");
2286 continue;
1682 return self.parseError(token, "multiple align qualifiers");
22871683 }
22881684 try stack.append(State { .ExpectToken = Token.Id.RParen });
2289 try stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_info.align_expr} });
1685 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &addr_of_info.align_expr} });
22901686 try stack.append(State { .ExpectToken = Token.Id.LParen });
22911687 continue;
22921688 },
22931689 Token.Id.Keyword_const => {
22941690 stack.append(state) catch unreachable;
22951691 if (addr_of_info.const_token != null) {
2296 try self.parseError(&stack, token, "duplicate qualifier: const");
2297 continue;
1692 return self.parseError(token, "duplicate qualifier: const");
22981693 }
22991694 addr_of_info.const_token = token;
23001695 continue;
......@@ -2302,8 +1697,7 @@ pub const Parser = struct {
23021697 Token.Id.Keyword_volatile => {
23031698 stack.append(state) catch unreachable;
23041699 if (addr_of_info.volatile_token != null) {
2305 try self.parseError(&stack, token, "duplicate qualifier: volatile");
2306 continue;
1700 return self.parseError(token, "duplicate qualifier: volatile");
23071701 }
23081702 addr_of_info.volatile_token = token;
23091703 continue;
......@@ -2315,391 +1709,1043 @@ pub const Parser = struct {
23151709 }
23161710 },
23171711
2318 State.FnProto => |fn_proto| {
2319 stack.append(State { .FnProtoAlign = fn_proto }) catch unreachable;
2320 try stack.append(State { .ParamDecl = fn_proto });
2321 try stack.append(State { .ExpectToken = Token.Id.LParen });
23221712
2323 const next_token = self.getNextToken();
2324 if (next_token.id == Token.Id.Identifier) {
2325 fn_proto.name_token = next_token;
1713 State.Payload => |opt_ctx| {
1714 const token = self.getNextToken();
1715 if (token.id != Token.Id.Pipe) {
1716 if (opt_ctx != OptionalCtx.Optional) {
1717 return self.parseError(token, "expected {}, found {}.",
1718 @tagName(Token.Id.Pipe),
1719 @tagName(token.id));
1720 }
1721
1722 self.putBackToken(token);
23261723 continue;
23271724 }
2328 self.putBackToken(next_token);
2329 continue;
2330 },
2331
2332 State.FnProtoAlign => |fn_proto| {
2333 stack.append(State { .FnProtoReturnType = fn_proto }) catch unreachable;
23341725
2335 if (self.eatToken(Token.Id.Keyword_align)) |align_token| {
2336 try stack.append(State { .ExpectToken = Token.Id.RParen });
2337 try stack.append(State { .Expression = DestPtr { .NullableField = &fn_proto.align_expr } });
2338 try stack.append(State { .ExpectToken = Token.Id.LParen });
2339 }
1726 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePayload,
1727 ast.NodePayload {
1728 .base = undefined,
1729 .lpipe = token,
1730 .error_symbol = undefined,
1731 .rpipe = undefined
1732 }
1733 );
23401734
1735 stack.append(State {
1736 .ExpectTokenSave = ExpectTokenSave {
1737 .id = Token.Id.Pipe,
1738 .ptr = &node.rpipe,
1739 }
1740 }) catch unreachable;
1741 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.error_symbol } });
23411742 continue;
23421743 },
2343
2344 State.FnProtoReturnType => |fn_proto| {
1744 State.PointerPayload => |opt_ctx| {
23451745 const token = self.getNextToken();
2346 switch (token.id) {
2347 Token.Id.Bang => {
2348 fn_proto.return_type = ast.NodeFnProto.ReturnType { .InferErrorSet = undefined };
2349 stack.append(State {
2350 .TypeExprBegin = DestPtr {.Field = &fn_proto.return_type.InferErrorSet},
2351 }) catch unreachable;
2352 continue;
2353 },
2354 else => {
2355 // TODO: this is a special case. Remove this when #760 is fixed
2356 if (token.id == Token.Id.Keyword_error) {
2357 if (self.isPeekToken(Token.Id.LBrace)) {
2358 fn_proto.return_type = ast.NodeFnProto.ReturnType {
2359 .Explicit = &(try self.createLiteral(arena, ast.NodeErrorType, token)).base
2360 };
2361 continue;
2362 }
2363 }
2364
2365 self.putBackToken(token);
2366 fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined };
2367 stack.append(State {
2368 .TypeExprBegin = DestPtr {.Field = &fn_proto.return_type.Explicit},
2369 }) catch unreachable;
2370 continue;
2371 },
2372 }
2373 },
1746 if (token.id != Token.Id.Pipe) {
1747 if (opt_ctx != OptionalCtx.Optional) {
1748 return self.parseError(token, "expected {}, found {}.",
1749 @tagName(Token.Id.Pipe),
1750 @tagName(token.id));
1751 }
23741752
2375 State.ParamDecl => |fn_proto| {
2376 if (self.eatToken(Token.Id.RParen)) |_| {
1753 self.putBackToken(token);
23771754 continue;
23781755 }
2379 const param_decl = try self.createAttachNode(arena, &fn_proto.params, ast.NodeParamDecl,
2380 ast.NodeParamDecl {
1756
1757 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePointerPayload,
1758 ast.NodePointerPayload {
23811759 .base = undefined,
2382 .comptime_token = null,
2383 .noalias_token = null,
2384 .name_token = null,
2385 .type_node = undefined,
2386 .var_args_token = null,
2387 },
1760 .lpipe = token,
1761 .ptr_token = null,
1762 .value_symbol = undefined,
1763 .rpipe = undefined
1764 }
23881765 );
2389 if (self.eatToken(Token.Id.Keyword_comptime)) |comptime_token| {
2390 param_decl.comptime_token = comptime_token;
2391 } else if (self.eatToken(Token.Id.Keyword_noalias)) |noalias_token| {
2392 param_decl.noalias_token = noalias_token;
2393 }
2394 if (self.eatToken(Token.Id.Identifier)) |identifier| {
2395 if (self.eatToken(Token.Id.Colon)) |_| {
2396 param_decl.name_token = identifier;
2397 } else {
2398 self.putBackToken(identifier);
1766
1767 stack.append(State {
1768 .ExpectTokenSave = ExpectTokenSave {
1769 .id = Token.Id.Pipe,
1770 .ptr = &node.rpipe,
23991771 }
2400 }
2401 if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| {
2402 param_decl.var_args_token = ellipsis3;
2403 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
1772 }) catch unreachable;
1773 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });
1774 try stack.append(State {
1775 .OptionalTokenSave = OptionalTokenSave {
1776 .id = Token.Id.Asterisk,
1777 .ptr = &node.ptr_token,
1778 }
1779 });
1780 continue;
1781 },
1782 State.PointerIndexPayload => |opt_ctx| {
1783 const token = self.getNextToken();
1784 if (token.id != Token.Id.Pipe) {
1785 if (opt_ctx != OptionalCtx.Optional) {
1786 return self.parseError(token, "expected {}, found {}.",
1787 @tagName(Token.Id.Pipe),
1788 @tagName(token.id));
1789 }
1790
1791 self.putBackToken(token);
24041792 continue;
24051793 }
24061794
2407 stack.append(State { .ParamDecl = fn_proto }) catch unreachable;
2408 try stack.append(State.ParamDeclComma);
1795 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePointerIndexPayload,
1796 ast.NodePointerIndexPayload {
1797 .base = undefined,
1798 .lpipe = token,
1799 .ptr_token = null,
1800 .value_symbol = undefined,
1801 .index_symbol = null,
1802 .rpipe = undefined
1803 }
1804 );
1805
1806 stack.append(State {
1807 .ExpectTokenSave = ExpectTokenSave {
1808 .id = Token.Id.Pipe,
1809 .ptr = &node.rpipe,
1810 }
1811 }) catch unreachable;
1812 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.index_symbol } });
1813 try stack.append(State { .IfToken = Token.Id.Comma });
1814 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });
24091815 try stack.append(State {
2410 .TypeExprBegin = DestPtr {.Field = &param_decl.type_node}
1816 .OptionalTokenSave = OptionalTokenSave {
1817 .id = Token.Id.Asterisk,
1818 .ptr = &node.ptr_token,
1819 }
24111820 });
24121821 continue;
24131822 },
24141823
2415 State.ParamDeclComma => {
1824
1825 State.Expression => |opt_ctx| {
24161826 const token = self.getNextToken();
24171827 switch (token.id) {
2418 Token.Id.RParen => {
2419 _ = stack.pop(); // pop off the ParamDecl
2420 continue;
2421 },
2422 Token.Id.Comma => continue,
2423 else => {
2424 try self.parseError(&stack, token, "expected ',' or ')', found {}", @tagName(token.id));
1828 Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {
1829 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeControlFlowExpression,
1830 ast.NodeControlFlowExpression {
1831 .base = undefined,
1832 .ltoken = token,
1833 .kind = undefined,
1834 .rhs = null,
1835 }
1836 );
1837
1838 stack.append(State { .Expression = OptionalCtx { .Optional = &node.rhs } }) catch unreachable;
1839
1840 switch (token.id) {
1841 Token.Id.Keyword_break => {
1842 node.kind = ast.NodeControlFlowExpression.Kind { .Break = null };
1843 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Break } });
1844 try stack.append(State { .IfToken = Token.Id.Colon });
1845 },
1846 Token.Id.Keyword_continue => {
1847 node.kind = ast.NodeControlFlowExpression.Kind { .Continue = null };
1848 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } });
1849 try stack.append(State { .IfToken = Token.Id.Colon });
1850 },
1851 Token.Id.Keyword_return => {
1852 node.kind = ast.NodeControlFlowExpression.Kind.Return;
1853 },
1854 else => unreachable,
1855 }
24251856 continue;
24261857 },
2427 }
2428 },
2429
2430 State.FnDef => |fn_proto| {
2431 const token = self.getNextToken();
2432 switch(token.id) {
2433 Token.Id.LBrace => {
2434 const block = try self.createNode(arena, ast.NodeBlock,
2435 ast.NodeBlock {
1858 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
1859 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePrefixOp,
1860 ast.NodePrefixOp {
24361861 .base = undefined,
2437 .label = null,
2438 .lbrace = token,
2439 .statements = ArrayList(&ast.Node).init(arena),
2440 .rbrace = undefined,
1862 .op_token = token,
1863 .op = switch (token.id) {
1864 Token.Id.Keyword_try => ast.NodePrefixOp.PrefixOp { .Try = void{} },
1865 Token.Id.Keyword_cancel => ast.NodePrefixOp.PrefixOp { .Cancel = void{} },
1866 Token.Id.Keyword_resume => ast.NodePrefixOp.PrefixOp { .Resume = void{} },
1867 else => unreachable,
1868 },
1869 .rhs = undefined,
24411870 }
24421871 );
2443 fn_proto.body_node = &block.base;
2444 stack.append(State { .Block = block }) catch unreachable;
1872
1873 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
24451874 continue;
24461875 },
2447 Token.Id.Semicolon => continue,
24481876 else => {
2449 try self.parseError(&stack, token, "expected ';' or '{{', found {}", @tagName(token.id));
1877 if (!try self.parseBlockExpr(&stack, arena, opt_ctx, token)) {
1878 self.putBackToken(token);
1879 stack.append(State { .UnwrapExpressionBegin = opt_ctx }) catch unreachable;
1880 }
1881 continue;
1882 }
1883 }
1884 },
1885 State.RangeExpressionBegin => |opt_ctx| {
1886 stack.append(State { .RangeExpressionEnd = opt_ctx }) catch unreachable;
1887 try stack.append(State { .Expression = opt_ctx });
1888 continue;
1889 },
1890 State.RangeExpressionEnd => |opt_ctx| {
1891 const lhs = opt_ctx.get() ?? continue;
1892
1893 if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| {
1894 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
1895 ast.NodeInfixOp {
1896 .base = undefined,
1897 .lhs = lhs,
1898 .op_token = ellipsis3,
1899 .op = ast.NodeInfixOp.InfixOp.Range,
1900 .rhs = undefined,
1901 }
1902 );
1903 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1904 continue;
1905 }
1906 },
1907 State.AssignmentExpressionBegin => |opt_ctx| {
1908 stack.append(State { .AssignmentExpressionEnd = opt_ctx }) catch unreachable;
1909 try stack.append(State { .Expression = opt_ctx });
1910 continue;
1911 },
1912
1913 State.AssignmentExpressionEnd => |opt_ctx| {
1914 const lhs = opt_ctx.get() ?? continue;
1915
1916 const token = self.getNextToken();
1917 if (tokenIdToAssignment(token.id)) |ass_id| {
1918 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
1919 ast.NodeInfixOp {
1920 .base = undefined,
1921 .lhs = lhs,
1922 .op_token = token,
1923 .op = ass_id,
1924 .rhs = undefined,
1925 }
1926 );
1927 stack.append(State { .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1928 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
1929 continue;
1930 } else {
1931 self.putBackToken(token);
1932 continue;
1933 }
1934 },
1935
1936 State.UnwrapExpressionBegin => |opt_ctx| {
1937 stack.append(State { .UnwrapExpressionEnd = opt_ctx }) catch unreachable;
1938 try stack.append(State { .BoolOrExpressionBegin = opt_ctx });
1939 continue;
1940 },
1941
1942 State.UnwrapExpressionEnd => |opt_ctx| {
1943 const lhs = opt_ctx.get() ?? continue;
1944
1945 const token = self.getNextToken();
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 );
1956
1957 stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1958 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
1959
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;
1967 }
1968 },
1969
1970 State.BoolOrExpressionBegin => |opt_ctx| {
1971 stack.append(State { .BoolOrExpressionEnd = opt_ctx }) catch unreachable;
1972 try stack.append(State { .BoolAndExpressionBegin = opt_ctx });
1973 continue;
1974 },
1975
1976 State.BoolOrExpressionEnd => |opt_ctx| {
1977 const lhs = opt_ctx.get() ?? continue;
1978
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;
1992 }
1993 },
1994
1995 State.BoolAndExpressionBegin => |opt_ctx| {
1996 stack.append(State { .BoolAndExpressionEnd = opt_ctx }) catch unreachable;
1997 try stack.append(State { .ComparisonExpressionBegin = opt_ctx });
1998 continue;
1999 },
2000
2001 State.BoolAndExpressionEnd => |opt_ctx| {
2002 const lhs = opt_ctx.get() ?? continue;
2003
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;
2017 }
2018 },
2019
2020 State.ComparisonExpressionBegin => |opt_ctx| {
2021 stack.append(State { .ComparisonExpressionEnd = opt_ctx }) catch unreachable;
2022 try stack.append(State { .BinaryOrExpressionBegin = opt_ctx });
2023 continue;
2024 },
2025
2026 State.ComparisonExpressionEnd => |opt_ctx| {
2027 const lhs = opt_ctx.get() ?? continue;
2028
2029 const token = self.getNextToken();
2030 if (tokenIdToComparison(token.id)) |comp_id| {
2031 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2032 ast.NodeInfixOp {
2033 .base = undefined,
2034 .lhs = lhs,
2035 .op_token = token,
2036 .op = comp_id,
2037 .rhs = undefined,
2038 }
2039 );
2040 stack.append(State { .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2041 try stack.append(State { .BinaryOrExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2042 continue;
2043 } else {
2044 self.putBackToken(token);
2045 continue;
2046 }
2047 },
2048
2049 State.BinaryOrExpressionBegin => |opt_ctx| {
2050 stack.append(State { .BinaryOrExpressionEnd = opt_ctx }) catch unreachable;
2051 try stack.append(State { .BinaryXorExpressionBegin = opt_ctx });
2052 continue;
2053 },
2054
2055 State.BinaryOrExpressionEnd => |opt_ctx| {
2056 const lhs = opt_ctx.get() ?? continue;
2057
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;
2071 }
2072 },
2073
2074 State.BinaryXorExpressionBegin => |opt_ctx| {
2075 stack.append(State { .BinaryXorExpressionEnd = opt_ctx }) catch unreachable;
2076 try stack.append(State { .BinaryAndExpressionBegin = opt_ctx });
2077 continue;
2078 },
2079
2080 State.BinaryXorExpressionEnd => |opt_ctx| {
2081 const lhs = opt_ctx.get() ?? continue;
2082
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;
2096 }
2097 },
2098
2099 State.BinaryAndExpressionBegin => |opt_ctx| {
2100 stack.append(State { .BinaryAndExpressionEnd = opt_ctx }) catch unreachable;
2101 try stack.append(State { .BitShiftExpressionBegin = opt_ctx });
2102 continue;
2103 },
2104
2105 State.BinaryAndExpressionEnd => |opt_ctx| {
2106 const lhs = opt_ctx.get() ?? continue;
2107
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;
2121 }
2122 },
2123
2124 State.BitShiftExpressionBegin => |opt_ctx| {
2125 stack.append(State { .BitShiftExpressionEnd = opt_ctx }) catch unreachable;
2126 try stack.append(State { .AdditionExpressionBegin = opt_ctx });
2127 continue;
2128 },
2129
2130 State.BitShiftExpressionEnd => |opt_ctx| {
2131 const lhs = opt_ctx.get() ?? continue;
2132
2133 const token = self.getNextToken();
2134 if (tokenIdToBitShift(token.id)) |bitshift_id| {
2135 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2136 ast.NodeInfixOp {
2137 .base = undefined,
2138 .lhs = lhs,
2139 .op_token = token,
2140 .op = bitshift_id,
2141 .rhs = undefined,
2142 }
2143 );
2144 stack.append(State { .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2145 try stack.append(State { .AdditionExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2146 continue;
2147 } else {
2148 self.putBackToken(token);
2149 continue;
2150 }
2151 },
2152
2153 State.AdditionExpressionBegin => |opt_ctx| {
2154 stack.append(State { .AdditionExpressionEnd = opt_ctx }) catch unreachable;
2155 try stack.append(State { .MultiplyExpressionBegin = opt_ctx });
2156 continue;
2157 },
2158
2159 State.AdditionExpressionEnd => |opt_ctx| {
2160 const lhs = opt_ctx.get() ?? continue;
2161
2162 const token = self.getNextToken();
2163 if (tokenIdToAddition(token.id)) |add_id| {
2164 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2165 ast.NodeInfixOp {
2166 .base = undefined,
2167 .lhs = lhs,
2168 .op_token = token,
2169 .op = add_id,
2170 .rhs = undefined,
2171 }
2172 );
2173 stack.append(State { .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2174 try stack.append(State { .MultiplyExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2175 continue;
2176 } else {
2177 self.putBackToken(token);
2178 continue;
2179 }
2180 },
2181
2182 State.MultiplyExpressionBegin => |opt_ctx| {
2183 stack.append(State { .MultiplyExpressionEnd = opt_ctx }) catch unreachable;
2184 try stack.append(State { .CurlySuffixExpressionBegin = opt_ctx });
2185 continue;
2186 },
2187
2188 State.MultiplyExpressionEnd => |opt_ctx| {
2189 const lhs = opt_ctx.get() ?? continue;
2190
2191 const token = self.getNextToken();
2192 if (tokenIdToMultiply(token.id)) |mult_id| {
2193 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2194 ast.NodeInfixOp {
2195 .base = undefined,
2196 .lhs = lhs,
2197 .op_token = token,
2198 .op = mult_id,
2199 .rhs = undefined,
2200 }
2201 );
2202 stack.append(State { .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2203 try stack.append(State { .CurlySuffixExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2204 continue;
2205 } else {
2206 self.putBackToken(token);
2207 continue;
2208 }
2209 },
2210
2211 State.CurlySuffixExpressionBegin => |opt_ctx| {
2212 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx }) catch unreachable;
2213 try stack.append(State { .IfToken = Token.Id.LBrace });
2214 try stack.append(State { .TypeExprBegin = opt_ctx });
2215 continue;
2216 },
2217
2218 State.CurlySuffixExpressionEnd => |opt_ctx| {
2219 const lhs = opt_ctx.get() ?? continue;
2220
2221 if (self.isPeekToken(Token.Id.Period)) {
2222 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
2223 ast.NodeSuffixOp {
2224 .base = undefined,
2225 .lhs = lhs,
2226 .op = ast.NodeSuffixOp.SuffixOp {
2227 .StructInitializer = ArrayList(&ast.NodeFieldInitializer).init(arena),
2228 },
2229 .rtoken = undefined,
2230 }
2231 );
2232 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2233 try stack.append(State { .IfToken = Token.Id.LBrace });
2234 try stack.append(State {
2235 .FieldInitListItemOrEnd = ListSave(&ast.NodeFieldInitializer) {
2236 .list = &node.op.StructInitializer,
2237 .ptr = &node.rtoken,
2238 }
2239 });
2240 continue;
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;
2263 },
2264
2265 State.TypeExprBegin => |opt_ctx| {
2266 stack.append(State { .TypeExprEnd = opt_ctx }) catch unreachable;
2267 try stack.append(State { .PrefixOpExpression = opt_ctx });
2268 continue;
2269 },
2270
2271 State.TypeExprEnd => |opt_ctx| {
2272 const lhs = opt_ctx.get() ?? continue;
2273
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;
2287 }
2288 },
2289
2290 State.PrefixOpExpression => |opt_ctx| {
2291 const token = self.getNextToken();
2292 if (tokenIdToPrefixOp(token.id)) |prefix_id| {
2293 var node = try self.createToCtxNode(arena, opt_ctx, ast.NodePrefixOp,
2294 ast.NodePrefixOp {
2295 .base = undefined,
2296 .op_token = token,
2297 .op = prefix_id,
2298 .rhs = undefined,
2299 }
2300 );
2301
2302 // Treat '**' token as two derefs
2303 if (token.id == Token.Id.AsteriskAsterisk) {
2304 const child = try self.createNode(arena, ast.NodePrefixOp,
2305 ast.NodePrefixOp {
2306 .base = undefined,
2307 .op_token = token,
2308 .op = prefix_id,
2309 .rhs = undefined,
2310 }
2311 );
2312 node.rhs = &child.base;
2313 node = child;
2314 }
2315
2316 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
2317 if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {
2318 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
2319 }
2320 continue;
2321 } else {
2322 self.putBackToken(token);
2323 stack.append(State { .SuffixOpExpressionBegin = opt_ctx }) catch unreachable;
2324 continue;
2325 }
2326 },
2327
2328 State.SuffixOpExpressionBegin => |opt_ctx| {
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;
2348 }
2349
2350 stack.append(State { .SuffixOpExpressionEnd = opt_ctx }) catch unreachable;
2351 try stack.append(State { .PrimaryExpression = opt_ctx });
2352 continue;
2353 },
2354
2355 State.SuffixOpExpressionEnd => |opt_ctx| {
2356 const lhs = opt_ctx.get() ?? continue;
2357
2358 const token = self.getNextToken();
2359 switch (token.id) {
2360 Token.Id.LParen => {
2361 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
2362 ast.NodeSuffixOp {
2363 .base = undefined,
2364 .lhs = lhs,
2365 .op = ast.NodeSuffixOp.SuffixOp {
2366 .Call = ast.NodeSuffixOp.CallInfo {
2367 .params = ArrayList(&ast.Node).init(arena),
2368 .async_attr = null,
2369 }
2370 },
2371 .rtoken = undefined,
2372 }
2373 );
2374 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2375 try stack.append(State {
2376 .ExprListItemOrEnd = ExprListCtx {
2377 .list = &node.op.Call.params,
2378 .end = Token.Id.RParen,
2379 .ptr = &node.rtoken,
2380 }
2381 });
2382 continue;
2383 },
2384 Token.Id.LBracket => {
2385 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
2386 ast.NodeSuffixOp {
2387 .base = undefined,
2388 .lhs = lhs,
2389 .op = ast.NodeSuffixOp.SuffixOp {
2390 .ArrayAccess = undefined,
2391 },
2392 .rtoken = undefined
2393 }
2394 );
2395 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2396 try stack.append(State { .SliceOrArrayAccess = node });
2397 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayAccess }});
2398 continue;
2399 },
2400 Token.Id.Period => {
2401 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2402 ast.NodeInfixOp {
2403 .base = undefined,
2404 .lhs = lhs,
2405 .op_token = token,
2406 .op = ast.NodeInfixOp.InfixOp.Period,
2407 .rhs = undefined,
2408 }
2409 );
2410 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2411 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.rhs } });
2412 continue;
2413 },
2414 else => {
2415 self.putBackToken(token);
2416 continue;
2417 },
2418 }
2419 },
2420
2421 State.PrimaryExpression => |opt_ctx| {
2422 const token = self.getNextToken();
2423 switch (token.id) {
2424 Token.Id.IntegerLiteral => {
2425 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeStringLiteral, token);
2426 continue;
2427 },
2428 Token.Id.FloatLiteral => {
2429 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeFloatLiteral, token);
2430 continue;
2431 },
2432 Token.Id.CharLiteral => {
2433 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeCharLiteral, token);
2434 continue;
2435 },
2436 Token.Id.Keyword_undefined => {
2437 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeUndefinedLiteral, token);
2438 continue;
2439 },
2440 Token.Id.Keyword_true, Token.Id.Keyword_false => {
2441 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeBoolLiteral, token);
2442 continue;
2443 },
2444 Token.Id.Keyword_null => {
2445 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeNullLiteral, token);
2446 continue;
2447 },
2448 Token.Id.Keyword_this => {
2449 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeThisLiteral, token);
2450 continue;
2451 },
2452 Token.Id.Keyword_var => {
2453 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeVarType, token);
2454 continue;
2455 },
2456 Token.Id.Keyword_unreachable => {
2457 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeUnreachable, token);
2458 continue;
2459 },
2460 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
2461 opt_ctx.store((try self.parseStringLiteral(arena, token)) ?? unreachable);
2462 continue;
2463 },
2464 Token.Id.LParen => {
2465 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeGroupedExpression,
2466 ast.NodeGroupedExpression {
2467 .base = undefined,
2468 .lparen = token,
2469 .expr = undefined,
2470 .rparen = undefined,
2471 }
2472 );
2473 stack.append(State {
2474 .ExpectTokenSave = ExpectTokenSave {
2475 .id = Token.Id.RParen,
2476 .ptr = &node.rparen,
2477 }
2478 }) catch unreachable;
2479 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
2480 continue;
2481 },
2482 Token.Id.Builtin => {
2483 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeBuiltinCall,
2484 ast.NodeBuiltinCall {
2485 .base = undefined,
2486 .builtin_token = token,
2487 .params = ArrayList(&ast.Node).init(arena),
2488 .rparen_token = undefined,
2489 }
2490 );
2491 stack.append(State {
2492 .ExprListItemOrEnd = ExprListCtx {
2493 .list = &node.params,
2494 .end = Token.Id.RParen,
2495 .ptr = &node.rparen_token,
2496 }
2497 }) catch unreachable;
2498 try stack.append(State { .ExpectToken = Token.Id.LParen, });
2499 continue;
2500 },
2501 Token.Id.LBracket => {
2502 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePrefixOp,
2503 ast.NodePrefixOp {
2504 .base = undefined,
2505 .op_token = token,
2506 .op = undefined,
2507 .rhs = undefined,
2508 }
2509 );
2510 stack.append(State { .SliceOrArrayType = node }) catch unreachable;
2511 continue;
2512 },
2513 Token.Id.Keyword_error => {
2514 stack.append(State {
2515 .ErrorTypeOrSetDecl = ErrorTypeOrSetDeclCtx {
2516 .error_token = token,
2517 .opt_ctx = opt_ctx
2518 }
2519 }) catch unreachable;
2520 continue;
2521 },
2522 Token.Id.Keyword_packed => {
2523 stack.append(State {
2524 .ContainerKind = ContainerKindCtx {
2525 .opt_ctx = opt_ctx,
2526 .ltoken = token,
2527 .layout = ast.NodeContainerDecl.Layout.Packed,
2528 },
2529 }) catch unreachable;
2530 continue;
2531 },
2532 Token.Id.Keyword_extern => {
2533 stack.append(State {
2534 .ExternType = ExternTypeCtx {
2535 .opt_ctx = opt_ctx,
2536 .extern_token = token,
2537 },
2538 }) catch unreachable;
2539 continue;
2540 },
2541 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
2542 self.putBackToken(token);
2543 stack.append(State {
2544 .ContainerKind = ContainerKindCtx {
2545 .opt_ctx = opt_ctx,
2546 .ltoken = token,
2547 .layout = ast.NodeContainerDecl.Layout.Auto,
2548 },
2549 }) catch unreachable;
2550 continue;
2551 },
2552 Token.Id.Identifier => {
2553 stack.append(State {
2554 .MaybeLabeledExpression = MaybeLabeledExpressionCtx {
2555 .label = token,
2556 .opt_ctx = opt_ctx
2557 }
2558 }) catch unreachable;
2559 continue;
2560 },
2561 Token.Id.Keyword_fn => {
2562 const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.NodeFnProto,
2563 ast.NodeFnProto {
2564 .base = undefined,
2565 .visib_token = null,
2566 .name_token = null,
2567 .fn_token = token,
2568 .params = ArrayList(&ast.Node).init(arena),
2569 .return_type = undefined,
2570 .var_args_token = null,
2571 .extern_export_inline_token = null,
2572 .cc_token = null,
2573 .async_attr = null,
2574 .body_node = null,
2575 .lib_name = null,
2576 .align_expr = null,
2577 }
2578 );
2579 stack.append(State { .FnProto = fn_proto }) catch unreachable;
2580 continue;
2581 },
2582 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
2583 const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.NodeFnProto,
2584 ast.NodeFnProto {
2585 .base = undefined,
2586 .visib_token = null,
2587 .name_token = null,
2588 .fn_token = undefined,
2589 .params = ArrayList(&ast.Node).init(arena),
2590 .return_type = undefined,
2591 .var_args_token = null,
2592 .extern_export_inline_token = null,
2593 .cc_token = token,
2594 .async_attr = null,
2595 .body_node = null,
2596 .lib_name = null,
2597 .align_expr = null,
2598 }
2599 );
2600 stack.append(State { .FnProto = fn_proto }) catch unreachable;
2601 try stack.append(State {
2602 .ExpectTokenSave = ExpectTokenSave {
2603 .id = Token.Id.Keyword_fn,
2604 .ptr = &fn_proto.fn_token
2605 }
2606 });
24502607 continue;
24512608 },
2452 }
2453 },
2454
2455 State.LabeledExpression => |ctx| {
2456 const token = self.getNextToken();
2457 switch (token.id) {
2458 Token.Id.LBrace => {
2459 const block = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeBlock,
2460 ast.NodeBlock {
2609 Token.Id.Keyword_asm => {
2610 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeAsm,
2611 ast.NodeAsm {
24612612 .base = undefined,
2462 .label = ctx.label,
2463 .lbrace = token,
2464 .statements = ArrayList(&ast.Node).init(arena),
2465 .rbrace = undefined,
2613 .asm_token = token,
2614 .volatile_token = null,
2615 .template = undefined,
2616 //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),
2617 .outputs = ArrayList(&ast.NodeAsmOutput).init(arena),
2618 .inputs = ArrayList(&ast.NodeAsmInput).init(arena),
2619 .cloppers = ArrayList(&ast.Node).init(arena),
2620 .rparen = undefined,
24662621 }
24672622 );
2468 stack.append(State { .Block = block }) catch unreachable;
2469 continue;
2470 },
2471 Token.Id.Keyword_while => {
24722623 stack.append(State {
2473 .While = LoopCtx {
2474 .label = ctx.label,
2475 .inline_token = null,
2476 .loop_token = token,
2477 .dest_ptr = ctx.dest_ptr,
2624 .ExpectTokenSave = ExpectTokenSave {
2625 .id = Token.Id.RParen,
2626 .ptr = &node.rparen,
24782627 }
24792628 }) catch unreachable;
2480 continue;
2481 },
2482 Token.Id.Keyword_for => {
2483 stack.append(State {
2484 .For = LoopCtx {
2485 .label = ctx.label,
2486 .inline_token = null,
2487 .loop_token = token,
2488 .dest_ptr = ctx.dest_ptr,
2629 try stack.append(State { .AsmClopperItems = &node.cloppers });
2630 try stack.append(State { .IfToken = Token.Id.Colon });
2631 try stack.append(State { .AsmInputItems = &node.inputs });
2632 try stack.append(State { .IfToken = Token.Id.Colon });
2633 try stack.append(State { .AsmOutputItems = &node.outputs });
2634 try stack.append(State { .IfToken = Token.Id.Colon });
2635 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.template } });
2636 try stack.append(State { .ExpectToken = Token.Id.LParen });
2637 try stack.append(State {
2638 .OptionalTokenSave = OptionalTokenSave {
2639 .id = Token.Id.Keyword_volatile,
2640 .ptr = &node.volatile_token,
24892641 }
2490 }) catch unreachable;
2491 continue;
2642 });
24922643 },
24932644 Token.Id.Keyword_inline => {
24942645 stack.append(State {
24952646 .Inline = InlineCtx {
2496 .label = ctx.label,
2647 .label = null,
24972648 .inline_token = token,
2498 .dest_ptr = ctx.dest_ptr,
2649 .opt_ctx = opt_ctx,
24992650 }
25002651 }) catch unreachable;
25012652 continue;
25022653 },
25032654 else => {
2504 try self.parseError(&stack, token, "expected 'while', 'for', 'inline' or '{{', found {}", @tagName(token.id));
2655 if (!try self.parseBlockExpr(&stack, arena, opt_ctx, token)) {
2656 self.putBackToken(token);
2657 if (opt_ctx != OptionalCtx.Optional) {
2658 return self.parseError(token, "expected primary expression, found {}", @tagName(token.id));
2659 }
2660 }
25052661 continue;
2506 },
2662 }
25072663 }
25082664 },
25092665
2510 State.Inline => |ctx| {
2511 const token = self.getNextToken();
2512 switch (token.id) {
2513 Token.Id.Keyword_while => {
2514 stack.append(State {
2515 .While = LoopCtx {
2516 .inline_token = ctx.inline_token,
2517 .label = ctx.label,
2518 .loop_token = token,
2519 .dest_ptr = ctx.dest_ptr,
2520 }
2521 }) catch unreachable;
2522 continue;
2523 },
2524 Token.Id.Keyword_for => {
2525 stack.append(State {
2526 .For = LoopCtx {
2527 .inline_token = ctx.inline_token,
2528 .label = ctx.label,
2529 .loop_token = token,
2530 .dest_ptr = ctx.dest_ptr,
2531 }
2532 }) catch unreachable;
2533 continue;
2534 },
2535 else => {
2536 try self.parseError(&stack, token, "expected 'while' or 'for', found {}", @tagName(token.id));
2537 continue;
2538 },
2666
2667 State.ErrorTypeOrSetDecl => |ctx| {
2668 if (self.eatToken(Token.Id.LBrace) == null) {
2669 _ = try self.createToCtxLiteral(arena, ctx.opt_ctx, ast.NodeErrorType, ctx.error_token);
2670 continue;
25392671 }
2540 },
25412672
2542 State.While => |ctx| {
2543 const node = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeWhile,
2544 ast.NodeWhile {
2673 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeErrorSetDecl,
2674 ast.NodeErrorSetDecl {
25452675 .base = undefined,
2546 .label = ctx.label,
2547 .inline_token = ctx.inline_token,
2548 .while_token = ctx.loop_token,
2549 .condition = undefined,
2550 .payload = null,
2551 .continue_expr = null,
2552 .body = undefined,
2553 .@"else" = null,
2676 .error_token = ctx.error_token,
2677 .decls = ArrayList(&ast.Node).init(arena),
2678 .rbrace_token = undefined,
25542679 }
25552680 );
2556 stack.append(State { .Else = &node.@"else" }) catch unreachable;
2557 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
2558 try stack.append(State { .WhileContinueExpr = &node.continue_expr });
2559 try stack.append(State { .PointerPayload = &node.payload });
2560 try stack.append(State { .ExpectToken = Token.Id.RParen });
2561 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
2562 try stack.append(State { .ExpectToken = Token.Id.LParen });
2563 },
25642681
2565 State.For => |ctx| {
2566 const node = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeFor,
2567 ast.NodeFor {
2568 .base = undefined,
2569 .label = ctx.label,
2570 .inline_token = ctx.inline_token,
2571 .for_token = ctx.loop_token,
2572 .array_expr = undefined,
2573 .payload = null,
2574 .body = undefined,
2575 .@"else" = null,
2682 stack.append(State {
2683 .IdentifierListItemOrEnd = ListSave(&ast.Node) {
2684 .list = &node.decls,
2685 .ptr = &node.rbrace_token,
25762686 }
2577 );
2578 stack.append(State { .Else = &node.@"else" }) catch unreachable;
2579 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
2580 try stack.append(State { .PointerIndexPayload = &node.payload });
2581 try stack.append(State { .ExpectToken = Token.Id.RParen });
2582 try stack.append(State { .Expression = DestPtr { .Field = &node.array_expr } });
2583 try stack.append(State { .ExpectToken = Token.Id.LParen });
2687 }) catch unreachable;
2688 continue;
25842689 },
2585
2586 State.Block => |block| {
2690 State.StringLiteral => |opt_ctx| {
25872691 const token = self.getNextToken();
2588 switch (token.id) {
2589 Token.Id.RBrace => {
2590 block.rbrace = token;
2591 continue;
2592 },
2593 else => {
2692 opt_ctx.store(
2693 (try self.parseStringLiteral(arena, token)) ?? {
25942694 self.putBackToken(token);
2595 stack.append(State { .Block = block }) catch unreachable;
2596 try stack.append(State { .Statement = block });
2695 if (opt_ctx != OptionalCtx.Optional) {
2696 return self.parseError(token, "expected primary expression, found {}", @tagName(token.id));
2697 }
2698
25972699 continue;
2598 },
2700 }
2701 );
2702 },
2703 State.Identifier => |opt_ctx| {
2704 if (self.eatToken(Token.Id.Identifier)) |ident_token| {
2705 _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeIdentifier, ident_token);
2706 continue;
2707 }
2708
2709 if (opt_ctx != OptionalCtx.Optional) {
2710 const token = self.getNextToken();
2711 return self.parseError(token, "expected identifier, found {}", @tagName(token.id));
25992712 }
26002713 },
26012714
2602 State.Statement => |block| {
2603 const next = self.getNextToken();
2604 switch (next.id) {
2605 Token.Id.Keyword_comptime => {
2606 const mut_token = self.getNextToken();
2607 if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
2608 const var_decl = try self.createAttachNode(arena, &block.statements, ast.NodeVarDecl,
2609 ast.NodeVarDecl {
2610 .base = undefined,
2611 .visib_token = null,
2612 .mut_token = mut_token,
2613 .comptime_token = next,
2614 .extern_export_token = null,
2615 .type_node = null,
2616 .align_node = null,
2617 .init_node = null,
2618 .lib_name = null,
2619 // initialized later
2620 .name_token = undefined,
2621 .eq_token = undefined,
2622 .semicolon_token = undefined,
2623 }
2624 );
2625 stack.append(State { .VarDecl = var_decl }) catch unreachable;
2626 continue;
2627 } else {
2628 self.putBackToken(mut_token);
2629 self.putBackToken(next);
2630 const statememt = try block.statements.addOne();
2631 stack.append(State { .Semicolon = statememt }) catch unreachable;
2632 try stack.append(State { .Expression = DestPtr{.Field = statememt } });
2633 }
2634 },
2635 Token.Id.Keyword_var, Token.Id.Keyword_const => {
2636 const var_decl = try self.createAttachNode(arena, &block.statements, ast.NodeVarDecl,
2637 ast.NodeVarDecl {
2638 .base = undefined,
2639 .visib_token = null,
2640 .mut_token = next,
2641 .comptime_token = null,
2642 .extern_export_token = null,
2643 .type_node = null,
2644 .align_node = null,
2645 .init_node = null,
2646 .lib_name = null,
2647 // initialized later
2648 .name_token = undefined,
2649 .eq_token = undefined,
2650 .semicolon_token = undefined,
2651 }
2652 );
2653 stack.append(State { .VarDecl = var_decl }) catch unreachable;
2654 continue;
2655 },
2656 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
2657 const node = try self.createAttachNode(arena, &block.statements, ast.NodeDefer,
2658 ast.NodeDefer {
2659 .base = undefined,
2660 .defer_token = next,
2661 .kind = switch (next.id) {
2662 Token.Id.Keyword_defer => ast.NodeDefer.Kind.Unconditional,
2663 Token.Id.Keyword_errdefer => ast.NodeDefer.Kind.Error,
2664 else => unreachable,
2665 },
2666 .expr = undefined,
2667 }
2668 );
2669 stack.append(State { .Semicolon = &node.base }) catch unreachable;
2670 try stack.append(State { .AssignmentExpressionBegin = DestPtr{.Field = &node.expr } });
2671 continue;
2672 },
2673 Token.Id.LBrace => {
2674 const inner_block = try self.createAttachNode(arena, &block.statements, ast.NodeBlock,
2675 ast.NodeBlock {
2676 .base = undefined,
2677 .label = null,
2678 .lbrace = next,
2679 .statements = ArrayList(&ast.Node).init(arena),
2680 .rbrace = undefined,
2681 }
2682 );
2683 stack.append(State { .Block = inner_block }) catch unreachable;
2684 continue;
2685 },
2686 else => {
2687 self.putBackToken(next);
2688 const statememt = try block.statements.addOne();
2689 stack.append(State { .Semicolon = statememt }) catch unreachable;
2690 try stack.append(State { .AssignmentExpressionBegin = DestPtr{.Field = statememt } });
2691 continue;
2692 }
2715
2716 State.ExpectToken => |token_id| {
2717 _ = try self.expectToken(token_id);
2718 continue;
2719 },
2720 State.ExpectTokenSave => |expect_token_save| {
2721 *expect_token_save.ptr = try self.expectToken(expect_token_save.id);
2722 continue;
2723 },
2724 State.IfToken => |token_id| {
2725 if (self.eatToken(token_id)) |_| {
2726 continue;
26932727 }
26942728
2729 _ = stack.pop();
2730 continue;
26952731 },
2732 State.IfTokenSave => |if_token_save| {
2733 if (self.eatToken(if_token_save.id)) |token| {
2734 *if_token_save.ptr = token;
2735 continue;
2736 }
26962737
2697 State.Semicolon => |node_ptr| {
2698 const node = *node_ptr;
2699 if (requireSemiColon(node)) {
2700 _ = (try self.expectToken(&stack, Token.Id.Semicolon)) ?? continue;
2738 _ = stack.pop();
2739 continue;
2740 },
2741 State.OptionalTokenSave => |optional_token_save| {
2742 if (self.eatToken(optional_token_save.id)) |token| {
2743 *optional_token_save.ptr = token;
2744 continue;
27012745 }
2702 }
2746
2747 continue;
2748 },
27032749 }
27042750 }
27052751 }
......@@ -2807,10 +2853,10 @@ pub const Parser = struct {
28072853 }
28082854 }
28092855
2810 fn parseBlockExpr(self: &Parser, stack: &ArrayList(State), arena: &mem.Allocator, dest_ptr: &const DestPtr, token: &const Token) !bool {
2856 fn parseBlockExpr(self: &Parser, stack: &ArrayList(State), arena: &mem.Allocator, ctx: &const OptionalCtx, token: &const Token) !bool {
28112857 switch (token.id) {
28122858 Token.Id.Keyword_suspend => {
2813 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuspend,
2859 const node = try self.createToCtxNode(arena, ctx, ast.NodeSuspend,
28142860 ast.NodeSuspend {
28152861 .base = undefined,
28162862 .suspend_token = *token,
......@@ -2820,11 +2866,11 @@ pub const Parser = struct {
28202866 );
28212867
28222868 stack.append(State { .SuspendBody = node }) catch unreachable;
2823 try stack.append(State { .Payload = &node.payload });
2869 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });
28242870 return true;
28252871 },
28262872 Token.Id.Keyword_if => {
2827 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeIf,
2873 const node = try self.createToCtxNode(arena, ctx, ast.NodeIf,
28282874 ast.NodeIf {
28292875 .base = undefined,
28302876 .if_token = *token,
......@@ -2836,10 +2882,10 @@ pub const Parser = struct {
28362882 );
28372883
28382884 stack.append(State { .Else = &node.@"else" }) catch unreachable;
2839 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
2840 try stack.append(State { .PointerPayload = &node.payload });
2885 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
2886 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
28412887 try stack.append(State { .ExpectToken = Token.Id.RParen });
2842 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
2888 try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } });
28432889 try stack.append(State { .ExpectToken = Token.Id.LParen });
28442890 return true;
28452891 },
......@@ -2849,7 +2895,7 @@ pub const Parser = struct {
28492895 .label = null,
28502896 .inline_token = null,
28512897 .loop_token = *token,
2852 .dest_ptr = *dest_ptr,
2898 .opt_ctx = *ctx,
28532899 }
28542900 }) catch unreachable;
28552901 return true;
......@@ -2860,13 +2906,13 @@ pub const Parser = struct {
28602906 .label = null,
28612907 .inline_token = null,
28622908 .loop_token = *token,
2863 .dest_ptr = *dest_ptr,
2909 .opt_ctx = *ctx,
28642910 }
28652911 }) catch unreachable;
28662912 return true;
28672913 },
28682914 Token.Id.Keyword_switch => {
2869 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSwitch,
2915 const node = try self.createToCtxNode(arena, ctx, ast.NodeSwitch,
28702916 ast.NodeSwitch {
28712917 .base = undefined,
28722918 .switch_token = *token,
......@@ -2884,23 +2930,23 @@ pub const Parser = struct {
28842930 }) catch unreachable;
28852931 try stack.append(State { .ExpectToken = Token.Id.LBrace });
28862932 try stack.append(State { .ExpectToken = Token.Id.RParen });
2887 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
2933 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
28882934 try stack.append(State { .ExpectToken = Token.Id.LParen });
28892935 return true;
28902936 },
28912937 Token.Id.Keyword_comptime => {
2892 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeComptime,
2938 const node = try self.createToCtxNode(arena, ctx, ast.NodeComptime,
28932939 ast.NodeComptime {
28942940 .base = undefined,
28952941 .comptime_token = *token,
28962942 .expr = undefined,
28972943 }
28982944 );
2899 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
2945 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
29002946 return true;
29012947 },
29022948 Token.Id.LBrace => {
2903 const block = try self.createToDestNode(arena, dest_ptr, ast.NodeBlock,
2949 const block = try self.createToCtxNode(arena, ctx, ast.NodeBlock,
29042950 ast.NodeBlock {
29052951 .base = undefined,
29062952 .label = null,
......@@ -2918,22 +2964,16 @@ pub const Parser = struct {
29182964 }
29192965 }
29202966
2921 fn commaOrEnd(self: &Parser, stack: &ArrayList(State), end: &const Token.Id, maybe_ptr: ?&Token, state_after_comma: &const State) !void {
2967 fn expectCommaOrEnd(self: &Parser, end: @TagType(Token.Id)) !?Token {
29222968 var token = self.getNextToken();
29232969 switch (token.id) {
2924 Token.Id.Comma => {
2925 stack.append(state_after_comma) catch unreachable;
2926 },
2970 Token.Id.Comma => return null,
29272971 else => {
2928 const IdTag = @TagType(Token.Id);
2929 if (IdTag(*end) == token.id) {
2930 if (maybe_ptr) |ptr| {
2931 *ptr = token;
2932 }
2933 return;
2972 if (end == token.id) {
2973 return token;
29342974 }
29352975
2936 try self.parseError(stack, token, "expected ',' or {}, found {}", @tagName(*end), @tagName(token.id));
2976 return self.parseError(token, "expected ',' or {}, found {}", @tagName(end), @tagName(token.id));
29372977 },
29382978 }
29392979 }
......@@ -2960,8 +3000,16 @@ pub const Parser = struct {
29603000 };
29613001 }
29623002
2963 fn tokenIdToComparison(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
2964 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) {
29653013 Token.Id.BangEqual => ast.NodeInfixOp.InfixOp { .BangEqual = void{} },
29663014 Token.Id.EqualEqual => ast.NodeInfixOp.InfixOp { .EqualEqual = void{} },
29673015 Token.Id.AngleBracketLeft => ast.NodeInfixOp.InfixOp { .LessThan = void{} },
......@@ -2972,16 +3020,16 @@ pub const Parser = struct {
29723020 };
29733021 }
29743022
2975 fn tokenIdToBitShift(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
2976 return switch (*id) {
3023 fn tokenIdToBitShift(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp {
3024 return switch (id) {
29773025 Token.Id.AngleBracketAngleBracketLeft => ast.NodeInfixOp.InfixOp { .BitShiftLeft = void{} },
29783026 Token.Id.AngleBracketAngleBracketRight => ast.NodeInfixOp.InfixOp { .BitShiftRight = void{} },
29793027 else => null,
29803028 };
29813029 }
29823030
2983 fn tokenIdToAddition(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
2984 return switch (*id) {
3031 fn tokenIdToAddition(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp {
3032 return switch (id) {
29853033 Token.Id.Minus => ast.NodeInfixOp.InfixOp { .Sub = void{} },
29863034 Token.Id.MinusPercent => ast.NodeInfixOp.InfixOp { .SubWrap = void{} },
29873035 Token.Id.Plus => ast.NodeInfixOp.InfixOp { .Add = void{} },
......@@ -2991,8 +3039,8 @@ pub const Parser = struct {
29913039 };
29923040 }
29933041
2994 fn tokenIdToMultiply(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
2995 return switch (*id) {
3042 fn tokenIdToMultiply(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp {
3043 return switch (id) {
29963044 Token.Id.Slash => ast.NodeInfixOp.InfixOp { .Div = void{} },
29973045 Token.Id.Asterisk => ast.NodeInfixOp.InfixOp { .Mult = void{} },
29983046 Token.Id.AsteriskAsterisk => ast.NodeInfixOp.InfixOp { .ArrayMult = void{} },
......@@ -3003,8 +3051,8 @@ pub const Parser = struct {
30033051 };
30043052 }
30053053
3006 fn tokenIdToPrefixOp(id: &const Token.Id) ?ast.NodePrefixOp.PrefixOp {
3007 return switch (*id) {
3054 fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.NodePrefixOp.PrefixOp {
3055 return switch (id) {
30083056 Token.Id.Bang => ast.NodePrefixOp.PrefixOp { .BoolNot = void{} },
30093057 Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} },
30103058 Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} },
......@@ -3049,9 +3097,9 @@ pub const Parser = struct {
30493097 return node;
30503098 }
30513099
3052 fn createToDestNode(self: &Parser, arena: &mem.Allocator, dest_ptr: &const DestPtr, comptime T: type, init_to: &const T) !&T {
3100 fn createToCtxNode(self: &Parser, arena: &mem.Allocator, opt_ctx: &const OptionalCtx, comptime T: type, init_to: &const T) !&T {
30533101 const node = try self.createNode(arena, T, init_to);
3054 dest_ptr.store(&node.base);
3102 opt_ctx.store(&node.base);
30553103
30563104 return node;
30573105 }
......@@ -3065,51 +3113,38 @@ pub const Parser = struct {
30653113 );
30663114 }
30673115
3068 fn parseError(self: &Parser, stack: &ArrayList(State), token: &const Token, comptime fmt: []const u8, args: ...) !void {
3069 // Before reporting an error. We pop the stack to see if our state was optional
3070 self.revertIfOptional(stack) catch {
3071 const loc = self.tokenizer.getTokenLocation(0, token);
3072 warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);
3073 warn("{}\n", self.tokenizer.buffer[loc.line_start..loc.line_end]);
3074 {
3075 var i: usize = 0;
3076 while (i < loc.column) : (i += 1) {
3077 warn(" ");
3078 }
3079 }
3080 {
3081 const caret_count = token.end - token.start;
3082 var i: usize = 0;
3083 while (i < caret_count) : (i += 1) {
3084 warn("~");
3085 }
3086 }
3087 warn("\n");
3088 return error.ParseError;
3089 };
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;
30903121 }
30913122
3092 fn revertIfOptional(self: &Parser, stack: &ArrayList(State)) !void {
3093 while (stack.popOrNull()) |state| {
3094 switch (state) {
3095 State.Optional => |revert| {
3096 *self = revert.parser;
3097 *self.tokenizer = revert.tokenizer;
3098 *revert.ptr = null;
3099 return;
3100 },
3101 else => { }
3123 fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) (error{ParseError}) {
3124 const loc = self.tokenizer.getTokenLocation(0, token);
3125 warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);
3126 warn("{}\n", self.tokenizer.buffer[loc.line_start..loc.line_end]);
3127 {
3128 var i: usize = 0;
3129 while (i < loc.column) : (i += 1) {
3130 warn(" ");
31023131 }
31033132 }
3104
3105 return error.NoOptionalStateFound;
3133 {
3134 const caret_count = token.end - token.start;
3135 var i: usize = 0;
3136 while (i < caret_count) : (i += 1) {
3137 warn("~");
3138 }
3139 }
3140 warn("\n");
3141 return error.ParseError;
31063142 }
31073143
3108 fn expectToken(self: &Parser, stack: &ArrayList(State), id: @TagType(Token.Id)) !?Token {
3144 fn expectToken(self: &Parser, id: @TagType(Token.Id)) !Token {
31093145 const token = self.getNextToken();
31103146 if (token.id != id) {
3111 try self.parseError(stack, token, "expected {}, found {}", @tagName(id), @tagName(token.id));
3112 return null;
3147 return self.parseError(token, "expected {}, found {}", @tagName(id), @tagName(token.id));
31133148 }
31143149 return token;
31153150 }
......@@ -3424,7 +3459,7 @@ pub const Parser = struct {
34243459 }
34253460
34263461 if (suspend_node.payload) |payload| {
3427 try stack.append(RenderState { .Expression = &payload.base });
3462 try stack.append(RenderState { .Expression = payload });
34283463 try stack.append(RenderState { .Text = " " });
34293464 }
34303465 },
......@@ -3435,7 +3470,7 @@ pub const Parser = struct {
34353470 if (prefix_op_node.op == ast.NodeInfixOp.InfixOp.Catch) {
34363471 if (prefix_op_node.op.Catch) |payload| {
34373472 try stack.append(RenderState { .Text = " " });
3438 try stack.append(RenderState { .Expression = &payload.base });
3473 try stack.append(RenderState { .Expression = payload });
34393474 }
34403475 try stack.append(RenderState { .Text = " catch " });
34413476 } else {
......@@ -3624,17 +3659,25 @@ pub const Parser = struct {
36243659 },
36253660 ast.Node.Id.ControlFlowExpression => {
36263661 const flow_expr = @fieldParentPtr(ast.NodeControlFlowExpression, "base", base);
3662
3663 if (flow_expr.rhs) |rhs| {
3664 try stack.append(RenderState { .Expression = rhs });
3665 try stack.append(RenderState { .Text = " " });
3666 }
3667
36273668 switch (flow_expr.kind) {
3628 ast.NodeControlFlowExpression.Kind.Break => |maybe_blk_token| {
3669 ast.NodeControlFlowExpression.Kind.Break => |maybe_label| {
36293670 try stream.print("break");
3630 if (maybe_blk_token) |blk_token| {
3631 try stream.print(" :{}", self.tokenizer.getTokenSlice(blk_token));
3671 if (maybe_label) |label| {
3672 try stream.print(" :");
3673 try stack.append(RenderState { .Expression = label });
36323674 }
36333675 },
3634 ast.NodeControlFlowExpression.Kind.Continue => |maybe_blk_token| {
3676 ast.NodeControlFlowExpression.Kind.Continue => |maybe_label| {
36353677 try stream.print("continue");
3636 if (maybe_blk_token) |blk_token| {
3637 try stream.print(" :{}", self.tokenizer.getTokenSlice(blk_token));
3678 if (maybe_label) |label| {
3679 try stream.print(" :");
3680 try stack.append(RenderState { .Expression = label });
36383681 }
36393682 },
36403683 ast.NodeControlFlowExpression.Kind.Return => {
......@@ -3642,25 +3685,20 @@ pub const Parser = struct {
36423685 },
36433686
36443687 }
3645
3646 if (flow_expr.rhs) |rhs| {
3647 try stream.print(" ");
3648 try stack.append(RenderState { .Expression = rhs });
3649 }
36503688 },
36513689 ast.Node.Id.Payload => {
36523690 const payload = @fieldParentPtr(ast.NodePayload, "base", base);
36533691 try stack.append(RenderState { .Text = "|"});
3654 try stack.append(RenderState { .Expression = &payload.error_symbol.base });
3692 try stack.append(RenderState { .Expression = payload.error_symbol });
36553693 try stack.append(RenderState { .Text = "|"});
36563694 },
36573695 ast.Node.Id.PointerPayload => {
36583696 const payload = @fieldParentPtr(ast.NodePointerPayload, "base", base);
36593697 try stack.append(RenderState { .Text = "|"});
3660 try stack.append(RenderState { .Expression = &payload.value_symbol.base });
3698 try stack.append(RenderState { .Expression = payload.value_symbol });
36613699
3662 if (payload.is_ptr) {
3663 try stack.append(RenderState { .Text = "*"});
3700 if (payload.ptr_token) |ptr_token| {
3701 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(ptr_token) });
36643702 }
36653703
36663704 try stack.append(RenderState { .Text = "|"});
......@@ -3670,14 +3708,14 @@ pub const Parser = struct {
36703708 try stack.append(RenderState { .Text = "|"});
36713709
36723710 if (payload.index_symbol) |index_symbol| {
3673 try stack.append(RenderState { .Expression = &index_symbol.base });
3711 try stack.append(RenderState { .Expression = index_symbol });
36743712 try stack.append(RenderState { .Text = ", "});
36753713 }
36763714
3677 try stack.append(RenderState { .Expression = &payload.value_symbol.base });
3715 try stack.append(RenderState { .Expression = payload.value_symbol });
36783716
3679 if (payload.is_ptr) {
3680 try stack.append(RenderState { .Text = "*"});
3717 if (payload.ptr_token) |ptr_token| {
3718 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(ptr_token) });
36813719 }
36823720
36833721 try stack.append(RenderState { .Text = "|"});
......@@ -3809,7 +3847,7 @@ pub const Parser = struct {
38093847 i -= 1;
38103848 const node = decls[i];
38113849 try stack.append(RenderState { .Text = "," });
3812 try stack.append(RenderState { .Expression = &node.base});
3850 try stack.append(RenderState { .Expression = node });
38133851 try stack.append(RenderState.PrintIndent);
38143852 try stack.append(RenderState {
38153853 .Text = blk: {
......@@ -3961,7 +3999,7 @@ pub const Parser = struct {
39613999 try stack.append(RenderState { .Expression = switch_case.expr });
39624000 if (switch_case.payload) |payload| {
39634001 try stack.append(RenderState { .Text = " " });
3964 try stack.append(RenderState { .Expression = &payload.base });
4002 try stack.append(RenderState { .Expression = payload });
39654003 }
39664004 try stack.append(RenderState { .Text = " => "});
39674005
......@@ -4003,7 +4041,7 @@ pub const Parser = struct {
40034041
40044042 if (else_node.payload) |payload| {
40054043 try stack.append(RenderState { .Text = " " });
4006 try stack.append(RenderState { .Expression = &payload.base });
4044 try stack.append(RenderState { .Expression = payload });
40074045 }
40084046 },
40094047 ast.Node.Id.While => {
......@@ -4048,7 +4086,7 @@ pub const Parser = struct {
40484086 }
40494087
40504088 if (while_node.payload) |payload| {
4051 try stack.append(RenderState { .Expression = &payload.base });
4089 try stack.append(RenderState { .Expression = payload });
40524090 try stack.append(RenderState { .Text = " " });
40534091 }
40544092
......@@ -4091,7 +4129,7 @@ pub const Parser = struct {
40914129 }
40924130
40934131 if (for_node.payload) |payload| {
4094 try stack.append(RenderState { .Expression = &payload.base });
4132 try stack.append(RenderState { .Expression = payload });
40954133 try stack.append(RenderState { .Text = " " });
40964134 }
40974135
......@@ -4124,7 +4162,7 @@ pub const Parser = struct {
41244162
41254163 if (@"else".payload) |payload| {
41264164 try stack.append(RenderState { .Text = " " });
4127 try stack.append(RenderState { .Expression = &payload.base });
4165 try stack.append(RenderState { .Expression = payload });
41284166 }
41294167
41304168 try stack.append(RenderState { .Text = " " });
......@@ -4138,7 +4176,7 @@ pub const Parser = struct {
41384176 try stack.append(RenderState { .Text = " " });
41394177
41404178 if (if_node.payload) |payload| {
4141 try stack.append(RenderState { .Expression = &payload.base });
4179 try stack.append(RenderState { .Expression = payload });
41424180 try stack.append(RenderState { .Text = " " });
41434181 }
41444182
......@@ -4150,8 +4188,8 @@ pub const Parser = struct {
41504188 const asm_node = @fieldParentPtr(ast.NodeAsm, "base", base);
41514189 try stream.print("{} ", self.tokenizer.getTokenSlice(asm_node.asm_token));
41524190
4153 if (asm_node.is_volatile) {
4154 try stream.write("volatile ");
4191 if (asm_node.volatile_token) |volatile_token| {
4192 try stream.print("{} ", self.tokenizer.getTokenSlice(volatile_token));
41554193 }
41564194
41574195 try stack.append(RenderState { .Indent = indent });
......@@ -4241,7 +4279,7 @@ pub const Parser = struct {
42414279 try stack.append(RenderState { .Text = " ("});
42424280 try stack.append(RenderState { .Expression = asm_input.constraint });
42434281 try stack.append(RenderState { .Text = "] "});
4244 try stack.append(RenderState { .Expression = &asm_input.symbolic_name.base});
4282 try stack.append(RenderState { .Expression = asm_input.symbolic_name });
42454283 try stack.append(RenderState { .Text = "["});
42464284 },
42474285 ast.Node.Id.AsmOutput => {
......@@ -4260,7 +4298,7 @@ pub const Parser = struct {
42604298 try stack.append(RenderState { .Text = " ("});
42614299 try stack.append(RenderState { .Expression = asm_output.constraint });
42624300 try stack.append(RenderState { .Text = "] "});
4263 try stack.append(RenderState { .Expression = &asm_output.symbolic_name.base});
4301 try stack.append(RenderState { .Expression = asm_output.symbolic_name });
42644302 try stack.append(RenderState { .Text = "["});
42654303 },
42664304