authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-12 16:08:23+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-12 16:08:23+02:00
log206c0b8bdb4838010d6a1e70135134dc3edc6723
tree3969f0899d9db4a103d11a156bb6de705af6db2e
parent0d8646d262ebc3db6631421db8fc79228b6622f8

std.zig.parser: Refactor, round 1:

* Removed the Optional state * We now have an OptionalCtx instead of DestPtr * OptionalCtx simulated return, instead of reverting states * OptionalCtx is a lot less hacky, but is still a small footgun * Trying to avoid consuming more than one token per state * This is required, because of comments * The C++ compiler allows comments between all tokens * We therefor have to consume comment tokens between each state * Reordered states so they are grouped in some logical fasion

2 files changed, 1935 insertions(+), 1868 deletions(-)

std/zig/ast.zig+47-31
......@@ -283,7 +283,7 @@ 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 {
......@@ -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,7 +756,7 @@ 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 {
......@@ -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 {
......@@ -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,
......@@ -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
......@@ -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
......@@ -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,
......@@ -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,7 +1406,7 @@ 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 {
......@@ -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+1888-1837
......@@ -59,36 +59,27 @@ pub const Parser = struct {
5959 lib_name: ?&ast.Node,
6060 };
6161
62 const TopLevelExternOrFieldCtx = struct {
63 visib_token: Token,
64 container_decl: &ast.NodeContainerDecl,
65 };
66
6267 const ContainerExternCtx = struct {
63 dest_ptr: DestPtr,
68 opt_ctx: OptionalCtx,
6469 ltoken: Token,
6570 layout: ast.NodeContainerDecl.Layout,
6671 };
6772
68 const DestPtr = union(enum) {
69 Field: &&ast.Node,
70 NullableField: &?&ast.Node,
71
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 }
78
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 }
85 };
86
8773 const ExpectTokenSave = struct {
8874 id: Token.Id,
8975 ptr: &Token,
9076 };
9177
78 const OptionalTokenSave = struct {
79 id: Token.Id,
80 ptr: &?Token,
81 };
82
9283 const RevertState = struct {
9384 parser: Parser,
9485 tokenizer: Tokenizer,
......@@ -104,11 +95,6 @@ pub const Parser = struct {
10495 ptr: &Token,
10596 };
10697
107 const ElseCtx = struct {
108 payload: ?DestPtr,
109 body: DestPtr,
110 };
111
11298 fn ListSave(comptime T: type) type {
11399 return struct {
114100 list: &ArrayList(T),
......@@ -118,118 +104,187 @@ pub const Parser = struct {
118104
119105 const LabelCtx = struct {
120106 label: ?Token,
121 dest_ptr: DestPtr,
107 opt_ctx: OptionalCtx,
122108 };
123109
124110 const InlineCtx = struct {
125111 label: ?Token,
126112 inline_token: ?Token,
127 dest_ptr: DestPtr,
113 opt_ctx: OptionalCtx,
128114 };
129115
130116 const LoopCtx = struct {
131117 label: ?Token,
132118 inline_token: ?Token,
133119 loop_token: Token,
134 dest_ptr: DestPtr,
120 opt_ctx: OptionalCtx,
135121 };
136122
137123 const AsyncEndCtx = struct {
138 dest_ptr: DestPtr,
124 ctx: OptionalCtx,
139125 attribute: &ast.NodeAsyncAttribute,
140126 };
141127
128 const ErrorTypeOrSetDeclCtx = struct {
129 opt_ctx: OptionalCtx,
130 error_token: Token,
131 };
132
133 const ParamDeclEndCtx = struct {
134 fn_proto: &ast.NodeFnProto,
135 param_decl: &ast.NodeParamDecl,
136 };
137
138 const ComptimeStatementCtx = struct {
139 comptime_token: Token,
140 block: &ast.NodeBlock,
141 };
142
143 const OptionalCtx = union(enum) {
144 Optional: &?&ast.Node,
145 RequiredNull: &?&ast.Node,
146 Required: &&ast.Node,
147
148 pub fn store(self: &const OptionalCtx, value: &ast.Node) void {
149 switch (*self) {
150 OptionalCtx.Optional => |ptr| *ptr = value,
151 OptionalCtx.RequiredNull => |ptr| *ptr = value,
152 OptionalCtx.Required => |ptr| *ptr = value,
153 }
154 }
155
156 pub fn get(self: &const OptionalCtx) ?&ast.Node {
157 switch (*self) {
158 OptionalCtx.Optional => |ptr| return *ptr,
159 OptionalCtx.RequiredNull => |ptr| return ??*ptr,
160 OptionalCtx.Required => |ptr| return *ptr,
161 }
162 }
163
164 pub fn toRequired(self: &const OptionalCtx) OptionalCtx {
165 switch (*self) {
166 OptionalCtx.Optional => |ptr| {
167 return OptionalCtx { .RequiredNull = ptr };
168 },
169 OptionalCtx.RequiredNull => |ptr| return *self,
170 OptionalCtx.Required => |ptr| return *self,
171 }
172 }
173 };
174
142175 const State = union(enum) {
143176 TopLevel,
144177 TopLevelExtern: TopLevelDeclCtx,
145178 TopLevelLibname: TopLevelDeclCtx,
146179 TopLevelDecl: TopLevelDeclCtx,
180 TopLevelExternOrField: TopLevelExternOrFieldCtx,
181
147182 ContainerExtern: ContainerExternCtx,
183 ContainerInitArgStart: &ast.NodeContainerDecl,
184 ContainerInitArg: &ast.NodeContainerDecl,
148185 ContainerDecl: &ast.NodeContainerDecl,
149 SliceOrArrayAccess: &ast.NodeSuffixOp,
150 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
186
151187 VarDecl: &ast.NodeVarDecl,
152188 VarDeclAlign: &ast.NodeVarDecl,
153189 VarDeclEq: &ast.NodeVarDecl,
154 IfToken: @TagType(Token.Id),
155 IfTokenSave: ExpectTokenSave,
156 ExpectToken: @TagType(Token.Id),
157 ExpectTokenSave: ExpectTokenSave,
190
191 FnDef: &ast.NodeFnProto,
158192 FnProto: &ast.NodeFnProto,
159193 FnProtoAlign: &ast.NodeFnProto,
160194 FnProtoReturnType: &ast.NodeFnProto,
195
161196 ParamDecl: &ast.NodeFnProto,
162 ParamDeclComma,
163 FnDef: &ast.NodeFnProto,
197 ParamDeclAliasOrComptime: &ast.NodeParamDecl,
198 ParamDeclName: &ast.NodeParamDecl,
199 ParamDeclEnd: ParamDeclEndCtx,
200 ParamDeclComma: &ast.NodeFnProto,
201
164202 LabeledExpression: LabelCtx,
165203 Inline: InlineCtx,
166204 While: LoopCtx,
205 WhileContinueExpr: &?&ast.Node,
167206 For: LoopCtx,
168 Block: &ast.NodeBlock,
169207 Else: &?&ast.NodeElse,
170 WhileContinueExpr: &?&ast.Node,
208
209 Block: &ast.NodeBlock,
171210 Statement: &ast.NodeBlock,
211 ComptimeStatement: ComptimeStatementCtx,
172212 Semicolon: &const &const ast.Node,
213
173214 AsmOutputItems: &ArrayList(&ast.NodeAsmOutput),
215 AsmOutputReturnOrType: &ast.NodeAsmOutput,
174216 AsmInputItems: &ArrayList(&ast.NodeAsmInput),
175217 AsmClopperItems: &ArrayList(&ast.Node),
218
176219 ExprListItemOrEnd: ExprListCtx,
177220 ExprListCommaOrEnd: ExprListCtx,
178221 FieldInitListItemOrEnd: ListSave(&ast.NodeFieldInitializer),
179222 FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),
180223 FieldListCommaOrEnd: &ast.NodeContainerDecl,
181 IdentifierListItemOrEnd: ListSave(&ast.NodeIdentifier),
182 IdentifierListCommaOrEnd: ListSave(&ast.NodeIdentifier),
224 IdentifierListItemOrEnd: ListSave(&ast.Node),
225 IdentifierListCommaOrEnd: ListSave(&ast.Node),
183226 SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),
184 SuspendBody: &ast.NodeSuspend,
185 AsyncEnd: AsyncEndCtx,
186 Payload: &?&ast.NodePayload,
187 PointerPayload: &?&ast.NodePointerPayload,
188 PointerIndexPayload: &?&ast.NodePointerIndexPayload,
189227 SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase),
228 SwitchCaseFirstItem: &ArrayList(&ast.Node),
190229 SwitchCaseItem: &ArrayList(&ast.Node),
191230 SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node),
192231
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,
232 SuspendBody: &ast.NodeSuspend,
233 AsyncAllocator: &ast.NodeAsyncAttribute,
234 AsyncEnd: AsyncEndCtx,
235
236 SliceOrArrayAccess: &ast.NodeSuffixOp,
237 SliceOrArrayType: &ast.NodePrefixOp,
238 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
239
240 Payload: OptionalCtx,
241 PointerPayload: OptionalCtx,
242 PointerIndexPayload: OptionalCtx,
243
244 Expression: OptionalCtx,
245 RangeExpressionBegin: OptionalCtx,
246 RangeExpressionEnd: OptionalCtx,
247 AssignmentExpressionBegin: OptionalCtx,
248 AssignmentExpressionEnd: OptionalCtx,
249 UnwrapExpressionBegin: OptionalCtx,
250 UnwrapExpressionEnd: OptionalCtx,
251 BoolOrExpressionBegin: OptionalCtx,
252 BoolOrExpressionEnd: OptionalCtx,
253 BoolAndExpressionBegin: OptionalCtx,
254 BoolAndExpressionEnd: OptionalCtx,
255 ComparisonExpressionBegin: OptionalCtx,
256 ComparisonExpressionEnd: OptionalCtx,
257 BinaryOrExpressionBegin: OptionalCtx,
258 BinaryOrExpressionEnd: OptionalCtx,
259 BinaryXorExpressionBegin: OptionalCtx,
260 BinaryXorExpressionEnd: OptionalCtx,
261 BinaryAndExpressionBegin: OptionalCtx,
262 BinaryAndExpressionEnd: OptionalCtx,
263 BitShiftExpressionBegin: OptionalCtx,
264 BitShiftExpressionEnd: OptionalCtx,
265 AdditionExpressionBegin: OptionalCtx,
266 AdditionExpressionEnd: OptionalCtx,
267 MultiplyExpressionBegin: OptionalCtx,
268 MultiplyExpressionEnd: OptionalCtx,
269 CurlySuffixExpressionBegin: OptionalCtx,
270 CurlySuffixExpressionEnd: OptionalCtx,
271 TypeExprBegin: OptionalCtx,
272 TypeExprEnd: OptionalCtx,
273 PrefixOpExpression: OptionalCtx,
274 SuffixOpExpressionBegin: OptionalCtx,
275 SuffixOpExpressionEnd: OptionalCtx,
276 PrimaryExpression: OptionalCtx,
277
278 ErrorTypeOrSetDecl: ErrorTypeOrSetDeclCtx,
279 StringLiteral: OptionalCtx,
280 Identifier: OptionalCtx,
281
282
283 IfToken: @TagType(Token.Id),
284 IfTokenSave: ExpectTokenSave,
285 ExpectToken: @TagType(Token.Id),
286 ExpectTokenSave: ExpectTokenSave,
287 OptionalTokenSave: OptionalTokenSave,
233288 };
234289
235290 /// Returns an AST tree, allocated with the parser's allocator.
......@@ -302,31 +357,31 @@ pub const Parser = struct {
302357 Token.Id.Keyword_test => {
303358 stack.append(State.TopLevel) catch unreachable;
304359
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
312360 const block = try self.createNode(arena, ast.NodeBlock,
313361 ast.NodeBlock {
314362 .base = undefined,
315363 .label = null,
316 .lbrace = lbrace,
364 .lbrace = undefined,
317365 .statements = ArrayList(&ast.Node).init(arena),
318366 .rbrace = undefined,
319367 }
320368 );
321 _ = try self.createAttachNode(arena, &root_node.decls, ast.NodeTestDecl,
369 const test_node = try self.createAttachNode(arena, &root_node.decls, ast.NodeTestDecl,
322370 ast.NodeTestDecl {
323371 .base = undefined,
324372 .test_token = token,
325 .name = name,
373 .name = undefined,
326374 .body_node = &block.base,
327375 }
328376 );
329377 stack.append(State { .Block = block }) catch unreachable;
378 try stack.append(State {
379 .ExpectTokenSave = ExpectTokenSave {
380 .id = Token.Id.LBrace,
381 .ptr = &block.rbrace,
382 }
383 });
384 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &test_node.name } });
330385 continue;
331386 },
332387 Token.Id.Eof => {
......@@ -346,15 +401,30 @@ pub const Parser = struct {
346401 continue;
347402 },
348403 Token.Id.Keyword_comptime => {
404 const block = try self.createNode(arena, ast.NodeBlock,
405 ast.NodeBlock {
406 .base = undefined,
407 .label = null,
408 .lbrace = undefined,
409 .statements = ArrayList(&ast.Node).init(arena),
410 .rbrace = undefined,
411 }
412 );
349413 const node = try self.createAttachNode(arena, &root_node.decls, ast.NodeComptime,
350414 ast.NodeComptime {
351415 .base = undefined,
352416 .comptime_token = token,
353 .expr = undefined,
417 .expr = &block.base,
354418 }
355419 );
356420 stack.append(State.TopLevel) catch unreachable;
357 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
421 try stack.append(State { .Block = block });
422 try stack.append(State {
423 .ExpectTokenSave = ExpectTokenSave {
424 .id = Token.Id.LBrace,
425 .ptr = &block.rbrace,
426 }
427 });
358428 continue;
359429 },
360430 else => {
......@@ -404,7 +474,6 @@ pub const Parser = struct {
404474 }
405475 }
406476 },
407
408477 State.TopLevelLibname => |ctx| {
409478 const lib_name = blk: {
410479 const lib_name_token = self.getNextToken();
......@@ -423,14 +492,12 @@ pub const Parser = struct {
423492 },
424493 }) catch unreachable;
425494 },
426
427495 State.TopLevelDecl => |ctx| {
428496 const token = self.getNextToken();
429497 switch (token.id) {
430498 Token.Id.Keyword_use => {
431499 if (ctx.extern_export_inline_token != null) {
432 try self.parseError(&stack, token, "Invalid token {}", @tagName((??ctx.extern_export_inline_token).id));
433 continue;
500 return self.parseError(token, "Invalid token {}", @tagName((??ctx.extern_export_inline_token).id));
434501 }
435502
436503 const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse,
......@@ -447,14 +514,13 @@ pub const Parser = struct {
447514 .ptr = &node.semicolon_token,
448515 }
449516 }) catch unreachable;
450 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
517 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
451518 continue;
452519 },
453520 Token.Id.Keyword_var, Token.Id.Keyword_const => {
454521 if (ctx.extern_export_inline_token) |extern_export_inline_token| {
455522 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;
523 return self.parseError(token, "Invalid token {}", @tagName(extern_export_inline_token.id));
458524 }
459525 }
460526
......@@ -564,82 +630,48 @@ pub const Parser = struct {
564630 }
565631 });
566632
567 const langle_bracket = self.getNextToken();
568 if (langle_bracket.id != Token.Id.AngleBracketLeft) {
569 self.putBackToken(langle_bracket);
570 continue;
571 }
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 } });
633 try stack.append(State { .AsyncAllocator = async_node });
581634 continue;
582635 },
583636 else => {
584 try self.parseError(&stack, token, "expected variable declaration or function, found {}", @tagName(token.id));
585 continue;
637 return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id));
586638 },
587639 }
588640 },
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;
641 State.TopLevelExternOrField => |ctx| {
642 if (self.eatToken(Token.Id.Identifier)) |identifier| {
643 std.debug.assert(ctx.container_decl.kind == ast.NodeContainerDecl.Kind.Struct);
644 const node = try self.createAttachNode(arena, &ctx.container_decl.fields_and_decls, ast.NodeStructField,
645 ast.NodeStructField {
646 .base = undefined,
647 .visib_token = ctx.visib_token,
648 .name_token = identifier,
649 .type_expr = undefined,
650 }
651 );
603652
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 });
653 stack.append(State { .FieldListCommaOrEnd = ctx.container_decl }) catch unreachable;
654 try stack.append(State { .Expression = OptionalCtx { .Required = &node.type_expr } });
655 try stack.append(State { .ExpectToken = Token.Id.Colon });
609656 continue;
610657 }
611658
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;
659 stack.append(State{ .ContainerDecl = ctx.container_decl }) catch unreachable;
660 try stack.append(State {
661 .TopLevelExtern = TopLevelDeclCtx {
662 .decls = &ctx.container_decl.fields_and_decls,
663 .visib_token = ctx.visib_token,
664 .extern_export_inline_token = null,
665 .lib_name = null,
636666 }
637 }
667 });
668 continue;
638669 },
639670
671
640672 State.ContainerExtern => |ctx| {
641673 const token = self.getNextToken();
642 const node = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeContainerDecl,
674 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeContainerDecl,
643675 ast.NodeContainerDecl {
644676 .base = undefined,
645677 .ltoken = ctx.ltoken,
......@@ -649,15 +681,14 @@ pub const Parser = struct {
649681 Token.Id.Keyword_union => ast.NodeContainerDecl.Kind.Union,
650682 Token.Id.Keyword_enum => ast.NodeContainerDecl.Kind.Enum,
651683 else => {
652 try self.parseError(&stack, token, "expected {}, {} or {}, found {}",
684 return self.parseError(token, "expected {}, {} or {}, found {}",
653685 @tagName(Token.Id.Keyword_struct),
654686 @tagName(Token.Id.Keyword_union),
655687 @tagName(Token.Id.Keyword_enum),
656688 @tagName(token.id));
657 continue;
658689 },
659690 },
660 .init_arg_expr = undefined,
691 .init_arg_expr = ast.NodeContainerDecl.InitArg.None,
661692 .fields_and_decls = ArrayList(&ast.Node).init(arena),
662693 .rbrace_token = undefined,
663694 }
......@@ -665,37 +696,34 @@ pub const Parser = struct {
665696
666697 stack.append(State { .ContainerDecl = node }) catch unreachable;
667698 try stack.append(State { .ExpectToken = Token.Id.LBrace });
699 try stack.append(State { .ContainerInitArgStart = node });
700 },
668701
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;
702 State.ContainerInitArgStart => |container_decl| {
703 if (self.eatToken(Token.Id.LParen) == null) {
673704 continue;
674705 }
675706
676 try stack.append(State { .ExpectToken = Token.Id.RParen });
707 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
708 try stack.append(State { .ContainerInitArg = container_decl });
709 },
677710
711 State.ContainerInitArg => |container_decl| {
678712 const init_arg_token = self.getNextToken();
679713 switch (init_arg_token.id) {
680714 Token.Id.Keyword_enum => {
681 node.init_arg_expr = ast.NodeContainerDecl.InitArg.Enum;
715 container_decl.init_arg_expr = ast.NodeContainerDecl.InitArg.Enum;
682716 },
683717 else => {
684718 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 });
719 container_decl.init_arg_expr = ast.NodeContainerDecl.InitArg { .Type = undefined };
720 stack.append(State { .Expression = OptionalCtx { .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;
691721 },
692722 }
693723 continue;
694724 },
695
696725 State.ContainerDecl => |container_decl| {
697726 const token = self.getNextToken();
698
699727 switch (token.id) {
700728 Token.Id.Identifier => {
701729 switch (container_decl.kind) {
......@@ -710,7 +738,7 @@ pub const Parser = struct {
710738 );
711739
712740 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
713 try stack.append(State { .Expression = DestPtr { .Field = &node.type_expr } });
741 try stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.type_expr } });
714742 try stack.append(State { .ExpectToken = Token.Id.Colon });
715743 continue;
716744 },
......@@ -724,14 +752,8 @@ pub const Parser = struct {
724752 );
725753
726754 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 } });
755 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &node.type_expr } });
756 try stack.append(State { .IfToken = Token.Id.Colon });
735757 continue;
736758 },
737759 ast.NodeContainerDecl.Kind.Enum => {
......@@ -744,52 +766,34 @@ pub const Parser = struct {
744766 );
745767
746768 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 } });
769 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &node.value } });
770 try stack.append(State { .IfToken = Token.Id.Equal });
755771 continue;
756772 },
757773 }
758774 },
759775 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 }
776 switch (container_decl.kind) {
777 ast.NodeContainerDecl.Kind.Struct => {
778 try stack.append(State {
779 .TopLevelExternOrField = TopLevelExternOrFieldCtx {
780 .visib_token = token,
781 .container_decl = container_decl,
782 }
783 });
784 },
785 else => {
786 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
787 try stack.append(State {
788 .TopLevelExtern = TopLevelDeclCtx {
789 .decls = &container_decl.fields_and_decls,
790 .visib_token = token,
791 .extern_export_inline_token = null,
792 .lib_name = null,
793 }
794 });
780795 }
781796 }
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;
793797 },
794798 Token.Id.Keyword_export => {
795799 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
......@@ -823,1883 +827,1947 @@ pub const Parser = struct {
823827 }
824828 },
825829
826 State.ExpectToken => |token_id| {
827 _ = (try self.expectToken(&stack, token_id)) ?? continue;
828 continue;
829 },
830
831 State.ExpectTokenSave => |expect_token_save| {
832 *expect_token_save.ptr = (try self.expectToken(&stack, expect_token_save.id)) ?? continue;
833 continue;
834 },
835830
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 }
831 State.VarDecl => |var_decl| {
832 stack.append(State { .VarDeclAlign = var_decl }) catch unreachable;
833 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} });
834 try stack.append(State { .IfToken = Token.Id.Colon });
835 try stack.append(State {
836 .ExpectTokenSave = ExpectTokenSave {
837 .id = Token.Id.Identifier,
838 .ptr = &var_decl.name_token,
839 }
840 });
843841 continue;
844842 },
843 State.VarDeclAlign => |var_decl| {
844 stack.append(State { .VarDeclEq = var_decl }) catch unreachable;
845845
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();
846 const next_token = self.getNextToken();
847 if (next_token.id == Token.Id.Keyword_align) {
848 try stack.append(State { .ExpectToken = Token.Id.RParen });
849 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.align_node} });
850 try stack.append(State { .ExpectToken = Token.Id.LParen });
851851 continue;
852852 }
853853
854 *if_token_save.ptr = token;
854 self.putBackToken(next_token);
855855 continue;
856856 },
857
858 State.Optional => { },
859
860 State.Expression => |dest_ptr| {
857 State.VarDeclEq => |var_decl| {
861858 const token = self.getNextToken();
862859 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
860 Token.Id.Equal => {
861 var_decl.eq_token = token;
874862 stack.append(State {
875 .Optional = RevertState {
876 .parser = *self,
877 .tokenizer = *self.tokenizer,
878 .ptr = &node.rhs,
879 }
863 .ExpectTokenSave = ExpectTokenSave {
864 .id = Token.Id.Semicolon,
865 .ptr = &var_decl.semicolon_token,
866 },
880867 }) catch unreachable;
881 try stack.append(State { .Expression = DestPtr { .NullableField = &node.rhs } });
868 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.init_node } });
882869 continue;
883870 },
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 }
871 Token.Id.Semicolon => {
872 var_decl.semicolon_token = token;
873 continue;
874 },
875 else => {
876 return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id));
877 }
878 }
879 },
891880
892 break :blk (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
893 };
894881
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
909 stack.append(State {
910 .Optional = RevertState {
911 .parser = *self,
912 .tokenizer = *self.tokenizer,
913 .ptr = &node.rhs,
914 }
915 }) catch unreachable;
916 try stack.append(State { .Expression = DestPtr { .NullableField = &node.rhs } });
917 continue;
918 },
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 {
882 State.FnDef => |fn_proto| {
883 const token = self.getNextToken();
884 switch(token.id) {
885 Token.Id.LBrace => {
886 const block = try self.createNode(arena, ast.NodeBlock,
887 ast.NodeBlock {
922888 .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,
889 .label = null,
890 .lbrace = token,
891 .statements = ArrayList(&ast.Node).init(arena),
892 .rbrace = undefined,
931893 }
932894 );
933
934 stack.append(State { .Expression = DestPtr { .Field = &node.rhs } }) catch unreachable;
895 fn_proto.body_node = &block.base;
896 stack.append(State { .Block = block }) catch unreachable;
935897 continue;
936898 },
899 Token.Id.Semicolon => continue,
937900 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;
943 }
901 return self.parseError(token, "expected ';' or '{{', found {}", @tagName(token.id));
902 },
944903 }
945904 },
905 State.FnProto => |fn_proto| {
906 stack.append(State { .FnProtoAlign = fn_proto }) catch unreachable;
907 try stack.append(State { .ParamDecl = fn_proto });
908 try stack.append(State { .ExpectToken = Token.Id.LParen });
946909
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;
910 const next_token = self.getNextToken();
911 if (next_token.id == Token.Id.Identifier) {
912 fn_proto.name_token = next_token;
913 continue;
965914 }
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 });
915 self.putBackToken(next_token);
973916 continue;
974917 },
918 State.FnProtoAlign => |fn_proto| {
919 stack.append(State { .FnProtoReturnType = fn_proto }) catch unreachable;
975920
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;
921 if (self.eatToken(Token.Id.Keyword_align)) |align_token| {
922 try stack.append(State { .ExpectToken = Token.Id.RParen });
923 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } });
924 try stack.append(State { .ExpectToken = Token.Id.LParen });
994925 }
995 },
996926
997 State.UnwrapExpressionBegin => |dest_ptr| {
998 stack.append(State { .UnwrapExpressionEnd = dest_ptr }) catch unreachable;
999 try stack.append(State { .BoolOrExpressionBegin = dest_ptr });
1000927 continue;
1001928 },
1002
1003 State.UnwrapExpressionEnd => |dest_ptr| {
929 State.FnProtoReturnType => |fn_proto| {
1004930 const token = self.getNextToken();
1005931 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 {
1009 .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,
1018 }
1019 );
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 }
932 Token.Id.Bang => {
933 fn_proto.return_type = ast.NodeFnProto.ReturnType { .InferErrorSet = undefined };
934 stack.append(State {
935 .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.InferErrorSet },
936 }) catch unreachable;
1027937 continue;
1028938 },
1029939 else => {
940 // TODO: this is a special case. Remove this when #760 is fixed
941 if (token.id == Token.Id.Keyword_error) {
942 if (self.isPeekToken(Token.Id.LBrace)) {
943 fn_proto.return_type = ast.NodeFnProto.ReturnType {
944 .Explicit = &(try self.createLiteral(arena, ast.NodeErrorType, token)).base
945 };
946 continue;
947 }
948 }
949
1030950 self.putBackToken(token);
951 fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined };
952 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.Explicit }, }) catch unreachable;
1031953 continue;
1032954 },
1033955 }
1034956 },
1035957
1036 State.BoolOrExpressionBegin => |dest_ptr| {
1037 stack.append(State { .BoolOrExpressionEnd = dest_ptr }) catch unreachable;
1038 try stack.append(State { .BoolAndExpressionBegin = dest_ptr });
1039 continue;
1040 },
1041958
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 },
959 State.ParamDecl => |fn_proto| {
960 if (self.eatToken(Token.Id.RParen)) |_| {
961 continue;
1063962 }
1064 },
963 const param_decl = try self.createAttachNode(arena, &fn_proto.params, ast.NodeParamDecl,
964 ast.NodeParamDecl {
965 .base = undefined,
966 .comptime_token = null,
967 .noalias_token = null,
968 .name_token = null,
969 .type_node = undefined,
970 .var_args_token = null,
971 },
972 );
1065973
1066 State.BoolAndExpressionBegin => |dest_ptr| {
1067 stack.append(State { .BoolAndExpressionEnd = dest_ptr }) catch unreachable;
1068 try stack.append(State { .ComparisonExpressionBegin = dest_ptr });
974 stack.append(State {
975 .ParamDeclEnd = ParamDeclEndCtx {
976 .param_decl = param_decl,
977 .fn_proto = fn_proto,
978 }
979 }) catch unreachable;
980 try stack.append(State { .ParamDeclName = param_decl });
981 try stack.append(State { .ParamDeclAliasOrComptime = param_decl });
1069982 continue;
1070983 },
1071
1072 State.BoolAndExpressionEnd => |dest_ptr| {
1073 const token = self.getNextToken();
1074 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 } });
1087 continue;
1088 },
1089 else => {
1090 self.putBackToken(token);
1091 continue;
1092 },
984 State.ParamDeclAliasOrComptime => |param_decl| {
985 if (self.eatToken(Token.Id.Keyword_comptime)) |comptime_token| {
986 param_decl.comptime_token = comptime_token;
987 } else if (self.eatToken(Token.Id.Keyword_noalias)) |noalias_token| {
988 param_decl.noalias_token = noalias_token;
1093989 }
1094990 },
1095
1096 State.ComparisonExpressionBegin => |dest_ptr| {
1097 stack.append(State { .ComparisonExpressionEnd = dest_ptr }) catch unreachable;
1098 try stack.append(State { .BinaryOrExpressionBegin = dest_ptr });
1099 continue;
991 State.ParamDeclName => |param_decl| {
992 // TODO: Here, we eat two tokens in one state. This means that we can't have
993 // comments between these two tokens.
994 if (self.eatToken(Token.Id.Identifier)) |ident_token| {
995 if (self.eatToken(Token.Id.Colon)) |_| {
996 param_decl.name_token = ident_token;
997 } else {
998 self.putBackToken(ident_token);
999 }
1000 }
11001001 },
1101
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);
1002 State.ParamDeclEnd => |ctx| {
1003 if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| {
1004 ctx.param_decl.var_args_token = ellipsis3;
1005 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
11191006 continue;
11201007 }
1121 },
11221008
1123 State.BinaryOrExpressionBegin => |dest_ptr| {
1124 stack.append(State { .BinaryOrExpressionEnd = dest_ptr }) catch unreachable;
1125 try stack.append(State { .BinaryXorExpressionBegin = dest_ptr });
1009 try stack.append(State { .ParamDeclComma = ctx.fn_proto });
1010 try stack.append(State {
1011 .TypeExprBegin = OptionalCtx { .Required = &ctx.param_decl.type_node }
1012 });
1013 },
1014 State.ParamDeclComma => |fn_proto| {
1015 var discard_end: Token = undefined;
1016 try self.commaOrEnd(&stack, Token.Id.RParen, &discard_end, State { .ParamDecl = fn_proto });
11261017 continue;
11271018 },
11281019
1129 State.BinaryOrExpressionEnd => |dest_ptr| {
1020
1021 State.LabeledExpression => |ctx| {
11301022 const token = self.getNextToken();
11311023 switch (token.id) {
1132 Token.Id.Pipe => {
1133 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1134 ast.NodeInfixOp {
1024 Token.Id.LBrace => {
1025 const block = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeBlock,
1026 ast.NodeBlock {
11351027 .base = undefined,
1136 .lhs = dest_ptr.get(),
1137 .op_token = token,
1138 .op = ast.NodeInfixOp.InfixOp.BitOr,
1139 .rhs = undefined,
1028 .label = ctx.label,
1029 .lbrace = token,
1030 .statements = ArrayList(&ast.Node).init(arena),
1031 .rbrace = undefined,
11401032 }
11411033 );
1142 stack.append(State { .BinaryOrExpressionEnd = dest_ptr }) catch unreachable;
1143 try stack.append(State { .BinaryXorExpressionBegin = DestPtr { .Field = &node.rhs } });
1034 stack.append(State { .Block = block }) catch unreachable;
11441035 continue;
11451036 },
1146 else => {
1147 self.putBackToken(token);
1037 Token.Id.Keyword_while => {
1038 stack.append(State {
1039 .While = LoopCtx {
1040 .label = ctx.label,
1041 .inline_token = null,
1042 .loop_token = token,
1043 .opt_ctx = ctx.opt_ctx.toRequired(),
1044 }
1045 }) catch unreachable;
11481046 continue;
11491047 },
1150 }
1151 },
1152
1153 State.BinaryXorExpressionBegin => |dest_ptr| {
1154 stack.append(State { .BinaryXorExpressionEnd = dest_ptr }) catch unreachable;
1155 try stack.append(State { .BinaryAndExpressionBegin = dest_ptr });
1156 continue;
1157 },
1158
1159 State.BinaryXorExpressionEnd => |dest_ptr| {
1160 const token = self.getNextToken();
1161 switch (token.id) {
1162 Token.Id.Caret => {
1163 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1164 ast.NodeInfixOp {
1165 .base = undefined,
1166 .lhs = dest_ptr.get(),
1167 .op_token = token,
1168 .op = ast.NodeInfixOp.InfixOp.BitXor,
1169 .rhs = undefined,
1048 Token.Id.Keyword_for => {
1049 stack.append(State {
1050 .For = LoopCtx {
1051 .label = ctx.label,
1052 .inline_token = null,
1053 .loop_token = token,
1054 .opt_ctx = ctx.opt_ctx.toRequired(),
11701055 }
1171 );
1172 stack.append(State { .BinaryXorExpressionEnd = dest_ptr }) catch unreachable;
1173 try stack.append(State { .BinaryAndExpressionBegin = DestPtr { .Field = &node.rhs } });
1056 }) catch unreachable;
1057 continue;
1058 },
1059 Token.Id.Keyword_inline => {
1060 stack.append(State {
1061 .Inline = InlineCtx {
1062 .label = ctx.label,
1063 .inline_token = token,
1064 .opt_ctx = ctx.opt_ctx.toRequired(),
1065 }
1066 }) catch unreachable;
11741067 continue;
11751068 },
11761069 else => {
1070 if (ctx.opt_ctx != OptionalCtx.Optional) {
1071 return self.parseError(token, "expected 'while', 'for', 'inline' or '{{', found {}", @tagName(token.id));
1072 }
1073
11771074 self.putBackToken(token);
11781075 continue;
11791076 },
11801077 }
11811078 },
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| {
1079 State.Inline => |ctx| {
11901080 const token = self.getNextToken();
11911081 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,
1082 Token.Id.Keyword_while => {
1083 stack.append(State {
1084 .While = LoopCtx {
1085 .inline_token = ctx.inline_token,
1086 .label = ctx.label,
1087 .loop_token = token,
1088 .opt_ctx = ctx.opt_ctx.toRequired(),
12001089 }
1201 );
1202 stack.append(State { .BinaryAndExpressionEnd = dest_ptr }) catch unreachable;
1203 try stack.append(State { .BitShiftExpressionBegin = DestPtr { .Field = &node.rhs } });
1090 }) catch unreachable;
1091 continue;
1092 },
1093 Token.Id.Keyword_for => {
1094 stack.append(State {
1095 .For = LoopCtx {
1096 .inline_token = ctx.inline_token,
1097 .label = ctx.label,
1098 .loop_token = token,
1099 .opt_ctx = ctx.opt_ctx.toRequired(),
1100 }
1101 }) catch unreachable;
12041102 continue;
12051103 },
12061104 else => {
1105 if (ctx.opt_ctx != OptionalCtx.Optional) {
1106 return self.parseError(token, "expected 'while' or 'for', found {}", @tagName(token.id));
1107 }
1108
12071109 self.putBackToken(token);
12081110 continue;
12091111 },
12101112 }
12111113 },
1212
1213 State.BitShiftExpressionBegin => |dest_ptr| {
1214 stack.append(State { .BitShiftExpressionEnd = dest_ptr }) catch unreachable;
1215 try stack.append(State { .AdditionExpressionBegin = dest_ptr });
1216 continue;
1114 State.While => |ctx| {
1115 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeWhile,
1116 ast.NodeWhile {
1117 .base = undefined,
1118 .label = ctx.label,
1119 .inline_token = ctx.inline_token,
1120 .while_token = ctx.loop_token,
1121 .condition = undefined,
1122 .payload = null,
1123 .continue_expr = null,
1124 .body = undefined,
1125 .@"else" = null,
1126 }
1127 );
1128 stack.append(State { .Else = &node.@"else" }) catch unreachable;
1129 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
1130 try stack.append(State { .WhileContinueExpr = &node.continue_expr });
1131 try stack.append(State { .IfToken = Token.Id.Colon });
1132 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
1133 try stack.append(State { .ExpectToken = Token.Id.RParen });
1134 try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } });
1135 try stack.append(State { .ExpectToken = Token.Id.LParen });
12171136 },
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 }
1137 State.WhileContinueExpr => |dest| {
1138 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
1139 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = dest } });
1140 try stack.append(State { .ExpectToken = Token.Id.LParen });
12381141 },
1239
1240 State.AdditionExpressionBegin => |dest_ptr| {
1241 stack.append(State { .AdditionExpressionEnd = dest_ptr }) catch unreachable;
1242 try stack.append(State { .MultiplyExpressionBegin = dest_ptr });
1243 continue;
1142 State.For => |ctx| {
1143 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeFor,
1144 ast.NodeFor {
1145 .base = undefined,
1146 .label = ctx.label,
1147 .inline_token = ctx.inline_token,
1148 .for_token = ctx.loop_token,
1149 .array_expr = undefined,
1150 .payload = null,
1151 .body = undefined,
1152 .@"else" = null,
1153 }
1154 );
1155 stack.append(State { .Else = &node.@"else" }) catch unreachable;
1156 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
1157 try stack.append(State { .PointerIndexPayload = OptionalCtx { .Optional = &node.payload } });
1158 try stack.append(State { .ExpectToken = Token.Id.RParen });
1159 try stack.append(State { .Expression = OptionalCtx { .Required = &node.array_expr } });
1160 try stack.append(State { .ExpectToken = Token.Id.LParen });
12441161 },
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);
1162 State.Else => |dest| {
1163 const else_token = self.getNextToken();
1164 if (else_token.id != Token.Id.Keyword_else) {
1165 self.putBackToken(else_token);
12631166 continue;
12641167 }
1265 },
1266
1267 State.MultiplyExpressionBegin => |dest_ptr| {
1268 stack.append(State { .MultiplyExpressionEnd = dest_ptr }) catch unreachable;
1269 try stack.append(State { .CurlySuffixExpressionBegin = dest_ptr });
1270 continue;
1271 },
12721168
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 {
1278 .base = undefined,
1279 .lhs = dest_ptr.get(),
1280 .op_token = token,
1281 .op = mult_id,
1282 .rhs = undefined,
1283 }
1284 );
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 },
1169 const node = try self.createNode(arena, ast.NodeElse,
1170 ast.NodeElse {
1171 .base = undefined,
1172 .else_token = else_token,
1173 .payload = null,
1174 .body = undefined,
1175 }
1176 );
1177 *dest = node;
12931178
1294 State.CurlySuffixExpressionBegin => |dest_ptr| {
1295 stack.append(State { .CurlySuffixExpressionEnd = dest_ptr }) catch unreachable;
1296 try stack.append(State { .TypeExprBegin = dest_ptr });
1297 continue;
1179 stack.append(State { .Expression = OptionalCtx { .Required = &node.body } }) catch unreachable;
1180 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });
12981181 },
12991182
1300 State.CurlySuffixExpressionEnd => |dest_ptr| {
1301 if (self.eatToken(Token.Id.LBrace) == null) {
1302 continue;
1303 }
13041183
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 });
1323 continue;
1324 } 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 });
1343 continue;
1184 State.Block => |block| {
1185 const token = self.getNextToken();
1186 switch (token.id) {
1187 Token.Id.RBrace => {
1188 block.rbrace = token;
1189 continue;
1190 },
1191 else => {
1192 self.putBackToken(token);
1193 stack.append(State { .Block = block }) catch unreachable;
1194 try stack.append(State { .Statement = block });
1195 continue;
1196 },
13441197 }
13451198 },
1346
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 },
1352
1353 State.TypeExprEnd => |dest_ptr| {
1199 State.Statement => |block| {
13541200 const token = self.getNextToken();
13551201 switch (token.id) {
1356 Token.Id.Bang => {
1357 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeInfixOp,
1358 ast.NodeInfixOp {
1202 Token.Id.Keyword_comptime => {
1203 stack.append(State {
1204 .ComptimeStatement = ComptimeStatementCtx {
1205 .comptime_token = token,
1206 .block = block,
1207 }
1208 }) catch unreachable;
1209 },
1210 Token.Id.Keyword_var, Token.Id.Keyword_const => {
1211 const var_decl = try self.createAttachNode(arena, &block.statements, ast.NodeVarDecl,
1212 ast.NodeVarDecl {
13591213 .base = undefined,
1360 .lhs = dest_ptr.get(),
1361 .op_token = token,
1362 .op = ast.NodeInfixOp.InfixOp.ErrorUnion,
1363 .rhs = undefined,
1214 .visib_token = null,
1215 .mut_token = token,
1216 .comptime_token = null,
1217 .extern_export_token = null,
1218 .type_node = null,
1219 .align_node = null,
1220 .init_node = null,
1221 .lib_name = null,
1222 // initialized later
1223 .name_token = undefined,
1224 .eq_token = undefined,
1225 .semicolon_token = undefined,
1226 }
1227 );
1228 stack.append(State { .VarDecl = var_decl }) catch unreachable;
1229 continue;
1230 },
1231 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
1232 const node = try self.createAttachNode(arena, &block.statements, ast.NodeDefer,
1233 ast.NodeDefer {
1234 .base = undefined,
1235 .defer_token = token,
1236 .kind = switch (token.id) {
1237 Token.Id.Keyword_defer => ast.NodeDefer.Kind.Unconditional,
1238 Token.Id.Keyword_errdefer => ast.NodeDefer.Kind.Error,
1239 else => unreachable,
1240 },
1241 .expr = undefined,
1242 }
1243 );
1244 stack.append(State { .Semicolon = &node.base }) catch unreachable;
1245 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
1246 continue;
1247 },
1248 Token.Id.LBrace => {
1249 const inner_block = try self.createAttachNode(arena, &block.statements, ast.NodeBlock,
1250 ast.NodeBlock {
1251 .base = undefined,
1252 .label = null,
1253 .lbrace = token,
1254 .statements = ArrayList(&ast.Node).init(arena),
1255 .rbrace = undefined,
13641256 }
13651257 );
1366 stack.append(State { .TypeExprEnd = dest_ptr }) catch unreachable;
1367 try stack.append(State { .PrefixOpExpression = DestPtr { .Field = &node.rhs } });
1258 stack.append(State { .Block = inner_block }) catch unreachable;
13681259 continue;
13691260 },
13701261 else => {
13711262 self.putBackToken(token);
1263 const statememt = try block.statements.addOne();
1264 stack.append(State { .Semicolon = statememt }) catch unreachable;
1265 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statememt } });
13721266 continue;
1373 },
1267 }
13741268 }
13751269 },
1376
1377 State.PrefixOpExpression => |dest_ptr| {
1270 State.ComptimeStatement => |ctx| {
13781271 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 {
1272 if (token.id == Token.Id.Keyword_var or token.id == Token.Id.Keyword_const) {
1273 const var_decl = try self.createAttachNode(arena, &ctx.block.statements, ast.NodeVarDecl,
1274 ast.NodeVarDecl {
13821275 .base = undefined,
1383 .op_token = token,
1384 .op = prefix_id,
1385 .rhs = undefined,
1276 .visib_token = null,
1277 .mut_token = token,
1278 .comptime_token = ctx.comptime_token,
1279 .extern_export_token = null,
1280 .type_node = null,
1281 .align_node = null,
1282 .init_node = null,
1283 .lib_name = null,
1284 // initialized later
1285 .name_token = undefined,
1286 .eq_token = undefined,
1287 .semicolon_token = undefined,
13861288 }
13871289 );
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;
1290 stack.append(State { .VarDecl = var_decl }) catch unreachable;
1291 continue;
1292 } else {
1293 self.putBackToken(token);
1294 self.putBackToken(ctx.comptime_token);
1295 const statememt = try ctx.block.statements.addOne();
1296 stack.append(State { .Semicolon = statememt }) catch unreachable;
1297 try stack.append(State { .Expression = OptionalCtx { .Required = statememt } });
1298 continue;
1299 }
1300 },
1301 State.Semicolon => |node_ptr| {
1302 const node = *node_ptr;
1303 if (requireSemiColon(node)) {
1304 stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable;
1305 }
1306 },
1307
1308
1309 State.AsmOutputItems => |items| {
1310 const lbracket = self.getNextToken();
1311 if (lbracket.id != Token.Id.LBracket) {
1312 self.putBackToken(lbracket);
1313 continue;
1314 }
1315
1316 const node = try self.createNode(arena, ast.NodeAsmOutput,
1317 ast.NodeAsmOutput {
1318 .base = undefined,
1319 .symbolic_name = undefined,
1320 .constraint = undefined,
1321 .kind = undefined,
14001322 }
1323 );
1324 try items.append(node);
14011325
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 });
1326 stack.append(State { .AsmOutputItems = items }) catch unreachable;
1327 try stack.append(State { .IfToken = Token.Id.Comma });
1328 try stack.append(State { .ExpectToken = Token.Id.RParen });
1329 try stack.append(State { .AsmOutputReturnOrType = node });
1330 try stack.append(State { .ExpectToken = Token.Id.LParen });
1331 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });
1332 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1333 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });
1334 },
1335 State.AsmOutputReturnOrType => |node| {
1336 const token = self.getNextToken();
1337 switch (token.id) {
1338 Token.Id.Identifier => {
1339 node.kind = ast.NodeAsmOutput.Kind { .Variable = try self.createLiteral(arena, ast.NodeIdentifier, token) };
1340 continue;
1341 },
1342 Token.Id.Arrow => {
1343 node.kind = ast.NodeAsmOutput.Kind { .Return = undefined };
1344 try stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.kind.Return } });
1345 continue;
1346 },
1347 else => {
1348 return self.parseError(token, "expected '->' or {}, found {}",
1349 @tagName(Token.Id.Identifier),
1350 @tagName(token.id));
1351 },
1352 }
1353 },
1354 State.AsmInputItems => |items| {
1355 const lbracket = self.getNextToken();
1356 if (lbracket.id != Token.Id.LBracket) {
1357 self.putBackToken(lbracket);
1358 continue;
1359 }
1360
1361 const node = try self.createNode(arena, ast.NodeAsmInput,
1362 ast.NodeAsmInput {
1363 .base = undefined,
1364 .symbolic_name = undefined,
1365 .constraint = undefined,
1366 .expr = undefined,
1367 }
1368 );
1369 try items.append(node);
1370
1371 stack.append(State { .AsmInputItems = items }) catch unreachable;
1372 try stack.append(State { .IfToken = Token.Id.Comma });
1373 try stack.append(State { .ExpectToken = Token.Id.RParen });
1374 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
1375 try stack.append(State { .ExpectToken = Token.Id.LParen });
1376 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });
1377 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1378 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });
1379 },
1380 State.AsmClopperItems => |items| {
1381 stack.append(State { .AsmClopperItems = items }) catch unreachable;
1382 try stack.append(State { .IfToken = Token.Id.Comma });
1383 try stack.append(State { .StringLiteral = OptionalCtx { .Required = try items.addOne() } });
1384 },
1385
1386
1387 State.ExprListItemOrEnd => |list_state| {
1388 if (self.eatToken(list_state.end)) |token| {
1389 *list_state.ptr = token;
1390 continue;
1391 }
1392
1393 stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable;
1394 try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } });
1395 },
1396 State.ExprListCommaOrEnd => |list_state| {
1397 try self.commaOrEnd(&stack, list_state.end, list_state.ptr, State { .ExprListItemOrEnd = list_state });
1398 continue;
1399 },
1400 State.FieldInitListItemOrEnd => |list_state| {
1401 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
1402 *list_state.ptr = rbrace;
1403 continue;
1404 }
1405
1406 const node = try self.createNode(arena, ast.NodeFieldInitializer,
1407 ast.NodeFieldInitializer {
1408 .base = undefined,
1409 .period_token = undefined,
1410 .name_token = undefined,
1411 .expr = undefined,
1412 }
1413 );
1414 try list_state.list.append(node);
1415
1416 stack.append(State { .FieldInitListCommaOrEnd = list_state }) catch unreachable;
1417 try stack.append(State { .Expression = OptionalCtx{ .Required = &node.expr } });
1418 try stack.append(State { .ExpectToken = Token.Id.Equal });
1419 try stack.append(State {
1420 .ExpectTokenSave = ExpectTokenSave {
1421 .id = Token.Id.Identifier,
1422 .ptr = &node.name_token,
1423 }
1424 });
1425 try stack.append(State {
1426 .ExpectTokenSave = ExpectTokenSave {
1427 .id = Token.Id.Period,
1428 .ptr = &node.period_token,
1429 }
1430 });
1431 },
1432 State.FieldInitListCommaOrEnd => |list_state| {
1433 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .FieldInitListItemOrEnd = list_state });
1434 continue;
1435 },
1436 State.FieldListCommaOrEnd => |container_decl| {
1437 try self.commaOrEnd(&stack, Token.Id.RBrace, &container_decl.rbrace_token,
1438 State { .ContainerDecl = container_decl });
1439 continue;
1440 },
1441 State.IdentifierListItemOrEnd => |list_state| {
1442 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
1443 *list_state.ptr = rbrace;
1444 continue;
1445 }
1446
1447 stack.append(State { .IdentifierListCommaOrEnd = list_state }) catch unreachable;
1448 try stack.append(State { .Identifier = OptionalCtx { .Required = try list_state.list.addOne() } });
1449 },
1450 State.IdentifierListCommaOrEnd => |list_state| {
1451 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .IdentifierListItemOrEnd = list_state });
1452 continue;
1453 },
1454 State.SwitchCaseOrEnd => |list_state| {
1455 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
1456 *list_state.ptr = rbrace;
1457 continue;
1458 }
1459
1460 const node = try self.createNode(arena, ast.NodeSwitchCase,
1461 ast.NodeSwitchCase {
1462 .base = undefined,
1463 .items = ArrayList(&ast.Node).init(arena),
1464 .payload = null,
1465 .expr = undefined,
14051466 }
1467 );
1468 try list_state.list.append(node);
1469 stack.append(State { .SwitchCaseCommaOrEnd = list_state }) catch unreachable;
1470 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .Required = &node.expr } });
1471 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
1472 try stack.append(State { .SwitchCaseFirstItem = &node.items });
1473
1474 },
1475 State.SwitchCaseCommaOrEnd => |list_state| {
1476 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .SwitchCaseOrEnd = list_state });
1477 continue;
1478 },
1479 State.SwitchCaseFirstItem => |case_items| {
1480 const token = self.getNextToken();
1481 if (token.id == Token.Id.Keyword_else) {
1482 const else_node = try self.createAttachNode(arena, case_items, ast.NodeSwitchElse,
1483 ast.NodeSwitchElse {
1484 .base = undefined,
1485 .token = token,
1486 }
1487 );
1488 try stack.append(State { .ExpectToken = Token.Id.EqualAngleBracketRight });
14061489 continue;
14071490 } else {
14081491 self.putBackToken(token);
1409 stack.append(State { .SuffixOpExpressionBegin = dest_ptr }) catch unreachable;
1492 try stack.append(State { .SwitchCaseItem = case_items });
14101493 continue;
14111494 }
14121495 },
1496 State.SwitchCaseItem => |case_items| {
1497 stack.append(State { .SwitchCaseItemCommaOrEnd = case_items }) catch unreachable;
1498 try stack.append(State { .RangeExpressionBegin = OptionalCtx { .Required = try case_items.addOne() } });
1499 },
1500 State.SwitchCaseItemCommaOrEnd => |case_items| {
1501 try self.commaOrEnd(&stack, Token.Id.EqualAngleBracketRight, null, State { .SwitchCaseItem = case_items });
1502 continue;
1503 },
14131504
1414 State.SuffixOpExpressionBegin => |dest_ptr| {
1415 const token = self.getNextToken();
1416 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 );
1426 stack.append(State {
1427 .AsyncEnd = AsyncEndCtx {
1428 .dest_ptr = dest_ptr,
1429 .attribute = async_node,
1430 }
1431 }) catch unreachable;
1432 try stack.append(State { .SuffixOpExpressionEnd = dest_ptr });
1433 try stack.append(State { .PrimaryExpression = dest_ptr });
14341505
1435 const langle_bracket = self.getNextToken();
1436 if (langle_bracket.id != Token.Id.AngleBracketLeft) {
1437 self.putBackToken(langle_bracket);
1506 State.SuspendBody => |suspend_node| {
1507 if (suspend_node.payload != null) {
1508 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = &suspend_node.body } });
1509 }
1510 continue;
1511 },
1512 State.AsyncAllocator => |async_node| {
1513 if (self.eatToken(Token.Id.AngleBracketLeft) == null) {
1514 continue;
1515 }
1516
1517 async_node.rangle_bracket = Token(undefined);
1518 try stack.append(State {
1519 .ExpectTokenSave = ExpectTokenSave {
1520 .id = Token.Id.AngleBracketRight,
1521 .ptr = &??async_node.rangle_bracket,
1522 }
1523 });
1524 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &async_node.allocator_type } });
1525 },
1526 State.AsyncEnd => |ctx| {
1527 const node = ctx.ctx.get() ?? continue;
1528
1529 switch (node.id) {
1530 ast.Node.Id.FnProto => {
1531 const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node);
1532 fn_proto.async_attr = ctx.attribute;
1533 },
1534 ast.Node.Id.SuffixOp => {
1535 const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node);
1536 if (suffix_op.op == ast.NodeSuffixOp.SuffixOp.Call) {
1537 suffix_op.op.Call.async_attr = ctx.attribute;
14381538 continue;
14391539 }
14401540
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 } });
1449 continue;
1541 return self.parseError(node.firstToken(), "expected {}, found {}.",
1542 @tagName(ast.NodeSuffixOp.SuffixOp.Call),
1543 @tagName(suffix_op.op));
14501544 },
14511545 else => {
1452 self.putBackToken(token);
1453 stack.append(State { .SuffixOpExpressionEnd = dest_ptr }) catch unreachable;
1454 try stack.append(State { .PrimaryExpression = dest_ptr });
1455 continue;
1546 return self.parseError(node.firstToken(), "expected {} or {}, found {}.",
1547 @tagName(ast.NodeSuffixOp.SuffixOp.Call),
1548 @tagName(ast.Node.Id.FnProto),
1549 @tagName(node.id));
14561550 }
14571551 }
14581552 },
14591553
1460 State.SuffixOpExpressionEnd => |dest_ptr| {
1461 const token = self.getNextToken();
1554
1555 State.SliceOrArrayAccess => |node| {
1556 var token = self.getNextToken();
14621557 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,
1558 Token.Id.Ellipsis2 => {
1559 const start = node.op.ArrayAccess;
1560 node.op = ast.NodeSuffixOp.SuffixOp {
1561 .Slice = ast.NodeSuffixOp.SliceRange {
1562 .start = start,
1563 .end = null,
14751564 }
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,
1565 };
1566
1567 stack.append(State {
1568 .ExpectTokenSave = ExpectTokenSave {
1569 .id = Token.Id.RBracket,
14821570 .ptr = &node.rtoken,
14831571 }
1484 });
1485 continue;
1486 },
1487 Token.Id.LBracket => {
1488 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuffixOp,
1489 ast.NodeSuffixOp {
1490 .base = undefined,
1491 .lhs = dest_ptr.get(),
1492 .op = ast.NodeSuffixOp.SuffixOp {
1493 .ArrayAccess = undefined,
1494 },
1495 .rtoken = undefined
1496 }
1497 );
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 }});
1572 }) catch unreachable;
1573 try stack.append(State { .Expression = OptionalCtx { .Optional = &node.op.Slice.end } });
15011574 continue;
15021575 },
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 {
1507 .base = undefined,
1508 .lhs = dest_ptr.get(),
1509 .op_token = token,
1510 .op = ast.NodeInfixOp.InfixOp.Period,
1511 .rhs = &identifier.base,
1512 }
1513 );
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 });
1576 Token.Id.RBracket => {
1577 node.rtoken = token;
15211578 continue;
15221579 },
15231580 else => {
1524 self.putBackToken(token);
1525 continue;
1526 },
1581 return self.parseError(token, "expected ']' or '..', found {}", @tagName(token.id));
1582 }
15271583 }
15281584 },
1585 State.SliceOrArrayType => |node| {
1586 if (self.eatToken(Token.Id.RBracket)) |_| {
1587 node.op = ast.NodePrefixOp.PrefixOp {
1588 .SliceType = ast.NodePrefixOp.AddrOfInfo {
1589 .align_expr = null,
1590 .bit_offset_start_token = null,
1591 .bit_offset_end_token = null,
1592 .const_token = null,
1593 .volatile_token = null,
1594 }
1595 };
1596 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1597 try stack.append(State { .AddrOfModifiers = &node.op.SliceType });
1598 continue;
1599 }
15291600
1530 State.PrimaryExpression => |dest_ptr| {
1531 const token = self.getNextToken();
1601 node.op = ast.NodePrefixOp.PrefixOp { .ArrayType = undefined };
1602 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1603 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1604 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayType } });
1605 continue;
1606 },
1607 State.AddrOfModifiers => |addr_of_info| {
1608 var token = self.getNextToken();
15321609 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);
1610 Token.Id.Keyword_align => {
1611 stack.append(state) catch unreachable;
1612 if (addr_of_info.align_expr != null) {
1613 return self.parseError(token, "multiple align qualifiers");
1614 }
1615 try stack.append(State { .ExpectToken = Token.Id.RParen });
1616 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &addr_of_info.align_expr} });
1617 try stack.append(State { .ExpectToken = Token.Id.LParen });
15551618 continue;
15561619 },
1557 Token.Id.Keyword_this => {
1558 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeThisLiteral, token)).base);
1620 Token.Id.Keyword_const => {
1621 stack.append(state) catch unreachable;
1622 if (addr_of_info.const_token != null) {
1623 return self.parseError(token, "duplicate qualifier: const");
1624 }
1625 addr_of_info.const_token = token;
15591626 continue;
15601627 },
1561 Token.Id.Keyword_var => {
1562 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeVarType, token)).base);
1628 Token.Id.Keyword_volatile => {
1629 stack.append(state) catch unreachable;
1630 if (addr_of_info.volatile_token != null) {
1631 return self.parseError(token, "duplicate qualifier: volatile");
1632 }
1633 addr_of_info.volatile_token = token;
15631634 continue;
15641635 },
1565 Token.Id.Keyword_unreachable => {
1566 dest_ptr.store(&(try self.createLiteral(arena, ast.NodeUnreachable, token)).base);
1636 else => {
1637 self.putBackToken(token);
15671638 continue;
15681639 },
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 {
1640 }
1641 },
1642
1643
1644 State.Payload => |opt_ctx| {
1645 const token = self.getNextToken();
1646 if (token.id != Token.Id.Pipe) {
1647 if (opt_ctx != OptionalCtx.Optional) {
1648 return self.parseError(token, "expected {}, found {}.",
1649 @tagName(Token.Id.Pipe),
1650 @tagName(token.id));
1651 }
1652
1653 self.putBackToken(token);
1654 continue;
1655 }
1656
1657 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePayload,
1658 ast.NodePayload {
1659 .base = undefined,
1660 .lpipe = token,
1661 .error_symbol = undefined,
1662 .rpipe = undefined
1663 }
1664 );
1665
1666 stack.append(State {
1667 .ExpectTokenSave = ExpectTokenSave {
1668 .id = Token.Id.Pipe,
1669 .ptr = &node.rpipe,
1670 }
1671 }) catch unreachable;
1672 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.error_symbol } });
1673 },
1674 State.PointerPayload => |opt_ctx| {
1675 const token = self.getNextToken();
1676 if (token.id != Token.Id.Pipe) {
1677 if (opt_ctx != OptionalCtx.Optional) {
1678 return self.parseError(token, "expected {}, found {}.",
1679 @tagName(Token.Id.Pipe),
1680 @tagName(token.id));
1681 }
1682
1683 self.putBackToken(token);
1684 continue;
1685 }
1686
1687 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePointerPayload,
1688 ast.NodePointerPayload {
1689 .base = undefined,
1690 .lpipe = token,
1691 .ptr_token = null,
1692 .value_symbol = undefined,
1693 .rpipe = undefined
1694 }
1695 );
1696
1697 stack.append(State {
1698 .ExpectTokenSave = ExpectTokenSave {
1699 .id = Token.Id.Pipe,
1700 .ptr = &node.rpipe,
1701 }
1702 }) catch unreachable;
1703 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });
1704 try stack.append(State {
1705 .OptionalTokenSave = OptionalTokenSave {
1706 .id = Token.Id.Asterisk,
1707 .ptr = &node.ptr_token,
1708 }
1709 });
1710 },
1711 State.PointerIndexPayload => |opt_ctx| {
1712 const token = self.getNextToken();
1713 if (token.id != Token.Id.Pipe) {
1714 if (opt_ctx != OptionalCtx.Optional) {
1715 return self.parseError(token, "expected {}, found {}.",
1716 @tagName(Token.Id.Pipe),
1717 @tagName(token.id));
1718 }
1719
1720 self.putBackToken(token);
1721 continue;
1722 }
1723
1724 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePointerIndexPayload,
1725 ast.NodePointerIndexPayload {
1726 .base = undefined,
1727 .lpipe = token,
1728 .ptr_token = null,
1729 .value_symbol = undefined,
1730 .index_symbol = null,
1731 .rpipe = undefined
1732 }
1733 );
1734
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 { .RequiredNull = &node.index_symbol } });
1742 try stack.append(State { .IfToken = Token.Id.Comma });
1743 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });
1744 try stack.append(State {
1745 .OptionalTokenSave = OptionalTokenSave {
1746 .id = Token.Id.Asterisk,
1747 .ptr = &node.ptr_token,
1748 }
1749 });
1750 },
1751
1752
1753 State.Expression => |opt_ctx| {
1754 const token = self.getNextToken();
1755 switch (token.id) {
1756 Token.Id.Keyword_return => {
1757 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeControlFlowExpression,
1758 ast.NodeControlFlowExpression {
15751759 .base = undefined,
1576 .lparen = token,
1577 .expr = undefined,
1578 .rparen = undefined,
1760 .ltoken = token,
1761 .kind = ast.NodeControlFlowExpression.Kind.Return,
1762 .rhs = null,
15791763 }
15801764 );
1581 stack.append(State {
1582 .ExpectTokenSave = ExpectTokenSave {
1583 .id = Token.Id.RParen,
1584 .ptr = &node.rparen,
1585 }
1586 }) catch unreachable;
1587 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
1765
1766 stack.append(State { .Expression = OptionalCtx { .Optional = &node.rhs } }) catch unreachable;
15881767 continue;
15891768 },
1590 Token.Id.Builtin => {
1591 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeBuiltinCall,
1592 ast.NodeBuiltinCall {
1769 Token.Id.Keyword_break, Token.Id.Keyword_continue => {
1770 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeControlFlowExpression,
1771 ast.NodeControlFlowExpression {
15931772 .base = undefined,
1594 .builtin_token = token,
1595 .params = ArrayList(&ast.Node).init(arena),
1596 .rparen_token = undefined,
1773 .ltoken = token,
1774 .kind = undefined,
1775 .rhs = null,
15971776 }
15981777 );
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, });
1607 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 }
16331778
1634 self.putBackToken(rbracket_token);
1779 stack.append(State { .Expression = OptionalCtx { .Optional = &node.rhs } }) catch unreachable;
16351780
1636 const node = try self.createToDestNode(arena, dest_ptr, ast.NodePrefixOp,
1781 switch (token.id) {
1782 Token.Id.Keyword_break => {
1783 node.kind = ast.NodeControlFlowExpression.Kind { .Break = null };
1784 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Break } });
1785 try stack.append(State { .IfToken = Token.Id.Colon });
1786 },
1787 Token.Id.Keyword_continue => {
1788 node.kind = ast.NodeControlFlowExpression.Kind { .Continue = null };
1789 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } });
1790 try stack.append(State { .IfToken = Token.Id.Colon });
1791 },
1792 else => unreachable,
1793 }
1794 continue;
1795 },
1796 Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
1797 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePrefixOp,
16371798 ast.NodePrefixOp {
16381799 .base = undefined,
16391800 .op_token = token,
1640 .op = ast.NodePrefixOp.PrefixOp{
1641 .ArrayType = undefined,
1801 .op = switch (token.id) {
1802 Token.Id.Keyword_try => ast.NodePrefixOp.PrefixOp { .Try = void{} },
1803 Token.Id.Keyword_cancel => ast.NodePrefixOp.PrefixOp { .Cancel = void{} },
1804 Token.Id.Keyword_resume => ast.NodePrefixOp.PrefixOp { .Resume = void{} },
1805 else => unreachable,
16421806 },
16431807 .rhs = undefined,
16441808 }
16451809 );
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 } });
16491810
1811 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1812 continue;
16501813 },
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;
1814 else => {
1815 if (!try self.parseBlockExpr(&stack, arena, opt_ctx, token)) {
1816 self.putBackToken(token);
1817 stack.append(State { .UnwrapExpressionBegin = opt_ctx }) catch unreachable;
16551818 }
1656
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 );
1665
1666 stack.append(State {
1667 .IdentifierListItemOrEnd = ListSave(&ast.NodeIdentifier) {
1668 .list = &node.decls,
1669 .ptr = &node.rbrace_token,
1670 }
1671 }) catch unreachable;
16721819 continue;
1673 },
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;
1820 }
1821 }
1822 },
1823 State.RangeExpressionBegin => |opt_ctx| {
1824 stack.append(State { .RangeExpressionEnd = opt_ctx }) catch unreachable;
1825 try stack.append(State { .Expression = opt_ctx });
1826 continue;
1827 },
1828 State.RangeExpressionEnd => |opt_ctx| {
1829 const lhs = opt_ctx.get() ?? continue;
1830
1831 if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| {
1832 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
1833 ast.NodeInfixOp {
1834 .base = undefined,
1835 .lhs = lhs,
1836 .op_token = ellipsis3,
1837 .op = ast.NodeInfixOp.InfixOp.Range,
1838 .rhs = undefined,
17051839 }
1840 );
1841 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1842 }
17061843
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;
1715 },
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;
1844 continue;
1845 },
1846 State.AssignmentExpressionBegin => |opt_ctx| {
1847 stack.append(State { .AssignmentExpressionEnd = opt_ctx }) catch unreachable;
1848 try stack.append(State { .Expression = opt_ctx });
1849 continue;
1850 },
1851
1852 State.AssignmentExpressionEnd => |opt_ctx| {
1853 const lhs = opt_ctx.get() ?? continue;
1854
1855 const token = self.getNextToken();
1856 if (tokenIdToAssignment(token.id)) |ass_id| {
1857 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
1858 ast.NodeInfixOp {
1859 .base = undefined,
1860 .lhs = lhs,
1861 .op_token = token,
1862 .op = ass_id,
1863 .rhs = undefined,
17321864 }
1865 );
1866 stack.append(State { .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1867 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
1868 continue;
1869 } else {
1870 self.putBackToken(token);
1871 continue;
1872 }
1873 },
17331874
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 {
1875 State.UnwrapExpressionBegin => |opt_ctx| {
1876 stack.append(State { .UnwrapExpressionEnd = opt_ctx }) catch unreachable;
1877 try stack.append(State { .BoolOrExpressionBegin = opt_ctx });
1878 continue;
1879 },
1880
1881 State.UnwrapExpressionEnd => |opt_ctx| {
1882 const lhs = opt_ctx.get() ?? continue;
1883
1884 const token = self.getNextToken();
1885 switch (token.id) {
1886 Token.Id.Keyword_catch, Token.Id.QuestionMarkQuestionMark => {
1887 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
1888 ast.NodeInfixOp {
17451889 .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,
1890 .lhs = lhs,
1891 .op_token = token,
1892 .op = switch (token.id) {
1893 Token.Id.Keyword_catch => ast.NodeInfixOp.InfixOp { .Catch = null },
1894 Token.Id.QuestionMarkQuestionMark => ast.NodeInfixOp.InfixOp { .UnwrapMaybe = void{} },
1895 else => unreachable,
1896 },
1897 .rhs = undefined,
17581898 }
17591899 );
1760 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1900
1901 stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1902 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
1903
1904 if (node.op == ast.NodeInfixOp.InfixOp.Catch) {
1905 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.op.Catch } });
1906 }
17611907 continue;
17621908 },
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;
1909 else => {
1910 self.putBackToken(token);
17831911 continue;
17841912 },
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;
1913 }
1914 },
17951915
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
1916 State.BoolOrExpressionBegin => |opt_ctx| {
1917 stack.append(State { .BoolOrExpressionEnd = opt_ctx }) catch unreachable;
1918 try stack.append(State { .BoolAndExpressionBegin = opt_ctx });
1919 continue;
1920 },
18021921
1803 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeAsm,
1804 ast.NodeAsm {
1922 State.BoolOrExpressionEnd => |opt_ctx| {
1923 const lhs = opt_ctx.get() ?? continue;
1924
1925 const token = self.getNextToken();
1926 switch (token.id) {
1927 Token.Id.Keyword_or => {
1928 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
1929 ast.NodeInfixOp {
18051930 .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,
1931 .lhs = lhs,
1932 .op_token = token,
1933 .op = ast.NodeInfixOp.InfixOp.BoolOr,
1934 .rhs = undefined,
18141935 }
18151936 );
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;
1937 stack.append(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1938 try stack.append(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });
18371939 continue;
18381940 },
18391941 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 }
1942 self.putBackToken(token);
18431943 continue;
1844 }
1944 },
18451945 }
18461946 },
18471947
1848 State.SliceOrArrayAccess => |node| {
1849 var token = self.getNextToken();
1948 State.BoolAndExpressionBegin => |opt_ctx| {
1949 stack.append(State { .BoolAndExpressionEnd = opt_ctx }) catch unreachable;
1950 try stack.append(State { .ComparisonExpressionBegin = opt_ctx });
1951 continue;
1952 },
1953
1954 State.BoolAndExpressionEnd => |opt_ctx| {
1955 const lhs = opt_ctx.get() ?? continue;
18501956
1957 const token = self.getNextToken();
18511958 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,
1959 Token.Id.Keyword_and => {
1960 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
1961 ast.NodeInfixOp {
1962 .base = undefined,
1963 .lhs = lhs,
1964 .op_token = token,
1965 .op = ast.NodeInfixOp.InfixOp.BoolAnd,
1966 .rhs = undefined,
18581967 }
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;
1968 );
1969 stack.append(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1970 try stack.append(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } });
18781971 continue;
18791972 },
18801973 else => {
1881 try self.parseError(&stack, token, "expected ']' or '..', found {}", @tagName(token.id));
1974 self.putBackToken(token);
18821975 continue;
1883 }
1976 },
18841977 }
18851978 },
18861979
1980 State.ComparisonExpressionBegin => |opt_ctx| {
1981 stack.append(State { .ComparisonExpressionEnd = opt_ctx }) catch unreachable;
1982 try stack.append(State { .BinaryOrExpressionBegin = opt_ctx });
1983 continue;
1984 },
18871985
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;
1986 State.ComparisonExpressionEnd => |opt_ctx| {
1987 const lhs = opt_ctx.get() ?? continue;
19001988
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));
1989 const token = self.getNextToken();
1990 if (tokenIdToComparison(token.id)) |comp_id| {
1991 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
1992 ast.NodeInfixOp {
1993 .base = undefined,
1994 .lhs = lhs,
1995 .op_token = token,
1996 .op = comp_id,
1997 .rhs = undefined,
1998 }
1999 );
2000 stack.append(State { .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2001 try stack.append(State { .BinaryOrExpressionBegin = OptionalCtx { .Required = &node.rhs } });
19042002 continue;
1905 };
2003 } else {
2004 self.putBackToken(token);
2005 continue;
2006 }
2007 },
19062008
1907 _ = (try self.expectToken(&stack, Token.Id.LParen)) ?? continue;
1908 try stack.append(State { .ExpectToken = Token.Id.RParen });
2009 State.BinaryOrExpressionBegin => |opt_ctx| {
2010 stack.append(State { .BinaryOrExpressionEnd = opt_ctx }) catch unreachable;
2011 try stack.append(State { .BinaryXorExpressionBegin = opt_ctx });
2012 continue;
2013 },
19092014
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);
2015 State.BinaryOrExpressionEnd => |opt_ctx| {
2016 const lhs = opt_ctx.get() ?? continue;
19192017
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 } });
2018 const token = self.getNextToken();
2019 switch (token.id) {
2020 Token.Id.Pipe => {
2021 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2022 ast.NodeInfixOp {
2023 .base = undefined,
2024 .lhs = lhs,
2025 .op_token = token,
2026 .op = ast.NodeInfixOp.InfixOp.BitOr,
2027 .rhs = undefined,
2028 }
2029 );
2030 stack.append(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2031 try stack.append(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2032 continue;
19282033 },
19292034 else => {
1930 try self.parseError(&stack, symbol_or_arrow, "expected '->' or {}, found {}",
1931 @tagName(Token.Id.Identifier),
1932 @tagName(symbol_or_arrow.id));
2035 self.putBackToken(token);
19332036 continue;
19342037 },
19352038 }
19362039 },
19372040
1938 State.AsmInputItems => |items| {
1939 const lbracket = self.getNextToken();
1940 if (lbracket.id != Token.Id.LBracket) {
1941 self.putBackToken(lbracket);
1942 continue;
1943 }
1944
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
1960 const node = try self.createNode(arena, ast.NodeAsmInput,
1961 ast.NodeAsmInput {
1962 .base = undefined,
1963 .symbolic_name = try self.createLiteral(arena, ast.NodeIdentifier, symbolic_name),
1964 .constraint = constraint,
1965 .expr = undefined,
1966 }
1967 );
1968 try items.append(node);
1969 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
1970 },
1971
1972 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
1980 stack.append(State { .AsmClopperItems = items }) catch unreachable;
1981 try stack.append(State { .IfToken = Token.Id.Comma });
2041 State.BinaryXorExpressionBegin => |opt_ctx| {
2042 stack.append(State { .BinaryXorExpressionEnd = opt_ctx }) catch unreachable;
2043 try stack.append(State { .BinaryAndExpressionBegin = opt_ctx });
2044 continue;
19822045 },
19832046
1984 State.ExprListItemOrEnd => |list_state| {
1985 var token = self.getNextToken();
2047 State.BinaryXorExpressionEnd => |opt_ctx| {
2048 const lhs = opt_ctx.get() ?? continue;
19862049
1987 const IdTag = @TagType(Token.Id);
1988 if (IdTag(list_state.end) == token.id) {
1989 *list_state.ptr = token;
1990 continue;
2050 const token = self.getNextToken();
2051 switch (token.id) {
2052 Token.Id.Caret => {
2053 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2054 ast.NodeInfixOp {
2055 .base = undefined,
2056 .lhs = lhs,
2057 .op_token = token,
2058 .op = ast.NodeInfixOp.InfixOp.BitXor,
2059 .rhs = undefined,
2060 }
2061 );
2062 stack.append(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2063 try stack.append(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2064 continue;
2065 },
2066 else => {
2067 self.putBackToken(token);
2068 continue;
2069 },
19912070 }
1992
1993 self.putBackToken(token);
1994 stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable;
1995 try stack.append(State { .Expression = DestPtr{ .Field = try list_state.list.addOne() } });
19962071 },
19972072
1998 State.FieldInitListItemOrEnd => |list_state| {
1999 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
2000 *list_state.ptr = rbrace;
2001 continue;
2002 }
2003
2004 const node = try self.createNode(arena, ast.NodeFieldInitializer,
2005 ast.NodeFieldInitializer {
2006 .base = undefined,
2007 .period_token = undefined,
2008 .name_token = undefined,
2009 .expr = undefined,
2010 }
2011 );
2012 try list_state.list.append(node);
2013
2014 stack.append(State { .FieldInitListCommaOrEnd = list_state }) catch unreachable;
2015 try stack.append(State { .Expression = DestPtr{.Field = &node.expr} });
2016 try stack.append(State { .ExpectToken = Token.Id.Equal });
2017 try stack.append(State {
2018 .ExpectTokenSave = ExpectTokenSave {
2019 .id = Token.Id.Identifier,
2020 .ptr = &node.name_token,
2021 }
2022 });
2023 try stack.append(State {
2024 .ExpectTokenSave = ExpectTokenSave {
2025 .id = Token.Id.Period,
2026 .ptr = &node.period_token,
2027 }
2028 });
2073 State.BinaryAndExpressionBegin => |opt_ctx| {
2074 stack.append(State { .BinaryAndExpressionEnd = opt_ctx }) catch unreachable;
2075 try stack.append(State { .BitShiftExpressionBegin = opt_ctx });
2076 continue;
20292077 },
20302078
2031 State.IdentifierListItemOrEnd => |list_state| {
2032 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
2033 *list_state.ptr = rbrace;
2034 continue;
2035 }
2036
2037 const node = try self.createLiteral(arena, ast.NodeIdentifier, Token(undefined));
2038 try list_state.list.append(node);
2079 State.BinaryAndExpressionEnd => |opt_ctx| {
2080 const lhs = opt_ctx.get() ?? continue;
20392081
2040 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 });
2082 const token = self.getNextToken();
2083 switch (token.id) {
2084 Token.Id.Ampersand => {
2085 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2086 ast.NodeInfixOp {
2087 .base = undefined,
2088 .lhs = lhs,
2089 .op_token = token,
2090 .op = ast.NodeInfixOp.InfixOp.BitAnd,
2091 .rhs = undefined,
2092 }
2093 );
2094 stack.append(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2095 try stack.append(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2096 continue;
2097 },
2098 else => {
2099 self.putBackToken(token);
2100 continue;
2101 },
2102 }
20472103 },
20482104
2049 State.SwitchCaseOrEnd => |list_state| {
2050 if (self.eatToken(Token.Id.RBrace)) |rbrace| {
2051 *list_state.ptr = rbrace;
2052 continue;
2053 }
2105 State.BitShiftExpressionBegin => |opt_ctx| {
2106 stack.append(State { .BitShiftExpressionEnd = opt_ctx }) catch unreachable;
2107 try stack.append(State { .AdditionExpressionBegin = opt_ctx });
2108 continue;
2109 },
20542110
2055 const node = try self.createNode(arena, ast.NodeSwitchCase,
2056 ast.NodeSwitchCase {
2057 .base = undefined,
2058 .items = ArrayList(&ast.Node).init(arena),
2059 .payload = null,
2060 .expr = undefined,
2061 }
2062 );
2063 try list_state.list.append(node);
2064 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 });
2111 State.BitShiftExpressionEnd => |opt_ctx| {
2112 const lhs = opt_ctx.get() ?? continue;
20672113
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,
2071 ast.NodeSwitchElse {
2114 const token = self.getNextToken();
2115 if (tokenIdToBitShift(token.id)) |bitshift_id| {
2116 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2117 ast.NodeInfixOp {
20722118 .base = undefined,
2073 .token = maybe_else,
2119 .lhs = lhs,
2120 .op_token = token,
2121 .op = bitshift_id,
2122 .rhs = undefined,
20742123 }
20752124 );
2076 try stack.append(State { .ExpectToken = Token.Id.EqualAngleBracketRight });
2125 stack.append(State { .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2126 try stack.append(State { .AdditionExpressionBegin = OptionalCtx { .Required = &node.rhs } });
20772127 continue;
20782128 } else {
2079 self.putBackToken(maybe_else);
2080 try stack.append(State { .SwitchCaseItem = &node.items });
2129 self.putBackToken(token);
20812130 continue;
20822131 }
20832132 },
20842133
2085 State.SwitchCaseItem => |case_items| {
2086 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 });
2134 State.AdditionExpressionBegin => |opt_ctx| {
2135 stack.append(State { .AdditionExpressionEnd = opt_ctx }) catch unreachable;
2136 try stack.append(State { .MultiplyExpressionBegin = opt_ctx });
20972137 continue;
20982138 },
20992139
2100 State.FieldListCommaOrEnd => |container_decl| {
2101 try self.commaOrEnd(&stack, Token.Id.RBrace, &container_decl.rbrace_token,
2102 State { .ContainerDecl = container_decl });
2103 continue;
2104 },
2140 State.AdditionExpressionEnd => |opt_ctx| {
2141 const lhs = opt_ctx.get() ?? continue;
21052142
2106 State.IdentifierListCommaOrEnd => |list_state| {
2107 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .IdentifierListItemOrEnd = list_state });
2108 continue;
2143 const token = self.getNextToken();
2144 if (tokenIdToAddition(token.id)) |add_id| {
2145 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2146 ast.NodeInfixOp {
2147 .base = undefined,
2148 .lhs = lhs,
2149 .op_token = token,
2150 .op = add_id,
2151 .rhs = undefined,
2152 }
2153 );
2154 stack.append(State { .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2155 try stack.append(State { .MultiplyExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2156 continue;
2157 } else {
2158 self.putBackToken(token);
2159 continue;
2160 }
21092161 },
21102162
2111 State.SwitchCaseCommaOrEnd => |list_state| {
2112 try self.commaOrEnd(&stack, Token.Id.RBrace, list_state.ptr, State { .SwitchCaseOrEnd = list_state });
2163 State.MultiplyExpressionBegin => |opt_ctx| {
2164 stack.append(State { .MultiplyExpressionEnd = opt_ctx }) catch unreachable;
2165 try stack.append(State { .CurlySuffixExpressionBegin = opt_ctx });
21132166 continue;
21142167 },
21152168
2116 State.SwitchCaseItemCommaOrEnd => |case_items| {
2117 try self.commaOrEnd(&stack, Token.Id.EqualAngleBracketRight, null, State { .SwitchCaseItem = case_items });
2118 continue;
2119 },
2169 State.MultiplyExpressionEnd => |opt_ctx| {
2170 const lhs = opt_ctx.get() ?? continue;
21202171
2121 State.Else => |dest| {
2122 const else_token = self.getNextToken();
2123 if (else_token.id != Token.Id.Keyword_else) {
2124 self.putBackToken(else_token);
2172 const token = self.getNextToken();
2173 if (tokenIdToMultiply(token.id)) |mult_id| {
2174 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2175 ast.NodeInfixOp {
2176 .base = undefined,
2177 .lhs = lhs,
2178 .op_token = token,
2179 .op = mult_id,
2180 .rhs = undefined,
2181 }
2182 );
2183 stack.append(State { .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2184 try stack.append(State { .CurlySuffixExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2185 continue;
2186 } else {
2187 self.putBackToken(token);
21252188 continue;
21262189 }
2190 },
21272191
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 });
2192 State.CurlySuffixExpressionBegin => |opt_ctx| {
2193 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx }) catch unreachable;
2194 try stack.append(State { .IfToken = Token.Id.LBrace });
2195 try stack.append(State { .TypeExprBegin = opt_ctx });
2196 continue;
21402197 },
21412198
2142 State.WhileContinueExpr => |dest| {
2143 const colon = self.getNextToken();
2144 if (colon.id != Token.Id.Colon) {
2145 self.putBackToken(colon);
2199 State.CurlySuffixExpressionEnd => |opt_ctx| {
2200 const lhs = opt_ctx.get() ?? continue;
2201
2202 if (self.isPeekToken(Token.Id.Period)) {
2203 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
2204 ast.NodeSuffixOp {
2205 .base = undefined,
2206 .lhs = lhs,
2207 .op = ast.NodeSuffixOp.SuffixOp {
2208 .StructInitializer = ArrayList(&ast.NodeFieldInitializer).init(arena),
2209 },
2210 .rtoken = undefined,
2211 }
2212 );
2213 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2214 try stack.append(State { .IfToken = Token.Id.LBrace });
2215 try stack.append(State {
2216 .FieldInitListItemOrEnd = ListSave(&ast.NodeFieldInitializer) {
2217 .list = &node.op.StructInitializer,
2218 .ptr = &node.rtoken,
2219 }
2220 });
2221 continue;
2222 } else {
2223 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
2224 ast.NodeSuffixOp {
2225 .base = undefined,
2226 .lhs = lhs,
2227 .op = ast.NodeSuffixOp.SuffixOp {
2228 .ArrayInitializer = ArrayList(&ast.Node).init(arena),
2229 },
2230 .rtoken = undefined,
2231 }
2232 );
2233 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2234 try stack.append(State { .IfToken = Token.Id.LBrace });
2235 try stack.append(State {
2236 .ExprListItemOrEnd = ExprListCtx {
2237 .list = &node.op.ArrayInitializer,
2238 .end = Token.Id.RBrace,
2239 .ptr = &node.rtoken,
2240 }
2241 });
21462242 continue;
21472243 }
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 } });
21522244 },
21532245
2154 State.SuspendBody => |suspend_node| {
2155 if (suspend_node.payload != null) {
2156 try stack.append(State { .AssignmentExpressionBegin = DestPtr { .NullableField = &suspend_node.body } });
2157 }
2246 State.TypeExprBegin => |opt_ctx| {
2247 stack.append(State { .TypeExprEnd = opt_ctx }) catch unreachable;
2248 try stack.append(State { .PrefixOpExpression = opt_ctx });
21582249 continue;
21592250 },
21602251
2161 State.AsyncEnd => |ctx| {
2162 const node = ctx.dest_ptr.get();
2163
2164 switch (node.id) {
2165 ast.Node.Id.FnProto => {
2166 const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node);
2167 fn_proto.async_attr = ctx.attribute;
2168 },
2169 ast.Node.Id.SuffixOp => {
2170 const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node);
2171 if (suffix_op.op == ast.NodeSuffixOp.SuffixOp.Call) {
2172 suffix_op.op.Call.async_attr = ctx.attribute;
2173 continue;
2174 }
2252 State.TypeExprEnd => |opt_ctx| {
2253 const lhs = opt_ctx.get() ?? continue;
21752254
2176 try self.parseError(&stack, node.firstToken(), "expected call or fn proto, found {}.",
2177 @tagName(suffix_op.op));
2255 const token = self.getNextToken();
2256 switch (token.id) {
2257 Token.Id.Bang => {
2258 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2259 ast.NodeInfixOp {
2260 .base = undefined,
2261 .lhs = lhs,
2262 .op_token = token,
2263 .op = ast.NodeInfixOp.InfixOp.ErrorUnion,
2264 .rhs = undefined,
2265 }
2266 );
2267 stack.append(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;
2268 try stack.append(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } });
21782269 continue;
21792270 },
21802271 else => {
2181 try self.parseError(&stack, node.firstToken(), "expected call or fn proto, found {}.",
2182 @tagName(node.id));
2272 self.putBackToken(token);
21832273 continue;
2184 }
2185 }
2186 },
2187
2188 State.Payload => |dest| {
2189 const lpipe = self.getNextToken();
2190 if (lpipe.id != Token.Id.Pipe) {
2191 self.putBackToken(lpipe);
2192 continue;
2274 },
21932275 }
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 );
22052276 },
22062277
2207 State.PointerPayload => |dest| {
2208 const lpipe = self.getNextToken();
2209 if (lpipe.id != Token.Id.Pipe) {
2210 self.putBackToken(lpipe);
2211 continue;
2212 }
2278 State.PrefixOpExpression => |opt_ctx| {
2279 const token = self.getNextToken();
2280 if (tokenIdToPrefixOp(token.id)) |prefix_id| {
2281 var node = try self.createToCtxNode(arena, opt_ctx, ast.NodePrefixOp,
2282 ast.NodePrefixOp {
2283 .base = undefined,
2284 .op_token = token,
2285 .op = prefix_id,
2286 .rhs = undefined,
2287 }
2288 );
22132289
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;
2290 if (token.id == Token.Id.AsteriskAsterisk) {
2291 const child = try self.createNode(arena, ast.NodePrefixOp,
2292 ast.NodePrefixOp {
2293 .base = undefined,
2294 .op_token = token,
2295 .op = prefix_id,
2296 .rhs = undefined,
2297 }
2298 );
2299 node.rhs = &child.base;
2300 node = child;
22212301 }
2222 };
22232302
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
2303 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
2304 if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {
2305 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
22332306 }
2234 );
2235 },
2236
2237 State.PointerIndexPayload => |dest| {
2238 const lpipe = self.getNextToken();
2239 if (lpipe.id != Token.Id.Pipe) {
2240 self.putBackToken(lpipe);
2307 continue;
2308 } else {
2309 self.putBackToken(token);
2310 stack.append(State { .SuffixOpExpressionBegin = opt_ctx }) catch unreachable;
22412311 continue;
22422312 }
2313 },
22432314
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;
2315 State.SuffixOpExpressionBegin => |opt_ctx| {
2316 const token = self.getNextToken();
2317 switch (token.id) {
2318 Token.Id.Keyword_async => {
2319 const async_node = try self.createNode(arena, ast.NodeAsyncAttribute,
2320 ast.NodeAsyncAttribute {
2321 .base = undefined,
2322 .async_token = token,
2323 .allocator_type = null,
2324 .rangle_bracket = null,
2325 }
2326 );
2327 stack.append(State {
2328 .AsyncEnd = AsyncEndCtx {
2329 .ctx = opt_ctx,
2330 .attribute = async_node,
2331 }
2332 }) catch unreachable;
2333 try stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() });
2334 try stack.append(State { .PrimaryExpression = opt_ctx.toRequired() });
2335 try stack.append(State { .AsyncAllocator = async_node });
2336 continue;
2337 },
2338 else => {
2339 self.putBackToken(token);
2340 stack.append(State { .SuffixOpExpressionEnd = opt_ctx }) catch unreachable;
2341 try stack.append(State { .PrimaryExpression = opt_ctx });
2342 continue;
22602343 }
2344 }
2345 },
22612346
2262 const symbol = (try self.expectToken(&stack, Token.Id.Identifier)) ?? continue;
2263 break :blk try self.createLiteral(arena, ast.NodeIdentifier, symbol);
2264 };
2347 State.SuffixOpExpressionEnd => |opt_ctx| {
2348 const lhs = opt_ctx.get() ?? continue;
22652349
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 );
2350 const token = self.getNextToken();
2351 switch (token.id) {
2352 Token.Id.LParen => {
2353 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
2354 ast.NodeSuffixOp {
2355 .base = undefined,
2356 .lhs = lhs,
2357 .op = ast.NodeSuffixOp.SuffixOp {
2358 .Call = ast.NodeSuffixOp.CallInfo {
2359 .params = ArrayList(&ast.Node).init(arena),
2360 .async_attr = null,
2361 }
2362 },
2363 .rtoken = undefined,
2364 }
2365 );
2366 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2367 try stack.append(State {
2368 .ExprListItemOrEnd = ExprListCtx {
2369 .list = &node.op.Call.params,
2370 .end = Token.Id.RParen,
2371 .ptr = &node.rtoken,
2372 }
2373 });
2374 continue;
2375 },
2376 Token.Id.LBracket => {
2377 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
2378 ast.NodeSuffixOp {
2379 .base = undefined,
2380 .lhs = lhs,
2381 .op = ast.NodeSuffixOp.SuffixOp {
2382 .ArrayAccess = undefined,
2383 },
2384 .rtoken = undefined
2385 }
2386 );
2387 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2388 try stack.append(State { .SliceOrArrayAccess = node });
2389 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayAccess }});
2390 continue;
2391 },
2392 Token.Id.Period => {
2393 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
2394 ast.NodeInfixOp {
2395 .base = undefined,
2396 .lhs = lhs,
2397 .op_token = token,
2398 .op = ast.NodeInfixOp.InfixOp.Period,
2399 .rhs = undefined,
2400 }
2401 );
2402 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2403 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.rhs } });
2404 continue;
2405 },
2406 else => {
2407 self.putBackToken(token);
2408 continue;
2409 },
2410 }
22772411 },
22782412
2279 State.AddrOfModifiers => |addr_of_info| {
2280 var token = self.getNextToken();
2413 State.PrimaryExpression => |opt_ctx| {
2414 const token = self.getNextToken();
22812415 switch (token.id) {
2282 Token.Id.Keyword_align => {
2283 stack.append(state) catch unreachable;
2284 if (addr_of_info.align_expr != null) {
2285 try self.parseError(&stack, token, "multiple align qualifiers");
2286 continue;
2287 }
2288 try stack.append(State { .ExpectToken = Token.Id.RParen });
2289 try stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_info.align_expr} });
2290 try stack.append(State { .ExpectToken = Token.Id.LParen });
2416 Token.Id.IntegerLiteral => {
2417 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base);
2418 continue;
2419 },
2420 Token.Id.FloatLiteral => {
2421 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeFloatLiteral, token)).base);
2422 continue;
2423 },
2424 Token.Id.CharLiteral => {
2425 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeCharLiteral, token)).base);
2426 continue;
2427 },
2428 Token.Id.Keyword_undefined => {
2429 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeUndefinedLiteral, token)).base);
2430 continue;
2431 },
2432 Token.Id.Keyword_true, Token.Id.Keyword_false => {
2433 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeBoolLiteral, token)).base);
22912434 continue;
22922435 },
2293 Token.Id.Keyword_const => {
2294 stack.append(state) catch unreachable;
2295 if (addr_of_info.const_token != null) {
2296 try self.parseError(&stack, token, "duplicate qualifier: const");
2297 continue;
2298 }
2299 addr_of_info.const_token = token;
2436 Token.Id.Keyword_null => {
2437 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeNullLiteral, token)).base);
23002438 continue;
23012439 },
2302 Token.Id.Keyword_volatile => {
2303 stack.append(state) catch unreachable;
2304 if (addr_of_info.volatile_token != null) {
2305 try self.parseError(&stack, token, "duplicate qualifier: volatile");
2306 continue;
2307 }
2308 addr_of_info.volatile_token = token;
2440 Token.Id.Keyword_this => {
2441 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeThisLiteral, token)).base);
23092442 continue;
23102443 },
2311 else => {
2312 self.putBackToken(token);
2444 Token.Id.Keyword_var => {
2445 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeVarType, token)).base);
23132446 continue;
23142447 },
2315 }
2316 },
2317
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 });
2322
2323 const next_token = self.getNextToken();
2324 if (next_token.id == Token.Id.Identifier) {
2325 fn_proto.name_token = next_token;
2326 continue;
2327 }
2328 self.putBackToken(next_token);
2329 continue;
2330 },
2331
2332 State.FnProtoAlign => |fn_proto| {
2333 stack.append(State { .FnProtoReturnType = fn_proto }) catch unreachable;
2334
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 }
2340
2341 continue;
2342 },
2343
2344 State.FnProtoReturnType => |fn_proto| {
2345 const token = self.getNextToken();
2346 switch (token.id) {
2347 Token.Id.Bang => {
2348 fn_proto.return_type = ast.NodeFnProto.ReturnType { .InferErrorSet = undefined };
2448 Token.Id.Keyword_unreachable => {
2449 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeUnreachable, token)).base);
2450 continue;
2451 },
2452 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
2453 opt_ctx.store((try self.parseStringLiteral(arena, token)) ?? unreachable);
2454 },
2455 Token.Id.LParen => {
2456 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeGroupedExpression,
2457 ast.NodeGroupedExpression {
2458 .base = undefined,
2459 .lparen = token,
2460 .expr = undefined,
2461 .rparen = undefined,
2462 }
2463 );
23492464 stack.append(State {
2350 .TypeExprBegin = DestPtr {.Field = &fn_proto.return_type.InferErrorSet},
2465 .ExpectTokenSave = ExpectTokenSave {
2466 .id = Token.Id.RParen,
2467 .ptr = &node.rparen,
2468 }
23512469 }) catch unreachable;
2470 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
23522471 continue;
23532472 },
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;
2473 Token.Id.Builtin => {
2474 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeBuiltinCall,
2475 ast.NodeBuiltinCall {
2476 .base = undefined,
2477 .builtin_token = token,
2478 .params = ArrayList(&ast.Node).init(arena),
2479 .rparen_token = undefined,
23622480 }
2363 }
2364
2365 self.putBackToken(token);
2366 fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined };
2481 );
23672482 stack.append(State {
2368 .TypeExprBegin = DestPtr {.Field = &fn_proto.return_type.Explicit},
2483 .ExprListItemOrEnd = ExprListCtx {
2484 .list = &node.params,
2485 .end = Token.Id.RParen,
2486 .ptr = &node.rparen_token,
2487 }
23692488 }) catch unreachable;
2489 try stack.append(State { .ExpectToken = Token.Id.LParen, });
23702490 continue;
23712491 },
2372 }
2373 },
2374
2375 State.ParamDecl => |fn_proto| {
2376 if (self.eatToken(Token.Id.RParen)) |_| {
2377 continue;
2378 }
2379 const param_decl = try self.createAttachNode(arena, &fn_proto.params, ast.NodeParamDecl,
2380 ast.NodeParamDecl {
2381 .base = undefined,
2382 .comptime_token = null,
2383 .noalias_token = null,
2384 .name_token = null,
2385 .type_node = undefined,
2386 .var_args_token = null,
2492 Token.Id.LBracket => {
2493 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePrefixOp,
2494 ast.NodePrefixOp {
2495 .base = undefined,
2496 .op_token = token,
2497 .op = undefined,
2498 .rhs = undefined,
2499 }
2500 );
2501 stack.append(State { .SliceOrArrayType = node }) catch unreachable;
23872502 },
2388 );
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);
2399 }
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;
2404 continue;
2405 }
2406
2407 stack.append(State { .ParamDecl = fn_proto }) catch unreachable;
2408 try stack.append(State.ParamDeclComma);
2409 try stack.append(State {
2410 .TypeExprBegin = DestPtr {.Field = &param_decl.type_node}
2411 });
2412 continue;
2413 },
2503 Token.Id.Keyword_error => {
2504 stack.append(State {
2505 .ErrorTypeOrSetDecl = ErrorTypeOrSetDeclCtx {
2506 .error_token = token,
2507 .opt_ctx = opt_ctx
2508 }
2509 }) catch unreachable;
2510 },
2511 Token.Id.Keyword_packed => {
2512 stack.append(State {
2513 .ContainerExtern = ContainerExternCtx {
2514 .opt_ctx = opt_ctx,
2515 .ltoken = token,
2516 .layout = ast.NodeContainerDecl.Layout.Packed,
2517 },
2518 }) catch unreachable;
2519 },
2520 Token.Id.Keyword_extern => {
2521 // TODO: Here, we eat two tokens in the same state. This prevents comments
2522 // from being between these two tokens.
2523 const next = self.getNextToken();
2524 if (next.id == Token.Id.Keyword_fn) {
2525 const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.NodeFnProto,
2526 ast.NodeFnProto {
2527 .base = undefined,
2528 .visib_token = null,
2529 .name_token = null,
2530 .fn_token = next,
2531 .params = ArrayList(&ast.Node).init(arena),
2532 .return_type = undefined,
2533 .var_args_token = null,
2534 .extern_export_inline_token = token,
2535 .cc_token = null,
2536 .async_attr = null,
2537 .body_node = null,
2538 .lib_name = null,
2539 .align_expr = null,
2540 }
2541 );
2542 stack.append(State { .FnProto = fn_proto }) catch unreachable;
2543 continue;
2544 }
24142545
2415 State.ParamDeclComma => {
2416 const token = self.getNextToken();
2417 switch (token.id) {
2418 Token.Id.RParen => {
2419 _ = stack.pop(); // pop off the ParamDecl
2420 continue;
2546 self.putBackToken(next);
2547 stack.append(State {
2548 .ContainerExtern = ContainerExternCtx {
2549 .opt_ctx = opt_ctx,
2550 .ltoken = token,
2551 .layout = ast.NodeContainerDecl.Layout.Extern,
2552 },
2553 }) catch unreachable;
24212554 },
2422 Token.Id.Comma => continue,
2423 else => {
2424 try self.parseError(&stack, token, "expected ',' or ')', found {}", @tagName(token.id));
2425 continue;
2555 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
2556 self.putBackToken(token);
2557 stack.append(State {
2558 .ContainerExtern = ContainerExternCtx {
2559 .opt_ctx = opt_ctx,
2560 .ltoken = token,
2561 .layout = ast.NodeContainerDecl.Layout.Auto,
2562 },
2563 }) catch unreachable;
24262564 },
2427 }
2428 },
2565 Token.Id.Identifier => {
2566 // TODO: Here, we eat two tokens in the same state. This prevents comments
2567 // from being between these two tokens.
2568 const next = self.getNextToken();
2569 if (next.id != Token.Id.Colon) {
2570 self.putBackToken(next);
2571 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeIdentifier, token)).base);
2572 continue;
2573 }
24292574
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 {
2575 stack.append(State {
2576 .LabeledExpression = LabelCtx {
2577 .label = token,
2578 .opt_ctx = opt_ctx
2579 }
2580 }) catch unreachable;
2581 continue;
2582 },
2583 Token.Id.Keyword_fn => {
2584 const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.NodeFnProto,
2585 ast.NodeFnProto {
24362586 .base = undefined,
2437 .label = null,
2438 .lbrace = token,
2439 .statements = ArrayList(&ast.Node).init(arena),
2440 .rbrace = undefined,
2587 .visib_token = null,
2588 .name_token = null,
2589 .fn_token = token,
2590 .params = ArrayList(&ast.Node).init(arena),
2591 .return_type = undefined,
2592 .var_args_token = null,
2593 .extern_export_inline_token = null,
2594 .cc_token = null,
2595 .async_attr = null,
2596 .body_node = null,
2597 .lib_name = null,
2598 .align_expr = null,
24412599 }
24422600 );
2443 fn_proto.body_node = &block.base;
2444 stack.append(State { .Block = block }) catch unreachable;
2601 stack.append(State { .FnProto = fn_proto }) catch unreachable;
24452602 continue;
24462603 },
2447 Token.Id.Semicolon => continue,
2448 else => {
2449 try self.parseError(&stack, token, "expected ';' or '{{', found {}", @tagName(token.id));
2604 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
2605 const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.NodeFnProto,
2606 ast.NodeFnProto {
2607 .base = undefined,
2608 .visib_token = null,
2609 .name_token = null,
2610 .fn_token = undefined,
2611 .params = ArrayList(&ast.Node).init(arena),
2612 .return_type = undefined,
2613 .var_args_token = null,
2614 .extern_export_inline_token = null,
2615 .cc_token = token,
2616 .async_attr = null,
2617 .body_node = null,
2618 .lib_name = null,
2619 .align_expr = null,
2620 }
2621 );
2622 stack.append(State { .FnProto = fn_proto }) catch unreachable;
2623 try stack.append(State {
2624 .ExpectTokenSave = ExpectTokenSave {
2625 .id = Token.Id.Keyword_fn,
2626 .ptr = &fn_proto.fn_token
2627 }
2628 });
24502629 continue;
24512630 },
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 {
2631 Token.Id.Keyword_asm => {
2632 const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeAsm,
2633 ast.NodeAsm {
24612634 .base = undefined,
2462 .label = ctx.label,
2463 .lbrace = token,
2464 .statements = ArrayList(&ast.Node).init(arena),
2465 .rbrace = undefined,
2635 .asm_token = token,
2636 .volatile_token = null,
2637 .template = undefined,
2638 //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),
2639 .outputs = ArrayList(&ast.NodeAsmOutput).init(arena),
2640 .inputs = ArrayList(&ast.NodeAsmInput).init(arena),
2641 .cloppers = ArrayList(&ast.Node).init(arena),
2642 .rparen = undefined,
24662643 }
24672644 );
2468 stack.append(State { .Block = block }) catch unreachable;
2469 continue;
2470 },
2471 Token.Id.Keyword_while => {
24722645 stack.append(State {
2473 .While = LoopCtx {
2474 .label = ctx.label,
2475 .inline_token = null,
2476 .loop_token = token,
2477 .dest_ptr = ctx.dest_ptr,
2646 .ExpectTokenSave = ExpectTokenSave {
2647 .id = Token.Id.RParen,
2648 .ptr = &node.rparen,
24782649 }
24792650 }) 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,
2651 try stack.append(State { .AsmClopperItems = &node.cloppers });
2652 try stack.append(State { .IfToken = Token.Id.Colon });
2653 try stack.append(State { .AsmInputItems = &node.inputs });
2654 try stack.append(State { .IfToken = Token.Id.Colon });
2655 try stack.append(State { .AsmOutputItems = &node.outputs });
2656 try stack.append(State { .IfToken = Token.Id.Colon });
2657 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.template } });
2658 try stack.append(State { .ExpectToken = Token.Id.LParen });
2659 try stack.append(State {
2660 .OptionalTokenSave = OptionalTokenSave {
2661 .id = Token.Id.Keyword_volatile,
2662 .ptr = &node.volatile_token,
24892663 }
2490 }) catch unreachable;
2491 continue;
2664 });
24922665 },
24932666 Token.Id.Keyword_inline => {
24942667 stack.append(State {
24952668 .Inline = InlineCtx {
2496 .label = ctx.label,
2669 .label = null,
24972670 .inline_token = token,
2498 .dest_ptr = ctx.dest_ptr,
2671 .opt_ctx = opt_ctx,
24992672 }
25002673 }) catch unreachable;
25012674 continue;
25022675 },
25032676 else => {
2504 try self.parseError(&stack, token, "expected 'while', 'for', 'inline' or '{{', found {}", @tagName(token.id));
2677 if (!try self.parseBlockExpr(&stack, arena, opt_ctx, token)) {
2678 self.putBackToken(token);
2679 if (opt_ctx != OptionalCtx.Optional) {
2680 return self.parseError(token, "expected primary expression, found {}", @tagName(token.id));
2681 }
2682 }
25052683 continue;
2506 },
2684 }
25072685 }
25082686 },
25092687
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 },
2688
2689 State.ErrorTypeOrSetDecl => |ctx| {
2690 if (self.eatToken(Token.Id.LBrace) == null) {
2691 ctx.opt_ctx.store(&(try self.createLiteral(arena, ast.NodeErrorType, ctx.error_token)).base);
2692 continue;
25392693 }
2540 },
25412694
2542 State.While => |ctx| {
2543 const node = try self.createToDestNode(arena, ctx.dest_ptr, ast.NodeWhile,
2544 ast.NodeWhile {
2695 const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeErrorSetDecl,
2696 ast.NodeErrorSetDecl {
25452697 .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,
2698 .error_token = ctx.error_token,
2699 .decls = ArrayList(&ast.Node).init(arena),
2700 .rbrace_token = undefined,
25542701 }
25552702 );
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 },
25642703
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,
2704 stack.append(State {
2705 .IdentifierListItemOrEnd = ListSave(&ast.Node) {
2706 .list = &node.decls,
2707 .ptr = &node.rbrace_token,
25762708 }
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 });
2709 }) catch unreachable;
2710 continue;
25842711 },
2585
2586 State.Block => |block| {
2712 State.StringLiteral => |opt_ctx| {
25872713 const token = self.getNextToken();
2588 switch (token.id) {
2589 Token.Id.RBrace => {
2590 block.rbrace = token;
2591 continue;
2592 },
2593 else => {
2714 opt_ctx.store(
2715 (try self.parseStringLiteral(arena, token)) ?? {
25942716 self.putBackToken(token);
2595 stack.append(State { .Block = block }) catch unreachable;
2596 try stack.append(State { .Statement = block });
2717 if (opt_ctx != OptionalCtx.Optional) {
2718 return self.parseError(token, "expected primary expression, found {}", @tagName(token.id));
2719 }
2720
25972721 continue;
2598 },
2722 }
2723 );
2724 },
2725 State.Identifier => |opt_ctx| {
2726 if (self.eatToken(Token.Id.Identifier)) |ident_token| {
2727 opt_ctx.store(&(try self.createLiteral(arena, ast.NodeIdentifier, ident_token)).base);
2728 continue;
2729 }
2730
2731 if (opt_ctx != OptionalCtx.Optional) {
2732 const token = self.getNextToken();
2733 return self.parseError(token, "expected identifier, found {}", @tagName(token.id));
25992734 }
26002735 },
26012736
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 }
2737
2738 State.ExpectToken => |token_id| {
2739 _ = try self.expectToken(token_id);
2740 continue;
2741 },
2742 State.ExpectTokenSave => |expect_token_save| {
2743 *expect_token_save.ptr = try self.expectToken(expect_token_save.id);
2744 continue;
2745 },
2746 State.IfToken => |token_id| {
2747 if (self.eatToken(token_id)) |_| {
2748 continue;
26932749 }
26942750
2751 _ = stack.pop();
2752 continue;
26952753 },
2754 State.IfTokenSave => |if_token_save| {
2755 if (self.eatToken(if_token_save.id)) |token| {
2756 *if_token_save.ptr = token;
2757 continue;
2758 }
26962759
2697 State.Semicolon => |node_ptr| {
2698 const node = *node_ptr;
2699 if (requireSemiColon(node)) {
2700 _ = (try self.expectToken(&stack, Token.Id.Semicolon)) ?? continue;
2760 _ = stack.pop();
2761 continue;
2762 },
2763 State.OptionalTokenSave => |optional_token_save| {
2764 if (self.eatToken(optional_token_save.id)) |token| {
2765 *optional_token_save.ptr = token;
2766 continue;
27012767 }
2702 }
2768
2769 continue;
2770 },
27032771 }
27042772 }
27052773 }
......@@ -2807,10 +2875,10 @@ pub const Parser = struct {
28072875 }
28082876 }
28092877
2810 fn parseBlockExpr(self: &Parser, stack: &ArrayList(State), arena: &mem.Allocator, dest_ptr: &const DestPtr, token: &const Token) !bool {
2878 fn parseBlockExpr(self: &Parser, stack: &ArrayList(State), arena: &mem.Allocator, ctx: &const OptionalCtx, token: &const Token) !bool {
28112879 switch (token.id) {
28122880 Token.Id.Keyword_suspend => {
2813 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSuspend,
2881 const node = try self.createToCtxNode(arena, ctx, ast.NodeSuspend,
28142882 ast.NodeSuspend {
28152883 .base = undefined,
28162884 .suspend_token = *token,
......@@ -2820,11 +2888,11 @@ pub const Parser = struct {
28202888 );
28212889
28222890 stack.append(State { .SuspendBody = node }) catch unreachable;
2823 try stack.append(State { .Payload = &node.payload });
2891 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });
28242892 return true;
28252893 },
28262894 Token.Id.Keyword_if => {
2827 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeIf,
2895 const node = try self.createToCtxNode(arena, ctx, ast.NodeIf,
28282896 ast.NodeIf {
28292897 .base = undefined,
28302898 .if_token = *token,
......@@ -2836,10 +2904,10 @@ pub const Parser = struct {
28362904 );
28372905
28382906 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 });
2907 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
2908 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
28412909 try stack.append(State { .ExpectToken = Token.Id.RParen });
2842 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
2910 try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } });
28432911 try stack.append(State { .ExpectToken = Token.Id.LParen });
28442912 return true;
28452913 },
......@@ -2849,7 +2917,7 @@ pub const Parser = struct {
28492917 .label = null,
28502918 .inline_token = null,
28512919 .loop_token = *token,
2852 .dest_ptr = *dest_ptr,
2920 .opt_ctx = *ctx,
28532921 }
28542922 }) catch unreachable;
28552923 return true;
......@@ -2860,13 +2928,13 @@ pub const Parser = struct {
28602928 .label = null,
28612929 .inline_token = null,
28622930 .loop_token = *token,
2863 .dest_ptr = *dest_ptr,
2931 .opt_ctx = *ctx,
28642932 }
28652933 }) catch unreachable;
28662934 return true;
28672935 },
28682936 Token.Id.Keyword_switch => {
2869 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeSwitch,
2937 const node = try self.createToCtxNode(arena, ctx, ast.NodeSwitch,
28702938 ast.NodeSwitch {
28712939 .base = undefined,
28722940 .switch_token = *token,
......@@ -2884,23 +2952,23 @@ pub const Parser = struct {
28842952 }) catch unreachable;
28852953 try stack.append(State { .ExpectToken = Token.Id.LBrace });
28862954 try stack.append(State { .ExpectToken = Token.Id.RParen });
2887 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
2955 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
28882956 try stack.append(State { .ExpectToken = Token.Id.LParen });
28892957 return true;
28902958 },
28912959 Token.Id.Keyword_comptime => {
2892 const node = try self.createToDestNode(arena, dest_ptr, ast.NodeComptime,
2960 const node = try self.createToCtxNode(arena, ctx, ast.NodeComptime,
28932961 ast.NodeComptime {
28942962 .base = undefined,
28952963 .comptime_token = *token,
28962964 .expr = undefined,
28972965 }
28982966 );
2899 try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
2967 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
29002968 return true;
29012969 },
29022970 Token.Id.LBrace => {
2903 const block = try self.createToDestNode(arena, dest_ptr, ast.NodeBlock,
2971 const block = try self.createToCtxNode(arena, ctx, ast.NodeBlock,
29042972 ast.NodeBlock {
29052973 .base = undefined,
29062974 .label = null,
......@@ -2933,7 +3001,7 @@ pub const Parser = struct {
29333001 return;
29343002 }
29353003
2936 try self.parseError(stack, token, "expected ',' or {}, found {}", @tagName(*end), @tagName(token.id));
3004 return self.parseError(token, "expected ',' or {}, found {}", @tagName(*end), @tagName(token.id));
29373005 },
29383006 }
29393007 }
......@@ -3049,9 +3117,9 @@ pub const Parser = struct {
30493117 return node;
30503118 }
30513119
3052 fn createToDestNode(self: &Parser, arena: &mem.Allocator, dest_ptr: &const DestPtr, comptime T: type, init_to: &const T) !&T {
3120 fn createToCtxNode(self: &Parser, arena: &mem.Allocator, opt_ctx: &const OptionalCtx, comptime T: type, init_to: &const T) !&T {
30533121 const node = try self.createNode(arena, T, init_to);
3054 dest_ptr.store(&node.base);
3122 opt_ctx.store(&node.base);
30553123
30563124 return node;
30573125 }
......@@ -3065,51 +3133,31 @@ pub const Parser = struct {
30653133 );
30663134 }
30673135
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 }
3136 fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) (error{ParseError}) {
3137 const loc = self.tokenizer.getTokenLocation(0, token);
3138 warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);
3139 warn("{}\n", self.tokenizer.buffer[loc.line_start..loc.line_end]);
3140 {
3141 var i: usize = 0;
3142 while (i < loc.column) : (i += 1) {
3143 warn(" ");
30863144 }
3087 warn("\n");
3088 return error.ParseError;
3089 };
3090 }
3091
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 => { }
3145 }
3146 {
3147 const caret_count = token.end - token.start;
3148 var i: usize = 0;
3149 while (i < caret_count) : (i += 1) {
3150 warn("~");
31023151 }
31033152 }
3104
3105 return error.NoOptionalStateFound;
3153 warn("\n");
3154 return error.ParseError;
31063155 }
31073156
3108 fn expectToken(self: &Parser, stack: &ArrayList(State), id: @TagType(Token.Id)) !?Token {
3157 fn expectToken(self: &Parser, id: @TagType(Token.Id)) !Token {
31093158 const token = self.getNextToken();
31103159 if (token.id != id) {
3111 try self.parseError(stack, token, "expected {}, found {}", @tagName(id), @tagName(token.id));
3112 return null;
3160 return self.parseError(token, "expected {}, found {}", @tagName(id), @tagName(token.id));
31133161 }
31143162 return token;
31153163 }
......@@ -3424,7 +3472,7 @@ pub const Parser = struct {
34243472 }
34253473
34263474 if (suspend_node.payload) |payload| {
3427 try stack.append(RenderState { .Expression = &payload.base });
3475 try stack.append(RenderState { .Expression = payload });
34283476 try stack.append(RenderState { .Text = " " });
34293477 }
34303478 },
......@@ -3435,7 +3483,7 @@ pub const Parser = struct {
34353483 if (prefix_op_node.op == ast.NodeInfixOp.InfixOp.Catch) {
34363484 if (prefix_op_node.op.Catch) |payload| {
34373485 try stack.append(RenderState { .Text = " " });
3438 try stack.append(RenderState { .Expression = &payload.base });
3486 try stack.append(RenderState { .Expression = payload });
34393487 }
34403488 try stack.append(RenderState { .Text = " catch " });
34413489 } else {
......@@ -3612,17 +3660,25 @@ pub const Parser = struct {
36123660 },
36133661 ast.Node.Id.ControlFlowExpression => {
36143662 const flow_expr = @fieldParentPtr(ast.NodeControlFlowExpression, "base", base);
3663
3664 if (flow_expr.rhs) |rhs| {
3665 try stack.append(RenderState { .Expression = rhs });
3666 try stack.append(RenderState { .Text = " " });
3667 }
3668
36153669 switch (flow_expr.kind) {
3616 ast.NodeControlFlowExpression.Kind.Break => |maybe_blk_token| {
3670 ast.NodeControlFlowExpression.Kind.Break => |maybe_label| {
36173671 try stream.print("break");
3618 if (maybe_blk_token) |blk_token| {
3619 try stream.print(" :{}", self.tokenizer.getTokenSlice(blk_token));
3672 if (maybe_label) |label| {
3673 try stream.print(" :");
3674 try stack.append(RenderState { .Expression = label });
36203675 }
36213676 },
3622 ast.NodeControlFlowExpression.Kind.Continue => |maybe_blk_token| {
3677 ast.NodeControlFlowExpression.Kind.Continue => |maybe_label| {
36233678 try stream.print("continue");
3624 if (maybe_blk_token) |blk_token| {
3625 try stream.print(" :{}", self.tokenizer.getTokenSlice(blk_token));
3679 if (maybe_label) |label| {
3680 try stream.print(" :");
3681 try stack.append(RenderState { .Expression = label });
36263682 }
36273683 },
36283684 ast.NodeControlFlowExpression.Kind.Return => {
......@@ -3630,25 +3686,20 @@ pub const Parser = struct {
36303686 },
36313687
36323688 }
3633
3634 if (flow_expr.rhs) |rhs| {
3635 try stream.print(" ");
3636 try stack.append(RenderState { .Expression = rhs });
3637 }
36383689 },
36393690 ast.Node.Id.Payload => {
36403691 const payload = @fieldParentPtr(ast.NodePayload, "base", base);
36413692 try stack.append(RenderState { .Text = "|"});
3642 try stack.append(RenderState { .Expression = &payload.error_symbol.base });
3693 try stack.append(RenderState { .Expression = payload.error_symbol });
36433694 try stack.append(RenderState { .Text = "|"});
36443695 },
36453696 ast.Node.Id.PointerPayload => {
36463697 const payload = @fieldParentPtr(ast.NodePointerPayload, "base", base);
36473698 try stack.append(RenderState { .Text = "|"});
3648 try stack.append(RenderState { .Expression = &payload.value_symbol.base });
3699 try stack.append(RenderState { .Expression = payload.value_symbol });
36493700
3650 if (payload.is_ptr) {
3651 try stack.append(RenderState { .Text = "*"});
3701 if (payload.ptr_token) |ptr_token| {
3702 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(ptr_token) });
36523703 }
36533704
36543705 try stack.append(RenderState { .Text = "|"});
......@@ -3658,14 +3709,14 @@ pub const Parser = struct {
36583709 try stack.append(RenderState { .Text = "|"});
36593710
36603711 if (payload.index_symbol) |index_symbol| {
3661 try stack.append(RenderState { .Expression = &index_symbol.base });
3712 try stack.append(RenderState { .Expression = index_symbol });
36623713 try stack.append(RenderState { .Text = ", "});
36633714 }
36643715
3665 try stack.append(RenderState { .Expression = &payload.value_symbol.base });
3716 try stack.append(RenderState { .Expression = payload.value_symbol });
36663717
3667 if (payload.is_ptr) {
3668 try stack.append(RenderState { .Text = "*"});
3718 if (payload.ptr_token) |ptr_token| {
3719 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(ptr_token) });
36693720 }
36703721
36713722 try stack.append(RenderState { .Text = "|"});
......@@ -3800,7 +3851,7 @@ pub const Parser = struct {
38003851 while (i != 0) {
38013852 i -= 1;
38023853 const node = decls[i];
3803 try stack.append(RenderState { .Expression = &node.base});
3854 try stack.append(RenderState { .Expression = node });
38043855 try stack.append(RenderState.PrintIndent);
38053856 try stack.append(RenderState {
38063857 .Text = blk: {
......@@ -3959,7 +4010,7 @@ pub const Parser = struct {
39594010 try stack.append(RenderState { .Expression = switch_case.expr });
39604011 if (switch_case.payload) |payload| {
39614012 try stack.append(RenderState { .Text = " " });
3962 try stack.append(RenderState { .Expression = &payload.base });
4013 try stack.append(RenderState { .Expression = payload });
39634014 }
39644015 try stack.append(RenderState { .Text = " => "});
39654016
......@@ -4000,7 +4051,7 @@ pub const Parser = struct {
40004051
40014052 if (else_node.payload) |payload| {
40024053 try stack.append(RenderState { .Text = " " });
4003 try stack.append(RenderState { .Expression = &payload.base });
4054 try stack.append(RenderState { .Expression = payload });
40044055 }
40054056 },
40064057 ast.Node.Id.While => {
......@@ -4045,7 +4096,7 @@ pub const Parser = struct {
40454096 }
40464097
40474098 if (while_node.payload) |payload| {
4048 try stack.append(RenderState { .Expression = &payload.base });
4099 try stack.append(RenderState { .Expression = payload });
40494100 try stack.append(RenderState { .Text = " " });
40504101 }
40514102
......@@ -4088,7 +4139,7 @@ pub const Parser = struct {
40884139 }
40894140
40904141 if (for_node.payload) |payload| {
4091 try stack.append(RenderState { .Expression = &payload.base });
4142 try stack.append(RenderState { .Expression = payload });
40924143 try stack.append(RenderState { .Text = " " });
40934144 }
40944145
......@@ -4121,7 +4172,7 @@ pub const Parser = struct {
41214172
41224173 if (@"else".payload) |payload| {
41234174 try stack.append(RenderState { .Text = " " });
4124 try stack.append(RenderState { .Expression = &payload.base });
4175 try stack.append(RenderState { .Expression = payload });
41254176 }
41264177
41274178 try stack.append(RenderState { .Text = " " });
......@@ -4135,7 +4186,7 @@ pub const Parser = struct {
41354186 try stack.append(RenderState { .Text = " " });
41364187
41374188 if (if_node.payload) |payload| {
4138 try stack.append(RenderState { .Expression = &payload.base });
4189 try stack.append(RenderState { .Expression = payload });
41394190 try stack.append(RenderState { .Text = " " });
41404191 }
41414192
......@@ -4147,8 +4198,8 @@ pub const Parser = struct {
41474198 const asm_node = @fieldParentPtr(ast.NodeAsm, "base", base);
41484199 try stream.print("{} ", self.tokenizer.getTokenSlice(asm_node.asm_token));
41494200
4150 if (asm_node.is_volatile) {
4151 try stream.write("volatile ");
4201 if (asm_node.volatile_token) |volatile_token| {
4202 try stream.print("{} ", self.tokenizer.getTokenSlice(volatile_token));
41524203 }
41534204
41544205 try stack.append(RenderState { .Indent = indent });
......@@ -4238,7 +4289,7 @@ pub const Parser = struct {
42384289 try stack.append(RenderState { .Text = " ("});
42394290 try stack.append(RenderState { .Expression = asm_input.constraint });
42404291 try stack.append(RenderState { .Text = "] "});
4241 try stack.append(RenderState { .Expression = &asm_input.symbolic_name.base});
4292 try stack.append(RenderState { .Expression = asm_input.symbolic_name });
42424293 try stack.append(RenderState { .Text = "["});
42434294 },
42444295 ast.Node.Id.AsmOutput => {
......@@ -4257,7 +4308,7 @@ pub const Parser = struct {
42574308 try stack.append(RenderState { .Text = " ("});
42584309 try stack.append(RenderState { .Expression = asm_output.constraint });
42594310 try stack.append(RenderState { .Text = "] "});
4260 try stack.append(RenderState { .Expression = &asm_output.symbolic_name.base});
4311 try stack.append(RenderState { .Expression = asm_output.symbolic_name });
42614312 try stack.append(RenderState { .Text = "["});
42624313 },
42634314