authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-09 21:17:05-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-09 21:17:05-04:00
log774b6ffe1e0577a2d1a32b04d71c86525627748a
tree27215adb7bc1552eb9b6a28b5854476f4187f74a
parent403e5239e3668f626ac105fbfbb08456b859963a

fix parser performance regression


2 files changed, 660 insertions(+), 662 deletions(-)

std/zig/parse.zig+327-328
...@@ -1,6 +1,5 @@...@@ -1,6 +1,5 @@
1const std = @import("../index.zig");1const std = @import("../index.zig");
2const assert = std.debug.assert;2const assert = std.debug.assert;
3const SegmentedList = std.SegmentedList;
4const mem = std.mem;3const mem = std.mem;
5const ast = std.zig.ast;4const ast = std.zig.ast;
6const Tokenizer = std.zig.Tokenizer;5const Tokenizer = std.zig.Tokenizer;
...@@ -15,7 +14,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -15,7 +14,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
15 var tree_arena = std.heap.ArenaAllocator.init(allocator);14 var tree_arena = std.heap.ArenaAllocator.init(allocator);
16 errdefer tree_arena.deinit();15 errdefer tree_arena.deinit();
1716
18 var stack = SegmentedList(State, 32).init(allocator);17 var stack = std.ArrayList(State).init(allocator);
19 defer stack.deinit();18 defer stack.deinit();
2019
21 const arena = &tree_arena.allocator;20 const arena = &tree_arena.allocator;
...@@ -46,11 +45,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -46,11 +45,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
46 }45 }
47 var tok_it = tree.tokens.iterator(0);46 var tok_it = tree.tokens.iterator(0);
4847
49 try stack.push(State.TopLevel);48 try stack.append(State.TopLevel);
5049
51 while (true) {50 while (true) {
52 // This gives us 1 free push that can't fail51 // This gives us 1 free push that can't fail
53 const state = ??stack.pop();52 const state = stack.pop();
5453
55 switch (state) {54 switch (state) {
56 State.TopLevel => {55 State.TopLevel => {
...@@ -65,7 +64,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -65,7 +64,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
65 const token_ptr = token.ptr;64 const token_ptr = token.ptr;
66 switch (token_ptr.id) {65 switch (token_ptr.id) {
67 Token.Id.Keyword_test => {66 Token.Id.Keyword_test => {
68 stack.push(State.TopLevel) catch unreachable;67 stack.append(State.TopLevel) catch unreachable;
6968
70 const block = try arena.construct(ast.Node.Block {69 const block = try arena.construct(ast.Node.Block {
71 .base = ast.Node {70 .base = ast.Node {
...@@ -86,14 +85,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -86,14 +85,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
86 .body_node = &block.base,85 .body_node = &block.base,
87 });86 });
88 try root_node.decls.push(&test_node.base);87 try root_node.decls.push(&test_node.base);
89 try stack.push(State { .Block = block });88 try stack.append(State { .Block = block });
90 try stack.push(State {89 try stack.append(State {
91 .ExpectTokenSave = ExpectTokenSave {90 .ExpectTokenSave = ExpectTokenSave {
92 .id = Token.Id.LBrace,91 .id = Token.Id.LBrace,
93 .ptr = &block.rbrace,92 .ptr = &block.rbrace,
94 }93 }
95 });94 });
96 try stack.push(State { .StringLiteral = OptionalCtx { .Required = &test_node.name } });95 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &test_node.name } });
97 continue;96 continue;
98 },97 },
99 Token.Id.Eof => {98 Token.Id.Eof => {
...@@ -102,8 +101,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -102,8 +101,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
102 return tree;101 return tree;
103 },102 },
104 Token.Id.Keyword_pub => {103 Token.Id.Keyword_pub => {
105 stack.push(State.TopLevel) catch unreachable;104 stack.append(State.TopLevel) catch unreachable;
106 try stack.push(State {105 try stack.append(State {
107 .TopLevelExtern = TopLevelDeclCtx {106 .TopLevelExtern = TopLevelDeclCtx {
108 .decls = &root_node.decls,107 .decls = &root_node.decls,
109 .visib_token = token_index,108 .visib_token = token_index,
...@@ -134,9 +133,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -134,9 +133,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
134 });133 });
135 try root_node.decls.push(&node.base);134 try root_node.decls.push(&node.base);
136135
137 stack.push(State.TopLevel) catch unreachable;136 stack.append(State.TopLevel) catch unreachable;
138 try stack.push(State { .Block = block });137 try stack.append(State { .Block = block });
139 try stack.push(State {138 try stack.append(State {
140 .ExpectTokenSave = ExpectTokenSave {139 .ExpectTokenSave = ExpectTokenSave {
141 .id = Token.Id.LBrace,140 .id = Token.Id.LBrace,
142 .ptr = &block.rbrace,141 .ptr = &block.rbrace,
...@@ -146,8 +145,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -146,8 +145,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
146 },145 },
147 else => {146 else => {
148 putBackToken(&tok_it, &tree);147 putBackToken(&tok_it, &tree);
149 stack.push(State.TopLevel) catch unreachable;148 stack.append(State.TopLevel) catch unreachable;
150 try stack.push(State {149 try stack.append(State {
151 .TopLevelExtern = TopLevelDeclCtx {150 .TopLevelExtern = TopLevelDeclCtx {
152 .decls = &root_node.decls,151 .decls = &root_node.decls,
153 .visib_token = null,152 .visib_token = null,
...@@ -166,7 +165,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -166,7 +165,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
166 const token_ptr = token.ptr;165 const token_ptr = token.ptr;
167 switch (token_ptr.id) {166 switch (token_ptr.id) {
168 Token.Id.Keyword_export, Token.Id.Keyword_inline => {167 Token.Id.Keyword_export, Token.Id.Keyword_inline => {
169 stack.push(State {168 stack.append(State {
170 .TopLevelDecl = TopLevelDeclCtx {169 .TopLevelDecl = TopLevelDeclCtx {
171 .decls = ctx.decls,170 .decls = ctx.decls,
172 .visib_token = ctx.visib_token,171 .visib_token = ctx.visib_token,
...@@ -181,7 +180,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -181,7 +180,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
181 continue;180 continue;
182 },181 },
183 Token.Id.Keyword_extern => {182 Token.Id.Keyword_extern => {
184 stack.push(State {183 stack.append(State {
185 .TopLevelLibname = TopLevelDeclCtx {184 .TopLevelLibname = TopLevelDeclCtx {
186 .decls = ctx.decls,185 .decls = ctx.decls,
187 .visib_token = ctx.visib_token,186 .visib_token = ctx.visib_token,
...@@ -197,7 +196,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -197,7 +196,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
197 },196 },
198 else => {197 else => {
199 putBackToken(&tok_it, &tree);198 putBackToken(&tok_it, &tree);
200 stack.push(State { .TopLevelDecl = ctx }) catch unreachable;199 stack.append(State { .TopLevelDecl = ctx }) catch unreachable;
201 continue;200 continue;
202 }201 }
203 }202 }
...@@ -213,7 +212,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -213,7 +212,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
213 };212 };
214 };213 };
215214
216 stack.push(State {215 stack.append(State {
217 .TopLevelDecl = TopLevelDeclCtx {216 .TopLevelDecl = TopLevelDeclCtx {
218 .decls = ctx.decls,217 .decls = ctx.decls,
219 .visib_token = ctx.visib_token,218 .visib_token = ctx.visib_token,
...@@ -246,13 +245,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -246,13 +245,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
246 });245 });
247 try ctx.decls.push(&node.base);246 try ctx.decls.push(&node.base);
248247
249 stack.push(State {248 stack.append(State {
250 .ExpectTokenSave = ExpectTokenSave {249 .ExpectTokenSave = ExpectTokenSave {
251 .id = Token.Id.Semicolon,250 .id = Token.Id.Semicolon,
252 .ptr = &node.semicolon_token,251 .ptr = &node.semicolon_token,
253 }252 }
254 }) catch unreachable;253 }) catch unreachable;
255 try stack.push(State { .Expression = OptionalCtx { .Required = &node.expr } });254 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
256 continue;255 continue;
257 },256 },
258 Token.Id.Keyword_var, Token.Id.Keyword_const => {257 Token.Id.Keyword_var, Token.Id.Keyword_const => {
...@@ -265,7 +264,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -265,7 +264,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
265 }264 }
266 }265 }
267266
268 try stack.push(State {267 try stack.append(State {
269 .VarDecl = VarDeclCtx {268 .VarDecl = VarDeclCtx {
270 .comments = ctx.comments,269 .comments = ctx.comments,
271 .visib_token = ctx.visib_token,270 .visib_token = ctx.visib_token,
...@@ -299,13 +298,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -299,13 +298,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
299 .align_expr = null,298 .align_expr = null,
300 });299 });
301 try ctx.decls.push(&fn_proto.base);300 try ctx.decls.push(&fn_proto.base);
302 stack.push(State { .FnDef = fn_proto }) catch unreachable;301 stack.append(State { .FnDef = fn_proto }) catch unreachable;
303 try stack.push(State { .FnProto = fn_proto });302 try stack.append(State { .FnProto = fn_proto });
304303
305 switch (token_ptr.id) {304 switch (token_ptr.id) {
306 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {305 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
307 fn_proto.cc_token = token_index;306 fn_proto.cc_token = token_index;
308 try stack.push(State {307 try stack.append(State {
309 .ExpectTokenSave = ExpectTokenSave {308 .ExpectTokenSave = ExpectTokenSave {
310 .id = Token.Id.Keyword_fn,309 .id = Token.Id.Keyword_fn,
311 .ptr = &fn_proto.fn_token,310 .ptr = &fn_proto.fn_token,
...@@ -324,13 +323,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -324,13 +323,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
324 );323 );
325 fn_proto.async_attr = async_node;324 fn_proto.async_attr = async_node;
326325
327 try stack.push(State {326 try stack.append(State {
328 .ExpectTokenSave = ExpectTokenSave {327 .ExpectTokenSave = ExpectTokenSave {
329 .id = Token.Id.Keyword_fn,328 .id = Token.Id.Keyword_fn,
330 .ptr = &fn_proto.fn_token,329 .ptr = &fn_proto.fn_token,
331 }330 }
332 });331 });
333 try stack.push(State { .AsyncAllocator = async_node });332 try stack.append(State { .AsyncAllocator = async_node });
334 continue;333 continue;
335 },334 },
336 Token.Id.Keyword_fn => {335 Token.Id.Keyword_fn => {
...@@ -363,14 +362,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -363,14 +362,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
363 const node_ptr = try ctx.container_decl.fields_and_decls.addOne();362 const node_ptr = try ctx.container_decl.fields_and_decls.addOne();
364 *node_ptr = &node.base;363 *node_ptr = &node.base;
365364
366 stack.push(State { .FieldListCommaOrEnd = ctx.container_decl }) catch unreachable;365 stack.append(State { .FieldListCommaOrEnd = ctx.container_decl }) catch unreachable;
367 try stack.push(State { .Expression = OptionalCtx { .Required = &node.type_expr } });366 try stack.append(State { .Expression = OptionalCtx { .Required = &node.type_expr } });
368 try stack.push(State { .ExpectToken = Token.Id.Colon });367 try stack.append(State { .ExpectToken = Token.Id.Colon });
369 continue;368 continue;
370 }369 }
371370
372 stack.push(State{ .ContainerDecl = ctx.container_decl }) catch unreachable;371 stack.append(State{ .ContainerDecl = ctx.container_decl }) catch unreachable;
373 try stack.push(State {372 try stack.append(State {
374 .TopLevelExtern = TopLevelDeclCtx {373 .TopLevelExtern = TopLevelDeclCtx {
375 .decls = &ctx.container_decl.fields_and_decls,374 .decls = &ctx.container_decl.fields_and_decls,
376 .visib_token = ctx.visib_token,375 .visib_token = ctx.visib_token,
...@@ -390,7 +389,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -390,7 +389,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
390 putBackToken(&tok_it, &tree);389 putBackToken(&tok_it, &tree);
391 continue;390 continue;
392 }391 }
393 stack.push(State { .Expression = ctx }) catch unreachable;392 stack.append(State { .Expression = ctx }) catch unreachable;
394 continue;393 continue;
395 },394 },
396395
...@@ -420,9 +419,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -420,9 +419,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
420 }419 }
421 );420 );
422421
423 stack.push(State { .ContainerDecl = node }) catch unreachable;422 stack.append(State { .ContainerDecl = node }) catch unreachable;
424 try stack.push(State { .ExpectToken = Token.Id.LBrace });423 try stack.append(State { .ExpectToken = Token.Id.LBrace });
425 try stack.push(State { .ContainerInitArgStart = node });424 try stack.append(State { .ContainerInitArgStart = node });
426 continue;425 continue;
427 },426 },
428427
...@@ -431,8 +430,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -431,8 +430,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
431 continue;430 continue;
432 }431 }
433432
434 stack.push(State { .ExpectToken = Token.Id.RParen }) catch unreachable;433 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
435 try stack.push(State { .ContainerInitArg = container_decl });434 try stack.append(State { .ContainerInitArg = container_decl });
436 continue;435 continue;
437 },436 },
438437
...@@ -447,8 +446,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -447,8 +446,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
447 const lparen_tok_index = lparen_tok.index;446 const lparen_tok_index = lparen_tok.index;
448 const lparen_tok_ptr = lparen_tok.ptr;447 const lparen_tok_ptr = lparen_tok.ptr;
449 if (lparen_tok_ptr.id == Token.Id.LParen) {448 if (lparen_tok_ptr.id == Token.Id.LParen) {
450 try stack.push(State { .ExpectToken = Token.Id.RParen } );449 try stack.append(State { .ExpectToken = Token.Id.RParen } );
451 try stack.push(State { .Expression = OptionalCtx {450 try stack.append(State { .Expression = OptionalCtx {
452 .RequiredNull = &container_decl.init_arg_expr.Enum,451 .RequiredNull = &container_decl.init_arg_expr.Enum,
453 } });452 } });
454 } else {453 } else {
...@@ -458,7 +457,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -458,7 +457,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
458 else => {457 else => {
459 putBackToken(&tok_it, &tree);458 putBackToken(&tok_it, &tree);
460 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg { .Type = undefined };459 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg { .Type = undefined };
461 stack.push(State { .Expression = OptionalCtx { .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;460 stack.append(State { .Expression = OptionalCtx { .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;
462 },461 },
463 }462 }
464 continue;463 continue;
...@@ -489,9 +488,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -489,9 +488,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
489 const node_ptr = try container_decl.fields_and_decls.addOne();488 const node_ptr = try container_decl.fields_and_decls.addOne();
490 *node_ptr = &node.base;489 *node_ptr = &node.base;
491490
492 try stack.push(State { .FieldListCommaOrEnd = container_decl });491 try stack.append(State { .FieldListCommaOrEnd = container_decl });
493 try stack.push(State { .TypeExprBegin = OptionalCtx { .Required = &node.type_expr } });492 try stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.type_expr } });
494 try stack.push(State { .ExpectToken = Token.Id.Colon });493 try stack.append(State { .ExpectToken = Token.Id.Colon });
495 continue;494 continue;
496 },495 },
497 ast.Node.ContainerDecl.Kind.Union => {496 ast.Node.ContainerDecl.Kind.Union => {
...@@ -504,10 +503,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -504,10 +503,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
504 });503 });
505 try container_decl.fields_and_decls.push(&node.base);504 try container_decl.fields_and_decls.push(&node.base);
506505
507 stack.push(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;506 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
508 try stack.push(State { .FieldInitValue = OptionalCtx { .RequiredNull = &node.value_expr } });507 try stack.append(State { .FieldInitValue = OptionalCtx { .RequiredNull = &node.value_expr } });
509 try stack.push(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &node.type_expr } });508 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &node.type_expr } });
510 try stack.push(State { .IfToken = Token.Id.Colon });509 try stack.append(State { .IfToken = Token.Id.Colon });
511 continue;510 continue;
512 },511 },
513 ast.Node.ContainerDecl.Kind.Enum => {512 ast.Node.ContainerDecl.Kind.Enum => {
...@@ -519,9 +518,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -519,9 +518,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
519 });518 });
520 try container_decl.fields_and_decls.push(&node.base);519 try container_decl.fields_and_decls.push(&node.base);
521520
522 stack.push(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;521 stack.append(State { .FieldListCommaOrEnd = container_decl }) catch unreachable;
523 try stack.push(State { .Expression = OptionalCtx { .RequiredNull = &node.value } });522 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &node.value } });
524 try stack.push(State { .IfToken = Token.Id.Equal });523 try stack.append(State { .IfToken = Token.Id.Equal });
525 continue;524 continue;
526 },525 },
527 }526 }
...@@ -529,7 +528,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -529,7 +528,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
529 Token.Id.Keyword_pub => {528 Token.Id.Keyword_pub => {
530 switch (container_decl.kind) {529 switch (container_decl.kind) {
531 ast.Node.ContainerDecl.Kind.Struct => {530 ast.Node.ContainerDecl.Kind.Struct => {
532 try stack.push(State {531 try stack.append(State {
533 .TopLevelExternOrField = TopLevelExternOrFieldCtx {532 .TopLevelExternOrField = TopLevelExternOrFieldCtx {
534 .visib_token = token_index,533 .visib_token = token_index,
535 .container_decl = container_decl,534 .container_decl = container_decl,
...@@ -539,8 +538,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -539,8 +538,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
539 continue;538 continue;
540 },539 },
541 else => {540 else => {
542 stack.push(State{ .ContainerDecl = container_decl }) catch unreachable;541 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
543 try stack.push(State {542 try stack.append(State {
544 .TopLevelExtern = TopLevelDeclCtx {543 .TopLevelExtern = TopLevelDeclCtx {
545 .decls = &container_decl.fields_and_decls,544 .decls = &container_decl.fields_and_decls,
546 .visib_token = token_index,545 .visib_token = token_index,
...@@ -554,8 +553,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -554,8 +553,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
554 }553 }
555 },554 },
556 Token.Id.Keyword_export => {555 Token.Id.Keyword_export => {
557 stack.push(State{ .ContainerDecl = container_decl }) catch unreachable;556 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
558 try stack.push(State {557 try stack.append(State {
559 .TopLevelExtern = TopLevelDeclCtx {558 .TopLevelExtern = TopLevelDeclCtx {
560 .decls = &container_decl.fields_and_decls,559 .decls = &container_decl.fields_and_decls,
561 .visib_token = token_index,560 .visib_token = token_index,
...@@ -578,8 +577,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -578,8 +577,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
578 },577 },
579 else => {578 else => {
580 putBackToken(&tok_it, &tree);579 putBackToken(&tok_it, &tree);
581 stack.push(State{ .ContainerDecl = container_decl }) catch unreachable;580 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
582 try stack.push(State {581 try stack.append(State {
583 .TopLevelExtern = TopLevelDeclCtx {582 .TopLevelExtern = TopLevelDeclCtx {
584 .decls = &container_decl.fields_and_decls,583 .decls = &container_decl.fields_and_decls,
585 .visib_token = null,584 .visib_token = null,
...@@ -615,10 +614,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -615,10 +614,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
615 });614 });
616 try ctx.list.push(&var_decl.base);615 try ctx.list.push(&var_decl.base);
617616
618 try stack.push(State { .VarDeclAlign = var_decl });617 try stack.append(State { .VarDeclAlign = var_decl });
619 try stack.push(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} });618 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} });
620 try stack.push(State { .IfToken = Token.Id.Colon });619 try stack.append(State { .IfToken = Token.Id.Colon });
621 try stack.push(State {620 try stack.append(State {
622 .ExpectTokenSave = ExpectTokenSave {621 .ExpectTokenSave = ExpectTokenSave {
623 .id = Token.Id.Identifier,622 .id = Token.Id.Identifier,
624 .ptr = &var_decl.name_token,623 .ptr = &var_decl.name_token,
...@@ -627,15 +626,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -627,15 +626,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
627 continue;626 continue;
628 },627 },
629 State.VarDeclAlign => |var_decl| {628 State.VarDeclAlign => |var_decl| {
630 try stack.push(State { .VarDeclEq = var_decl });629 try stack.append(State { .VarDeclEq = var_decl });
631630
632 const next_token = nextToken(&tok_it, &tree);631 const next_token = nextToken(&tok_it, &tree);
633 const next_token_index = next_token.index;632 const next_token_index = next_token.index;
634 const next_token_ptr = next_token.ptr;633 const next_token_ptr = next_token.ptr;
635 if (next_token_ptr.id == Token.Id.Keyword_align) {634 if (next_token_ptr.id == Token.Id.Keyword_align) {
636 try stack.push(State { .ExpectToken = Token.Id.RParen });635 try stack.append(State { .ExpectToken = Token.Id.RParen });
637 try stack.push(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.align_node} });636 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.align_node} });
638 try stack.push(State { .ExpectToken = Token.Id.LParen });637 try stack.append(State { .ExpectToken = Token.Id.LParen });
639 continue;638 continue;
640 }639 }
641640
...@@ -649,13 +648,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -649,13 +648,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
649 switch (token_ptr.id) {648 switch (token_ptr.id) {
650 Token.Id.Equal => {649 Token.Id.Equal => {
651 var_decl.eq_token = token_index;650 var_decl.eq_token = token_index;
652 stack.push(State {651 stack.append(State {
653 .ExpectTokenSave = ExpectTokenSave {652 .ExpectTokenSave = ExpectTokenSave {
654 .id = Token.Id.Semicolon,653 .id = Token.Id.Semicolon,
655 .ptr = &var_decl.semicolon_token,654 .ptr = &var_decl.semicolon_token,
656 },655 },
657 }) catch unreachable;656 }) catch unreachable;
658 try stack.push(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.init_node } });657 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &var_decl.init_node } });
659 continue;658 continue;
660 },659 },
661 Token.Id.Semicolon => {660 Token.Id.Semicolon => {
...@@ -686,7 +685,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -686,7 +685,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
686 .rbrace = undefined,685 .rbrace = undefined,
687 });686 });
688 fn_proto.body_node = &block.base;687 fn_proto.body_node = &block.base;
689 stack.push(State { .Block = block }) catch unreachable;688 stack.append(State { .Block = block }) catch unreachable;
690 continue;689 continue;
691 },690 },
692 Token.Id.Semicolon => continue,691 Token.Id.Semicolon => continue,
...@@ -699,9 +698,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -699,9 +698,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
699 }698 }
700 },699 },
701 State.FnProto => |fn_proto| {700 State.FnProto => |fn_proto| {
702 stack.push(State { .FnProtoAlign = fn_proto }) catch unreachable;701 stack.append(State { .FnProtoAlign = fn_proto }) catch unreachable;
703 try stack.push(State { .ParamDecl = fn_proto });702 try stack.append(State { .ParamDecl = fn_proto });
704 try stack.push(State { .ExpectToken = Token.Id.LParen });703 try stack.append(State { .ExpectToken = Token.Id.LParen });
705704
706 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |name_token| {705 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |name_token| {
707 fn_proto.name_token = name_token;706 fn_proto.name_token = name_token;
...@@ -709,12 +708,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -709,12 +708,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
709 continue;708 continue;
710 },709 },
711 State.FnProtoAlign => |fn_proto| {710 State.FnProtoAlign => |fn_proto| {
712 stack.push(State { .FnProtoReturnType = fn_proto }) catch unreachable;711 stack.append(State { .FnProtoReturnType = fn_proto }) catch unreachable;
713712
714 if (eatToken(&tok_it, &tree, Token.Id.Keyword_align)) |align_token| {713 if (eatToken(&tok_it, &tree, Token.Id.Keyword_align)) |align_token| {
715 try stack.push(State { .ExpectToken = Token.Id.RParen });714 try stack.append(State { .ExpectToken = Token.Id.RParen });
716 try stack.push(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } });715 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &fn_proto.align_expr } });
717 try stack.push(State { .ExpectToken = Token.Id.LParen });716 try stack.append(State { .ExpectToken = Token.Id.LParen });
718 }717 }
719 continue;718 continue;
720 },719 },
...@@ -725,7 +724,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -725,7 +724,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
725 switch (token_ptr.id) {724 switch (token_ptr.id) {
726 Token.Id.Bang => {725 Token.Id.Bang => {
727 fn_proto.return_type = ast.Node.FnProto.ReturnType { .InferErrorSet = undefined };726 fn_proto.return_type = ast.Node.FnProto.ReturnType { .InferErrorSet = undefined };
728 stack.push(State {727 stack.append(State {
729 .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.InferErrorSet },728 .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.InferErrorSet },
730 }) catch unreachable;729 }) catch unreachable;
731 continue;730 continue;
...@@ -747,7 +746,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -747,7 +746,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
747746
748 putBackToken(&tok_it, &tree);747 putBackToken(&tok_it, &tree);
749 fn_proto.return_type = ast.Node.FnProto.ReturnType { .Explicit = undefined };748 fn_proto.return_type = ast.Node.FnProto.ReturnType { .Explicit = undefined };
750 stack.push(State { .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.Explicit }, }) catch unreachable;749 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.Explicit }, }) catch unreachable;
751 continue;750 continue;
752 },751 },
753 }752 }
...@@ -768,14 +767,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -768,14 +767,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
768 });767 });
769 try fn_proto.params.push(&param_decl.base);768 try fn_proto.params.push(&param_decl.base);
770769
771 stack.push(State {770 stack.append(State {
772 .ParamDeclEnd = ParamDeclEndCtx {771 .ParamDeclEnd = ParamDeclEndCtx {
773 .param_decl = param_decl,772 .param_decl = param_decl,
774 .fn_proto = fn_proto,773 .fn_proto = fn_proto,
775 }774 }
776 }) catch unreachable;775 }) catch unreachable;
777 try stack.push(State { .ParamDeclName = param_decl });776 try stack.append(State { .ParamDeclName = param_decl });
778 try stack.push(State { .ParamDeclAliasOrComptime = param_decl });777 try stack.append(State { .ParamDeclAliasOrComptime = param_decl });
779 continue;778 continue;
780 },779 },
781 State.ParamDeclAliasOrComptime => |param_decl| {780 State.ParamDeclAliasOrComptime => |param_decl| {
...@@ -801,12 +800,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -801,12 +800,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
801 State.ParamDeclEnd => |ctx| {800 State.ParamDeclEnd => |ctx| {
802 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {801 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {
803 ctx.param_decl.var_args_token = ellipsis3;802 ctx.param_decl.var_args_token = ellipsis3;
804 stack.push(State { .ExpectToken = Token.Id.RParen }) catch unreachable;803 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
805 continue;804 continue;
806 }805 }
807806
808 try stack.push(State { .ParamDeclComma = ctx.fn_proto });807 try stack.append(State { .ParamDeclComma = ctx.fn_proto });
809 try stack.push(State {808 try stack.append(State {
810 .TypeExprBegin = OptionalCtx { .Required = &ctx.param_decl.type_node }809 .TypeExprBegin = OptionalCtx { .Required = &ctx.param_decl.type_node }
811 });810 });
812 continue;811 continue;
...@@ -815,7 +814,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -815,7 +814,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
815 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {814 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {
816 ExpectCommaOrEndResult.end_token => |t| {815 ExpectCommaOrEndResult.end_token => |t| {
817 if (t == null) {816 if (t == null) {
818 stack.push(State { .ParamDecl = fn_proto }) catch unreachable;817 stack.append(State { .ParamDecl = fn_proto }) catch unreachable;
819 }818 }
820 continue;819 continue;
821 },820 },
...@@ -828,7 +827,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -828,7 +827,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
828827
829 State.MaybeLabeledExpression => |ctx| {828 State.MaybeLabeledExpression => |ctx| {
830 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {829 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {
831 stack.push(State {830 stack.append(State {
832 .LabeledExpression = LabelCtx {831 .LabeledExpression = LabelCtx {
833 .label = ctx.label,832 .label = ctx.label,
834 .opt_ctx = ctx.opt_ctx,833 .opt_ctx = ctx.opt_ctx,
...@@ -855,11 +854,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -855,11 +854,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
855 .rbrace = undefined,854 .rbrace = undefined,
856 }855 }
857 );856 );
858 stack.push(State { .Block = block }) catch unreachable;857 stack.append(State { .Block = block }) catch unreachable;
859 continue;858 continue;
860 },859 },
861 Token.Id.Keyword_while => {860 Token.Id.Keyword_while => {
862 stack.push(State {861 stack.append(State {
863 .While = LoopCtx {862 .While = LoopCtx {
864 .label = ctx.label,863 .label = ctx.label,
865 .inline_token = null,864 .inline_token = null,
...@@ -870,7 +869,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -870,7 +869,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
870 continue;869 continue;
871 },870 },
872 Token.Id.Keyword_for => {871 Token.Id.Keyword_for => {
873 stack.push(State {872 stack.append(State {
874 .For = LoopCtx {873 .For = LoopCtx {
875 .label = ctx.label,874 .label = ctx.label,
876 .inline_token = null,875 .inline_token = null,
...@@ -891,12 +890,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -891,12 +890,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
891 .body = null,890 .body = null,
892 });891 });
893 ctx.opt_ctx.store(&node.base);892 ctx.opt_ctx.store(&node.base);
894 stack.push(State { .SuspendBody = node }) catch unreachable;893 stack.append(State { .SuspendBody = node }) catch unreachable;
895 try stack.push(State { .Payload = OptionalCtx { .Optional = &node.payload } });894 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });
896 continue;895 continue;
897 },896 },
898 Token.Id.Keyword_inline => {897 Token.Id.Keyword_inline => {
899 stack.push(State {898 stack.append(State {
900 .Inline = InlineCtx {899 .Inline = InlineCtx {
901 .label = ctx.label,900 .label = ctx.label,
902 .inline_token = token_index,901 .inline_token = token_index,
...@@ -924,7 +923,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -924,7 +923,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
924 const token_ptr = token.ptr;923 const token_ptr = token.ptr;
925 switch (token_ptr.id) {924 switch (token_ptr.id) {
926 Token.Id.Keyword_while => {925 Token.Id.Keyword_while => {
927 stack.push(State {926 stack.append(State {
928 .While = LoopCtx {927 .While = LoopCtx {
929 .inline_token = ctx.inline_token,928 .inline_token = ctx.inline_token,
930 .label = ctx.label,929 .label = ctx.label,
...@@ -935,7 +934,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -935,7 +934,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
935 continue;934 continue;
936 },935 },
937 Token.Id.Keyword_for => {936 Token.Id.Keyword_for => {
938 stack.push(State {937 stack.append(State {
939 .For = LoopCtx {938 .For = LoopCtx {
940 .inline_token = ctx.inline_token,939 .inline_token = ctx.inline_token,
941 .label = ctx.label,940 .label = ctx.label,
...@@ -972,20 +971,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -972,20 +971,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
972 .@"else" = null,971 .@"else" = null,
973 }972 }
974 );973 );
975 stack.push(State { .Else = &node.@"else" }) catch unreachable;974 stack.append(State { .Else = &node.@"else" }) catch unreachable;
976 try stack.push(State { .Expression = OptionalCtx { .Required = &node.body } });975 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
977 try stack.push(State { .WhileContinueExpr = &node.continue_expr });976 try stack.append(State { .WhileContinueExpr = &node.continue_expr });
978 try stack.push(State { .IfToken = Token.Id.Colon });977 try stack.append(State { .IfToken = Token.Id.Colon });
979 try stack.push(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });978 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
980 try stack.push(State { .ExpectToken = Token.Id.RParen });979 try stack.append(State { .ExpectToken = Token.Id.RParen });
981 try stack.push(State { .Expression = OptionalCtx { .Required = &node.condition } });980 try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } });
982 try stack.push(State { .ExpectToken = Token.Id.LParen });981 try stack.append(State { .ExpectToken = Token.Id.LParen });
983 continue;982 continue;
984 },983 },
985 State.WhileContinueExpr => |dest| {984 State.WhileContinueExpr => |dest| {
986 stack.push(State { .ExpectToken = Token.Id.RParen }) catch unreachable;985 stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
987 try stack.push(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = dest } });986 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = dest } });
988 try stack.push(State { .ExpectToken = Token.Id.LParen });987 try stack.append(State { .ExpectToken = Token.Id.LParen });
989 continue;988 continue;
990 },989 },
991 State.For => |ctx| {990 State.For => |ctx| {
...@@ -1001,12 +1000,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1001,12 +1000,12 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1001 .@"else" = null,1000 .@"else" = null,
1002 }1001 }
1003 );1002 );
1004 stack.push(State { .Else = &node.@"else" }) catch unreachable;1003 stack.append(State { .Else = &node.@"else" }) catch unreachable;
1005 try stack.push(State { .Expression = OptionalCtx { .Required = &node.body } });1004 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
1006 try stack.push(State { .PointerIndexPayload = OptionalCtx { .Optional = &node.payload } });1005 try stack.append(State { .PointerIndexPayload = OptionalCtx { .Optional = &node.payload } });
1007 try stack.push(State { .ExpectToken = Token.Id.RParen });1006 try stack.append(State { .ExpectToken = Token.Id.RParen });
1008 try stack.push(State { .Expression = OptionalCtx { .Required = &node.array_expr } });1007 try stack.append(State { .Expression = OptionalCtx { .Required = &node.array_expr } });
1009 try stack.push(State { .ExpectToken = Token.Id.LParen });1008 try stack.append(State { .ExpectToken = Token.Id.LParen });
1010 continue;1009 continue;
1011 },1010 },
1012 State.Else => |dest| {1011 State.Else => |dest| {
...@@ -1021,8 +1020,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1021,8 +1020,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1021 );1020 );
1022 *dest = node;1021 *dest = node;
10231022
1024 stack.push(State { .Expression = OptionalCtx { .Required = &node.body } }) catch unreachable;1023 stack.append(State { .Expression = OptionalCtx { .Required = &node.body } }) catch unreachable;
1025 try stack.push(State { .Payload = OptionalCtx { .Optional = &node.payload } });1024 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });
1026 continue;1025 continue;
1027 } else {1026 } else {
1028 continue;1027 continue;
...@@ -1041,7 +1040,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1041,7 +1040,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1041 },1040 },
1042 else => {1041 else => {
1043 putBackToken(&tok_it, &tree);1042 putBackToken(&tok_it, &tree);
1044 stack.push(State { .Block = block }) catch unreachable;1043 stack.append(State { .Block = block }) catch unreachable;
10451044
1046 var any_comments = false;1045 var any_comments = false;
1047 while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| {1046 while (try eatLineComment(arena, &tok_it, &tree)) |line_comment| {
...@@ -1050,7 +1049,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1050,7 +1049,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1050 }1049 }
1051 if (any_comments) continue;1050 if (any_comments) continue;
10521051
1053 try stack.push(State { .Statement = block });1052 try stack.append(State { .Statement = block });
1054 continue;1053 continue;
1055 },1054 },
1056 }1055 }
...@@ -1061,7 +1060,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1061,7 +1060,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1061 const token_ptr = token.ptr;1060 const token_ptr = token.ptr;
1062 switch (token_ptr.id) {1061 switch (token_ptr.id) {
1063 Token.Id.Keyword_comptime => {1062 Token.Id.Keyword_comptime => {
1064 stack.push(State {1063 stack.append(State {
1065 .ComptimeStatement = ComptimeStatementCtx {1064 .ComptimeStatement = ComptimeStatementCtx {
1066 .comptime_token = token_index,1065 .comptime_token = token_index,
1067 .block = block,1066 .block = block,
...@@ -1070,7 +1069,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1070,7 +1069,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1070 continue;1069 continue;
1071 },1070 },
1072 Token.Id.Keyword_var, Token.Id.Keyword_const => {1071 Token.Id.Keyword_var, Token.Id.Keyword_const => {
1073 stack.push(State {1072 stack.append(State {
1074 .VarDecl = VarDeclCtx {1073 .VarDecl = VarDeclCtx {
1075 .comments = null,1074 .comments = null,
1076 .visib_token = null,1075 .visib_token = null,
...@@ -1099,8 +1098,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1099,8 +1098,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1099 const node_ptr = try block.statements.addOne();1098 const node_ptr = try block.statements.addOne();
1100 *node_ptr = &node.base;1099 *node_ptr = &node.base;
11011100
1102 stack.push(State { .Semicolon = node_ptr }) catch unreachable;1101 stack.append(State { .Semicolon = node_ptr }) catch unreachable;
1103 try stack.push(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });1102 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
1104 continue;1103 continue;
1105 },1104 },
1106 Token.Id.LBrace => {1105 Token.Id.LBrace => {
...@@ -1113,14 +1112,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1113,14 +1112,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1113 });1112 });
1114 try block.statements.push(&inner_block.base);1113 try block.statements.push(&inner_block.base);
11151114
1116 stack.push(State { .Block = inner_block }) catch unreachable;1115 stack.append(State { .Block = inner_block }) catch unreachable;
1117 continue;1116 continue;
1118 },1117 },
1119 else => {1118 else => {
1120 putBackToken(&tok_it, &tree);1119 putBackToken(&tok_it, &tree);
1121 const statement = try block.statements.addOne();1120 const statement = try block.statements.addOne();
1122 try stack.push(State { .Semicolon = statement });1121 try stack.append(State { .Semicolon = statement });
1123 try stack.push(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } });1122 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } });
1124 continue;1123 continue;
1125 }1124 }
1126 }1125 }
...@@ -1131,7 +1130,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1131,7 +1130,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1131 const token_ptr = token.ptr;1130 const token_ptr = token.ptr;
1132 switch (token_ptr.id) {1131 switch (token_ptr.id) {
1133 Token.Id.Keyword_var, Token.Id.Keyword_const => {1132 Token.Id.Keyword_var, Token.Id.Keyword_const => {
1134 stack.push(State {1133 stack.append(State {
1135 .VarDecl = VarDeclCtx {1134 .VarDecl = VarDeclCtx {
1136 .comments = null,1135 .comments = null,
1137 .visib_token = null,1136 .visib_token = null,
...@@ -1148,8 +1147,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1148,8 +1147,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1148 putBackToken(&tok_it, &tree);1147 putBackToken(&tok_it, &tree);
1149 putBackToken(&tok_it, &tree);1148 putBackToken(&tok_it, &tree);
1150 const statement = try ctx.block.statements.addOne();1149 const statement = try ctx.block.statements.addOne();
1151 try stack.push(State { .Semicolon = statement });1150 try stack.append(State { .Semicolon = statement });
1152 try stack.push(State { .Expression = OptionalCtx { .Required = statement } });1151 try stack.append(State { .Expression = OptionalCtx { .Required = statement } });
1153 continue;1152 continue;
1154 }1153 }
1155 }1154 }
...@@ -1157,7 +1156,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1157,7 +1156,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1157 State.Semicolon => |node_ptr| {1156 State.Semicolon => |node_ptr| {
1158 const node = *node_ptr;1157 const node = *node_ptr;
1159 if (node.requireSemiColon()) {1158 if (node.requireSemiColon()) {
1160 stack.push(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable;1159 stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable;
1161 continue;1160 continue;
1162 }1161 }
1163 continue;1162 continue;
...@@ -1182,14 +1181,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1182,14 +1181,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1182 );1181 );
1183 try items.push(node);1182 try items.push(node);
11841183
1185 stack.push(State { .AsmOutputItems = items }) catch unreachable;1184 stack.append(State { .AsmOutputItems = items }) catch unreachable;
1186 try stack.push(State { .IfToken = Token.Id.Comma });1185 try stack.append(State { .IfToken = Token.Id.Comma });
1187 try stack.push(State { .ExpectToken = Token.Id.RParen });1186 try stack.append(State { .ExpectToken = Token.Id.RParen });
1188 try stack.push(State { .AsmOutputReturnOrType = node });1187 try stack.append(State { .AsmOutputReturnOrType = node });
1189 try stack.push(State { .ExpectToken = Token.Id.LParen });1188 try stack.append(State { .ExpectToken = Token.Id.LParen });
1190 try stack.push(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });1189 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });
1191 try stack.push(State { .ExpectToken = Token.Id.RBracket });1190 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1192 try stack.push(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });1191 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });
1193 continue;1192 continue;
1194 },1193 },
1195 State.AsmOutputReturnOrType => |node| {1194 State.AsmOutputReturnOrType => |node| {
...@@ -1203,7 +1202,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1203,7 +1202,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1203 },1202 },
1204 Token.Id.Arrow => {1203 Token.Id.Arrow => {
1205 node.kind = ast.Node.AsmOutput.Kind { .Return = undefined };1204 node.kind = ast.Node.AsmOutput.Kind { .Return = undefined };
1206 try stack.push(State { .TypeExprBegin = OptionalCtx { .Required = &node.kind.Return } });1205 try stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.kind.Return } });
1207 continue;1206 continue;
1208 },1207 },
1209 else => {1208 else => {
...@@ -1235,20 +1234,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1235,20 +1234,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1235 );1234 );
1236 try items.push(node);1235 try items.push(node);
12371236
1238 stack.push(State { .AsmInputItems = items }) catch unreachable;1237 stack.append(State { .AsmInputItems = items }) catch unreachable;
1239 try stack.push(State { .IfToken = Token.Id.Comma });1238 try stack.append(State { .IfToken = Token.Id.Comma });
1240 try stack.push(State { .ExpectToken = Token.Id.RParen });1239 try stack.append(State { .ExpectToken = Token.Id.RParen });
1241 try stack.push(State { .Expression = OptionalCtx { .Required = &node.expr } });1240 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
1242 try stack.push(State { .ExpectToken = Token.Id.LParen });1241 try stack.append(State { .ExpectToken = Token.Id.LParen });
1243 try stack.push(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });1242 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.constraint } });
1244 try stack.push(State { .ExpectToken = Token.Id.RBracket });1243 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1245 try stack.push(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });1244 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.symbolic_name } });
1246 continue;1245 continue;
1247 },1246 },
1248 State.AsmClobberItems => |items| {1247 State.AsmClobberItems => |items| {
1249 stack.push(State { .AsmClobberItems = items }) catch unreachable;1248 stack.append(State { .AsmClobberItems = items }) catch unreachable;
1250 try stack.push(State { .IfToken = Token.Id.Comma });1249 try stack.append(State { .IfToken = Token.Id.Comma });
1251 try stack.push(State { .StringLiteral = OptionalCtx { .Required = try items.addOne() } });1250 try stack.append(State { .StringLiteral = OptionalCtx { .Required = try items.addOne() } });
1252 continue;1251 continue;
1253 },1252 },
12541253
...@@ -1259,8 +1258,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1259,8 +1258,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1259 continue;1258 continue;
1260 }1259 }
12611260
1262 stack.push(State { .ExprListCommaOrEnd = list_state }) catch unreachable;1261 stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable;
1263 try stack.push(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } });1262 try stack.append(State { .Expression = OptionalCtx { .Required = try list_state.list.addOne() } });
1264 continue;1263 continue;
1265 },1264 },
1266 State.ExprListCommaOrEnd => |list_state| {1265 State.ExprListCommaOrEnd => |list_state| {
...@@ -1269,7 +1268,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1269,7 +1268,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1269 *list_state.ptr = end;1268 *list_state.ptr = end;
1270 continue;1269 continue;
1271 } else {1270 } else {
1272 stack.push(State { .ExprListItemOrEnd = list_state }) catch unreachable;1271 stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable;
1273 continue;1272 continue;
1274 },1273 },
1275 ExpectCommaOrEndResult.parse_error => |e| {1274 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1298,16 +1297,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1298,16 +1297,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1298 });1297 });
1299 try list_state.list.push(&node.base);1298 try list_state.list.push(&node.base);
13001299
1301 stack.push(State { .FieldInitListCommaOrEnd = list_state }) catch unreachable;1300 stack.append(State { .FieldInitListCommaOrEnd = list_state }) catch unreachable;
1302 try stack.push(State { .Expression = OptionalCtx{ .Required = &node.expr } });1301 try stack.append(State { .Expression = OptionalCtx{ .Required = &node.expr } });
1303 try stack.push(State { .ExpectToken = Token.Id.Equal });1302 try stack.append(State { .ExpectToken = Token.Id.Equal });
1304 try stack.push(State {1303 try stack.append(State {
1305 .ExpectTokenSave = ExpectTokenSave {1304 .ExpectTokenSave = ExpectTokenSave {
1306 .id = Token.Id.Identifier,1305 .id = Token.Id.Identifier,
1307 .ptr = &node.name_token,1306 .ptr = &node.name_token,
1308 }1307 }
1309 });1308 });
1310 try stack.push(State {1309 try stack.append(State {
1311 .ExpectTokenSave = ExpectTokenSave {1310 .ExpectTokenSave = ExpectTokenSave {
1312 .id = Token.Id.Period,1311 .id = Token.Id.Period,
1313 .ptr = &node.period_token,1312 .ptr = &node.period_token,
...@@ -1321,7 +1320,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1321,7 +1320,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1321 *list_state.ptr = end;1320 *list_state.ptr = end;
1322 continue;1321 continue;
1323 } else {1322 } else {
1324 stack.push(State { .FieldInitListItemOrEnd = list_state }) catch unreachable;1323 stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable;
1325 continue;1324 continue;
1326 },1325 },
1327 ExpectCommaOrEndResult.parse_error => |e| {1326 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1336,7 +1335,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1336,7 +1335,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1336 container_decl.rbrace_token = end;1335 container_decl.rbrace_token = end;
1337 continue;1336 continue;
1338 } else {1337 } else {
1339 try stack.push(State { .ContainerDecl = container_decl });1338 try stack.append(State { .ContainerDecl = container_decl });
1340 continue;1339 continue;
1341 },1340 },
1342 ExpectCommaOrEndResult.parse_error => |e| {1341 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1357,8 +1356,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1357,8 +1356,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
13571356
1358 const node_ptr = try list_state.list.addOne();1357 const node_ptr = try list_state.list.addOne();
13591358
1360 try stack.push(State { .ErrorTagListCommaOrEnd = list_state });1359 try stack.append(State { .ErrorTagListCommaOrEnd = list_state });
1361 try stack.push(State { .ErrorTag = node_ptr });1360 try stack.append(State { .ErrorTag = node_ptr });
1362 continue;1361 continue;
1363 },1362 },
1364 State.ErrorTagListCommaOrEnd => |list_state| {1363 State.ErrorTagListCommaOrEnd => |list_state| {
...@@ -1367,7 +1366,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1367,7 +1366,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1367 *list_state.ptr = end;1366 *list_state.ptr = end;
1368 continue;1367 continue;
1369 } else {1368 } else {
1370 stack.push(State { .ErrorTagListItemOrEnd = list_state }) catch unreachable;1369 stack.append(State { .ErrorTagListItemOrEnd = list_state }) catch unreachable;
1371 continue;1370 continue;
1372 },1371 },
1373 ExpectCommaOrEndResult.parse_error => |e| {1372 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1396,10 +1395,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1396,10 +1395,10 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1396 .expr = undefined,1395 .expr = undefined,
1397 });1396 });
1398 try list_state.list.push(&node.base);1397 try list_state.list.push(&node.base);
1399 try stack.push(State { .SwitchCaseCommaOrEnd = list_state });1398 try stack.append(State { .SwitchCaseCommaOrEnd = list_state });
1400 try stack.push(State { .AssignmentExpressionBegin = OptionalCtx { .Required = &node.expr } });1399 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .Required = &node.expr } });
1401 try stack.push(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });1400 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
1402 try stack.push(State { .SwitchCaseFirstItem = &node.items });1401 try stack.append(State { .SwitchCaseFirstItem = &node.items });
14031402
1404 continue;1403 continue;
1405 },1404 },
...@@ -1410,7 +1409,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1410,7 +1409,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1410 *list_state.ptr = end;1409 *list_state.ptr = end;
1411 continue;1410 continue;
1412 } else {1411 } else {
1413 try stack.push(State { .SwitchCaseOrEnd = list_state });1412 try stack.append(State { .SwitchCaseOrEnd = list_state });
1414 continue;1413 continue;
1415 },1414 },
1416 ExpectCommaOrEndResult.parse_error => |e| {1415 ExpectCommaOrEndResult.parse_error => |e| {
...@@ -1431,23 +1430,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1431,23 +1430,23 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1431 });1430 });
1432 try case_items.push(&else_node.base);1431 try case_items.push(&else_node.base);
14331432
1434 try stack.push(State { .ExpectToken = Token.Id.EqualAngleBracketRight });1433 try stack.append(State { .ExpectToken = Token.Id.EqualAngleBracketRight });
1435 continue;1434 continue;
1436 } else {1435 } else {
1437 putBackToken(&tok_it, &tree);1436 putBackToken(&tok_it, &tree);
1438 try stack.push(State { .SwitchCaseItem = case_items });1437 try stack.append(State { .SwitchCaseItem = case_items });
1439 continue;1438 continue;
1440 }1439 }
1441 },1440 },
1442 State.SwitchCaseItem => |case_items| {1441 State.SwitchCaseItem => |case_items| {
1443 stack.push(State { .SwitchCaseItemCommaOrEnd = case_items }) catch unreachable;1442 stack.append(State { .SwitchCaseItemCommaOrEnd = case_items }) catch unreachable;
1444 try stack.push(State { .RangeExpressionBegin = OptionalCtx { .Required = try case_items.addOne() } });1443 try stack.append(State { .RangeExpressionBegin = OptionalCtx { .Required = try case_items.addOne() } });
1445 },1444 },
1446 State.SwitchCaseItemCommaOrEnd => |case_items| {1445 State.SwitchCaseItemCommaOrEnd => |case_items| {
1447 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.EqualAngleBracketRight)) {1446 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.EqualAngleBracketRight)) {
1448 ExpectCommaOrEndResult.end_token => |t| {1447 ExpectCommaOrEndResult.end_token => |t| {
1449 if (t == null) {1448 if (t == null) {
1450 stack.push(State { .SwitchCaseItem = case_items }) catch unreachable;1449 stack.append(State { .SwitchCaseItem = case_items }) catch unreachable;
1451 }1450 }
1452 continue;1451 continue;
1453 },1452 },
...@@ -1462,7 +1461,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1462,7 +1461,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
14621461
1463 State.SuspendBody => |suspend_node| {1462 State.SuspendBody => |suspend_node| {
1464 if (suspend_node.payload != null) {1463 if (suspend_node.payload != null) {
1465 try stack.push(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = &suspend_node.body } });1464 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx { .RequiredNull = &suspend_node.body } });
1466 }1465 }
1467 continue;1466 continue;
1468 },1467 },
...@@ -1472,13 +1471,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1472,13 +1471,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1472 }1471 }
14731472
1474 async_node.rangle_bracket = TokenIndex(0);1473 async_node.rangle_bracket = TokenIndex(0);
1475 try stack.push(State {1474 try stack.append(State {
1476 .ExpectTokenSave = ExpectTokenSave {1475 .ExpectTokenSave = ExpectTokenSave {
1477 .id = Token.Id.AngleBracketRight,1476 .id = Token.Id.AngleBracketRight,
1478 .ptr = &??async_node.rangle_bracket,1477 .ptr = &??async_node.rangle_bracket,
1479 }1478 }
1480 });1479 });
1481 try stack.push(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &async_node.allocator_type } });1480 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &async_node.allocator_type } });
1482 continue;1481 continue;
1483 },1482 },
1484 State.AsyncEnd => |ctx| {1483 State.AsyncEnd => |ctx| {
...@@ -1533,11 +1532,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1533,11 +1532,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1533 .align_expr = null,1532 .align_expr = null,
1534 });1533 });
1535 ctx.opt_ctx.store(&fn_proto.base);1534 ctx.opt_ctx.store(&fn_proto.base);
1536 stack.push(State { .FnProto = fn_proto }) catch unreachable;1535 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1537 continue;1536 continue;
1538 }1537 }
15391538
1540 stack.push(State {1539 stack.append(State {
1541 .ContainerKind = ContainerKindCtx {1540 .ContainerKind = ContainerKindCtx {
1542 .opt_ctx = ctx.opt_ctx,1541 .opt_ctx = ctx.opt_ctx,
1543 .ltoken = ctx.extern_token,1542 .ltoken = ctx.extern_token,
...@@ -1560,13 +1559,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1560,13 +1559,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1560 }1559 }
1561 };1560 };
15621561
1563 stack.push(State {1562 stack.append(State {
1564 .ExpectTokenSave = ExpectTokenSave {1563 .ExpectTokenSave = ExpectTokenSave {
1565 .id = Token.Id.RBracket,1564 .id = Token.Id.RBracket,
1566 .ptr = &node.rtoken,1565 .ptr = &node.rtoken,
1567 }1566 }
1568 }) catch unreachable;1567 }) catch unreachable;
1569 try stack.push(State { .Expression = OptionalCtx { .Optional = &node.op.Slice.end } });1568 try stack.append(State { .Expression = OptionalCtx { .Optional = &node.op.Slice.end } });
1570 continue;1569 continue;
1571 },1570 },
1572 Token.Id.RBracket => {1571 Token.Id.RBracket => {
...@@ -1592,15 +1591,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1592,15 +1591,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1592 .volatile_token = null,1591 .volatile_token = null,
1593 }1592 }
1594 };1593 };
1595 stack.push(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;1594 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1596 try stack.push(State { .AddrOfModifiers = &node.op.SliceType });1595 try stack.append(State { .AddrOfModifiers = &node.op.SliceType });
1597 continue;1596 continue;
1598 }1597 }
15991598
1600 node.op = ast.Node.PrefixOp.Op { .ArrayType = undefined };1599 node.op = ast.Node.PrefixOp.Op { .ArrayType = undefined };
1601 stack.push(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;1600 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1602 try stack.push(State { .ExpectToken = Token.Id.RBracket });1601 try stack.append(State { .ExpectToken = Token.Id.RBracket });
1603 try stack.push(State { .Expression = OptionalCtx { .Required = &node.op.ArrayType } });1602 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayType } });
1604 continue;1603 continue;
1605 },1604 },
1606 State.AddrOfModifiers => |addr_of_info| {1605 State.AddrOfModifiers => |addr_of_info| {
...@@ -1609,20 +1608,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1609,20 +1608,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1609 const token_ptr = token.ptr;1608 const token_ptr = token.ptr;
1610 switch (token_ptr.id) {1609 switch (token_ptr.id) {
1611 Token.Id.Keyword_align => {1610 Token.Id.Keyword_align => {
1612 stack.push(state) catch unreachable;1611 stack.append(state) catch unreachable;
1613 if (addr_of_info.align_expr != null) {1612 if (addr_of_info.align_expr != null) {
1614 *(try tree.errors.addOne()) = Error {1613 *(try tree.errors.addOne()) = Error {
1615 .ExtraAlignQualifier = Error.ExtraAlignQualifier { .token = token_index },1614 .ExtraAlignQualifier = Error.ExtraAlignQualifier { .token = token_index },
1616 };1615 };
1617 return tree;1616 return tree;
1618 }1617 }
1619 try stack.push(State { .ExpectToken = Token.Id.RParen });1618 try stack.append(State { .ExpectToken = Token.Id.RParen });
1620 try stack.push(State { .Expression = OptionalCtx { .RequiredNull = &addr_of_info.align_expr} });1619 try stack.append(State { .Expression = OptionalCtx { .RequiredNull = &addr_of_info.align_expr} });
1621 try stack.push(State { .ExpectToken = Token.Id.LParen });1620 try stack.append(State { .ExpectToken = Token.Id.LParen });
1622 continue;1621 continue;
1623 },1622 },
1624 Token.Id.Keyword_const => {1623 Token.Id.Keyword_const => {
1625 stack.push(state) catch unreachable;1624 stack.append(state) catch unreachable;
1626 if (addr_of_info.const_token != null) {1625 if (addr_of_info.const_token != null) {
1627 *(try tree.errors.addOne()) = Error {1626 *(try tree.errors.addOne()) = Error {
1628 .ExtraConstQualifier = Error.ExtraConstQualifier { .token = token_index },1627 .ExtraConstQualifier = Error.ExtraConstQualifier { .token = token_index },
...@@ -1633,7 +1632,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1633,7 +1632,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1633 continue;1632 continue;
1634 },1633 },
1635 Token.Id.Keyword_volatile => {1634 Token.Id.Keyword_volatile => {
1636 stack.push(state) catch unreachable;1635 stack.append(state) catch unreachable;
1637 if (addr_of_info.volatile_token != null) {1636 if (addr_of_info.volatile_token != null) {
1638 *(try tree.errors.addOne()) = Error {1637 *(try tree.errors.addOne()) = Error {
1639 .ExtraVolatileQualifier = Error.ExtraVolatileQualifier { .token = token_index },1638 .ExtraVolatileQualifier = Error.ExtraVolatileQualifier { .token = token_index },
...@@ -1679,13 +1678,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1679,13 +1678,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1679 }1678 }
1680 );1679 );
16811680
1682 stack.push(State {1681 stack.append(State {
1683 .ExpectTokenSave = ExpectTokenSave {1682 .ExpectTokenSave = ExpectTokenSave {
1684 .id = Token.Id.Pipe,1683 .id = Token.Id.Pipe,
1685 .ptr = &node.rpipe,1684 .ptr = &node.rpipe,
1686 }1685 }
1687 }) catch unreachable;1686 }) catch unreachable;
1688 try stack.push(State { .Identifier = OptionalCtx { .Required = &node.error_symbol } });1687 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.error_symbol } });
1689 continue;1688 continue;
1690 },1689 },
1691 State.PointerPayload => |opt_ctx| {1690 State.PointerPayload => |opt_ctx| {
...@@ -1717,14 +1716,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1717,14 +1716,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1717 }1716 }
1718 );1717 );
17191718
1720 try stack.push(State {1719 try stack.append(State {
1721 .ExpectTokenSave = ExpectTokenSave {1720 .ExpectTokenSave = ExpectTokenSave {
1722 .id = Token.Id.Pipe,1721 .id = Token.Id.Pipe,
1723 .ptr = &node.rpipe,1722 .ptr = &node.rpipe,
1724 }1723 }
1725 });1724 });
1726 try stack.push(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });1725 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });
1727 try stack.push(State {1726 try stack.append(State {
1728 .OptionalTokenSave = OptionalTokenSave {1727 .OptionalTokenSave = OptionalTokenSave {
1729 .id = Token.Id.Asterisk,1728 .id = Token.Id.Asterisk,
1730 .ptr = &node.ptr_token,1729 .ptr = &node.ptr_token,
...@@ -1762,16 +1761,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1762,16 +1761,16 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1762 }1761 }
1763 );1762 );
17641763
1765 stack.push(State {1764 stack.append(State {
1766 .ExpectTokenSave = ExpectTokenSave {1765 .ExpectTokenSave = ExpectTokenSave {
1767 .id = Token.Id.Pipe,1766 .id = Token.Id.Pipe,
1768 .ptr = &node.rpipe,1767 .ptr = &node.rpipe,
1769 }1768 }
1770 }) catch unreachable;1769 }) catch unreachable;
1771 try stack.push(State { .Identifier = OptionalCtx { .RequiredNull = &node.index_symbol } });1770 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.index_symbol } });
1772 try stack.push(State { .IfToken = Token.Id.Comma });1771 try stack.append(State { .IfToken = Token.Id.Comma });
1773 try stack.push(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });1772 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.value_symbol } });
1774 try stack.push(State {1773 try stack.append(State {
1775 .OptionalTokenSave = OptionalTokenSave {1774 .OptionalTokenSave = OptionalTokenSave {
1776 .id = Token.Id.Asterisk,1775 .id = Token.Id.Asterisk,
1777 .ptr = &node.ptr_token,1776 .ptr = &node.ptr_token,
...@@ -1796,18 +1795,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1796,18 +1795,18 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1796 }1795 }
1797 );1796 );
17981797
1799 stack.push(State { .Expression = OptionalCtx { .Optional = &node.rhs } }) catch unreachable;1798 stack.append(State { .Expression = OptionalCtx { .Optional = &node.rhs } }) catch unreachable;
18001799
1801 switch (token_ptr.id) {1800 switch (token_ptr.id) {
1802 Token.Id.Keyword_break => {1801 Token.Id.Keyword_break => {
1803 node.kind = ast.Node.ControlFlowExpression.Kind { .Break = null };1802 node.kind = ast.Node.ControlFlowExpression.Kind { .Break = null };
1804 try stack.push(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Break } });1803 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Break } });
1805 try stack.push(State { .IfToken = Token.Id.Colon });1804 try stack.append(State { .IfToken = Token.Id.Colon });
1806 },1805 },
1807 Token.Id.Keyword_continue => {1806 Token.Id.Keyword_continue => {
1808 node.kind = ast.Node.ControlFlowExpression.Kind { .Continue = null };1807 node.kind = ast.Node.ControlFlowExpression.Kind { .Continue = null };
1809 try stack.push(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } });1808 try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } });
1810 try stack.push(State { .IfToken = Token.Id.Colon });1809 try stack.append(State { .IfToken = Token.Id.Colon });
1811 },1810 },
1812 Token.Id.Keyword_return => {1811 Token.Id.Keyword_return => {
1813 node.kind = ast.Node.ControlFlowExpression.Kind.Return;1812 node.kind = ast.Node.ControlFlowExpression.Kind.Return;
...@@ -1831,21 +1830,21 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1831,21 +1830,21 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1831 }1830 }
1832 );1831 );
18331832
1834 stack.push(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;1833 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1835 continue;1834 continue;
1836 },1835 },
1837 else => {1836 else => {
1838 if (!try parseBlockExpr(&stack, arena, opt_ctx, token_ptr, token_index)) {1837 if (!try parseBlockExpr(&stack, arena, opt_ctx, token_ptr, token_index)) {
1839 putBackToken(&tok_it, &tree);1838 putBackToken(&tok_it, &tree);
1840 stack.push(State { .UnwrapExpressionBegin = opt_ctx }) catch unreachable;1839 stack.append(State { .UnwrapExpressionBegin = opt_ctx }) catch unreachable;
1841 }1840 }
1842 continue;1841 continue;
1843 }1842 }
1844 }1843 }
1845 },1844 },
1846 State.RangeExpressionBegin => |opt_ctx| {1845 State.RangeExpressionBegin => |opt_ctx| {
1847 stack.push(State { .RangeExpressionEnd = opt_ctx }) catch unreachable;1846 stack.append(State { .RangeExpressionEnd = opt_ctx }) catch unreachable;
1848 try stack.push(State { .Expression = opt_ctx });1847 try stack.append(State { .Expression = opt_ctx });
1849 continue;1848 continue;
1850 },1849 },
1851 State.RangeExpressionEnd => |opt_ctx| {1850 State.RangeExpressionEnd => |opt_ctx| {
...@@ -1861,13 +1860,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1861,13 +1860,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1861 .rhs = undefined,1860 .rhs = undefined,
1862 }1861 }
1863 );1862 );
1864 stack.push(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;1863 stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
1865 continue;1864 continue;
1866 }1865 }
1867 },1866 },
1868 State.AssignmentExpressionBegin => |opt_ctx| {1867 State.AssignmentExpressionBegin => |opt_ctx| {
1869 stack.push(State { .AssignmentExpressionEnd = opt_ctx }) catch unreachable;1868 stack.append(State { .AssignmentExpressionEnd = opt_ctx }) catch unreachable;
1870 try stack.push(State { .Expression = opt_ctx });1869 try stack.append(State { .Expression = opt_ctx });
1871 continue;1870 continue;
1872 },1871 },
18731872
...@@ -1887,8 +1886,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1887,8 +1886,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1887 .rhs = undefined,1886 .rhs = undefined,
1888 }1887 }
1889 );1888 );
1890 stack.push(State { .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1889 stack.append(State { .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1891 try stack.push(State { .Expression = OptionalCtx { .Required = &node.rhs } });1890 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
1892 continue;1891 continue;
1893 } else {1892 } else {
1894 putBackToken(&tok_it, &tree);1893 putBackToken(&tok_it, &tree);
...@@ -1897,8 +1896,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1897,8 +1896,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1897 },1896 },
18981897
1899 State.UnwrapExpressionBegin => |opt_ctx| {1898 State.UnwrapExpressionBegin => |opt_ctx| {
1900 stack.push(State { .UnwrapExpressionEnd = opt_ctx }) catch unreachable;1899 stack.append(State { .UnwrapExpressionEnd = opt_ctx }) catch unreachable;
1901 try stack.push(State { .BoolOrExpressionBegin = opt_ctx });1900 try stack.append(State { .BoolOrExpressionBegin = opt_ctx });
1902 continue;1901 continue;
1903 },1902 },
19041903
...@@ -1919,11 +1918,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1919,11 +1918,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1919 }1918 }
1920 );1919 );
19211920
1922 stack.push(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1921 stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1923 try stack.push(State { .Expression = OptionalCtx { .Required = &node.rhs } });1922 try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
19241923
1925 if (node.op == ast.Node.InfixOp.Op.Catch) {1924 if (node.op == ast.Node.InfixOp.Op.Catch) {
1926 try stack.push(State { .Payload = OptionalCtx { .Optional = &node.op.Catch } });1925 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.op.Catch } });
1927 }1926 }
1928 continue;1927 continue;
1929 } else {1928 } else {
...@@ -1933,8 +1932,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1933,8 +1932,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1933 },1932 },
19341933
1935 State.BoolOrExpressionBegin => |opt_ctx| {1934 State.BoolOrExpressionBegin => |opt_ctx| {
1936 stack.push(State { .BoolOrExpressionEnd = opt_ctx }) catch unreachable;1935 stack.append(State { .BoolOrExpressionEnd = opt_ctx }) catch unreachable;
1937 try stack.push(State { .BoolAndExpressionBegin = opt_ctx });1936 try stack.append(State { .BoolAndExpressionBegin = opt_ctx });
1938 continue;1937 continue;
1939 },1938 },
19401939
...@@ -1951,15 +1950,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1951,15 +1950,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1951 .rhs = undefined,1950 .rhs = undefined,
1952 }1951 }
1953 );1952 );
1954 stack.push(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1953 stack.append(State { .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1955 try stack.push(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });1954 try stack.append(State { .BoolAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });
1956 continue;1955 continue;
1957 }1956 }
1958 },1957 },
19591958
1960 State.BoolAndExpressionBegin => |opt_ctx| {1959 State.BoolAndExpressionBegin => |opt_ctx| {
1961 stack.push(State { .BoolAndExpressionEnd = opt_ctx }) catch unreachable;1960 stack.append(State { .BoolAndExpressionEnd = opt_ctx }) catch unreachable;
1962 try stack.push(State { .ComparisonExpressionBegin = opt_ctx });1961 try stack.append(State { .ComparisonExpressionBegin = opt_ctx });
1963 continue;1962 continue;
1964 },1963 },
19651964
...@@ -1976,15 +1975,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -1976,15 +1975,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
1976 .rhs = undefined,1975 .rhs = undefined,
1977 }1976 }
1978 );1977 );
1979 stack.push(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;1978 stack.append(State { .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
1980 try stack.push(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } });1979 try stack.append(State { .ComparisonExpressionBegin = OptionalCtx { .Required = &node.rhs } });
1981 continue;1980 continue;
1982 }1981 }
1983 },1982 },
19841983
1985 State.ComparisonExpressionBegin => |opt_ctx| {1984 State.ComparisonExpressionBegin => |opt_ctx| {
1986 stack.push(State { .ComparisonExpressionEnd = opt_ctx }) catch unreachable;1985 stack.append(State { .ComparisonExpressionEnd = opt_ctx }) catch unreachable;
1987 try stack.push(State { .BinaryOrExpressionBegin = opt_ctx });1986 try stack.append(State { .BinaryOrExpressionBegin = opt_ctx });
1988 continue;1987 continue;
1989 },1988 },
19901989
...@@ -2004,8 +2003,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2004,8 +2003,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2004 .rhs = undefined,2003 .rhs = undefined,
2005 }2004 }
2006 );2005 );
2007 stack.push(State { .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2006 stack.append(State { .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2008 try stack.push(State { .BinaryOrExpressionBegin = OptionalCtx { .Required = &node.rhs } });2007 try stack.append(State { .BinaryOrExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2009 continue;2008 continue;
2010 } else {2009 } else {
2011 putBackToken(&tok_it, &tree);2010 putBackToken(&tok_it, &tree);
...@@ -2014,8 +2013,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2014,8 +2013,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2014 },2013 },
20152014
2016 State.BinaryOrExpressionBegin => |opt_ctx| {2015 State.BinaryOrExpressionBegin => |opt_ctx| {
2017 stack.push(State { .BinaryOrExpressionEnd = opt_ctx }) catch unreachable;2016 stack.append(State { .BinaryOrExpressionEnd = opt_ctx }) catch unreachable;
2018 try stack.push(State { .BinaryXorExpressionBegin = opt_ctx });2017 try stack.append(State { .BinaryXorExpressionBegin = opt_ctx });
2019 continue;2018 continue;
2020 },2019 },
20212020
...@@ -2032,15 +2031,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2032,15 +2031,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2032 .rhs = undefined,2031 .rhs = undefined,
2033 }2032 }
2034 );2033 );
2035 stack.push(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2034 stack.append(State { .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2036 try stack.push(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } });2035 try stack.append(State { .BinaryXorExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2037 continue;2036 continue;
2038 }2037 }
2039 },2038 },
20402039
2041 State.BinaryXorExpressionBegin => |opt_ctx| {2040 State.BinaryXorExpressionBegin => |opt_ctx| {
2042 stack.push(State { .BinaryXorExpressionEnd = opt_ctx }) catch unreachable;2041 stack.append(State { .BinaryXorExpressionEnd = opt_ctx }) catch unreachable;
2043 try stack.push(State { .BinaryAndExpressionBegin = opt_ctx });2042 try stack.append(State { .BinaryAndExpressionBegin = opt_ctx });
2044 continue;2043 continue;
2045 },2044 },
20462045
...@@ -2057,15 +2056,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2057,15 +2056,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2057 .rhs = undefined,2056 .rhs = undefined,
2058 }2057 }
2059 );2058 );
2060 stack.push(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2059 stack.append(State { .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2061 try stack.push(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });2060 try stack.append(State { .BinaryAndExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2062 continue;2061 continue;
2063 }2062 }
2064 },2063 },
20652064
2066 State.BinaryAndExpressionBegin => |opt_ctx| {2065 State.BinaryAndExpressionBegin => |opt_ctx| {
2067 stack.push(State { .BinaryAndExpressionEnd = opt_ctx }) catch unreachable;2066 stack.append(State { .BinaryAndExpressionEnd = opt_ctx }) catch unreachable;
2068 try stack.push(State { .BitShiftExpressionBegin = opt_ctx });2067 try stack.append(State { .BitShiftExpressionBegin = opt_ctx });
2069 continue;2068 continue;
2070 },2069 },
20712070
...@@ -2082,15 +2081,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2082,15 +2081,15 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2082 .rhs = undefined,2081 .rhs = undefined,
2083 }2082 }
2084 );2083 );
2085 stack.push(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2084 stack.append(State { .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2086 try stack.push(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } });2085 try stack.append(State { .BitShiftExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2087 continue;2086 continue;
2088 }2087 }
2089 },2088 },
20902089
2091 State.BitShiftExpressionBegin => |opt_ctx| {2090 State.BitShiftExpressionBegin => |opt_ctx| {
2092 stack.push(State { .BitShiftExpressionEnd = opt_ctx }) catch unreachable;2091 stack.append(State { .BitShiftExpressionEnd = opt_ctx }) catch unreachable;
2093 try stack.push(State { .AdditionExpressionBegin = opt_ctx });2092 try stack.append(State { .AdditionExpressionBegin = opt_ctx });
2094 continue;2093 continue;
2095 },2094 },
20962095
...@@ -2110,8 +2109,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2110,8 +2109,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2110 .rhs = undefined,2109 .rhs = undefined,
2111 }2110 }
2112 );2111 );
2113 stack.push(State { .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2112 stack.append(State { .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2114 try stack.push(State { .AdditionExpressionBegin = OptionalCtx { .Required = &node.rhs } });2113 try stack.append(State { .AdditionExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2115 continue;2114 continue;
2116 } else {2115 } else {
2117 putBackToken(&tok_it, &tree);2116 putBackToken(&tok_it, &tree);
...@@ -2120,8 +2119,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2120,8 +2119,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2120 },2119 },
21212120
2122 State.AdditionExpressionBegin => |opt_ctx| {2121 State.AdditionExpressionBegin => |opt_ctx| {
2123 stack.push(State { .AdditionExpressionEnd = opt_ctx }) catch unreachable;2122 stack.append(State { .AdditionExpressionEnd = opt_ctx }) catch unreachable;
2124 try stack.push(State { .MultiplyExpressionBegin = opt_ctx });2123 try stack.append(State { .MultiplyExpressionBegin = opt_ctx });
2125 continue;2124 continue;
2126 },2125 },
21272126
...@@ -2141,8 +2140,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2141,8 +2140,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2141 .rhs = undefined,2140 .rhs = undefined,
2142 }2141 }
2143 );2142 );
2144 stack.push(State { .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2143 stack.append(State { .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2145 try stack.push(State { .MultiplyExpressionBegin = OptionalCtx { .Required = &node.rhs } });2144 try stack.append(State { .MultiplyExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2146 continue;2145 continue;
2147 } else {2146 } else {
2148 putBackToken(&tok_it, &tree);2147 putBackToken(&tok_it, &tree);
...@@ -2151,8 +2150,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2151,8 +2150,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2151 },2150 },
21522151
2153 State.MultiplyExpressionBegin => |opt_ctx| {2152 State.MultiplyExpressionBegin => |opt_ctx| {
2154 stack.push(State { .MultiplyExpressionEnd = opt_ctx }) catch unreachable;2153 stack.append(State { .MultiplyExpressionEnd = opt_ctx }) catch unreachable;
2155 try stack.push(State { .CurlySuffixExpressionBegin = opt_ctx });2154 try stack.append(State { .CurlySuffixExpressionBegin = opt_ctx });
2156 continue;2155 continue;
2157 },2156 },
21582157
...@@ -2172,8 +2171,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2172,8 +2171,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2172 .rhs = undefined,2171 .rhs = undefined,
2173 }2172 }
2174 );2173 );
2175 stack.push(State { .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2174 stack.append(State { .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2176 try stack.push(State { .CurlySuffixExpressionBegin = OptionalCtx { .Required = &node.rhs } });2175 try stack.append(State { .CurlySuffixExpressionBegin = OptionalCtx { .Required = &node.rhs } });
2177 continue;2176 continue;
2178 } else {2177 } else {
2179 putBackToken(&tok_it, &tree);2178 putBackToken(&tok_it, &tree);
...@@ -2182,9 +2181,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2182,9 +2181,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2182 },2181 },
21832182
2184 State.CurlySuffixExpressionBegin => |opt_ctx| {2183 State.CurlySuffixExpressionBegin => |opt_ctx| {
2185 stack.push(State { .CurlySuffixExpressionEnd = opt_ctx }) catch unreachable;2184 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx }) catch unreachable;
2186 try stack.push(State { .IfToken = Token.Id.LBrace });2185 try stack.append(State { .IfToken = Token.Id.LBrace });
2187 try stack.push(State { .TypeExprBegin = opt_ctx });2186 try stack.append(State { .TypeExprBegin = opt_ctx });
2188 continue;2187 continue;
2189 },2188 },
21902189
...@@ -2202,9 +2201,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2202,9 +2201,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2202 });2201 });
2203 opt_ctx.store(&node.base);2202 opt_ctx.store(&node.base);
22042203
2205 stack.push(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2204 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2206 try stack.push(State { .IfToken = Token.Id.LBrace });2205 try stack.append(State { .IfToken = Token.Id.LBrace });
2207 try stack.push(State {2206 try stack.append(State {
2208 .FieldInitListItemOrEnd = ListSave(@typeOf(node.op.StructInitializer)) {2207 .FieldInitListItemOrEnd = ListSave(@typeOf(node.op.StructInitializer)) {
2209 .list = &node.op.StructInitializer,2208 .list = &node.op.StructInitializer,
2210 .ptr = &node.rtoken,2209 .ptr = &node.rtoken,
...@@ -2223,9 +2222,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2223,9 +2222,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2223 .rtoken = undefined,2222 .rtoken = undefined,
2224 }2223 }
2225 );2224 );
2226 stack.push(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2225 stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2227 try stack.push(State { .IfToken = Token.Id.LBrace });2226 try stack.append(State { .IfToken = Token.Id.LBrace });
2228 try stack.push(State {2227 try stack.append(State {
2229 .ExprListItemOrEnd = ExprListCtx {2228 .ExprListItemOrEnd = ExprListCtx {
2230 .list = &node.op.ArrayInitializer,2229 .list = &node.op.ArrayInitializer,
2231 .end = Token.Id.RBrace,2230 .end = Token.Id.RBrace,
...@@ -2236,8 +2235,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2236,8 +2235,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2236 },2235 },
22372236
2238 State.TypeExprBegin => |opt_ctx| {2237 State.TypeExprBegin => |opt_ctx| {
2239 stack.push(State { .TypeExprEnd = opt_ctx }) catch unreachable;2238 stack.append(State { .TypeExprEnd = opt_ctx }) catch unreachable;
2240 try stack.push(State { .PrefixOpExpression = opt_ctx });2239 try stack.append(State { .PrefixOpExpression = opt_ctx });
2241 continue;2240 continue;
2242 },2241 },
22432242
...@@ -2254,8 +2253,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2254,8 +2253,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2254 .rhs = undefined,2253 .rhs = undefined,
2255 }2254 }
2256 );2255 );
2257 stack.push(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;2256 stack.append(State { .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;
2258 try stack.push(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } });2257 try stack.append(State { .PrefixOpExpression = OptionalCtx { .Required = &node.rhs } });
2259 continue;2258 continue;
2260 }2259 }
2261 },2260 },
...@@ -2288,14 +2287,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2288,14 +2287,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2288 node = child;2287 node = child;
2289 }2288 }
22902289
2291 stack.push(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;2290 stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
2292 if (node.op == ast.Node.PrefixOp.Op.AddrOf) {2291 if (node.op == ast.Node.PrefixOp.Op.AddrOf) {
2293 try stack.push(State { .AddrOfModifiers = &node.op.AddrOf });2292 try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
2294 }2293 }
2295 continue;2294 continue;
2296 } else {2295 } else {
2297 putBackToken(&tok_it, &tree);2296 putBackToken(&tok_it, &tree);
2298 stack.push(State { .SuffixOpExpressionBegin = opt_ctx }) catch unreachable;2297 stack.append(State { .SuffixOpExpressionBegin = opt_ctx }) catch unreachable;
2299 continue;2298 continue;
2300 }2299 }
2301 },2300 },
...@@ -2310,20 +2309,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2310,20 +2309,20 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2310 .rangle_bracket = null,2309 .rangle_bracket = null,
2311 }2310 }
2312 );2311 );
2313 stack.push(State {2312 stack.append(State {
2314 .AsyncEnd = AsyncEndCtx {2313 .AsyncEnd = AsyncEndCtx {
2315 .ctx = opt_ctx,2314 .ctx = opt_ctx,
2316 .attribute = async_node,2315 .attribute = async_node,
2317 }2316 }
2318 }) catch unreachable;2317 }) catch unreachable;
2319 try stack.push(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() });2318 try stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() });
2320 try stack.push(State { .PrimaryExpression = opt_ctx.toRequired() });2319 try stack.append(State { .PrimaryExpression = opt_ctx.toRequired() });
2321 try stack.push(State { .AsyncAllocator = async_node });2320 try stack.append(State { .AsyncAllocator = async_node });
2322 continue;2321 continue;
2323 }2322 }
23242323
2325 stack.push(State { .SuffixOpExpressionEnd = opt_ctx }) catch unreachable;2324 stack.append(State { .SuffixOpExpressionEnd = opt_ctx }) catch unreachable;
2326 try stack.push(State { .PrimaryExpression = opt_ctx });2325 try stack.append(State { .PrimaryExpression = opt_ctx });
2327 continue;2326 continue;
2328 },2327 },
23292328
...@@ -2348,8 +2347,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2348,8 +2347,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2348 .rtoken = undefined,2347 .rtoken = undefined,
2349 }2348 }
2350 );2349 );
2351 stack.push(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2350 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2352 try stack.push(State {2351 try stack.append(State {
2353 .ExprListItemOrEnd = ExprListCtx {2352 .ExprListItemOrEnd = ExprListCtx {
2354 .list = &node.op.Call.params,2353 .list = &node.op.Call.params,
2355 .end = Token.Id.RParen,2354 .end = Token.Id.RParen,
...@@ -2369,9 +2368,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2369,9 +2368,9 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2369 .rtoken = undefined2368 .rtoken = undefined
2370 }2369 }
2371 );2370 );
2372 stack.push(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2371 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2373 try stack.push(State { .SliceOrArrayAccess = node });2372 try stack.append(State { .SliceOrArrayAccess = node });
2374 try stack.push(State { .Expression = OptionalCtx { .Required = &node.op.ArrayAccess }});2373 try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayAccess }});
2375 continue;2374 continue;
2376 },2375 },
2377 Token.Id.Period => {2376 Token.Id.Period => {
...@@ -2384,8 +2383,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2384,8 +2383,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2384 .rhs = undefined,2383 .rhs = undefined,
2385 }2384 }
2386 );2385 );
2387 stack.push(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;2386 stack.append(State { .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
2388 try stack.push(State { .Identifier = OptionalCtx { .Required = &node.rhs } });2387 try stack.append(State { .Identifier = OptionalCtx { .Required = &node.rhs } });
2389 continue;2388 continue;
2390 },2389 },
2391 else => {2390 else => {
...@@ -2455,7 +2454,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2455,7 +2454,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2455 .return_type = undefined,2454 .return_type = undefined,
2456 };2455 };
2457 const return_type_ptr = &((??node.result).return_type);2456 const return_type_ptr = &((??node.result).return_type);
2458 try stack.push(State { .Expression = OptionalCtx { .Required = return_type_ptr, } });2457 try stack.append(State { .Expression = OptionalCtx { .Required = return_type_ptr, } });
2459 continue;2458 continue;
2460 },2459 },
2461 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {2460 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
...@@ -2471,13 +2470,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2471,13 +2470,13 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2471 .rparen = undefined,2470 .rparen = undefined,
2472 }2471 }
2473 );2472 );
2474 stack.push(State {2473 stack.append(State {
2475 .ExpectTokenSave = ExpectTokenSave {2474 .ExpectTokenSave = ExpectTokenSave {
2476 .id = Token.Id.RParen,2475 .id = Token.Id.RParen,
2477 .ptr = &node.rparen,2476 .ptr = &node.rparen,
2478 }2477 }
2479 }) catch unreachable;2478 }) catch unreachable;
2480 try stack.push(State { .Expression = OptionalCtx { .Required = &node.expr } });2479 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
2481 continue;2480 continue;
2482 },2481 },
2483 Token.Id.Builtin => {2482 Token.Id.Builtin => {
...@@ -2489,14 +2488,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2489,14 +2488,14 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2489 .rparen_token = undefined,2488 .rparen_token = undefined,
2490 }2489 }
2491 );2490 );
2492 stack.push(State {2491 stack.append(State {
2493 .ExprListItemOrEnd = ExprListCtx {2492 .ExprListItemOrEnd = ExprListCtx {
2494 .list = &node.params,2493 .list = &node.params,
2495 .end = Token.Id.RParen,2494 .end = Token.Id.RParen,
2496 .ptr = &node.rparen_token,2495 .ptr = &node.rparen_token,
2497 }2496 }
2498 }) catch unreachable;2497 }) catch unreachable;
2499 try stack.push(State { .ExpectToken = Token.Id.LParen, });2498 try stack.append(State { .ExpectToken = Token.Id.LParen, });
2500 continue;2499 continue;
2501 },2500 },
2502 Token.Id.LBracket => {2501 Token.Id.LBracket => {
...@@ -2508,11 +2507,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2508,11 +2507,11 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2508 .rhs = undefined,2507 .rhs = undefined,
2509 }2508 }
2510 );2509 );
2511 stack.push(State { .SliceOrArrayType = node }) catch unreachable;2510 stack.append(State { .SliceOrArrayType = node }) catch unreachable;
2512 continue;2511 continue;
2513 },2512 },
2514 Token.Id.Keyword_error => {2513 Token.Id.Keyword_error => {
2515 stack.push(State {2514 stack.append(State {
2516 .ErrorTypeOrSetDecl = ErrorTypeOrSetDeclCtx {2515 .ErrorTypeOrSetDecl = ErrorTypeOrSetDeclCtx {
2517 .error_token = token.index,2516 .error_token = token.index,
2518 .opt_ctx = opt_ctx2517 .opt_ctx = opt_ctx
...@@ -2521,7 +2520,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2521,7 +2520,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2521 continue;2520 continue;
2522 },2521 },
2523 Token.Id.Keyword_packed => {2522 Token.Id.Keyword_packed => {
2524 stack.push(State {2523 stack.append(State {
2525 .ContainerKind = ContainerKindCtx {2524 .ContainerKind = ContainerKindCtx {
2526 .opt_ctx = opt_ctx,2525 .opt_ctx = opt_ctx,
2527 .ltoken = token.index,2526 .ltoken = token.index,
...@@ -2531,7 +2530,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2531,7 +2530,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2531 continue;2530 continue;
2532 },2531 },
2533 Token.Id.Keyword_extern => {2532 Token.Id.Keyword_extern => {
2534 stack.push(State {2533 stack.append(State {
2535 .ExternType = ExternTypeCtx {2534 .ExternType = ExternTypeCtx {
2536 .opt_ctx = opt_ctx,2535 .opt_ctx = opt_ctx,
2537 .extern_token = token.index,2536 .extern_token = token.index,
...@@ -2542,7 +2541,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2542,7 +2541,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2542 },2541 },
2543 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {2542 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
2544 putBackToken(&tok_it, &tree);2543 putBackToken(&tok_it, &tree);
2545 stack.push(State {2544 stack.append(State {
2546 .ContainerKind = ContainerKindCtx {2545 .ContainerKind = ContainerKindCtx {
2547 .opt_ctx = opt_ctx,2546 .opt_ctx = opt_ctx,
2548 .ltoken = token.index,2547 .ltoken = token.index,
...@@ -2552,7 +2551,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2552,7 +2551,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2552 continue;2551 continue;
2553 },2552 },
2554 Token.Id.Identifier => {2553 Token.Id.Identifier => {
2555 stack.push(State {2554 stack.append(State {
2556 .MaybeLabeledExpression = MaybeLabeledExpressionCtx {2555 .MaybeLabeledExpression = MaybeLabeledExpressionCtx {
2557 .label = token.index,2556 .label = token.index,
2558 .opt_ctx = opt_ctx2557 .opt_ctx = opt_ctx
...@@ -2580,7 +2579,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2580,7 +2579,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2580 .align_expr = null,2579 .align_expr = null,
2581 });2580 });
2582 opt_ctx.store(&fn_proto.base);2581 opt_ctx.store(&fn_proto.base);
2583 stack.push(State { .FnProto = fn_proto }) catch unreachable;2582 stack.append(State { .FnProto = fn_proto }) catch unreachable;
2584 continue;2583 continue;
2585 },2584 },
2586 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {2585 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
...@@ -2603,8 +2602,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2603,8 +2602,8 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2603 .align_expr = null,2602 .align_expr = null,
2604 });2603 });
2605 opt_ctx.store(&fn_proto.base);2604 opt_ctx.store(&fn_proto.base);
2606 stack.push(State { .FnProto = fn_proto }) catch unreachable;2605 stack.append(State { .FnProto = fn_proto }) catch unreachable;
2607 try stack.push(State {2606 try stack.append(State {
2608 .ExpectTokenSave = ExpectTokenSave {2607 .ExpectTokenSave = ExpectTokenSave {
2609 .id = Token.Id.Keyword_fn,2608 .id = Token.Id.Keyword_fn,
2610 .ptr = &fn_proto.fn_token2609 .ptr = &fn_proto.fn_token
...@@ -2625,21 +2624,21 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2625,21 +2624,21 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2625 .rparen = undefined,2624 .rparen = undefined,
2626 }2625 }
2627 );2626 );
2628 stack.push(State {2627 stack.append(State {
2629 .ExpectTokenSave = ExpectTokenSave {2628 .ExpectTokenSave = ExpectTokenSave {
2630 .id = Token.Id.RParen,2629 .id = Token.Id.RParen,
2631 .ptr = &node.rparen,2630 .ptr = &node.rparen,
2632 }2631 }
2633 }) catch unreachable;2632 }) catch unreachable;
2634 try stack.push(State { .AsmClobberItems = &node.clobbers });2633 try stack.append(State { .AsmClobberItems = &node.clobbers });
2635 try stack.push(State { .IfToken = Token.Id.Colon });2634 try stack.append(State { .IfToken = Token.Id.Colon });
2636 try stack.push(State { .AsmInputItems = &node.inputs });2635 try stack.append(State { .AsmInputItems = &node.inputs });
2637 try stack.push(State { .IfToken = Token.Id.Colon });2636 try stack.append(State { .IfToken = Token.Id.Colon });
2638 try stack.push(State { .AsmOutputItems = &node.outputs });2637 try stack.append(State { .AsmOutputItems = &node.outputs });
2639 try stack.push(State { .IfToken = Token.Id.Colon });2638 try stack.append(State { .IfToken = Token.Id.Colon });
2640 try stack.push(State { .StringLiteral = OptionalCtx { .Required = &node.template } });2639 try stack.append(State { .StringLiteral = OptionalCtx { .Required = &node.template } });
2641 try stack.push(State { .ExpectToken = Token.Id.LParen });2640 try stack.append(State { .ExpectToken = Token.Id.LParen });
2642 try stack.push(State {2641 try stack.append(State {
2643 .OptionalTokenSave = OptionalTokenSave {2642 .OptionalTokenSave = OptionalTokenSave {
2644 .id = Token.Id.Keyword_volatile,2643 .id = Token.Id.Keyword_volatile,
2645 .ptr = &node.volatile_token,2644 .ptr = &node.volatile_token,
...@@ -2647,7 +2646,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2647,7 +2646,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2647 });2646 });
2648 },2647 },
2649 Token.Id.Keyword_inline => {2648 Token.Id.Keyword_inline => {
2650 stack.push(State {2649 stack.append(State {
2651 .Inline = InlineCtx {2650 .Inline = InlineCtx {
2652 .label = null,2651 .label = null,
2653 .inline_token = token.index,2652 .inline_token = token.index,
...@@ -2688,7 +2687,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {...@@ -2688,7 +2687,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
2688 });2687 });
2689 ctx.opt_ctx.store(&node.base);2688 ctx.opt_ctx.store(&node.base);
26902689
2691 stack.push(State {2690 stack.append(State {
2692 .ErrorTagListItemOrEnd = ListSave(@typeOf(node.decls)) {2691 .ErrorTagListItemOrEnd = ListSave(@typeOf(node.decls)) {
2693 .list = &node.decls,2692 .list = &node.decls,
2694 .ptr = &node.rbrace_token,2693 .ptr = &node.rbrace_token,
...@@ -3153,7 +3152,7 @@ fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterato...@@ -3153,7 +3152,7 @@ fn parseStringLiteral(arena: &mem.Allocator, tok_it: &ast.Tree.TokenList.Iterato
3153 }3152 }
3154}3153}
31553154
3156fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx: &const OptionalCtx,3155fn parseBlockExpr(stack: &std.ArrayList(State), arena: &mem.Allocator, ctx: &const OptionalCtx,
3157 token_ptr: &const Token, token_index: TokenIndex) !bool {3156 token_ptr: &const Token, token_index: TokenIndex) !bool {
3158 switch (token_ptr.id) {3157 switch (token_ptr.id) {
3159 Token.Id.Keyword_suspend => {3158 Token.Id.Keyword_suspend => {
...@@ -3167,8 +3166,8 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:...@@ -3167,8 +3166,8 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:
3167 }3166 }
3168 );3167 );
31693168
3170 stack.push(State { .SuspendBody = node }) catch unreachable;3169 stack.append(State { .SuspendBody = node }) catch unreachable;
3171 try stack.push(State { .Payload = OptionalCtx { .Optional = &node.payload } });3170 try stack.append(State { .Payload = OptionalCtx { .Optional = &node.payload } });
3172 return true;3171 return true;
3173 },3172 },
3174 Token.Id.Keyword_if => {3173 Token.Id.Keyword_if => {
...@@ -3183,16 +3182,16 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:...@@ -3183,16 +3182,16 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:
3183 }3182 }
3184 );3183 );
31853184
3186 stack.push(State { .Else = &node.@"else" }) catch unreachable;3185 stack.append(State { .Else = &node.@"else" }) catch unreachable;
3187 try stack.push(State { .Expression = OptionalCtx { .Required = &node.body } });3186 try stack.append(State { .Expression = OptionalCtx { .Required = &node.body } });
3188 try stack.push(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });3187 try stack.append(State { .PointerPayload = OptionalCtx { .Optional = &node.payload } });
3189 try stack.push(State { .ExpectToken = Token.Id.RParen });3188 try stack.append(State { .ExpectToken = Token.Id.RParen });
3190 try stack.push(State { .Expression = OptionalCtx { .Required = &node.condition } });3189 try stack.append(State { .Expression = OptionalCtx { .Required = &node.condition } });
3191 try stack.push(State { .ExpectToken = Token.Id.LParen });3190 try stack.append(State { .ExpectToken = Token.Id.LParen });
3192 return true;3191 return true;
3193 },3192 },
3194 Token.Id.Keyword_while => {3193 Token.Id.Keyword_while => {
3195 stack.push(State {3194 stack.append(State {
3196 .While = LoopCtx {3195 .While = LoopCtx {
3197 .label = null,3196 .label = null,
3198 .inline_token = null,3197 .inline_token = null,
...@@ -3203,7 +3202,7 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:...@@ -3203,7 +3202,7 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:
3203 return true;3202 return true;
3204 },3203 },
3205 Token.Id.Keyword_for => {3204 Token.Id.Keyword_for => {
3206 stack.push(State {3205 stack.append(State {
3207 .For = LoopCtx {3206 .For = LoopCtx {
3208 .label = null,3207 .label = null,
3209 .inline_token = null,3208 .inline_token = null,
...@@ -3225,16 +3224,16 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:...@@ -3225,16 +3224,16 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:
3225 });3224 });
3226 ctx.store(&node.base);3225 ctx.store(&node.base);
32273226
3228 stack.push(State {3227 stack.append(State {
3229 .SwitchCaseOrEnd = ListSave(@typeOf(node.cases)) {3228 .SwitchCaseOrEnd = ListSave(@typeOf(node.cases)) {
3230 .list = &node.cases,3229 .list = &node.cases,
3231 .ptr = &node.rbrace,3230 .ptr = &node.rbrace,
3232 },3231 },
3233 }) catch unreachable;3232 }) catch unreachable;
3234 try stack.push(State { .ExpectToken = Token.Id.LBrace });3233 try stack.append(State { .ExpectToken = Token.Id.LBrace });
3235 try stack.push(State { .ExpectToken = Token.Id.RParen });3234 try stack.append(State { .ExpectToken = Token.Id.RParen });
3236 try stack.push(State { .Expression = OptionalCtx { .Required = &node.expr } });3235 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
3237 try stack.push(State { .ExpectToken = Token.Id.LParen });3236 try stack.append(State { .ExpectToken = Token.Id.LParen });
3238 return true;3237 return true;
3239 },3238 },
3240 Token.Id.Keyword_comptime => {3239 Token.Id.Keyword_comptime => {
...@@ -3246,7 +3245,7 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:...@@ -3246,7 +3245,7 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:
3246 .doc_comments = null,3245 .doc_comments = null,
3247 }3246 }
3248 );3247 );
3249 try stack.push(State { .Expression = OptionalCtx { .Required = &node.expr } });3248 try stack.append(State { .Expression = OptionalCtx { .Required = &node.expr } });
3250 return true;3249 return true;
3251 },3250 },
3252 Token.Id.LBrace => {3251 Token.Id.LBrace => {
...@@ -3258,7 +3257,7 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:...@@ -3258,7 +3257,7 @@ fn parseBlockExpr(stack: &SegmentedList(State, 32), arena: &mem.Allocator, ctx:
3258 .rbrace = undefined,3257 .rbrace = undefined,
3259 });3258 });
3260 ctx.store(&block.base);3259 ctx.store(&block.base);
3261 stack.push(State { .Block = block }) catch unreachable;3260 stack.append(State { .Block = block }) catch unreachable;
3262 return true;3261 return true;
3263 },3262 },
3264 else => {3263 else => {
...@@ -3473,10 +3472,10 @@ const RenderAstFrame = struct {...@@ -3473,10 +3472,10 @@ const RenderAstFrame = struct {
3473};3472};
34743473
3475pub fn renderAst(allocator: &mem.Allocator, tree: &const ast.Tree, stream: var) !void {3474pub fn renderAst(allocator: &mem.Allocator, tree: &const ast.Tree, stream: var) !void {
3476 var stack = SegmentedList(State, 32).init(allocator);3475 var stack = std.ArrayList(State).init(allocator);
3477 defer stack.deinit();3476 defer stack.deinit();
34783477
3479 try stack.push(RenderAstFrame {3478 try stack.append(RenderAstFrame {
3480 .node = &root_node.base,3479 .node = &root_node.base,
3481 .indent = 0,3480 .indent = 0,
3482 });3481 });
...@@ -3491,7 +3490,7 @@ pub fn renderAst(allocator: &mem.Allocator, tree: &const ast.Tree, stream: var)...@@ -3491,7 +3490,7 @@ pub fn renderAst(allocator: &mem.Allocator, tree: &const ast.Tree, stream: var)
3491 try stream.print("{}\n", @tagName(frame.node.id));3490 try stream.print("{}\n", @tagName(frame.node.id));
3492 var child_i: usize = 0;3491 var child_i: usize = 0;
3493 while (frame.node.iterate(child_i)) |child| : (child_i += 1) {3492 while (frame.node.iterate(child_i)) |child| : (child_i += 1) {
3494 try stack.push(RenderAstFrame {3493 try stack.append(RenderAstFrame {
3495 .node = child,3494 .node = child,
3496 .indent = frame.indent + 2,3495 .indent = frame.indent + 2,
3497 });3496 });
std/zig/render.zig+333-334
...@@ -1,6 +1,5 @@...@@ -1,6 +1,5 @@
1const std = @import("../index.zig");1const std = @import("../index.zig");
2const assert = std.debug.assert;2const assert = std.debug.assert;
3const SegmentedList = std.SegmentedList;
4const mem = std.mem;3const mem = std.mem;
5const ast = std.zig.ast;4const ast = std.zig.ast;
6const Token = std.zig.Token;5const Token = std.zig.Token;
...@@ -22,19 +21,19 @@ const RenderState = union(enum) {...@@ -22,19 +21,19 @@ const RenderState = union(enum) {
22const indent_delta = 4;21const indent_delta = 4;
2322
24pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {23pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
25 var stack = SegmentedList(RenderState, 32).init(allocator);24 var stack = std.ArrayList(RenderState).init(allocator);
26 defer stack.deinit();25 defer stack.deinit();
2726
28 {27 {
29 try stack.push(RenderState { .Text = "\n"});28 try stack.append(RenderState { .Text = "\n"});
3029
31 var i = tree.root_node.decls.len;30 var i = tree.root_node.decls.len;
32 while (i != 0) {31 while (i != 0) {
33 i -= 1;32 i -= 1;
34 const decl = *tree.root_node.decls.at(i);33 const decl = *tree.root_node.decls.at(i);
35 try stack.push(RenderState {.TopLevelDecl = decl});34 try stack.append(RenderState {.TopLevelDecl = decl});
36 if (i != 0) {35 if (i != 0) {
37 try stack.push(RenderState {36 try stack.append(RenderState {
38 .Text = blk: {37 .Text = blk: {
39 const prev_node = *tree.root_node.decls.at(i - 1);38 const prev_node = *tree.root_node.decls.at(i - 1);
40 const prev_node_last_token = tree.tokens.at(prev_node.lastToken());39 const prev_node_last_token = tree.tokens.at(prev_node.lastToken());
...@@ -50,7 +49,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -50,7 +49,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
50 }49 }
5150
52 var indent: usize = 0;51 var indent: usize = 0;
53 while (stack.pop()) |state| {52 while (stack.popOrNull()) |state| {
54 switch (state) {53 switch (state) {
55 RenderState.TopLevelDecl => |decl| {54 RenderState.TopLevelDecl => |decl| {
56 switch (decl.id) {55 switch (decl.id) {
...@@ -59,13 +58,13 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -59,13 +58,13 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
59 try renderComments(tree, stream, fn_proto, indent);58 try renderComments(tree, stream, fn_proto, indent);
6059
61 if (fn_proto.body_node) |body_node| {60 if (fn_proto.body_node) |body_node| {
62 stack.push(RenderState { .Expression = body_node}) catch unreachable;61 stack.append(RenderState { .Expression = body_node}) catch unreachable;
63 try stack.push(RenderState { .Text = " "});62 try stack.append(RenderState { .Text = " "});
64 } else {63 } else {
65 stack.push(RenderState { .Text = ";" }) catch unreachable;64 stack.append(RenderState { .Text = ";" }) catch unreachable;
66 }65 }
6766
68 try stack.push(RenderState { .Expression = decl });67 try stack.append(RenderState { .Expression = decl });
69 },68 },
70 ast.Node.Id.Use => {69 ast.Node.Id.Use => {
71 const use_decl = @fieldParentPtr(ast.Node.Use, "base", decl);70 const use_decl = @fieldParentPtr(ast.Node.Use, "base", decl);
...@@ -73,21 +72,21 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -73,21 +72,21 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
73 try stream.print("{} ", tree.tokenSlice(visib_token));72 try stream.print("{} ", tree.tokenSlice(visib_token));
74 }73 }
75 try stream.print("use ");74 try stream.print("use ");
76 try stack.push(RenderState { .Text = ";" });75 try stack.append(RenderState { .Text = ";" });
77 try stack.push(RenderState { .Expression = use_decl.expr });76 try stack.append(RenderState { .Expression = use_decl.expr });
78 },77 },
79 ast.Node.Id.VarDecl => {78 ast.Node.Id.VarDecl => {
80 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl);79 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl);
81 try renderComments(tree, stream, var_decl, indent);80 try renderComments(tree, stream, var_decl, indent);
82 try stack.push(RenderState { .VarDecl = var_decl});81 try stack.append(RenderState { .VarDecl = var_decl});
83 },82 },
84 ast.Node.Id.TestDecl => {83 ast.Node.Id.TestDecl => {
85 const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl);84 const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl);
86 try renderComments(tree, stream, test_decl, indent);85 try renderComments(tree, stream, test_decl, indent);
87 try stream.print("test ");86 try stream.print("test ");
88 try stack.push(RenderState { .Expression = test_decl.body_node });87 try stack.append(RenderState { .Expression = test_decl.body_node });
89 try stack.push(RenderState { .Text = " " });88 try stack.append(RenderState { .Text = " " });
90 try stack.push(RenderState { .Expression = test_decl.name });89 try stack.append(RenderState { .Expression = test_decl.name });
91 },90 },
92 ast.Node.Id.StructField => {91 ast.Node.Id.StructField => {
93 const field = @fieldParentPtr(ast.Node.StructField, "base", decl);92 const field = @fieldParentPtr(ast.Node.StructField, "base", decl);
...@@ -96,24 +95,24 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -96,24 +95,24 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
96 try stream.print("{} ", tree.tokenSlice(visib_token));95 try stream.print("{} ", tree.tokenSlice(visib_token));
97 }96 }
98 try stream.print("{}: ", tree.tokenSlice(field.name_token));97 try stream.print("{}: ", tree.tokenSlice(field.name_token));
99 try stack.push(RenderState { .Token = field.lastToken() + 1 });98 try stack.append(RenderState { .Token = field.lastToken() + 1 });
100 try stack.push(RenderState { .Expression = field.type_expr});99 try stack.append(RenderState { .Expression = field.type_expr});
101 },100 },
102 ast.Node.Id.UnionTag => {101 ast.Node.Id.UnionTag => {
103 const tag = @fieldParentPtr(ast.Node.UnionTag, "base", decl);102 const tag = @fieldParentPtr(ast.Node.UnionTag, "base", decl);
104 try renderComments(tree, stream, tag, indent);103 try renderComments(tree, stream, tag, indent);
105 try stream.print("{}", tree.tokenSlice(tag.name_token));104 try stream.print("{}", tree.tokenSlice(tag.name_token));
106105
107 try stack.push(RenderState { .Text = "," });106 try stack.append(RenderState { .Text = "," });
108107
109 if (tag.value_expr) |value_expr| {108 if (tag.value_expr) |value_expr| {
110 try stack.push(RenderState { .Expression = value_expr });109 try stack.append(RenderState { .Expression = value_expr });
111 try stack.push(RenderState { .Text = " = " });110 try stack.append(RenderState { .Text = " = " });
112 }111 }
113112
114 if (tag.type_expr) |type_expr| {113 if (tag.type_expr) |type_expr| {
115 try stream.print(": ");114 try stream.print(": ");
116 try stack.push(RenderState { .Expression = type_expr});115 try stack.append(RenderState { .Expression = type_expr});
117 }116 }
118 },117 },
119 ast.Node.Id.EnumTag => {118 ast.Node.Id.EnumTag => {
...@@ -121,10 +120,10 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -121,10 +120,10 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
121 try renderComments(tree, stream, tag, indent);120 try renderComments(tree, stream, tag, indent);
122 try stream.print("{}", tree.tokenSlice(tag.name_token));121 try stream.print("{}", tree.tokenSlice(tag.name_token));
123122
124 try stack.push(RenderState { .Text = "," });123 try stack.append(RenderState { .Text = "," });
125 if (tag.value) |value| {124 if (tag.value) |value| {
126 try stream.print(" = ");125 try stream.print(" = ");
127 try stack.push(RenderState { .Expression = value});126 try stack.append(RenderState { .Expression = value});
128 }127 }
129 },128 },
130 ast.Node.Id.ErrorTag => {129 ast.Node.Id.ErrorTag => {
...@@ -133,8 +132,8 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -133,8 +132,8 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
133 try stream.print("{}", tree.tokenSlice(tag.name_token));132 try stream.print("{}", tree.tokenSlice(tag.name_token));
134 },133 },
135 ast.Node.Id.Comptime => {134 ast.Node.Id.Comptime => {
136 try stack.push(RenderState { .MaybeSemiColon = decl });135 try stack.append(RenderState { .MaybeSemiColon = decl });
137 try stack.push(RenderState { .Expression = decl });136 try stack.append(RenderState { .Expression = decl });
138 },137 },
139 ast.Node.Id.LineComment => {138 ast.Node.Id.LineComment => {
140 const line_comment_node = @fieldParentPtr(ast.Node.LineComment, "base", decl);139 const line_comment_node = @fieldParentPtr(ast.Node.LineComment, "base", decl);
...@@ -145,42 +144,42 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -145,42 +144,42 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
145 },144 },
146145
147 RenderState.VarDecl => |var_decl| {146 RenderState.VarDecl => |var_decl| {
148 try stack.push(RenderState { .Token = var_decl.semicolon_token });147 try stack.append(RenderState { .Token = var_decl.semicolon_token });
149 if (var_decl.init_node) |init_node| {148 if (var_decl.init_node) |init_node| {
150 try stack.push(RenderState { .Expression = init_node });149 try stack.append(RenderState { .Expression = init_node });
151 const text = if (init_node.id == ast.Node.Id.MultilineStringLiteral) " =" else " = ";150 const text = if (init_node.id == ast.Node.Id.MultilineStringLiteral) " =" else " = ";
152 try stack.push(RenderState { .Text = text });151 try stack.append(RenderState { .Text = text });
153 }152 }
154 if (var_decl.align_node) |align_node| {153 if (var_decl.align_node) |align_node| {
155 try stack.push(RenderState { .Text = ")" });154 try stack.append(RenderState { .Text = ")" });
156 try stack.push(RenderState { .Expression = align_node });155 try stack.append(RenderState { .Expression = align_node });
157 try stack.push(RenderState { .Text = " align(" });156 try stack.append(RenderState { .Text = " align(" });
158 }157 }
159 if (var_decl.type_node) |type_node| {158 if (var_decl.type_node) |type_node| {
160 try stack.push(RenderState { .Expression = type_node });159 try stack.append(RenderState { .Expression = type_node });
161 try stack.push(RenderState { .Text = ": " });160 try stack.append(RenderState { .Text = ": " });
162 }161 }
163 try stack.push(RenderState { .Text = tree.tokenSlice(var_decl.name_token) });162 try stack.append(RenderState { .Text = tree.tokenSlice(var_decl.name_token) });
164 try stack.push(RenderState { .Text = " " });163 try stack.append(RenderState { .Text = " " });
165 try stack.push(RenderState { .Text = tree.tokenSlice(var_decl.mut_token) });164 try stack.append(RenderState { .Text = tree.tokenSlice(var_decl.mut_token) });
166165
167 if (var_decl.comptime_token) |comptime_token| {166 if (var_decl.comptime_token) |comptime_token| {
168 try stack.push(RenderState { .Text = " " });167 try stack.append(RenderState { .Text = " " });
169 try stack.push(RenderState { .Text = tree.tokenSlice(comptime_token) });168 try stack.append(RenderState { .Text = tree.tokenSlice(comptime_token) });
170 }169 }
171170
172 if (var_decl.extern_export_token) |extern_export_token| {171 if (var_decl.extern_export_token) |extern_export_token| {
173 if (var_decl.lib_name != null) {172 if (var_decl.lib_name != null) {
174 try stack.push(RenderState { .Text = " " });173 try stack.append(RenderState { .Text = " " });
175 try stack.push(RenderState { .Expression = ??var_decl.lib_name });174 try stack.append(RenderState { .Expression = ??var_decl.lib_name });
176 }175 }
177 try stack.push(RenderState { .Text = " " });176 try stack.append(RenderState { .Text = " " });
178 try stack.push(RenderState { .Text = tree.tokenSlice(extern_export_token) });177 try stack.append(RenderState { .Text = tree.tokenSlice(extern_export_token) });
179 }178 }
180179
181 if (var_decl.visib_token) |visib_token| {180 if (var_decl.visib_token) |visib_token| {
182 try stack.push(RenderState { .Text = " " });181 try stack.append(RenderState { .Text = " " });
183 try stack.push(RenderState { .Text = tree.tokenSlice(visib_token) });182 try stack.append(RenderState { .Text = tree.tokenSlice(visib_token) });
184 }183 }
185 },184 },
186185
...@@ -198,7 +197,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -198,7 +197,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
198 if (param_decl.var_args_token) |var_args_token| {197 if (param_decl.var_args_token) |var_args_token| {
199 try stream.print("{}", tree.tokenSlice(var_args_token));198 try stream.print("{}", tree.tokenSlice(var_args_token));
200 } else {199 } else {
201 try stack.push(RenderState { .Expression = param_decl.type_node});200 try stack.append(RenderState { .Expression = param_decl.type_node});
202 }201 }
203 },202 },
204 RenderState.Text => |bytes| {203 RenderState.Text => |bytes| {
...@@ -219,18 +218,18 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -219,18 +218,18 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
219 try stream.write("{}");218 try stream.write("{}");
220 } else {219 } else {
221 try stream.write("{");220 try stream.write("{");
222 try stack.push(RenderState { .Text = "}"});221 try stack.append(RenderState { .Text = "}"});
223 try stack.push(RenderState.PrintIndent);222 try stack.append(RenderState.PrintIndent);
224 try stack.push(RenderState { .Indent = indent});223 try stack.append(RenderState { .Indent = indent});
225 try stack.push(RenderState { .Text = "\n"});224 try stack.append(RenderState { .Text = "\n"});
226 var i = block.statements.len;225 var i = block.statements.len;
227 while (i != 0) {226 while (i != 0) {
228 i -= 1;227 i -= 1;
229 const statement_node = *block.statements.at(i);228 const statement_node = *block.statements.at(i);
230 try stack.push(RenderState { .Statement = statement_node});229 try stack.append(RenderState { .Statement = statement_node});
231 try stack.push(RenderState.PrintIndent);230 try stack.append(RenderState.PrintIndent);
232 try stack.push(RenderState { .Indent = indent + indent_delta});231 try stack.append(RenderState { .Indent = indent + indent_delta});
233 try stack.push(RenderState {232 try stack.append(RenderState {
234 .Text = blk: {233 .Text = blk: {
235 if (i != 0) {234 if (i != 0) {
236 const prev_node = *block.statements.at(i - 1);235 const prev_node = *block.statements.at(i - 1);
...@@ -249,21 +248,21 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -249,21 +248,21 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
249 ast.Node.Id.Defer => {248 ast.Node.Id.Defer => {
250 const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base);249 const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base);
251 try stream.print("{} ", tree.tokenSlice(defer_node.defer_token));250 try stream.print("{} ", tree.tokenSlice(defer_node.defer_token));
252 try stack.push(RenderState { .Expression = defer_node.expr });251 try stack.append(RenderState { .Expression = defer_node.expr });
253 },252 },
254 ast.Node.Id.Comptime => {253 ast.Node.Id.Comptime => {
255 const comptime_node = @fieldParentPtr(ast.Node.Comptime, "base", base);254 const comptime_node = @fieldParentPtr(ast.Node.Comptime, "base", base);
256 try stream.print("{} ", tree.tokenSlice(comptime_node.comptime_token));255 try stream.print("{} ", tree.tokenSlice(comptime_node.comptime_token));
257 try stack.push(RenderState { .Expression = comptime_node.expr });256 try stack.append(RenderState { .Expression = comptime_node.expr });
258 },257 },
259 ast.Node.Id.AsyncAttribute => {258 ast.Node.Id.AsyncAttribute => {
260 const async_attr = @fieldParentPtr(ast.Node.AsyncAttribute, "base", base);259 const async_attr = @fieldParentPtr(ast.Node.AsyncAttribute, "base", base);
261 try stream.print("{}", tree.tokenSlice(async_attr.async_token));260 try stream.print("{}", tree.tokenSlice(async_attr.async_token));
262261
263 if (async_attr.allocator_type) |allocator_type| {262 if (async_attr.allocator_type) |allocator_type| {
264 try stack.push(RenderState { .Text = ">" });263 try stack.append(RenderState { .Text = ">" });
265 try stack.push(RenderState { .Expression = allocator_type });264 try stack.append(RenderState { .Expression = allocator_type });
266 try stack.push(RenderState { .Text = "<" });265 try stack.append(RenderState { .Text = "<" });
267 }266 }
268 },267 },
269 ast.Node.Id.Suspend => {268 ast.Node.Id.Suspend => {
...@@ -274,25 +273,25 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -274,25 +273,25 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
274 try stream.print("{}", tree.tokenSlice(suspend_node.suspend_token));273 try stream.print("{}", tree.tokenSlice(suspend_node.suspend_token));
275274
276 if (suspend_node.body) |body| {275 if (suspend_node.body) |body| {
277 try stack.push(RenderState { .Expression = body });276 try stack.append(RenderState { .Expression = body });
278 try stack.push(RenderState { .Text = " " });277 try stack.append(RenderState { .Text = " " });
279 }278 }
280279
281 if (suspend_node.payload) |payload| {280 if (suspend_node.payload) |payload| {
282 try stack.push(RenderState { .Expression = payload });281 try stack.append(RenderState { .Expression = payload });
283 try stack.push(RenderState { .Text = " " });282 try stack.append(RenderState { .Text = " " });
284 }283 }
285 },284 },
286 ast.Node.Id.InfixOp => {285 ast.Node.Id.InfixOp => {
287 const prefix_op_node = @fieldParentPtr(ast.Node.InfixOp, "base", base);286 const prefix_op_node = @fieldParentPtr(ast.Node.InfixOp, "base", base);
288 try stack.push(RenderState { .Expression = prefix_op_node.rhs });287 try stack.append(RenderState { .Expression = prefix_op_node.rhs });
289288
290 if (prefix_op_node.op == ast.Node.InfixOp.Op.Catch) {289 if (prefix_op_node.op == ast.Node.InfixOp.Op.Catch) {
291 if (prefix_op_node.op.Catch) |payload| {290 if (prefix_op_node.op.Catch) |payload| {
292 try stack.push(RenderState { .Text = " " });291 try stack.append(RenderState { .Text = " " });
293 try stack.push(RenderState { .Expression = payload });292 try stack.append(RenderState { .Expression = payload });
294 }293 }
295 try stack.push(RenderState { .Text = " catch " });294 try stack.append(RenderState { .Text = " catch " });
296 } else {295 } else {
297 const text = switch (prefix_op_node.op) {296 const text = switch (prefix_op_node.op) {
298 ast.Node.InfixOp.Op.Add => " + ",297 ast.Node.InfixOp.Op.Add => " + ",
...@@ -340,46 +339,46 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -340,46 +339,46 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
340 ast.Node.InfixOp.Op.Catch => unreachable,339 ast.Node.InfixOp.Op.Catch => unreachable,
341 };340 };
342341
343 try stack.push(RenderState { .Text = text });342 try stack.append(RenderState { .Text = text });
344 }343 }
345 try stack.push(RenderState { .Expression = prefix_op_node.lhs });344 try stack.append(RenderState { .Expression = prefix_op_node.lhs });
346 },345 },
347 ast.Node.Id.PrefixOp => {346 ast.Node.Id.PrefixOp => {
348 const prefix_op_node = @fieldParentPtr(ast.Node.PrefixOp, "base", base);347 const prefix_op_node = @fieldParentPtr(ast.Node.PrefixOp, "base", base);
349 try stack.push(RenderState { .Expression = prefix_op_node.rhs });348 try stack.append(RenderState { .Expression = prefix_op_node.rhs });
350 switch (prefix_op_node.op) {349 switch (prefix_op_node.op) {
351 ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| {350 ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| {
352 try stream.write("&");351 try stream.write("&");
353 if (addr_of_info.volatile_token != null) {352 if (addr_of_info.volatile_token != null) {
354 try stack.push(RenderState { .Text = "volatile "});353 try stack.append(RenderState { .Text = "volatile "});
355 }354 }
356 if (addr_of_info.const_token != null) {355 if (addr_of_info.const_token != null) {
357 try stack.push(RenderState { .Text = "const "});356 try stack.append(RenderState { .Text = "const "});
358 }357 }
359 if (addr_of_info.align_expr) |align_expr| {358 if (addr_of_info.align_expr) |align_expr| {
360 try stream.print("align(");359 try stream.print("align(");
361 try stack.push(RenderState { .Text = ") "});360 try stack.append(RenderState { .Text = ") "});
362 try stack.push(RenderState { .Expression = align_expr});361 try stack.append(RenderState { .Expression = align_expr});
363 }362 }
364 },363 },
365 ast.Node.PrefixOp.Op.SliceType => |addr_of_info| {364 ast.Node.PrefixOp.Op.SliceType => |addr_of_info| {
366 try stream.write("[]");365 try stream.write("[]");
367 if (addr_of_info.volatile_token != null) {366 if (addr_of_info.volatile_token != null) {
368 try stack.push(RenderState { .Text = "volatile "});367 try stack.append(RenderState { .Text = "volatile "});
369 }368 }
370 if (addr_of_info.const_token != null) {369 if (addr_of_info.const_token != null) {
371 try stack.push(RenderState { .Text = "const "});370 try stack.append(RenderState { .Text = "const "});
372 }371 }
373 if (addr_of_info.align_expr) |align_expr| {372 if (addr_of_info.align_expr) |align_expr| {
374 try stream.print("align(");373 try stream.print("align(");
375 try stack.push(RenderState { .Text = ") "});374 try stack.append(RenderState { .Text = ") "});
376 try stack.push(RenderState { .Expression = align_expr});375 try stack.append(RenderState { .Expression = align_expr});
377 }376 }
378 },377 },
379 ast.Node.PrefixOp.Op.ArrayType => |array_index| {378 ast.Node.PrefixOp.Op.ArrayType => |array_index| {
380 try stack.push(RenderState { .Text = "]"});379 try stack.append(RenderState { .Text = "]"});
381 try stack.push(RenderState { .Expression = array_index});380 try stack.append(RenderState { .Expression = array_index});
382 try stack.push(RenderState { .Text = "["});381 try stack.append(RenderState { .Text = "["});
383 },382 },
384 ast.Node.PrefixOp.Op.BitNot => try stream.write("~"),383 ast.Node.PrefixOp.Op.BitNot => try stream.write("~"),
385 ast.Node.PrefixOp.Op.BoolNot => try stream.write("!"),384 ast.Node.PrefixOp.Op.BoolNot => try stream.write("!"),
...@@ -399,70 +398,70 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -399,70 +398,70 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
399398
400 switch (suffix_op.op) {399 switch (suffix_op.op) {
401 @TagType(ast.Node.SuffixOp.Op).Call => |*call_info| {400 @TagType(ast.Node.SuffixOp.Op).Call => |*call_info| {
402 try stack.push(RenderState { .Text = ")"});401 try stack.append(RenderState { .Text = ")"});
403 var i = call_info.params.len;402 var i = call_info.params.len;
404 while (i != 0) {403 while (i != 0) {
405 i -= 1;404 i -= 1;
406 const param_node = *call_info.params.at(i);405 const param_node = *call_info.params.at(i);
407 try stack.push(RenderState { .Expression = param_node});406 try stack.append(RenderState { .Expression = param_node});
408 if (i != 0) {407 if (i != 0) {
409 try stack.push(RenderState { .Text = ", " });408 try stack.append(RenderState { .Text = ", " });
410 }409 }
411 }410 }
412 try stack.push(RenderState { .Text = "("});411 try stack.append(RenderState { .Text = "("});
413 try stack.push(RenderState { .Expression = suffix_op.lhs });412 try stack.append(RenderState { .Expression = suffix_op.lhs });
414413
415 if (call_info.async_attr) |async_attr| {414 if (call_info.async_attr) |async_attr| {
416 try stack.push(RenderState { .Text = " "});415 try stack.append(RenderState { .Text = " "});
417 try stack.push(RenderState { .Expression = &async_attr.base });416 try stack.append(RenderState { .Expression = &async_attr.base });
418 }417 }
419 },418 },
420 ast.Node.SuffixOp.Op.ArrayAccess => |index_expr| {419 ast.Node.SuffixOp.Op.ArrayAccess => |index_expr| {
421 try stack.push(RenderState { .Text = "]"});420 try stack.append(RenderState { .Text = "]"});
422 try stack.push(RenderState { .Expression = index_expr});421 try stack.append(RenderState { .Expression = index_expr});
423 try stack.push(RenderState { .Text = "["});422 try stack.append(RenderState { .Text = "["});
424 try stack.push(RenderState { .Expression = suffix_op.lhs });423 try stack.append(RenderState { .Expression = suffix_op.lhs });
425 },424 },
426 @TagType(ast.Node.SuffixOp.Op).Slice => |range| {425 @TagType(ast.Node.SuffixOp.Op).Slice => |range| {
427 try stack.push(RenderState { .Text = "]"});426 try stack.append(RenderState { .Text = "]"});
428 if (range.end) |end| {427 if (range.end) |end| {
429 try stack.push(RenderState { .Expression = end});428 try stack.append(RenderState { .Expression = end});
430 }429 }
431 try stack.push(RenderState { .Text = ".."});430 try stack.append(RenderState { .Text = ".."});
432 try stack.push(RenderState { .Expression = range.start});431 try stack.append(RenderState { .Expression = range.start});
433 try stack.push(RenderState { .Text = "["});432 try stack.append(RenderState { .Text = "["});
434 try stack.push(RenderState { .Expression = suffix_op.lhs });433 try stack.append(RenderState { .Expression = suffix_op.lhs });
435 },434 },
436 ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {435 ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {
437 if (field_inits.len == 0) {436 if (field_inits.len == 0) {
438 try stack.push(RenderState { .Text = "{}" });437 try stack.append(RenderState { .Text = "{}" });
439 try stack.push(RenderState { .Expression = suffix_op.lhs });438 try stack.append(RenderState { .Expression = suffix_op.lhs });
440 continue;439 continue;
441 }440 }
442 if (field_inits.len == 1) {441 if (field_inits.len == 1) {
443 const field_init = *field_inits.at(0);442 const field_init = *field_inits.at(0);
444443
445 try stack.push(RenderState { .Text = " }" });444 try stack.append(RenderState { .Text = " }" });
446 try stack.push(RenderState { .Expression = field_init });445 try stack.append(RenderState { .Expression = field_init });
447 try stack.push(RenderState { .Text = "{ " });446 try stack.append(RenderState { .Text = "{ " });
448 try stack.push(RenderState { .Expression = suffix_op.lhs });447 try stack.append(RenderState { .Expression = suffix_op.lhs });
449 continue;448 continue;
450 }449 }
451 try stack.push(RenderState { .Text = "}"});450 try stack.append(RenderState { .Text = "}"});
452 try stack.push(RenderState.PrintIndent);451 try stack.append(RenderState.PrintIndent);
453 try stack.push(RenderState { .Indent = indent });452 try stack.append(RenderState { .Indent = indent });
454 try stack.push(RenderState { .Text = "\n" });453 try stack.append(RenderState { .Text = "\n" });
455 var i = field_inits.len;454 var i = field_inits.len;
456 while (i != 0) {455 while (i != 0) {
457 i -= 1;456 i -= 1;
458 const field_init = *field_inits.at(i);457 const field_init = *field_inits.at(i);
459 if (field_init.id != ast.Node.Id.LineComment) {458 if (field_init.id != ast.Node.Id.LineComment) {
460 try stack.push(RenderState { .Text = "," });459 try stack.append(RenderState { .Text = "," });
461 }460 }
462 try stack.push(RenderState { .Expression = field_init });461 try stack.append(RenderState { .Expression = field_init });
463 try stack.push(RenderState.PrintIndent);462 try stack.append(RenderState.PrintIndent);
464 if (i != 0) {463 if (i != 0) {
465 try stack.push(RenderState { .Text = blk: {464 try stack.append(RenderState { .Text = blk: {
466 const prev_node = *field_inits.at(i - 1);465 const prev_node = *field_inits.at(i - 1);
467 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;466 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;
468 const loc = tree.tokenLocation(prev_node_last_token_end, field_init.firstToken());467 const loc = tree.tokenLocation(prev_node_last_token_end, field_init.firstToken());
...@@ -473,40 +472,40 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -473,40 +472,40 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
473 }});472 }});
474 }473 }
475 }474 }
476 try stack.push(RenderState { .Indent = indent + indent_delta });475 try stack.append(RenderState { .Indent = indent + indent_delta });
477 try stack.push(RenderState { .Text = "{\n"});476 try stack.append(RenderState { .Text = "{\n"});
478 try stack.push(RenderState { .Expression = suffix_op.lhs });477 try stack.append(RenderState { .Expression = suffix_op.lhs });
479 },478 },
480 ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {479 ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {
481 if (exprs.len == 0) {480 if (exprs.len == 0) {
482 try stack.push(RenderState { .Text = "{}" });481 try stack.append(RenderState { .Text = "{}" });
483 try stack.push(RenderState { .Expression = suffix_op.lhs });482 try stack.append(RenderState { .Expression = suffix_op.lhs });
484 continue;483 continue;
485 }484 }
486 if (exprs.len == 1) {485 if (exprs.len == 1) {
487 const expr = *exprs.at(0);486 const expr = *exprs.at(0);
488487
489 try stack.push(RenderState { .Text = "}" });488 try stack.append(RenderState { .Text = "}" });
490 try stack.push(RenderState { .Expression = expr });489 try stack.append(RenderState { .Expression = expr });
491 try stack.push(RenderState { .Text = "{" });490 try stack.append(RenderState { .Text = "{" });
492 try stack.push(RenderState { .Expression = suffix_op.lhs });491 try stack.append(RenderState { .Expression = suffix_op.lhs });
493 continue;492 continue;
494 }493 }
495494
496 try stack.push(RenderState { .Text = "}"});495 try stack.append(RenderState { .Text = "}"});
497 try stack.push(RenderState.PrintIndent);496 try stack.append(RenderState.PrintIndent);
498 try stack.push(RenderState { .Indent = indent });497 try stack.append(RenderState { .Indent = indent });
499 var i = exprs.len;498 var i = exprs.len;
500 while (i != 0) {499 while (i != 0) {
501 i -= 1;500 i -= 1;
502 const expr = *exprs.at(i);501 const expr = *exprs.at(i);
503 try stack.push(RenderState { .Text = ",\n" });502 try stack.append(RenderState { .Text = ",\n" });
504 try stack.push(RenderState { .Expression = expr });503 try stack.append(RenderState { .Expression = expr });
505 try stack.push(RenderState.PrintIndent);504 try stack.append(RenderState.PrintIndent);
506 }505 }
507 try stack.push(RenderState { .Indent = indent + indent_delta });506 try stack.append(RenderState { .Indent = indent + indent_delta });
508 try stack.push(RenderState { .Text = "{\n"});507 try stack.append(RenderState { .Text = "{\n"});
509 try stack.push(RenderState { .Expression = suffix_op.lhs });508 try stack.append(RenderState { .Expression = suffix_op.lhs });
510 },509 },
511 }510 }
512 },511 },
...@@ -514,8 +513,8 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -514,8 +513,8 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
514 const flow_expr = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", base);513 const flow_expr = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", base);
515514
516 if (flow_expr.rhs) |rhs| {515 if (flow_expr.rhs) |rhs| {
517 try stack.push(RenderState { .Expression = rhs });516 try stack.append(RenderState { .Expression = rhs });
518 try stack.push(RenderState { .Text = " " });517 try stack.append(RenderState { .Text = " " });
519 }518 }
520519
521 switch (flow_expr.kind) {520 switch (flow_expr.kind) {
...@@ -523,14 +522,14 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -523,14 +522,14 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
523 try stream.print("break");522 try stream.print("break");
524 if (maybe_label) |label| {523 if (maybe_label) |label| {
525 try stream.print(" :");524 try stream.print(" :");
526 try stack.push(RenderState { .Expression = label });525 try stack.append(RenderState { .Expression = label });
527 }526 }
528 },527 },
529 ast.Node.ControlFlowExpression.Kind.Continue => |maybe_label| {528 ast.Node.ControlFlowExpression.Kind.Continue => |maybe_label| {
530 try stream.print("continue");529 try stream.print("continue");
531 if (maybe_label) |label| {530 if (maybe_label) |label| {
532 try stream.print(" :");531 try stream.print(" :");
533 try stack.push(RenderState { .Expression = label });532 try stack.append(RenderState { .Expression = label });
534 }533 }
535 },534 },
536 ast.Node.ControlFlowExpression.Kind.Return => {535 ast.Node.ControlFlowExpression.Kind.Return => {
...@@ -541,48 +540,48 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -541,48 +540,48 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
541 },540 },
542 ast.Node.Id.Payload => {541 ast.Node.Id.Payload => {
543 const payload = @fieldParentPtr(ast.Node.Payload, "base", base);542 const payload = @fieldParentPtr(ast.Node.Payload, "base", base);
544 try stack.push(RenderState { .Text = "|"});543 try stack.append(RenderState { .Text = "|"});
545 try stack.push(RenderState { .Expression = payload.error_symbol });544 try stack.append(RenderState { .Expression = payload.error_symbol });
546 try stack.push(RenderState { .Text = "|"});545 try stack.append(RenderState { .Text = "|"});
547 },546 },
548 ast.Node.Id.PointerPayload => {547 ast.Node.Id.PointerPayload => {
549 const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base);548 const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base);
550 try stack.push(RenderState { .Text = "|"});549 try stack.append(RenderState { .Text = "|"});
551 try stack.push(RenderState { .Expression = payload.value_symbol });550 try stack.append(RenderState { .Expression = payload.value_symbol });
552551
553 if (payload.ptr_token) |ptr_token| {552 if (payload.ptr_token) |ptr_token| {
554 try stack.push(RenderState { .Text = tree.tokenSlice(ptr_token) });553 try stack.append(RenderState { .Text = tree.tokenSlice(ptr_token) });
555 }554 }
556555
557 try stack.push(RenderState { .Text = "|"});556 try stack.append(RenderState { .Text = "|"});
558 },557 },
559 ast.Node.Id.PointerIndexPayload => {558 ast.Node.Id.PointerIndexPayload => {
560 const payload = @fieldParentPtr(ast.Node.PointerIndexPayload, "base", base);559 const payload = @fieldParentPtr(ast.Node.PointerIndexPayload, "base", base);
561 try stack.push(RenderState { .Text = "|"});560 try stack.append(RenderState { .Text = "|"});
562561
563 if (payload.index_symbol) |index_symbol| {562 if (payload.index_symbol) |index_symbol| {
564 try stack.push(RenderState { .Expression = index_symbol });563 try stack.append(RenderState { .Expression = index_symbol });
565 try stack.push(RenderState { .Text = ", "});564 try stack.append(RenderState { .Text = ", "});
566 }565 }
567566
568 try stack.push(RenderState { .Expression = payload.value_symbol });567 try stack.append(RenderState { .Expression = payload.value_symbol });
569568
570 if (payload.ptr_token) |ptr_token| {569 if (payload.ptr_token) |ptr_token| {
571 try stack.push(RenderState { .Text = tree.tokenSlice(ptr_token) });570 try stack.append(RenderState { .Text = tree.tokenSlice(ptr_token) });
572 }571 }
573572
574 try stack.push(RenderState { .Text = "|"});573 try stack.append(RenderState { .Text = "|"});
575 },574 },
576 ast.Node.Id.GroupedExpression => {575 ast.Node.Id.GroupedExpression => {
577 const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base);576 const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base);
578 try stack.push(RenderState { .Text = ")"});577 try stack.append(RenderState { .Text = ")"});
579 try stack.push(RenderState { .Expression = grouped_expr.expr });578 try stack.append(RenderState { .Expression = grouped_expr.expr });
580 try stack.push(RenderState { .Text = "("});579 try stack.append(RenderState { .Text = "("});
581 },580 },
582 ast.Node.Id.FieldInitializer => {581 ast.Node.Id.FieldInitializer => {
583 const field_init = @fieldParentPtr(ast.Node.FieldInitializer, "base", base);582 const field_init = @fieldParentPtr(ast.Node.FieldInitializer, "base", base);
584 try stream.print(".{} = ", tree.tokenSlice(field_init.name_token));583 try stream.print(".{} = ", tree.tokenSlice(field_init.name_token));
585 try stack.push(RenderState { .Expression = field_init.expr });584 try stack.append(RenderState { .Expression = field_init.expr });
586 },585 },
587 ast.Node.Id.IntegerLiteral => {586 ast.Node.Id.IntegerLiteral => {
588 const integer_literal = @fieldParentPtr(ast.Node.IntegerLiteral, "base", base);587 const integer_literal = @fieldParentPtr(ast.Node.IntegerLiteral, "base", base);
...@@ -640,20 +639,20 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -640,20 +639,20 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
640 }639 }
641640
642 if (container_decl.fields_and_decls.len == 0) {641 if (container_decl.fields_and_decls.len == 0) {
643 try stack.push(RenderState { .Text = "{}"});642 try stack.append(RenderState { .Text = "{}"});
644 } else {643 } else {
645 try stack.push(RenderState { .Text = "}"});644 try stack.append(RenderState { .Text = "}"});
646 try stack.push(RenderState.PrintIndent);645 try stack.append(RenderState.PrintIndent);
647 try stack.push(RenderState { .Indent = indent });646 try stack.append(RenderState { .Indent = indent });
648 try stack.push(RenderState { .Text = "\n"});647 try stack.append(RenderState { .Text = "\n"});
649648
650 var i = container_decl.fields_and_decls.len;649 var i = container_decl.fields_and_decls.len;
651 while (i != 0) {650 while (i != 0) {
652 i -= 1;651 i -= 1;
653 const node = *container_decl.fields_and_decls.at(i);652 const node = *container_decl.fields_and_decls.at(i);
654 try stack.push(RenderState { .TopLevelDecl = node});653 try stack.append(RenderState { .TopLevelDecl = node});
655 try stack.push(RenderState.PrintIndent);654 try stack.append(RenderState.PrintIndent);
656 try stack.push(RenderState {655 try stack.append(RenderState {
657 .Text = blk: {656 .Text = blk: {
658 if (i != 0) {657 if (i != 0) {
659 const prev_node = *container_decl.fields_and_decls.at(i - 1);658 const prev_node = *container_decl.fields_and_decls.at(i - 1);
...@@ -667,25 +666,25 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -667,25 +666,25 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
667 },666 },
668 });667 });
669 }668 }
670 try stack.push(RenderState { .Indent = indent + indent_delta});669 try stack.append(RenderState { .Indent = indent + indent_delta});
671 try stack.push(RenderState { .Text = "{"});670 try stack.append(RenderState { .Text = "{"});
672 }671 }
673672
674 switch (container_decl.init_arg_expr) {673 switch (container_decl.init_arg_expr) {
675 ast.Node.ContainerDecl.InitArg.None => try stack.push(RenderState { .Text = " "}),674 ast.Node.ContainerDecl.InitArg.None => try stack.append(RenderState { .Text = " "}),
676 ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {675 ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {
677 if (enum_tag_type) |expr| {676 if (enum_tag_type) |expr| {
678 try stack.push(RenderState { .Text = ")) "});677 try stack.append(RenderState { .Text = ")) "});
679 try stack.push(RenderState { .Expression = expr});678 try stack.append(RenderState { .Expression = expr});
680 try stack.push(RenderState { .Text = "(enum("});679 try stack.append(RenderState { .Text = "(enum("});
681 } else {680 } else {
682 try stack.push(RenderState { .Text = "(enum) "});681 try stack.append(RenderState { .Text = "(enum) "});
683 }682 }
684 },683 },
685 ast.Node.ContainerDecl.InitArg.Type => |type_expr| {684 ast.Node.ContainerDecl.InitArg.Type => |type_expr| {
686 try stack.push(RenderState { .Text = ") "});685 try stack.append(RenderState { .Text = ") "});
687 try stack.push(RenderState { .Expression = type_expr});686 try stack.append(RenderState { .Expression = type_expr});
688 try stack.push(RenderState { .Text = "("});687 try stack.append(RenderState { .Text = "("});
689 },688 },
690 }689 }
691 },690 },
...@@ -710,28 +709,28 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -710,28 +709,28 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
710709
711710
712 try stream.write("error{");711 try stream.write("error{");
713 try stack.push(RenderState { .Text = "}" });712 try stack.append(RenderState { .Text = "}" });
714 try stack.push(RenderState { .TopLevelDecl = node });713 try stack.append(RenderState { .TopLevelDecl = node });
715 continue;714 continue;
716 }715 }
717716
718 try stream.write("error{");717 try stream.write("error{");
719718
720 try stack.push(RenderState { .Text = "}"});719 try stack.append(RenderState { .Text = "}"});
721 try stack.push(RenderState.PrintIndent);720 try stack.append(RenderState.PrintIndent);
722 try stack.push(RenderState { .Indent = indent });721 try stack.append(RenderState { .Indent = indent });
723 try stack.push(RenderState { .Text = "\n"});722 try stack.append(RenderState { .Text = "\n"});
724723
725 var i = err_set_decl.decls.len;724 var i = err_set_decl.decls.len;
726 while (i != 0) {725 while (i != 0) {
727 i -= 1;726 i -= 1;
728 const node = *err_set_decl.decls.at(i);727 const node = *err_set_decl.decls.at(i);
729 if (node.id != ast.Node.Id.LineComment) {728 if (node.id != ast.Node.Id.LineComment) {
730 try stack.push(RenderState { .Text = "," });729 try stack.append(RenderState { .Text = "," });
731 }730 }
732 try stack.push(RenderState { .TopLevelDecl = node });731 try stack.append(RenderState { .TopLevelDecl = node });
733 try stack.push(RenderState.PrintIndent);732 try stack.append(RenderState.PrintIndent);
734 try stack.push(RenderState {733 try stack.append(RenderState {
735 .Text = blk: {734 .Text = blk: {
736 if (i != 0) {735 if (i != 0) {
737 const prev_node = *err_set_decl.decls.at(i - 1);736 const prev_node = *err_set_decl.decls.at(i - 1);
...@@ -745,7 +744,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -745,7 +744,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
745 },744 },
746 });745 });
747 }746 }
748 try stack.push(RenderState { .Indent = indent + indent_delta});747 try stack.append(RenderState { .Indent = indent + indent_delta});
749 },748 },
750 ast.Node.Id.MultilineStringLiteral => {749 ast.Node.Id.MultilineStringLiteral => {
751 const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base);750 const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base);
...@@ -766,14 +765,14 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -766,14 +765,14 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
766 ast.Node.Id.BuiltinCall => {765 ast.Node.Id.BuiltinCall => {
767 const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base);766 const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base);
768 try stream.print("{}(", tree.tokenSlice(builtin_call.builtin_token));767 try stream.print("{}(", tree.tokenSlice(builtin_call.builtin_token));
769 try stack.push(RenderState { .Text = ")"});768 try stack.append(RenderState { .Text = ")"});
770 var i = builtin_call.params.len;769 var i = builtin_call.params.len;
771 while (i != 0) {770 while (i != 0) {
772 i -= 1;771 i -= 1;
773 const param_node = *builtin_call.params.at(i);772 const param_node = *builtin_call.params.at(i);
774 try stack.push(RenderState { .Expression = param_node});773 try stack.append(RenderState { .Expression = param_node});
775 if (i != 0) {774 if (i != 0) {
776 try stack.push(RenderState { .Text = ", " });775 try stack.append(RenderState { .Text = ", " });
777 }776 }
778 }777 }
779 },778 },
...@@ -782,63 +781,63 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -782,63 +781,63 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
782781
783 switch (fn_proto.return_type) {782 switch (fn_proto.return_type) {
784 ast.Node.FnProto.ReturnType.Explicit => |node| {783 ast.Node.FnProto.ReturnType.Explicit => |node| {
785 try stack.push(RenderState { .Expression = node});784 try stack.append(RenderState { .Expression = node});
786 },785 },
787 ast.Node.FnProto.ReturnType.InferErrorSet => |node| {786 ast.Node.FnProto.ReturnType.InferErrorSet => |node| {
788 try stack.push(RenderState { .Expression = node});787 try stack.append(RenderState { .Expression = node});
789 try stack.push(RenderState { .Text = "!"});788 try stack.append(RenderState { .Text = "!"});
790 },789 },
791 }790 }
792791
793 if (fn_proto.align_expr) |align_expr| {792 if (fn_proto.align_expr) |align_expr| {
794 try stack.push(RenderState { .Text = ") " });793 try stack.append(RenderState { .Text = ") " });
795 try stack.push(RenderState { .Expression = align_expr});794 try stack.append(RenderState { .Expression = align_expr});
796 try stack.push(RenderState { .Text = "align(" });795 try stack.append(RenderState { .Text = "align(" });
797 }796 }
798797
799 try stack.push(RenderState { .Text = ") " });798 try stack.append(RenderState { .Text = ") " });
800 var i = fn_proto.params.len;799 var i = fn_proto.params.len;
801 while (i != 0) {800 while (i != 0) {
802 i -= 1;801 i -= 1;
803 const param_decl_node = *fn_proto.params.at(i);802 const param_decl_node = *fn_proto.params.at(i);
804 try stack.push(RenderState { .ParamDecl = param_decl_node});803 try stack.append(RenderState { .ParamDecl = param_decl_node});
805 if (i != 0) {804 if (i != 0) {
806 try stack.push(RenderState { .Text = ", " });805 try stack.append(RenderState { .Text = ", " });
807 }806 }
808 }807 }
809808
810 try stack.push(RenderState { .Text = "(" });809 try stack.append(RenderState { .Text = "(" });
811 if (fn_proto.name_token) |name_token| {810 if (fn_proto.name_token) |name_token| {
812 try stack.push(RenderState { .Text = tree.tokenSlice(name_token) });811 try stack.append(RenderState { .Text = tree.tokenSlice(name_token) });
813 try stack.push(RenderState { .Text = " " });812 try stack.append(RenderState { .Text = " " });
814 }813 }
815814
816 try stack.push(RenderState { .Text = "fn" });815 try stack.append(RenderState { .Text = "fn" });
817816
818 if (fn_proto.async_attr) |async_attr| {817 if (fn_proto.async_attr) |async_attr| {
819 try stack.push(RenderState { .Text = " " });818 try stack.append(RenderState { .Text = " " });
820 try stack.push(RenderState { .Expression = &async_attr.base });819 try stack.append(RenderState { .Expression = &async_attr.base });
821 }820 }
822821
823 if (fn_proto.cc_token) |cc_token| {822 if (fn_proto.cc_token) |cc_token| {
824 try stack.push(RenderState { .Text = " " });823 try stack.append(RenderState { .Text = " " });
825 try stack.push(RenderState { .Text = tree.tokenSlice(cc_token) });824 try stack.append(RenderState { .Text = tree.tokenSlice(cc_token) });
826 }825 }
827826
828 if (fn_proto.lib_name) |lib_name| {827 if (fn_proto.lib_name) |lib_name| {
829 try stack.push(RenderState { .Text = " " });828 try stack.append(RenderState { .Text = " " });
830 try stack.push(RenderState { .Expression = lib_name });829 try stack.append(RenderState { .Expression = lib_name });
831 }830 }
832 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {831 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
833 try stack.push(RenderState { .Text = " " });832 try stack.append(RenderState { .Text = " " });
834 try stack.push(RenderState { .Text = tree.tokenSlice(extern_export_inline_token) });833 try stack.append(RenderState { .Text = tree.tokenSlice(extern_export_inline_token) });
835 }834 }
836835
837 if (fn_proto.visib_token) |visib_token_index| {836 if (fn_proto.visib_token) |visib_token_index| {
838 const visib_token = tree.tokens.at(visib_token_index);837 const visib_token = tree.tokens.at(visib_token_index);
839 assert(visib_token.id == Token.Id.Keyword_pub or visib_token.id == Token.Id.Keyword_export);838 assert(visib_token.id == Token.Id.Keyword_pub or visib_token.id == Token.Id.Keyword_export);
840 try stack.push(RenderState { .Text = " " });839 try stack.append(RenderState { .Text = " " });
841 try stack.push(RenderState { .Text = tree.tokenSlice(visib_token_index) });840 try stack.append(RenderState { .Text = tree.tokenSlice(visib_token_index) });
842 }841 }
843 },842 },
844 ast.Node.Id.PromiseType => {843 ast.Node.Id.PromiseType => {
...@@ -846,7 +845,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -846,7 +845,7 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
846 try stream.write(tree.tokenSlice(promise_type.promise_token));845 try stream.write(tree.tokenSlice(promise_type.promise_token));
847 if (promise_type.result) |result| {846 if (promise_type.result) |result| {
848 try stream.write(tree.tokenSlice(result.arrow_token));847 try stream.write(tree.tokenSlice(result.arrow_token));
849 try stack.push(RenderState { .Expression = result.return_type});848 try stack.append(RenderState { .Expression = result.return_type});
850 }849 }
851 },850 },
852 ast.Node.Id.LineComment => {851 ast.Node.Id.LineComment => {
...@@ -860,23 +859,23 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -860,23 +859,23 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
860 try stream.print("{} (", tree.tokenSlice(switch_node.switch_token));859 try stream.print("{} (", tree.tokenSlice(switch_node.switch_token));
861860
862 if (switch_node.cases.len == 0) {861 if (switch_node.cases.len == 0) {
863 try stack.push(RenderState { .Text = ") {}"});862 try stack.append(RenderState { .Text = ") {}"});
864 try stack.push(RenderState { .Expression = switch_node.expr });863 try stack.append(RenderState { .Expression = switch_node.expr });
865 continue;864 continue;
866 }865 }
867866
868 try stack.push(RenderState { .Text = "}"});867 try stack.append(RenderState { .Text = "}"});
869 try stack.push(RenderState.PrintIndent);868 try stack.append(RenderState.PrintIndent);
870 try stack.push(RenderState { .Indent = indent });869 try stack.append(RenderState { .Indent = indent });
871 try stack.push(RenderState { .Text = "\n"});870 try stack.append(RenderState { .Text = "\n"});
872871
873 var i = switch_node.cases.len;872 var i = switch_node.cases.len;
874 while (i != 0) {873 while (i != 0) {
875 i -= 1;874 i -= 1;
876 const node = *switch_node.cases.at(i);875 const node = *switch_node.cases.at(i);
877 try stack.push(RenderState { .Expression = node});876 try stack.append(RenderState { .Expression = node});
878 try stack.push(RenderState.PrintIndent);877 try stack.append(RenderState.PrintIndent);
879 try stack.push(RenderState {878 try stack.append(RenderState {
880 .Text = blk: {879 .Text = blk: {
881 if (i != 0) {880 if (i != 0) {
882 const prev_node = *switch_node.cases.at(i - 1);881 const prev_node = *switch_node.cases.at(i - 1);
...@@ -890,29 +889,29 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -890,29 +889,29 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
890 },889 },
891 });890 });
892 }891 }
893 try stack.push(RenderState { .Indent = indent + indent_delta});892 try stack.append(RenderState { .Indent = indent + indent_delta});
894 try stack.push(RenderState { .Text = ") {"});893 try stack.append(RenderState { .Text = ") {"});
895 try stack.push(RenderState { .Expression = switch_node.expr });894 try stack.append(RenderState { .Expression = switch_node.expr });
896 },895 },
897 ast.Node.Id.SwitchCase => {896 ast.Node.Id.SwitchCase => {
898 const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base);897 const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base);
899898
900 try stack.push(RenderState { .Token = switch_case.lastToken() + 1 });899 try stack.append(RenderState { .Token = switch_case.lastToken() + 1 });
901 try stack.push(RenderState { .Expression = switch_case.expr });900 try stack.append(RenderState { .Expression = switch_case.expr });
902 if (switch_case.payload) |payload| {901 if (switch_case.payload) |payload| {
903 try stack.push(RenderState { .Text = " " });902 try stack.append(RenderState { .Text = " " });
904 try stack.push(RenderState { .Expression = payload });903 try stack.append(RenderState { .Expression = payload });
905 }904 }
906 try stack.push(RenderState { .Text = " => "});905 try stack.append(RenderState { .Text = " => "});
907906
908 var i = switch_case.items.len;907 var i = switch_case.items.len;
909 while (i != 0) {908 while (i != 0) {
910 i -= 1;909 i -= 1;
911 try stack.push(RenderState { .Expression = *switch_case.items.at(i) });910 try stack.append(RenderState { .Expression = *switch_case.items.at(i) });
912911
913 if (i != 0) {912 if (i != 0) {
914 try stack.push(RenderState.PrintIndent);913 try stack.append(RenderState.PrintIndent);
915 try stack.push(RenderState { .Text = ",\n" });914 try stack.append(RenderState { .Text = ",\n" });
916 }915 }
917 }916 }
918 },917 },
...@@ -929,20 +928,20 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -929,20 +928,20 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
929 ast.Node.Id.For, ast.Node.Id.While,928 ast.Node.Id.For, ast.Node.Id.While,
930 ast.Node.Id.Switch => {929 ast.Node.Id.Switch => {
931 try stream.print(" ");930 try stream.print(" ");
932 try stack.push(RenderState { .Expression = else_node.body });931 try stack.append(RenderState { .Expression = else_node.body });
933 },932 },
934 else => {933 else => {
935 try stack.push(RenderState { .Indent = indent });934 try stack.append(RenderState { .Indent = indent });
936 try stack.push(RenderState { .Expression = else_node.body });935 try stack.append(RenderState { .Expression = else_node.body });
937 try stack.push(RenderState.PrintIndent);936 try stack.append(RenderState.PrintIndent);
938 try stack.push(RenderState { .Indent = indent + indent_delta });937 try stack.append(RenderState { .Indent = indent + indent_delta });
939 try stack.push(RenderState { .Text = "\n" });938 try stack.append(RenderState { .Text = "\n" });
940 }939 }
941 }940 }
942941
943 if (else_node.payload) |payload| {942 if (else_node.payload) |payload| {
944 try stack.push(RenderState { .Text = " " });943 try stack.append(RenderState { .Text = " " });
945 try stack.push(RenderState { .Expression = payload });944 try stack.append(RenderState { .Expression = payload });
946 }945 }
947 },946 },
948 ast.Node.Id.While => {947 ast.Node.Id.While => {
...@@ -958,42 +957,42 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -958,42 +957,42 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
958 try stream.print("{} ", tree.tokenSlice(while_node.while_token));957 try stream.print("{} ", tree.tokenSlice(while_node.while_token));
959958
960 if (while_node.@"else") |@"else"| {959 if (while_node.@"else") |@"else"| {
961 try stack.push(RenderState { .Expression = &@"else".base });960 try stack.append(RenderState { .Expression = &@"else".base });
962961
963 if (while_node.body.id == ast.Node.Id.Block) {962 if (while_node.body.id == ast.Node.Id.Block) {
964 try stack.push(RenderState { .Text = " " });963 try stack.append(RenderState { .Text = " " });
965 } else {964 } else {
966 try stack.push(RenderState.PrintIndent);965 try stack.append(RenderState.PrintIndent);
967 try stack.push(RenderState { .Text = "\n" });966 try stack.append(RenderState { .Text = "\n" });
968 }967 }
969 }968 }
970969
971 if (while_node.body.id == ast.Node.Id.Block) {970 if (while_node.body.id == ast.Node.Id.Block) {
972 try stack.push(RenderState { .Expression = while_node.body });971 try stack.append(RenderState { .Expression = while_node.body });
973 try stack.push(RenderState { .Text = " " });972 try stack.append(RenderState { .Text = " " });
974 } else {973 } else {
975 try stack.push(RenderState { .Indent = indent });974 try stack.append(RenderState { .Indent = indent });
976 try stack.push(RenderState { .Expression = while_node.body });975 try stack.append(RenderState { .Expression = while_node.body });
977 try stack.push(RenderState.PrintIndent);976 try stack.append(RenderState.PrintIndent);
978 try stack.push(RenderState { .Indent = indent + indent_delta });977 try stack.append(RenderState { .Indent = indent + indent_delta });
979 try stack.push(RenderState { .Text = "\n" });978 try stack.append(RenderState { .Text = "\n" });
980 }979 }
981980
982 if (while_node.continue_expr) |continue_expr| {981 if (while_node.continue_expr) |continue_expr| {
983 try stack.push(RenderState { .Text = ")" });982 try stack.append(RenderState { .Text = ")" });
984 try stack.push(RenderState { .Expression = continue_expr });983 try stack.append(RenderState { .Expression = continue_expr });
985 try stack.push(RenderState { .Text = ": (" });984 try stack.append(RenderState { .Text = ": (" });
986 try stack.push(RenderState { .Text = " " });985 try stack.append(RenderState { .Text = " " });
987 }986 }
988987
989 if (while_node.payload) |payload| {988 if (while_node.payload) |payload| {
990 try stack.push(RenderState { .Expression = payload });989 try stack.append(RenderState { .Expression = payload });
991 try stack.push(RenderState { .Text = " " });990 try stack.append(RenderState { .Text = " " });
992 }991 }
993992
994 try stack.push(RenderState { .Text = ")" });993 try stack.append(RenderState { .Text = ")" });
995 try stack.push(RenderState { .Expression = while_node.condition });994 try stack.append(RenderState { .Expression = while_node.condition });
996 try stack.push(RenderState { .Text = "(" });995 try stack.append(RenderState { .Text = "(" });
997 },996 },
998 ast.Node.Id.For => {997 ast.Node.Id.For => {
999 const for_node = @fieldParentPtr(ast.Node.For, "base", base);998 const for_node = @fieldParentPtr(ast.Node.For, "base", base);
...@@ -1008,35 +1007,35 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -1008,35 +1007,35 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
1008 try stream.print("{} ", tree.tokenSlice(for_node.for_token));1007 try stream.print("{} ", tree.tokenSlice(for_node.for_token));
10091008
1010 if (for_node.@"else") |@"else"| {1009 if (for_node.@"else") |@"else"| {
1011 try stack.push(RenderState { .Expression = &@"else".base });1010 try stack.append(RenderState { .Expression = &@"else".base });
10121011
1013 if (for_node.body.id == ast.Node.Id.Block) {1012 if (for_node.body.id == ast.Node.Id.Block) {
1014 try stack.push(RenderState { .Text = " " });1013 try stack.append(RenderState { .Text = " " });
1015 } else {1014 } else {
1016 try stack.push(RenderState.PrintIndent);1015 try stack.append(RenderState.PrintIndent);
1017 try stack.push(RenderState { .Text = "\n" });1016 try stack.append(RenderState { .Text = "\n" });
1018 }1017 }
1019 }1018 }
10201019
1021 if (for_node.body.id == ast.Node.Id.Block) {1020 if (for_node.body.id == ast.Node.Id.Block) {
1022 try stack.push(RenderState { .Expression = for_node.body });1021 try stack.append(RenderState { .Expression = for_node.body });
1023 try stack.push(RenderState { .Text = " " });1022 try stack.append(RenderState { .Text = " " });
1024 } else {1023 } else {
1025 try stack.push(RenderState { .Indent = indent });1024 try stack.append(RenderState { .Indent = indent });
1026 try stack.push(RenderState { .Expression = for_node.body });1025 try stack.append(RenderState { .Expression = for_node.body });
1027 try stack.push(RenderState.PrintIndent);1026 try stack.append(RenderState.PrintIndent);
1028 try stack.push(RenderState { .Indent = indent + indent_delta });1027 try stack.append(RenderState { .Indent = indent + indent_delta });
1029 try stack.push(RenderState { .Text = "\n" });1028 try stack.append(RenderState { .Text = "\n" });
1030 }1029 }
10311030
1032 if (for_node.payload) |payload| {1031 if (for_node.payload) |payload| {
1033 try stack.push(RenderState { .Expression = payload });1032 try stack.append(RenderState { .Expression = payload });
1034 try stack.push(RenderState { .Text = " " });1033 try stack.append(RenderState { .Text = " " });
1035 }1034 }
10361035
1037 try stack.push(RenderState { .Text = ")" });1036 try stack.append(RenderState { .Text = ")" });
1038 try stack.push(RenderState { .Expression = for_node.array_expr });1037 try stack.append(RenderState { .Expression = for_node.array_expr });
1039 try stack.push(RenderState { .Text = "(" });1038 try stack.append(RenderState { .Text = "(" });
1040 },1039 },
1041 ast.Node.Id.If => {1040 ast.Node.Id.If => {
1042 const if_node = @fieldParentPtr(ast.Node.If, "base", base);1041 const if_node = @fieldParentPtr(ast.Node.If, "base", base);
...@@ -1047,42 +1046,42 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -1047,42 +1046,42 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
1047 ast.Node.Id.For, ast.Node.Id.While,1046 ast.Node.Id.For, ast.Node.Id.While,
1048 ast.Node.Id.Switch => {1047 ast.Node.Id.Switch => {
1049 if (if_node.@"else") |@"else"| {1048 if (if_node.@"else") |@"else"| {
1050 try stack.push(RenderState { .Expression = &@"else".base });1049 try stack.append(RenderState { .Expression = &@"else".base });
10511050
1052 if (if_node.body.id == ast.Node.Id.Block) {1051 if (if_node.body.id == ast.Node.Id.Block) {
1053 try stack.push(RenderState { .Text = " " });1052 try stack.append(RenderState { .Text = " " });
1054 } else {1053 } else {
1055 try stack.push(RenderState.PrintIndent);1054 try stack.append(RenderState.PrintIndent);
1056 try stack.push(RenderState { .Text = "\n" });1055 try stack.append(RenderState { .Text = "\n" });
1057 }1056 }
1058 }1057 }
1059 },1058 },
1060 else => {1059 else => {
1061 if (if_node.@"else") |@"else"| {1060 if (if_node.@"else") |@"else"| {
1062 try stack.push(RenderState { .Expression = @"else".body });1061 try stack.append(RenderState { .Expression = @"else".body });
10631062
1064 if (@"else".payload) |payload| {1063 if (@"else".payload) |payload| {
1065 try stack.push(RenderState { .Text = " " });1064 try stack.append(RenderState { .Text = " " });
1066 try stack.push(RenderState { .Expression = payload });1065 try stack.append(RenderState { .Expression = payload });
1067 }1066 }
10681067
1069 try stack.push(RenderState { .Text = " " });1068 try stack.append(RenderState { .Text = " " });
1070 try stack.push(RenderState { .Text = tree.tokenSlice(@"else".else_token) });1069 try stack.append(RenderState { .Text = tree.tokenSlice(@"else".else_token) });
1071 try stack.push(RenderState { .Text = " " });1070 try stack.append(RenderState { .Text = " " });
1072 }1071 }
1073 }1072 }
1074 }1073 }
10751074
1076 try stack.push(RenderState { .Expression = if_node.body });1075 try stack.append(RenderState { .Expression = if_node.body });
10771076
1078 if (if_node.payload) |payload| {1077 if (if_node.payload) |payload| {
1079 try stack.push(RenderState { .Text = " " });1078 try stack.append(RenderState { .Text = " " });
1080 try stack.push(RenderState { .Expression = payload });1079 try stack.append(RenderState { .Expression = payload });
1081 }1080 }
10821081
1083 try stack.push(RenderState { .NonBreakToken = if_node.condition.lastToken() + 1 });1082 try stack.append(RenderState { .NonBreakToken = if_node.condition.lastToken() + 1 });
1084 try stack.push(RenderState { .Expression = if_node.condition });1083 try stack.append(RenderState { .Expression = if_node.condition });
1085 try stack.push(RenderState { .Text = "(" });1084 try stack.append(RenderState { .Text = "(" });
1086 },1085 },
1087 ast.Node.Id.Asm => {1086 ast.Node.Id.Asm => {
1088 const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base);1087 const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base);
...@@ -1092,33 +1091,33 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -1092,33 +1091,33 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
1092 try stream.print("{} ", tree.tokenSlice(volatile_token));1091 try stream.print("{} ", tree.tokenSlice(volatile_token));
1093 }1092 }
10941093
1095 try stack.push(RenderState { .Indent = indent });1094 try stack.append(RenderState { .Indent = indent });
1096 try stack.push(RenderState { .Text = ")" });1095 try stack.append(RenderState { .Text = ")" });
1097 {1096 {
1098 var i = asm_node.clobbers.len;1097 var i = asm_node.clobbers.len;
1099 while (i != 0) {1098 while (i != 0) {
1100 i -= 1;1099 i -= 1;
1101 try stack.push(RenderState { .Expression = *asm_node.clobbers.at(i) });1100 try stack.append(RenderState { .Expression = *asm_node.clobbers.at(i) });
11021101
1103 if (i != 0) {1102 if (i != 0) {
1104 try stack.push(RenderState { .Text = ", " });1103 try stack.append(RenderState { .Text = ", " });
1105 }1104 }
1106 }1105 }
1107 }1106 }
1108 try stack.push(RenderState { .Text = ": " });1107 try stack.append(RenderState { .Text = ": " });
1109 try stack.push(RenderState.PrintIndent);1108 try stack.append(RenderState.PrintIndent);
1110 try stack.push(RenderState { .Indent = indent + indent_delta });1109 try stack.append(RenderState { .Indent = indent + indent_delta });
1111 try stack.push(RenderState { .Text = "\n" });1110 try stack.append(RenderState { .Text = "\n" });
1112 {1111 {
1113 var i = asm_node.inputs.len;1112 var i = asm_node.inputs.len;
1114 while (i != 0) {1113 while (i != 0) {
1115 i -= 1;1114 i -= 1;
1116 const node = *asm_node.inputs.at(i);1115 const node = *asm_node.inputs.at(i);
1117 try stack.push(RenderState { .Expression = &node.base});1116 try stack.append(RenderState { .Expression = &node.base});
11181117
1119 if (i != 0) {1118 if (i != 0) {
1120 try stack.push(RenderState.PrintIndent);1119 try stack.append(RenderState.PrintIndent);
1121 try stack.push(RenderState {1120 try stack.append(RenderState {
1122 .Text = blk: {1121 .Text = blk: {
1123 const prev_node = *asm_node.inputs.at(i - 1);1122 const prev_node = *asm_node.inputs.at(i - 1);
1124 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;1123 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;
...@@ -1129,25 +1128,25 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -1129,25 +1128,25 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
1129 break :blk "\n";1128 break :blk "\n";
1130 },1129 },
1131 });1130 });
1132 try stack.push(RenderState { .Text = "," });1131 try stack.append(RenderState { .Text = "," });
1133 }1132 }
1134 }1133 }
1135 }1134 }
1136 try stack.push(RenderState { .Indent = indent + indent_delta + 2});1135 try stack.append(RenderState { .Indent = indent + indent_delta + 2});
1137 try stack.push(RenderState { .Text = ": "});1136 try stack.append(RenderState { .Text = ": "});
1138 try stack.push(RenderState.PrintIndent);1137 try stack.append(RenderState.PrintIndent);
1139 try stack.push(RenderState { .Indent = indent + indent_delta});1138 try stack.append(RenderState { .Indent = indent + indent_delta});
1140 try stack.push(RenderState { .Text = "\n" });1139 try stack.append(RenderState { .Text = "\n" });
1141 {1140 {
1142 var i = asm_node.outputs.len;1141 var i = asm_node.outputs.len;
1143 while (i != 0) {1142 while (i != 0) {
1144 i -= 1;1143 i -= 1;
1145 const node = *asm_node.outputs.at(i);1144 const node = *asm_node.outputs.at(i);
1146 try stack.push(RenderState { .Expression = &node.base});1145 try stack.append(RenderState { .Expression = &node.base});
11471146
1148 if (i != 0) {1147 if (i != 0) {
1149 try stack.push(RenderState.PrintIndent);1148 try stack.append(RenderState.PrintIndent);
1150 try stack.push(RenderState {1149 try stack.append(RenderState {
1151 .Text = blk: {1150 .Text = blk: {
1152 const prev_node = *asm_node.outputs.at(i - 1);1151 const prev_node = *asm_node.outputs.at(i - 1);
1153 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;1152 const prev_node_last_token_end = tree.tokens.at(prev_node.lastToken()).end;
...@@ -1158,47 +1157,47 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -1158,47 +1157,47 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
1158 break :blk "\n";1157 break :blk "\n";
1159 },1158 },
1160 });1159 });
1161 try stack.push(RenderState { .Text = "," });1160 try stack.append(RenderState { .Text = "," });
1162 }1161 }
1163 }1162 }
1164 }1163 }
1165 try stack.push(RenderState { .Indent = indent + indent_delta + 2});1164 try stack.append(RenderState { .Indent = indent + indent_delta + 2});
1166 try stack.push(RenderState { .Text = ": "});1165 try stack.append(RenderState { .Text = ": "});
1167 try stack.push(RenderState.PrintIndent);1166 try stack.append(RenderState.PrintIndent);
1168 try stack.push(RenderState { .Indent = indent + indent_delta});1167 try stack.append(RenderState { .Indent = indent + indent_delta});
1169 try stack.push(RenderState { .Text = "\n" });1168 try stack.append(RenderState { .Text = "\n" });
1170 try stack.push(RenderState { .Expression = asm_node.template });1169 try stack.append(RenderState { .Expression = asm_node.template });
1171 try stack.push(RenderState { .Text = "(" });1170 try stack.append(RenderState { .Text = "(" });
1172 },1171 },
1173 ast.Node.Id.AsmInput => {1172 ast.Node.Id.AsmInput => {
1174 const asm_input = @fieldParentPtr(ast.Node.AsmInput, "base", base);1173 const asm_input = @fieldParentPtr(ast.Node.AsmInput, "base", base);
11751174
1176 try stack.push(RenderState { .Text = ")"});1175 try stack.append(RenderState { .Text = ")"});
1177 try stack.push(RenderState { .Expression = asm_input.expr});1176 try stack.append(RenderState { .Expression = asm_input.expr});
1178 try stack.push(RenderState { .Text = " ("});1177 try stack.append(RenderState { .Text = " ("});
1179 try stack.push(RenderState { .Expression = asm_input.constraint });1178 try stack.append(RenderState { .Expression = asm_input.constraint });
1180 try stack.push(RenderState { .Text = "] "});1179 try stack.append(RenderState { .Text = "] "});
1181 try stack.push(RenderState { .Expression = asm_input.symbolic_name });1180 try stack.append(RenderState { .Expression = asm_input.symbolic_name });
1182 try stack.push(RenderState { .Text = "["});1181 try stack.append(RenderState { .Text = "["});
1183 },1182 },
1184 ast.Node.Id.AsmOutput => {1183 ast.Node.Id.AsmOutput => {
1185 const asm_output = @fieldParentPtr(ast.Node.AsmOutput, "base", base);1184 const asm_output = @fieldParentPtr(ast.Node.AsmOutput, "base", base);
11861185
1187 try stack.push(RenderState { .Text = ")"});1186 try stack.append(RenderState { .Text = ")"});
1188 switch (asm_output.kind) {1187 switch (asm_output.kind) {
1189 ast.Node.AsmOutput.Kind.Variable => |variable_name| {1188 ast.Node.AsmOutput.Kind.Variable => |variable_name| {
1190 try stack.push(RenderState { .Expression = &variable_name.base});1189 try stack.append(RenderState { .Expression = &variable_name.base});
1191 },1190 },
1192 ast.Node.AsmOutput.Kind.Return => |return_type| {1191 ast.Node.AsmOutput.Kind.Return => |return_type| {
1193 try stack.push(RenderState { .Expression = return_type});1192 try stack.append(RenderState { .Expression = return_type});
1194 try stack.push(RenderState { .Text = "-> "});1193 try stack.append(RenderState { .Text = "-> "});
1195 },1194 },
1196 }1195 }
1197 try stack.push(RenderState { .Text = " ("});1196 try stack.append(RenderState { .Text = " ("});
1198 try stack.push(RenderState { .Expression = asm_output.constraint });1197 try stack.append(RenderState { .Expression = asm_output.constraint });
1199 try stack.push(RenderState { .Text = "] "});1198 try stack.append(RenderState { .Text = "] "});
1200 try stack.push(RenderState { .Expression = asm_output.symbolic_name });1199 try stack.append(RenderState { .Expression = asm_output.symbolic_name });
1201 try stack.push(RenderState { .Text = "["});1200 try stack.append(RenderState { .Text = "["});
1202 },1201 },
12031202
1204 ast.Node.Id.StructField,1203 ast.Node.Id.StructField,
...@@ -1215,11 +1214,11 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {...@@ -1215,11 +1214,11 @@ pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) !void {
1215 switch (base.id) {1214 switch (base.id) {
1216 ast.Node.Id.VarDecl => {1215 ast.Node.Id.VarDecl => {
1217 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);1216 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
1218 try stack.push(RenderState { .VarDecl = var_decl});1217 try stack.append(RenderState { .VarDecl = var_decl});
1219 },1218 },
1220 else => {1219 else => {
1221 try stack.push(RenderState { .MaybeSemiColon = base });1220 try stack.append(RenderState { .MaybeSemiColon = base });
1222 try stack.push(RenderState { .Expression = base });1221 try stack.append(RenderState { .Expression = base });
1223 },1222 },
1224 }1223 }
1225 },1224 },