authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-02 21:05:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-02 21:05:53-07:00
log1a83b29bea486050544acc7935c0c438da2c2654
tree1327d0432403bad38734f49809633f3295a1aebd
parent0c6b98b82568edd982d8f7b7820a0a1173c5c5d2

zig fmt: implement if, call, field access, assignment


4 files changed, 798 insertions(+), 581 deletions(-)

lib/std/zig/ast.zig+296-79
...@@ -16,11 +16,7 @@ pub const TokenList = std.MultiArrayList(struct {...@@ -16,11 +16,7 @@ pub const TokenList = std.MultiArrayList(struct {
16 tag: Token.Tag,16 tag: Token.Tag,
17 start: ByteOffset,17 start: ByteOffset,
18});18});
19pub const NodeList = std.MultiArrayList(struct {19pub const NodeList = std.MultiArrayList(Node);
20 tag: Node.Tag,
21 main_token: TokenIndex,
22 data: Node.Data,
23});
2420
25pub const Tree = struct {21pub const Tree = struct {
26 /// Reference to externally-owned data.22 /// Reference to externally-owned data.
...@@ -76,6 +72,16 @@ pub const Tree = struct {...@@ -76,6 +72,16 @@ pub const Tree = struct {
76 return loc;72 return loc;
77 }73 }
7874
75 pub fn extraData(tree: Tree, index: usize, comptime T: type) T {
76 const fields = std.meta.fields(T);
77 var result: T = undefined;
78 inline for (fields) |field, i| {
79 comptime assert(field.field_type == Node.Index);
80 @field(result, field.name) = tree.extra_data[index + i];
81 }
82 return result;
83 }
84
79 pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {85 pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {
80 const tokens = tree.tokens.items(.tag);86 const tokens = tree.tokens.items(.tag);
81 switch (parse_error) {87 switch (parse_error) {
...@@ -189,7 +195,8 @@ pub const Tree = struct {...@@ -189,7 +195,8 @@ pub const Tree = struct {
189 const tags = tree.nodes.items(.tag);195 const tags = tree.nodes.items(.tag);
190 const datas = tree.nodes.items(.data);196 const datas = tree.nodes.items(.data);
191 const main_tokens = tree.nodes.items(.main_token);197 const main_tokens = tree.nodes.items(.main_token);
192 switch (tags[node]) {198 var n = node;
199 while (true) switch (tags[n]) {
193 .Root => return 0,200 .Root => return 0,
194201
195 .UsingNamespace,202 .UsingNamespace,
...@@ -210,20 +217,25 @@ pub const Tree = struct {...@@ -210,20 +217,25 @@ pub const Tree = struct {
210 .StructInitDot,217 .StructInitDot,
211 .Switch,218 .Switch,
212 .IfSimple,219 .IfSimple,
213 .IfSimpleOptional,
214 .If,220 .If,
215 .IfOptional,
216 .IfError,
217 .Suspend,221 .Suspend,
218 .Resume,222 .Resume,
219 .Continue,223 .Continue,
220 .Break,224 .Break,
221 .Return,225 .Return,
222 .AnyFrameType,226 .AnyFrameType,
223 .OneToken,
224 .Identifier,227 .Identifier,
228 .AnyFrameLiteral,
229 .CharLiteral,
230 .IntegerLiteral,
231 .FloatLiteral,
232 .FalseLiteral,
233 .TrueLiteral,
234 .NullLiteral,
235 .UndefinedLiteral,
236 .UnreachableLiteral,
225 .EnumLiteral,237 .EnumLiteral,
226 .MultilineStringLiteral,238 .StringLiteral,
227 .GroupedExpression,239 .GroupedExpression,
228 .BuiltinCallTwo,240 .BuiltinCallTwo,
229 .BuiltinCall,241 .BuiltinCall,
...@@ -234,7 +246,7 @@ pub const Tree = struct {...@@ -234,7 +246,7 @@ pub const Tree = struct {
234 .Block,246 .Block,
235 .AsmSimple,247 .AsmSimple,
236 .Asm,248 .Asm,
237 => return main_tokens[node],249 => return main_tokens[n],
238250
239 .Catch,251 .Catch,
240 .FieldAccess,252 .FieldAccess,
...@@ -290,7 +302,7 @@ pub const Tree = struct {...@@ -290,7 +302,7 @@ pub const Tree = struct {
290 .SwitchCaseOne,302 .SwitchCaseOne,
291 .SwitchRange,303 .SwitchRange,
292 .FnDecl,304 .FnDecl,
293 => return tree.firstToken(datas[node].lhs),305 => n = datas[n].lhs,
294306
295 .GlobalVarDecl,307 .GlobalVarDecl,
296 .LocalVarDecl,308 .LocalVarDecl,
...@@ -305,12 +317,8 @@ pub const Tree = struct {...@@ -305,12 +317,8 @@ pub const Tree = struct {
305 .StructInit,317 .StructInit,
306 .SwitchCaseMulti,318 .SwitchCaseMulti,
307 .WhileSimple,319 .WhileSimple,
308 .WhileSimpleOptional,
309 .WhileCont,320 .WhileCont,
310 .WhileContOptional,
311 .While,321 .While,
312 .WhileOptional,
313 .WhileError,
314 .ForSimple,322 .ForSimple,
315 .For,323 .For,
316 .FnProtoSimple,324 .FnProtoSimple,
...@@ -329,19 +337,19 @@ pub const Tree = struct {...@@ -329,19 +337,19 @@ pub const Tree = struct {
329 .ErrorValue,337 .ErrorValue,
330 .ErrorUnion,338 .ErrorUnion,
331 => @panic("TODO finish implementing firstToken"),339 => @panic("TODO finish implementing firstToken"),
332 }340 };
333 }341 }
334342
335 pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex {343 pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex {
336 const tags = tree.nodes.items(.tag);344 const tags = tree.nodes.items(.tag);
337 const datas = tree.nodes.items(.data);345 const datas = tree.nodes.items(.data);
338 const main_tokens = tree.nodes.items(.main_token);346 const main_tokens = tree.nodes.items(.main_token);
339 switch (tags[node]) {347 var n = node;
340 .Root,348 var end_offset: TokenIndex = 0;
349 while (true) switch (tags[n]) {
350 .Root => return @intCast(TokenIndex, tree.tokens.len - 1),
351
341 .UsingNamespace,352 .UsingNamespace,
342 .TestDecl,
343 .ErrDefer,
344 .Defer,
345 .BoolNot,353 .BoolNot,
346 .Negation,354 .Negation,
347 .BitNot,355 .BitNot,
...@@ -350,39 +358,16 @@ pub const Tree = struct {...@@ -350,39 +358,16 @@ pub const Tree = struct {
350 .Try,358 .Try,
351 .Await,359 .Await,
352 .OptionalType,360 .OptionalType,
353 .ArrayInitDotTwo,
354 .ArrayInitDot,
355 .StructInitDotTwo,
356 .StructInitDot,
357 .Switch,
358 .IfSimple,
359 .IfSimpleOptional,
360 .If,
361 .IfOptional,
362 .IfError,
363 .Suspend,361 .Suspend,
364 .Resume,362 .Resume,
365 .Continue,
366 .Break,363 .Break,
367 .Return,364 .Return,
368 .AnyFrameType,365 => n = datas[n].lhs,
369 .OneToken,366
370 .Identifier,367 .TestDecl,
371 .EnumLiteral,368 .ErrDefer,
372 .MultilineStringLiteral,369 .Defer,
373 .GroupedExpression,
374 .BuiltinCallTwo,
375 .BuiltinCall,
376 .ErrorSetDecl,
377 .AnyType,
378 .Comptime,
379 .Nosuspend,
380 .Block,
381 .AsmSimple,
382 .Asm,
383 .Catch,370 .Catch,
384 .FieldAccess,
385 .UnwrapOptional,
386 .EqualEqual,371 .EqualEqual,
387 .BangEqual,372 .BangEqual,
388 .LessThan,373 .LessThan,
...@@ -422,6 +407,63 @@ pub const Tree = struct {...@@ -422,6 +407,63 @@ pub const Tree = struct {
422 .OrElse,407 .OrElse,
423 .BoolAnd,408 .BoolAnd,
424 .BoolOr,409 .BoolOr,
410 .AnyFrameType,
411 .ErrorUnion,
412 .Comptime,
413 .Nosuspend,
414 .IfSimple,
415 .WhileSimple,
416 => n = datas[n].rhs,
417
418 .FieldAccess,
419 .UnwrapOptional,
420 .GroupedExpression,
421 .StringLiteral,
422 => return datas[n].rhs + end_offset,
423
424 .AnyType,
425 .AnyFrameLiteral,
426 .CharLiteral,
427 .IntegerLiteral,
428 .FloatLiteral,
429 .FalseLiteral,
430 .TrueLiteral,
431 .NullLiteral,
432 .UndefinedLiteral,
433 .UnreachableLiteral,
434 => return main_tokens[n] + end_offset,
435
436 .Call => {
437 end_offset += 1; // for the `)`
438 const params = tree.extraData(datas[n].rhs, Node.SubRange);
439 if (params.end - params.start == 0) {
440 return main_tokens[n] + end_offset;
441 }
442 n = tree.extra_data[params.end - 1]; // last parameter
443 },
444 .CallOne => {
445 end_offset += 1; // for the `)`
446 if (datas[n].rhs == 0) {
447 return main_tokens[n] + end_offset;
448 }
449 n = datas[n].rhs;
450 },
451
452 .ArrayInitDotTwo,
453 .ArrayInitDot,
454 .StructInitDotTwo,
455 .StructInitDot,
456 .Switch,
457 .If,
458 .Continue,
459 .Identifier,
460 .EnumLiteral,
461 .BuiltinCallTwo,
462 .BuiltinCall,
463 .ErrorSetDecl,
464 .Block,
465 .AsmSimple,
466 .Asm,
425 .SliceOpen,467 .SliceOpen,
426 .Slice,468 .Slice,
427 .Deref,469 .Deref,
...@@ -429,8 +471,6 @@ pub const Tree = struct {...@@ -429,8 +471,6 @@ pub const Tree = struct {
429 .ArrayInitOne,471 .ArrayInitOne,
430 .ArrayInit,472 .ArrayInit,
431 .StructInitOne,473 .StructInitOne,
432 .CallOne,
433 .Call,
434 .SwitchCaseOne,474 .SwitchCaseOne,
435 .SwitchRange,475 .SwitchRange,
436 .FnDecl,476 .FnDecl,
...@@ -446,13 +486,8 @@ pub const Tree = struct {...@@ -446,13 +486,8 @@ pub const Tree = struct {
446 .SliceType,486 .SliceType,
447 .StructInit,487 .StructInit,
448 .SwitchCaseMulti,488 .SwitchCaseMulti,
449 .WhileSimple,
450 .WhileSimpleOptional,
451 .WhileCont,489 .WhileCont,
452 .WhileContOptional,
453 .While,490 .While,
454 .WhileOptional,
455 .WhileError,
456 .ForSimple,491 .ForSimple,
457 .For,492 .For,
458 .FnProtoSimple,493 .FnProtoSimple,
...@@ -469,12 +504,178 @@ pub const Tree = struct {...@@ -469,12 +504,178 @@ pub const Tree = struct {
469 .AsmOutput,504 .AsmOutput,
470 .AsmInput,505 .AsmInput,
471 .ErrorValue,506 .ErrorValue,
472 .ErrorUnion,
473 => @panic("TODO finish implementing lastToken"),507 => @panic("TODO finish implementing lastToken"),
508 };
509 }
510
511 pub fn tokensOnSameLine(tree: Tree, token1: TokenIndex, token2: TokenIndex) bool {
512 const token_starts = tree.tokens.items(.start);
513 const source = tree.source[token_starts[token1]..token_starts[token2]];
514 return mem.indexOfScalar(u8, source, '\n') == null;
515 }
516
517 pub fn globalVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {
518 assert(tree.nodes.items(.tag)[node] == .GlobalVarDecl);
519 const data = tree.nodes.items(.data)[node];
520 const extra = tree.extraData(data.lhs, Node.GlobalVarDecl);
521 return tree.fullVarDecl(.{
522 .type_node = extra.type_node,
523 .align_node = extra.align_node,
524 .section_node = extra.section_node,
525 .init_node = data.rhs,
526 .mut_token = tree.nodes.items(.main_token)[node],
527 });
528 }
529
530 pub fn localVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {
531 assert(tree.nodes.items(.tag)[node] == .LocalVarDecl);
532 const data = tree.nodes.items(.data)[node];
533 const extra = tree.extraData(data.lhs, Node.LocalVarDecl);
534 return tree.fullVarDecl(.{
535 .type_node = extra.type_node,
536 .align_node = extra.align_node,
537 .section_node = 0,
538 .init_node = data.rhs,
539 .mut_token = tree.nodes.items(.main_token)[node],
540 });
541 }
542
543 pub fn simpleVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {
544 assert(tree.nodes.items(.tag)[node] == .SimpleVarDecl);
545 const data = tree.nodes.items(.data)[node];
546 return tree.fullVarDecl(.{
547 .type_node = data.lhs,
548 .align_node = 0,
549 .section_node = 0,
550 .init_node = data.rhs,
551 .mut_token = tree.nodes.items(.main_token)[node],
552 });
553 }
554
555 pub fn alignedVarDecl(tree: Tree, node: Node.Index) Full.VarDecl {
556 assert(tree.nodes.items(.tag)[node] == .AlignedVarDecl);
557 const data = tree.nodes.items(.data)[node];
558 return tree.fullVarDecl(.{
559 .type_node = 0,
560 .align_node = data.lhs,
561 .section_node = 0,
562 .init_node = data.rhs,
563 .mut_token = tree.nodes.items(.main_token)[node],
564 });
565 }
566
567 pub fn ifSimple(tree: Tree, node: Node.Index) Full.If {
568 assert(tree.nodes.items(.tag)[node] == .IfSimple);
569 const data = tree.nodes.items(.data)[node];
570 return tree.fullIf(.{
571 .cond_expr = data.lhs,
572 .then_expr = data.rhs,
573 .else_expr = 0,
574 .if_token = tree.nodes.items(.main_token)[node],
575 });
576 }
577
578 pub fn ifFull(tree: Tree, node: Node.Index) Full.If {
579 assert(tree.nodes.items(.tag)[node] == .If);
580 const data = tree.nodes.items(.data)[node];
581 const extra = tree.extraData(data.rhs, Node.If);
582 return tree.fullIf(.{
583 .cond_expr = data.lhs,
584 .then_expr = extra.then_expr,
585 .else_expr = extra.else_expr,
586 .if_token = tree.nodes.items(.main_token)[node],
587 });
588 }
589
590 fn fullVarDecl(tree: Tree, info: Full.VarDecl.Ast) Full.VarDecl {
591 const token_tags = tree.tokens.items(.tag);
592 var result: Full.VarDecl = .{
593 .ast = info,
594 .visib_token = null,
595 .extern_export_token = null,
596 .lib_name = null,
597 .threadlocal_token = null,
598 .comptime_token = null,
599 };
600 var i = info.mut_token;
601 while (i > 0) {
602 i -= 1;
603 switch (token_tags[i]) {
604 .Keyword_extern, .Keyword_export => result.extern_export_token = i,
605 .Keyword_comptime => result.comptime_token = i,
606 .Keyword_pub => result.visib_token = i,
607 .Keyword_threadlocal => result.threadlocal_token = i,
608 .StringLiteral => result.lib_name = i,
609 else => break,
610 }
611 }
612 return result;
613 }
614
615 fn fullIf(tree: Tree, info: Full.If.Ast) Full.If {
616 const token_tags = tree.tokens.items(.tag);
617 var result: Full.If = .{
618 .ast = info,
619 .payload_token = null,
620 .error_token = null,
621 .else_token = undefined,
622 };
623 // if (cond_expr) |x|
624 // ^ ^
625 const payload_pipe = tree.lastToken(info.cond_expr) + 2;
626 if (token_tags[payload_pipe] == .Pipe) {
627 result.payload_token = payload_pipe + 1;
628 }
629 if (info.else_expr != 0) {
630 // then_expr else |x|
631 // ^ ^
632 result.else_token = tree.lastToken(info.then_expr) + 1;
633 if (token_tags[result.else_token + 1] == .Pipe) {
634 result.error_token = result.else_token + 2;
635 }
474 }636 }
637 return result;
475 }638 }
476};639};
477640
641/// Fully assembled AST node information.
642pub const Full = struct {
643 pub const VarDecl = struct {
644 visib_token: ?TokenIndex,
645 extern_export_token: ?TokenIndex,
646 lib_name: ?TokenIndex,
647 threadlocal_token: ?TokenIndex,
648 comptime_token: ?TokenIndex,
649 ast: Ast,
650
651 pub const Ast = struct {
652 mut_token: TokenIndex,
653 type_node: Node.Index,
654 align_node: Node.Index,
655 section_node: Node.Index,
656 init_node: Node.Index,
657 };
658 };
659
660 pub const If = struct {
661 // Points to the first token after the `|`. Will either be an identifier or
662 // a `*` (with an identifier immediately after it).
663 payload_token: ?TokenIndex,
664 // Points to the identifier after the `|`.
665 error_token: ?TokenIndex,
666 // Populated only if else_expr != 0.
667 else_token: TokenIndex,
668 ast: Ast,
669
670 pub const Ast = struct {
671 if_token: TokenIndex,
672 cond_expr: Node.Index,
673 then_expr: Node.Index,
674 else_expr: Node.Index,
675 };
676 };
677};
678
478pub const Error = union(enum) {679pub const Error = union(enum) {
479 InvalidToken: InvalidToken,680 InvalidToken: InvalidToken,
480 ExpectedContainerMembers: ExpectedContainerMembers,681 ExpectedContainerMembers: ExpectedContainerMembers,
...@@ -706,7 +907,9 @@ pub const Error = union(enum) {...@@ -706,7 +907,9 @@ pub const Error = union(enum) {
706};907};
707908
708pub const Node = struct {909pub const Node = struct {
709 index: Index,910 tag: Tag,
911 main_token: TokenIndex,
912 data: Data,
710913
711 pub const Index = u32;914 pub const Index = u32;
712915
...@@ -718,22 +921,26 @@ pub const Node = struct {...@@ -718,22 +921,26 @@ pub const Node = struct {
718 pub const Tag = enum {921 pub const Tag = enum {
719 /// sub_list[lhs...rhs]922 /// sub_list[lhs...rhs]
720 Root,923 Root,
721 /// lhs is the sub-expression. rhs is unused.924 /// `usingnamespace lhs;`. rhs unused. main_token is `usingnamespace`.
722 UsingNamespace,925 UsingNamespace,
723 /// lhs is test name token (must be string literal), if any.926 /// lhs is test name token (must be string literal), if any.
724 /// rhs is the body node.927 /// rhs is the body node.
725 TestDecl,928 TestDecl,
726 /// lhs is the index into extra_data.929 /// lhs is the index into extra_data.
727 /// rhs is the initialization expression, if any.930 /// rhs is the initialization expression, if any.
931 /// main_token is `var` or `const`.
728 GlobalVarDecl,932 GlobalVarDecl,
729 /// `var a: x align(y) = rhs`933 /// `var a: x align(y) = rhs`
730 /// lhs is the index into local_var_decl_list.934 /// lhs is the index into extra_data.
935 /// main_token is `var` or `const`.
731 LocalVarDecl,936 LocalVarDecl,
732 /// `var a: lhs = rhs`. lhs and rhs may be unused.937 /// `var a: lhs = rhs`. lhs and rhs may be unused.
733 /// Can be local or global.938 /// Can be local or global.
939 /// main_token is `var` or `const`.
734 SimpleVarDecl,940 SimpleVarDecl,
735 /// `var a align(lhs) = rhs`. lhs and rhs may be unused.941 /// `var a align(lhs) = rhs`. lhs and rhs may be unused.
736 /// Can be local or global.942 /// Can be local or global.
943 /// main_token is `var` or `const`.
737 AlignedVarDecl,944 AlignedVarDecl,
738 /// lhs is the identifier token payload if any,945 /// lhs is the identifier token payload if any,
739 /// rhs is the deferred expression.946 /// rhs is the deferred expression.
...@@ -901,33 +1108,26 @@ pub const Node = struct {...@@ -901,33 +1108,26 @@ pub const Node = struct {
901 /// `lhs...rhs`.1108 /// `lhs...rhs`.
902 SwitchRange,1109 SwitchRange,
903 /// `while (lhs) rhs`.1110 /// `while (lhs) rhs`.
904 WhileSimple,
905 /// `while (lhs) |x| rhs`.1111 /// `while (lhs) |x| rhs`.
906 WhileSimpleOptional,1112 WhileSimple,
907 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.1113 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
908 WhileCont,
909 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.1114 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
910 WhileContOptional,1115 WhileCont,
911 /// `while (lhs) : (a) b else c`. `While[rhs]`.1116 /// `while (lhs) : (a) b else c`. `While[rhs]`.
912 While,
913 /// `while (lhs) |x| : (a) b else c`. `While[rhs]`.1117 /// `while (lhs) |x| : (a) b else c`. `While[rhs]`.
914 WhileOptional,
915 /// `while (lhs) |x| : (a) b else |y| c`. `While[rhs]`.1118 /// `while (lhs) |x| : (a) b else |y| c`. `While[rhs]`.
916 WhileError,1119 While,
917 /// `for (lhs) rhs`.1120 /// `for (lhs) rhs`.
918 ForSimple,1121 ForSimple,
919 /// `for (lhs) a else b`. `if_list[rhs]`.1122 /// `for (lhs) a else b`. `if_list[rhs]`.
920 For,1123 For,
921 /// `if (lhs) rhs`.1124 /// `if (lhs) rhs`.
922 IfSimple,
923 /// `if (lhs) |a| rhs`.1125 /// `if (lhs) |a| rhs`.
924 IfSimpleOptional,1126 IfSimple,
925 /// `if (lhs) a else b`. `if_list[rhs]`.1127 /// `if (lhs) a else b`. `if_list[rhs]`.
926 If,
927 /// `if (lhs) |x| a else b`. `if_list[rhs]`.1128 /// `if (lhs) |x| a else b`. `if_list[rhs]`.
928 IfOptional,
929 /// `if (lhs) |x| a else |y| b`. `if_list[rhs]`.1129 /// `if (lhs) |x| a else |y| b`. `if_list[rhs]`.
930 IfError,1130 If,
931 /// `suspend lhs`. lhs can be omitted. rhs is unused.1131 /// `suspend lhs`. lhs can be omitted. rhs is unused.
932 Suspend,1132 Suspend,
933 /// `resume lhs`. rhs is unused.1133 /// `resume lhs`. rhs is unused.
...@@ -955,10 +1155,24 @@ pub const Node = struct {...@@ -955,10 +1155,24 @@ pub const Node = struct {
955 FnDecl,1155 FnDecl,
956 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.1156 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
957 AnyFrameType,1157 AnyFrameType,
958 /// Could be integer literal, float literal, char literal, bool literal,
959 /// null literal, undefined literal, unreachable, depending on the token.
960 /// Both lhs and rhs unused.1158 /// Both lhs and rhs unused.
961 OneToken,1159 AnyFrameLiteral,
1160 /// Both lhs and rhs unused.
1161 CharLiteral,
1162 /// Both lhs and rhs unused.
1163 IntegerLiteral,
1164 /// Both lhs and rhs unused.
1165 FloatLiteral,
1166 /// Both lhs and rhs unused.
1167 FalseLiteral,
1168 /// Both lhs and rhs unused.
1169 TrueLiteral,
1170 /// Both lhs and rhs unused.
1171 NullLiteral,
1172 /// Both lhs and rhs unused.
1173 UndefinedLiteral,
1174 /// Both lhs and rhs unused.
1175 UnreachableLiteral,
962 /// Both lhs and rhs unused.1176 /// Both lhs and rhs unused.
963 /// Most identifiers will not have explicit AST nodes, however for expressions1177 /// Most identifiers will not have explicit AST nodes, however for expressions
964 /// which could be one of many different kinds of AST nodes, there will be an1178 /// which could be one of many different kinds of AST nodes, there will be an
...@@ -966,8 +1180,11 @@ pub const Node = struct {...@@ -966,8 +1180,11 @@ pub const Node = struct {
966 Identifier,1180 Identifier,
967 /// lhs is the dot token index, rhs unused, main_token is the identifier.1181 /// lhs is the dot token index, rhs unused, main_token is the identifier.
968 EnumLiteral,1182 EnumLiteral,
969 /// Both lhs and rhs unused.1183 /// main_token is the first token index (redundant with lhs)
970 MultilineStringLiteral,1184 /// lhs is the first token index; rhs is the last token index.
1185 /// Could be a series of MultilineStringLiteralLine tokens, or a single
1186 /// StringLiteral token.
1187 StringLiteral,
971 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.1188 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
972 GroupedExpression,1189 GroupedExpression,
973 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.1190 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
lib/std/zig/parse.zig+119-109
...@@ -832,7 +832,7 @@ const Parser = struct {...@@ -832,7 +832,7 @@ const Parser = struct {
832 }832 }
833 if (p.eatToken(.Semicolon)) |_| {833 if (p.eatToken(.Semicolon)) |_| {
834 return p.addNode(.{834 return p.addNode(.{
835 .tag = if (then_payload == 0) .IfSimple else .IfSimpleOptional,835 .tag = .IfSimple,
836 .main_token = if_token,836 .main_token = if_token,
837 .data = .{837 .data = .{
838 .lhs = condition,838 .lhs = condition,
...@@ -848,7 +848,7 @@ const Parser = struct {...@@ -848,7 +848,7 @@ const Parser = struct {
848 return p.fail(.{ .ExpectedSemiOrElse = .{ .token = p.tok_i } });848 return p.fail(.{ .ExpectedSemiOrElse = .{ .token = p.tok_i } });
849 }849 }
850 return p.addNode(.{850 return p.addNode(.{
851 .tag = if (then_payload == 0) .IfSimple else .IfSimpleOptional,851 .tag = .IfSimple,
852 .main_token = if_token,852 .main_token = if_token,
853 .data = .{853 .data = .{
854 .lhs = condition,854 .lhs = condition,
...@@ -858,14 +858,8 @@ const Parser = struct {...@@ -858,14 +858,8 @@ const Parser = struct {
858 };858 };
859 const else_payload = try p.parsePayload();859 const else_payload = try p.parsePayload();
860 const else_expr = try p.expectStatement();860 const else_expr = try p.expectStatement();
861 const tag = if (else_payload != 0)
862 Node.Tag.IfError
863 else if (then_payload != 0)
864 Node.Tag.IfOptional
865 else
866 Node.Tag.If;
867 return p.addNode(.{861 return p.addNode(.{
868 .tag = tag,862 .tag = .If,
869 .main_token = if_token,863 .main_token = if_token,
870 .data = .{864 .data = .{
871 .lhs = condition,865 .lhs = condition,
...@@ -994,7 +988,7 @@ const Parser = struct {...@@ -994,7 +988,7 @@ const Parser = struct {
994 if (p.eatToken(.Semicolon)) |_| {988 if (p.eatToken(.Semicolon)) |_| {
995 if (continue_expr == 0) {989 if (continue_expr == 0) {
996 return p.addNode(.{990 return p.addNode(.{
997 .tag = if (then_payload == 0) .WhileSimple else .WhileSimpleOptional,991 .tag = .WhileSimple,
998 .main_token = while_token,992 .main_token = while_token,
999 .data = .{993 .data = .{
1000 .lhs = condition,994 .lhs = condition,
...@@ -1003,7 +997,7 @@ const Parser = struct {...@@ -1003,7 +997,7 @@ const Parser = struct {
1003 });997 });
1004 } else {998 } else {
1005 return p.addNode(.{999 return p.addNode(.{
1006 .tag = if (then_payload == 0) .WhileCont else .WhileContOptional,1000 .tag = .WhileCont,
1007 .main_token = while_token,1001 .main_token = while_token,
1008 .data = .{1002 .data = .{
1009 .lhs = condition,1003 .lhs = condition,
...@@ -1024,7 +1018,7 @@ const Parser = struct {...@@ -1024,7 +1018,7 @@ const Parser = struct {
1024 }1018 }
1025 if (continue_expr == 0) {1019 if (continue_expr == 0) {
1026 return p.addNode(.{1020 return p.addNode(.{
1027 .tag = if (then_payload == 0) .WhileSimple else .WhileSimpleOptional,1021 .tag = .WhileSimple,
1028 .main_token = while_token,1022 .main_token = while_token,
1029 .data = .{1023 .data = .{
1030 .lhs = condition,1024 .lhs = condition,
...@@ -1033,7 +1027,7 @@ const Parser = struct {...@@ -1033,7 +1027,7 @@ const Parser = struct {
1033 });1027 });
1034 } else {1028 } else {
1035 return p.addNode(.{1029 return p.addNode(.{
1036 .tag = if (then_payload == 0) .WhileCont else .WhileContOptional,1030 .tag = .WhileCont,
1037 .main_token = while_token,1031 .main_token = while_token,
1038 .data = .{1032 .data = .{
1039 .lhs = condition,1033 .lhs = condition,
...@@ -1047,14 +1041,8 @@ const Parser = struct {...@@ -1047,14 +1041,8 @@ const Parser = struct {
1047 };1041 };
1048 const else_payload = try p.parsePayload();1042 const else_payload = try p.parsePayload();
1049 const else_expr = try p.expectStatement();1043 const else_expr = try p.expectStatement();
1050 const tag = if (else_payload != 0)
1051 Node.Tag.WhileError
1052 else if (then_payload != 0)
1053 Node.Tag.WhileOptional
1054 else
1055 Node.Tag.While;
1056 return p.addNode(.{1044 return p.addNode(.{
1057 .tag = tag,1045 .tag = .While,
1058 .main_token = while_token,1046 .main_token = while_token,
1059 .data = .{1047 .data = .{
1060 .lhs = condition,1048 .lhs = condition,
...@@ -1948,7 +1936,7 @@ const Parser = struct {...@@ -1948,7 +1936,7 @@ const Parser = struct {
1948 const else_token = p.eatToken(.Keyword_else) orelse {1936 const else_token = p.eatToken(.Keyword_else) orelse {
1949 if (continue_expr == 0) {1937 if (continue_expr == 0) {
1950 return p.addNode(.{1938 return p.addNode(.{
1951 .tag = if (then_payload == 0) .WhileSimple else .WhileSimpleOptional,1939 .tag = .WhileSimple,
1952 .main_token = while_token,1940 .main_token = while_token,
1953 .data = .{1941 .data = .{
1954 .lhs = condition,1942 .lhs = condition,
...@@ -1957,7 +1945,7 @@ const Parser = struct {...@@ -1957,7 +1945,7 @@ const Parser = struct {
1957 });1945 });
1958 } else {1946 } else {
1959 return p.addNode(.{1947 return p.addNode(.{
1960 .tag = if (then_payload == 0) .WhileCont else .WhileContOptional,1948 .tag = .WhileCont,
1961 .main_token = while_token,1949 .main_token = while_token,
1962 .data = .{1950 .data = .{
1963 .lhs = condition,1951 .lhs = condition,
...@@ -1971,14 +1959,8 @@ const Parser = struct {...@@ -1971,14 +1959,8 @@ const Parser = struct {
1971 };1959 };
1972 const else_payload = try p.parsePayload();1960 const else_payload = try p.parsePayload();
1973 const else_expr = try p.expectExpr();1961 const else_expr = try p.expectExpr();
1974 const tag = if (else_payload != 0)
1975 Node.Tag.WhileError
1976 else if (then_payload != 0)
1977 Node.Tag.WhileOptional
1978 else
1979 Node.Tag.While;
1980 return p.addNode(.{1962 return p.addNode(.{
1981 .tag = tag,1963 .tag = .While,
1982 .main_token = while_token,1964 .main_token = while_token,
1983 .data = .{1965 .data = .{
1984 .lhs = condition,1966 .lhs = condition,
...@@ -2229,24 +2211,89 @@ const Parser = struct {...@@ -2229,24 +2211,89 @@ const Parser = struct {
2229 /// LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)2211 /// LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
2230 fn parsePrimaryTypeExpr(p: *Parser) !Node.Index {2212 fn parsePrimaryTypeExpr(p: *Parser) !Node.Index {
2231 switch (p.token_tags[p.tok_i]) {2213 switch (p.token_tags[p.tok_i]) {
2232 .CharLiteral,2214 .CharLiteral => return p.addNode(.{
2233 .IntegerLiteral,2215 .tag = .CharLiteral,
2234 .FloatLiteral,2216 .main_token = p.nextToken(),
2235 .StringLiteral,2217 .data = .{
2236 .Keyword_false,2218 .lhs = undefined,
2237 .Keyword_true,2219 .rhs = undefined,
2238 .Keyword_null,2220 },
2239 .Keyword_undefined,2221 }),
2240 .Keyword_unreachable,2222 .IntegerLiteral => return p.addNode(.{
2241 .Keyword_anyframe,2223 .tag = .IntegerLiteral,
2242 => return p.addNode(.{2224 .main_token = p.nextToken(),
2243 .tag = .OneToken,2225 .data = .{
2226 .lhs = undefined,
2227 .rhs = undefined,
2228 },
2229 }),
2230 .FloatLiteral => return p.addNode(.{
2231 .tag = .FloatLiteral,
2232 .main_token = p.nextToken(),
2233 .data = .{
2234 .lhs = undefined,
2235 .rhs = undefined,
2236 },
2237 }),
2238 .Keyword_false => return p.addNode(.{
2239 .tag = .FalseLiteral,
2240 .main_token = p.nextToken(),
2241 .data = .{
2242 .lhs = undefined,
2243 .rhs = undefined,
2244 },
2245 }),
2246 .Keyword_true => return p.addNode(.{
2247 .tag = .TrueLiteral,
2248 .main_token = p.nextToken(),
2249 .data = .{
2250 .lhs = undefined,
2251 .rhs = undefined,
2252 },
2253 }),
2254 .Keyword_null => return p.addNode(.{
2255 .tag = .NullLiteral,
2256 .main_token = p.nextToken(),
2257 .data = .{
2258 .lhs = undefined,
2259 .rhs = undefined,
2260 },
2261 }),
2262 .Keyword_undefined => return p.addNode(.{
2263 .tag = .UndefinedLiteral,
2264 .main_token = p.nextToken(),
2265 .data = .{
2266 .lhs = undefined,
2267 .rhs = undefined,
2268 },
2269 }),
2270 .Keyword_unreachable => return p.addNode(.{
2271 .tag = .UnreachableLiteral,
2272 .main_token = p.nextToken(),
2273 .data = .{
2274 .lhs = undefined,
2275 .rhs = undefined,
2276 },
2277 }),
2278 .Keyword_anyframe => return p.addNode(.{
2279 .tag = .AnyFrameLiteral,
2244 .main_token = p.nextToken(),2280 .main_token = p.nextToken(),
2245 .data = .{2281 .data = .{
2246 .lhs = undefined,2282 .lhs = undefined,
2247 .rhs = undefined,2283 .rhs = undefined,
2248 },2284 },
2249 }),2285 }),
2286 .StringLiteral => {
2287 const main_token = p.nextToken();
2288 return p.addNode(.{
2289 .tag = .StringLiteral,
2290 .main_token = main_token,
2291 .data = .{
2292 .lhs = main_token,
2293 .rhs = main_token,
2294 },
2295 });
2296 },
22502297
2251 .Builtin => return p.parseBuiltinCall(),2298 .Builtin => return p.parseBuiltinCall(),
2252 .Keyword_fn => return p.parseFnProto(),2299 .Keyword_fn => return p.parseFnProto(),
...@@ -2280,11 +2327,11 @@ const Parser = struct {...@@ -2280,11 +2327,11 @@ const Parser = struct {
2280 p.tok_i += 1;2327 p.tok_i += 1;
2281 }2328 }
2282 return p.addNode(.{2329 return p.addNode(.{
2283 .tag = .OneToken,2330 .tag = .StringLiteral,
2284 .main_token = first_line,2331 .main_token = first_line,
2285 .data = .{2332 .data = .{
2286 .lhs = undefined,2333 .lhs = first_line,
2287 .rhs = undefined,2334 .rhs = p.tok_i - 1,
2288 },2335 },
2289 });2336 });
2290 },2337 },
...@@ -2641,7 +2688,7 @@ const Parser = struct {...@@ -2641,7 +2688,7 @@ const Parser = struct {
2641 const else_token = p.eatToken(.Keyword_else) orelse {2688 const else_token = p.eatToken(.Keyword_else) orelse {
2642 if (continue_expr == 0) {2689 if (continue_expr == 0) {
2643 return p.addNode(.{2690 return p.addNode(.{
2644 .tag = if (then_payload == 0) .WhileSimple else .WhileSimpleOptional,2691 .tag = .WhileSimple,
2645 .main_token = while_token,2692 .main_token = while_token,
2646 .data = .{2693 .data = .{
2647 .lhs = condition,2694 .lhs = condition,
...@@ -2650,7 +2697,7 @@ const Parser = struct {...@@ -2650,7 +2697,7 @@ const Parser = struct {
2650 });2697 });
2651 } else {2698 } else {
2652 return p.addNode(.{2699 return p.addNode(.{
2653 .tag = if (then_payload == 0) .WhileCont else .WhileContOptional,2700 .tag = .WhileCont,
2654 .main_token = while_token,2701 .main_token = while_token,
2655 .data = .{2702 .data = .{
2656 .lhs = condition,2703 .lhs = condition,
...@@ -2664,14 +2711,8 @@ const Parser = struct {...@@ -2664,14 +2711,8 @@ const Parser = struct {
2664 };2711 };
2665 const else_payload = try p.parsePayload();2712 const else_payload = try p.parsePayload();
2666 const else_expr = try p.expectTypeExpr();2713 const else_expr = try p.expectTypeExpr();
2667 const tag = if (else_payload != 0)
2668 Node.Tag.WhileError
2669 else if (then_payload != 0)
2670 Node.Tag.WhileOptional
2671 else
2672 Node.Tag.While;
2673 return p.addNode(.{2714 return p.addNode(.{
2674 .tag = tag,2715 .tag = .While,
2675 .main_token = while_token,2716 .main_token = while_token,
2676 .data = .{2717 .data = .{
2677 .lhs = condition,2718 .lhs = condition,
...@@ -3450,7 +3491,7 @@ const Parser = struct {...@@ -3450,7 +3491,7 @@ const Parser = struct {
3450 });3491 });
3451 // Pretend this was an identifier so we can continue parsing.3492 // Pretend this was an identifier so we can continue parsing.
3452 return p.addNode(.{3493 return p.addNode(.{
3453 .tag = .OneToken,3494 .tag = .Identifier,
3454 .main_token = builtin_token,3495 .main_token = builtin_token,
3455 .data = .{3496 .data = .{
3456 .lhs = undefined,3497 .lhs = undefined,
...@@ -3470,59 +3511,31 @@ const Parser = struct {...@@ -3470,59 +3511,31 @@ const Parser = struct {
3470 });3511 });
3471 }3512 }
34723513
3473 fn parseOneToken(p: *Parser, token_tag: Token.Tag) !Node.Index {
3474 const token = p.eatToken(token_tag) orelse return null_node;
3475 return p.addNode(.{
3476 .tag = .OneToken,
3477 .main_token = token,
3478 .data = .{
3479 .lhs = undefined,
3480 .rhs = undefined,
3481 },
3482 });
3483 }
3484
3485 fn expectOneToken(p: *Parser, token_tag: Token.Tag) !Node.Index {
3486 const node = try p.expectOneTokenRecoverable(token_tag);
3487 if (node == 0) return error.ParseError;
3488 return node;
3489 }
3490
3491 fn expectOneTokenRecoverable(p: *Parser, token_tag: Token.Tag) !Node.Index {
3492 const node = p.parseOneToken(token_tag);
3493 if (node == 0) {
3494 try p.warn(.{
3495 .ExpectedToken = .{
3496 .token = p.tok_i,
3497 .expected_id = token_tag,
3498 },
3499 });
3500 }
3501 return node;
3502 }
3503
3504 // string literal or multiline string literal3514 // string literal or multiline string literal
3505 fn parseStringLiteral(p: *Parser) !Node.Index {3515 fn parseStringLiteral(p: *Parser) !Node.Index {
3506 switch (p.token_tags[p.tok_i]) {3516 switch (p.token_tags[p.tok_i]) {
3507 .StringLiteral => return p.addNode(.{3517 .StringLiteral => {
3508 .tag = .OneToken,3518 const main_token = p.nextToken();
3509 .main_token = p.nextToken(),3519 return p.addNode(.{
3510 .data = .{3520 .tag = .StringLiteral,
3511 .lhs = undefined,3521 .main_token = main_token,
3512 .rhs = undefined,3522 .data = .{
3513 },3523 .lhs = main_token,
3514 }),3524 .rhs = main_token,
3525 },
3526 });
3527 },
3515 .MultilineStringLiteralLine => {3528 .MultilineStringLiteralLine => {
3516 const first_line = p.nextToken();3529 const first_line = p.nextToken();
3517 while (p.token_tags[p.tok_i] == .MultilineStringLiteralLine) {3530 while (p.token_tags[p.tok_i] == .MultilineStringLiteralLine) {
3518 p.tok_i += 1;3531 p.tok_i += 1;
3519 }3532 }
3520 return p.addNode(.{3533 return p.addNode(.{
3521 .tag = .OneToken,3534 .tag = .StringLiteral,
3522 .main_token = first_line,3535 .main_token = first_line,
3523 .data = .{3536 .data = .{
3524 .lhs = undefined,3537 .lhs = first_line,
3525 .rhs = undefined,3538 .rhs = p.tok_i - 1,
3526 },3539 },
3527 });3540 });
3528 },3541 },
...@@ -3539,11 +3552,14 @@ const Parser = struct {...@@ -3539,11 +3552,14 @@ const Parser = struct {
3539 }3552 }
35403553
3541 fn expectIntegerLiteral(p: *Parser) !Node.Index {3554 fn expectIntegerLiteral(p: *Parser) !Node.Index {
3542 const node = p.parseOneToken(.IntegerLiteral);3555 return p.addNode(.{
3543 if (node != 0) {3556 .tag = .IntegerLiteral,
3544 return p.fail(.{ .ExpectedIntegerLiteral = .{ .token = p.tok_i } });3557 .main_token = try p.expectToken(.IntegerLiteral),
3545 }3558 .data = .{
3546 return node;3559 .lhs = undefined,
3560 .rhs = undefined,
3561 },
3562 });
3547 }3563 }
35483564
3549 /// KEYWORD_if LPAREN Expr RPAREN PtrPayload? Body (KEYWORD_else Payload? Body)?3565 /// KEYWORD_if LPAREN Expr RPAREN PtrPayload? Body (KEYWORD_else Payload? Body)?
...@@ -3558,7 +3574,7 @@ const Parser = struct {...@@ -3558,7 +3574,7 @@ const Parser = struct {
3558 if (then_expr == 0) return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });3574 if (then_expr == 0) return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });
35593575
3560 const else_token = p.eatToken(.Keyword_else) orelse return p.addNode(.{3576 const else_token = p.eatToken(.Keyword_else) orelse return p.addNode(.{
3561 .tag = if (then_payload == 0) .IfSimple else .IfSimpleOptional,3577 .tag = .IfSimple,
3562 .main_token = if_token,3578 .main_token = if_token,
3563 .data = .{3579 .data = .{
3564 .lhs = condition,3580 .lhs = condition,
...@@ -3569,14 +3585,8 @@ const Parser = struct {...@@ -3569,14 +3585,8 @@ const Parser = struct {
3569 const else_expr = try bodyParseFn(p);3585 const else_expr = try bodyParseFn(p);
3570 if (else_expr == 0) return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });3586 if (else_expr == 0) return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });
35713587
3572 const tag = if (else_payload != 0)
3573 Node.Tag.IfError
3574 else if (then_payload != 0)
3575 Node.Tag.IfOptional
3576 else
3577 Node.Tag.If;
3578 return p.addNode(.{3588 return p.addNode(.{
3579 .tag = tag,3589 .tag = .If,
3580 .main_token = if_token,3590 .main_token = if_token,
3581 .data = .{3591 .data = .{
3582 .lhs = condition,3592 .lhs = condition,
lib/std/zig/parser_test.zig+10-10
...@@ -81,16 +81,16 @@ test "zig fmt: doc comments on test" {...@@ -81,16 +81,16 @@ test "zig fmt: doc comments on test" {
81 );81 );
82}82}
8383
84//test "zig fmt: if statment" {84test "zig fmt: if statment" {
85// try testCanonical(85 try testCanonical(
86// \\test "" {86 \\test "" {
87// \\ if (optional()) |some|87 \\ if (optional()) |some|
88// \\ bar = some.foo();88 \\ bar = some.foo();
89// \\}89 \\}
90// \\90 \\
91// );91 );
92//}92}
93//93
94//test "zig fmt: top-level fields" {94//test "zig fmt: top-level fields" {
95// try testCanonical(95// try testCanonical(
96// \\a: did_you_know,96// \\a: did_you_know,
lib/std/zig/render.zig+373-383
...@@ -69,15 +69,15 @@ fn renderRoot(ais: *Ais, tree: ast.Tree) Error!void {...@@ -69,15 +69,15 @@ fn renderRoot(ais: *Ais, tree: ast.Tree) Error!void {
69 if (root_decls.len == 0) return;69 if (root_decls.len == 0) return;
7070
71 for (root_decls) |decl| {71 for (root_decls) |decl| {
72 try renderTopLevelDecl(ais, tree, decl);72 return renderContainerDecl(ais, tree, decl, .Newline);
73 }73 }
74}74}
7575
76fn renderExtraNewline(tree: ast.Tree, ais: *Ais, node: ast.Node.Index) Error!void {76fn renderExtraNewline(ais: *Ais, tree: ast.Tree, node: ast.Node.Index) Error!void {
77 return renderExtraNewlineToken(tree, ais, tree.firstToken(node));77 return renderExtraNewlineToken(ais, tree, tree.firstToken(node));
78}78}
7979
80fn renderExtraNewlineToken(tree: ast.Tree, ais: *Ais, first_token: ast.TokenIndex) Error!void {80fn renderExtraNewlineToken(ais: *Ais, tree: ast.Tree, first_token: ast.TokenIndex) Error!void {
81 @panic("TODO implement renderExtraNewlineToken");81 @panic("TODO implement renderExtraNewlineToken");
82 //var prev_token = first_token;82 //var prev_token = first_token;
83 //if (prev_token == 0) return;83 //if (prev_token == 0) return;
...@@ -96,14 +96,11 @@ fn renderExtraNewlineToken(tree: ast.Tree, ais: *Ais, first_token: ast.TokenInde...@@ -96,14 +96,11 @@ fn renderExtraNewlineToken(tree: ast.Tree, ais: *Ais, first_token: ast.TokenInde
96 //}96 //}
97}97}
9898
99fn renderTopLevelDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index) Error!void {
100 return renderContainerDecl(ais, tree, decl, .Newline);
101}
102
103fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) Error!void {99fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) Error!void {
104 const token_tags = tree.tokens.items(.tag);100 const token_tags = tree.tokens.items(.tag);
105 const main_tokens = tree.nodes.items(.main_token);101 const main_tokens = tree.nodes.items(.main_token);
106 const datas = tree.nodes.items(.data);102 const datas = tree.nodes.items(.data);
103 try renderDocComments(ais, tree, tree.firstToken(decl));
107 switch (tree.nodes.items(.tag)[decl]) {104 switch (tree.nodes.items(.tag)[decl]) {
108 .UsingNamespace,105 .UsingNamespace,
109 .FnProtoSimple,106 .FnProtoSimple,
...@@ -111,10 +108,6 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S...@@ -111,10 +108,6 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S
111 .FnProtoOne,108 .FnProtoOne,
112 .FnProto,109 .FnProto,
113 .FnDecl,110 .FnDecl,
114 .GlobalVarDecl,
115 .LocalVarDecl,
116 .SimpleVarDecl,
117 .AlignedVarDecl,
118 .ContainerFieldInit,111 .ContainerFieldInit,
119 .ContainerFieldAlign,112 .ContainerFieldAlign,
120 .ContainerField,113 .ContainerField,
...@@ -145,16 +138,13 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S...@@ -145,16 +138,13 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S
145 // try renderToken(ais, tree, use_decl.semicolon_token, space); // ;138 // try renderToken(ais, tree, use_decl.semicolon_token, space); // ;
146 // },139 // },
147140
148 // .VarDecl => {141 .GlobalVarDecl => return renderVarDecl(ais, tree, tree.globalVarDecl(decl)),
149 // const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl);142 .LocalVarDecl => return renderVarDecl(ais, tree, tree.localVarDecl(decl)),
150143 .SimpleVarDecl => return renderVarDecl(ais, tree, tree.simpleVarDecl(decl)),
151 // try renderDocComments(ais, tree, var_decl, var_decl.getDocComments());144 .AlignedVarDecl => return renderVarDecl(ais, tree, tree.alignedVarDecl(decl)),
152 // try renderVarDecl(allocator, ais, tree, var_decl);
153 // },
154145
155 .TestDecl => {146 .TestDecl => {
156 const test_token = main_tokens[decl];147 const test_token = main_tokens[decl];
157 try renderDocComments(ais, tree, test_token);
158 try renderToken(ais, tree, test_token, .Space);148 try renderToken(ais, tree, test_token, .Space);
159 if (token_tags[test_token + 1] == .StringLiteral) {149 if (token_tags[test_token + 1] == .StringLiteral) {
160 try renderToken(ais, tree, test_token + 1, .Space);150 try renderToken(ais, tree, test_token + 1, .Space);
...@@ -251,21 +241,20 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S...@@ -251,21 +241,20 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S
251fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {241fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
252 const token_tags = tree.tokens.items(.tag);242 const token_tags = tree.tokens.items(.tag);
253 const main_tokens = tree.nodes.items(.main_token);243 const main_tokens = tree.nodes.items(.main_token);
254 switch (tree.nodes.items(.tag)[node]) {244 const node_tags = tree.nodes.items(.tag);
255 //.Identifier,245 const datas = tree.nodes.items(.data);
256 //.IntegerLiteral,246 switch (node_tags[node]) {
257 //.FloatLiteral,247 .Identifier,
258 //.StringLiteral,248 .IntegerLiteral,
259 //.CharLiteral,249 .FloatLiteral,
260 //.BoolLiteral,250 .StringLiteral,
261 //.NullLiteral,251 .CharLiteral,
262 //.Unreachable,252 .TrueLiteral,
263 //.ErrorType,253 .FalseLiteral,
264 //.UndefinedLiteral,254 .NullLiteral,
265 //=> {255 .UnreachableLiteral,
266 // const casted_node = base.cast(ast.Node.OneToken).?;256 .UndefinedLiteral,
267 // return renderToken(ais, tree, casted_node.token, space);257 => return renderToken(ais, tree, main_tokens[node], space),
268 //},
269258
270 //.AnyType => {259 //.AnyType => {
271 // const any_type = base.castTag(.AnyType).?;260 // const any_type = base.castTag(.AnyType).?;
...@@ -299,16 +288,37 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -299,16 +288,37 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
299288
300 try renderToken(ais, tree, lbrace, .Newline);289 try renderToken(ais, tree, lbrace, .Newline);
301290
302 for (statements) |statement, i| {291 for (statements) |stmt, i| {
303 try renderStatement(ais, tree, statement);292 switch (node_tags[stmt]) {
293 .GlobalVarDecl => try renderVarDecl(ais, tree, tree.globalVarDecl(stmt)),
294 .LocalVarDecl => try renderVarDecl(ais, tree, tree.localVarDecl(stmt)),
295 .SimpleVarDecl => try renderVarDecl(ais, tree, tree.simpleVarDecl(stmt)),
296 .AlignedVarDecl => try renderVarDecl(ais, tree, tree.alignedVarDecl(stmt)),
297 else => {
298 const semicolon = tree.lastToken(stmt) + 1;
299 if (token_tags[semicolon] == .Semicolon) {
300 try renderExpression(ais, tree, stmt, .None);
301 try renderToken(ais, tree, semicolon, .Newline);
302 } else {
303 try renderExpression(ais, tree, stmt, .Newline);
304 }
305 },
306 }
304307
305 if (i + 1 < statements.len) {308 if (i + 1 < statements.len) {
306 try renderExtraNewline(tree, ais, statements[i + 1]);309 try renderExtraNewline(ais, tree, statements[i + 1]);
307 }310 }
308 }311 }
309 ais.popIndent();312 ais.popIndent();
310 const rbrace = tree.lastToken(statements[statements.len - 1]) + 1;313 // The rbrace could be +1 or +2 from the last token of the last
311 return renderToken(ais, tree, rbrace, space);314 // statement in the block because lastToken() does not count semicolons.
315 const maybe_rbrace = tree.lastToken(statements[statements.len - 1]) + 1;
316 if (token_tags[maybe_rbrace] == .RBrace) {
317 return renderToken(ais, tree, maybe_rbrace, space);
318 } else {
319 assert(token_tags[maybe_rbrace + 1] == .RBrace);
320 return renderToken(ais, tree, maybe_rbrace + 1, space);
321 }
312 }322 }
313 },323 },
314324
...@@ -322,8 +332,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -322,8 +332,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
322 // return renderExpression(ais, tree, defer_node.expr, space);332 // return renderExpression(ais, tree, defer_node.expr, space);
323 //},333 //},
324 .Comptime => {334 .Comptime => {
325 const comptime_token = tree.nodes.items(.main_token)[node];335 const comptime_token = main_tokens[node];
326 const block = tree.nodes.items(.data)[node].lhs;336 const block = datas[node].lhs;
327 try renderToken(ais, tree, comptime_token, .Space);337 try renderToken(ais, tree, comptime_token, .Space);
328 return renderExpression(ais, tree, block, space);338 return renderExpression(ais, tree, block, space);
329 },339 },
...@@ -369,71 +379,78 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -369,71 +379,78 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
369 // ais.pushIndentOneShot();379 // ais.pushIndentOneShot();
370 // return renderExpression(ais, tree, infix_op_node.rhs, space);380 // return renderExpression(ais, tree, infix_op_node.rhs, space);
371 //},381 //},
382 .FieldAccess => {
383 const field_access = datas[node];
384 try renderExpression(ais, tree, field_access.lhs, .None);
385 try renderToken(ais, tree, main_tokens[node], .None);
386 return renderToken(ais, tree, field_access.rhs, .None);
387 },
372388
373 //.Add,389 .ErrorUnion,
374 //.AddWrap,390 .SwitchRange,
375 //.ArrayCat,391 => {
376 //.ArrayMult,392 const infix = datas[node];
377 //.Assign,393 try renderExpression(ais, tree, infix.lhs, .None);
378 //.AssignBitAnd,394 try renderToken(ais, tree, main_tokens[node], .None);
379 //.AssignBitOr,395 return renderExpression(ais, tree, infix.rhs, space);
380 //.AssignBitShiftLeft,396 },
381 //.AssignBitShiftRight,
382 //.AssignBitXor,
383 //.AssignDiv,
384 //.AssignSub,
385 //.AssignSubWrap,
386 //.AssignMod,
387 //.AssignAdd,
388 //.AssignAddWrap,
389 //.AssignMul,
390 //.AssignMulWrap,
391 //.BangEqual,
392 //.BitAnd,
393 //.BitOr,
394 //.BitShiftLeft,
395 //.BitShiftRight,
396 //.BitXor,
397 //.BoolAnd,
398 //.BoolOr,
399 //.Div,
400 //.EqualEqual,
401 //.ErrorUnion,
402 //.GreaterOrEqual,
403 //.GreaterThan,
404 //.LessOrEqual,
405 //.LessThan,
406 //.MergeErrorSets,
407 //.Mod,
408 //.Mul,
409 //.MulWrap,
410 //.Period,
411 //.Range,
412 //.Sub,
413 //.SubWrap,
414 //.OrElse,
415 //=> {
416 // const infix_op_node = @fieldParentPtr(ast.Node.SimpleInfixOp, "base", base);
417
418 // const op_space = switch (base.tag) {
419 // .Period, .ErrorUnion, .Range => Space.None,
420 // else => Space.Space,
421 // };
422 // try renderExpression(ais, tree, infix_op_node.lhs, op_space);
423
424 // const after_op_space = blk: {
425 // const loc = tree.tokenLocation(tree.token_locs[infix_op_node.op_token].end, tree.nextToken(infix_op_node.op_token));
426 // break :blk if (loc.line == 0) op_space else Space.Newline;
427 // };
428397
429 // {398 .Add,
430 // ais.pushIndent();399 .AddWrap,
431 // defer ais.popIndent();400 .ArrayCat,
432 // try renderToken(ais, tree, infix_op_node.op_token, after_op_space);401 .ArrayMult,
433 // }402 .Assign,
434 // ais.pushIndentOneShot();403 .AssignBitAnd,
435 // return renderExpression(ais, tree, infix_op_node.rhs, space);404 .AssignBitOr,
436 //},405 .AssignBitShiftLeft,
406 .AssignBitShiftRight,
407 .AssignBitXor,
408 .AssignDiv,
409 .AssignSub,
410 .AssignSubWrap,
411 .AssignMod,
412 .AssignAdd,
413 .AssignAddWrap,
414 .AssignMul,
415 .AssignMulWrap,
416 .BangEqual,
417 .BitAnd,
418 .BitOr,
419 .BitShiftLeft,
420 .BitShiftRight,
421 .BitXor,
422 .BoolAnd,
423 .BoolOr,
424 .Div,
425 .EqualEqual,
426 .GreaterOrEqual,
427 .GreaterThan,
428 .LessOrEqual,
429 .LessThan,
430 .MergeErrorSets,
431 .Mod,
432 .Mul,
433 .MulWrap,
434 .Sub,
435 .SubWrap,
436 .OrElse,
437 => {
438 const infix = datas[node];
439 try renderExpression(ais, tree, infix.lhs, .Space);
440
441 const op_token = main_tokens[node];
442 const after_op_space: Space = if (tree.tokensOnSameLine(op_token, op_token + 1))
443 .Space
444 else
445 .Newline;
446 {
447 ais.pushIndent();
448 try renderToken(ais, tree, op_token, after_op_space);
449 ais.popIndent();
450 }
451 ais.pushIndentOneShot();
452 return renderExpression(ais, tree, infix.rhs, space);
453 },
437454
438 //.BitNot,455 //.BitNot,
439 //.BoolNot,456 //.BoolNot,
...@@ -769,7 +786,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -769,7 +786,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
769786
770 // column_counter = 0;787 // column_counter = 0;
771 // try renderToken(ais, tree, comma, Space.Newline); // ,788 // try renderToken(ais, tree, comma, Space.Newline); // ,
772 // try renderExtraNewline(tree, ais, next_expr);789 // try renderExtraNewline(ais, tree, next_expr);
773 // } else {790 // } else {
774 // const maybe_comma = tree.nextToken(expr.*.lastToken());791 // const maybe_comma = tree.nextToken(expr.*.lastToken());
775 // if (tree.token_tags[maybe_comma] == .Comma) {792 // if (tree.token_tags[maybe_comma] == .Comma) {
...@@ -932,7 +949,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -932,7 +949,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
932 // const comma = tree.nextToken(field_init.lastToken());949 // const comma = tree.nextToken(field_init.lastToken());
933 // try renderToken(ais, tree, comma, Space.Newline);950 // try renderToken(ais, tree, comma, Space.Newline);
934951
935 // try renderExtraNewline(tree, ais, next_field_init);952 // try renderExtraNewline(ais, tree, next_field_init);
936 // } else {953 // } else {
937 // try renderExpression(ais, tree, field_init, Space.Comma);954 // try renderExpression(ais, tree, field_init, Space.Comma);
938 // }955 // }
...@@ -942,74 +959,63 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -942,74 +959,63 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
942 // return renderToken(ais, tree, rtoken, space);959 // return renderToken(ais, tree, rtoken, space);
943 //},960 //},
944961
945 //.Call => {962 .Call => {
946 // const call = @fieldParentPtr(ast.Node.Call, "base", base);963 const call = datas[node];
947 // if (call.async_token) |async_token| {964 const params_range = tree.extraData(call.rhs, ast.Node.SubRange);
948 // try renderToken(ais, tree, async_token, Space.Space);965 const params = tree.extra_data[params_range.start..params_range.end];
949 // }966 const async_token = tree.firstToken(call.lhs) - 1;
950967 if (token_tags[async_token] == .Keyword_async) {
951 // try renderExpression(ais, tree, call.lhs, Space.None);968 try renderToken(ais, tree, async_token, .Space);
952969 }
953 // const lparen = tree.nextToken(call.lhs.lastToken());970 try renderExpression(ais, tree, call.lhs, .None);
954971
955 // if (call.params_len == 0) {972 const lparen = main_tokens[node];
956 // try renderToken(ais, tree, lparen, Space.None);
957 // return renderToken(ais, tree, call.rtoken, space);
958 // }
959973
960 // const src_has_trailing_comma = blk: {974 if (params.len == 0) {
961 // const maybe_comma = tree.prevToken(call.rtoken);975 try renderToken(ais, tree, lparen, .None);
962 // break :blk tree.token_tags[maybe_comma] == .Comma;976 return renderToken(ais, tree, lparen + 1, space); // )
963 // };977 }
964978
965 // if (src_has_trailing_comma) {979 const last_param = params[params.len - 1];
966 // {980 const after_last_param_tok = tree.lastToken(last_param) + 1;
967 // ais.pushIndent();981 if (token_tags[after_last_param_tok] == .Comma) {
968 // defer ais.popIndent();982 ais.pushIndent();
983 try renderToken(ais, tree, lparen, Space.Newline); // (
984 for (params) |param_node, i| {
985 if (i + 1 < params.len) {
986 try renderExpression(ais, tree, param_node, Space.None);
969987
970 // try renderToken(ais, tree, lparen, Space.Newline); // (988 // Unindent the comma for multiline string literals
971 // const params = call.params();989 const is_multiline_string = node_tags[param_node] == .StringLiteral and
972 // for (params) |param_node, i| {990 token_tags[main_tokens[param_node]] == .MultilineStringLiteralLine;
973 // if (i + 1 < params.len) {991 if (is_multiline_string) ais.popIndent();
974 // const next_node = params[i + 1];
975 // try renderExpression(ais, tree, param_node, Space.None);
976992
977 // // Unindent the comma for multiline string literals993 const comma = tree.lastToken(param_node) + 1;
978 // const maybe_multiline_string = param_node.firstToken();994 try renderToken(ais, tree, comma, Space.Newline); // ,
979 // const is_multiline_string = tree.token_tags[maybe_multiline_string] == .MultilineStringLiteralLine;
980 // if (is_multiline_string) ais.popIndent();
981 // defer if (is_multiline_string) ais.pushIndent();
982995
983 // const comma = tree.nextToken(param_node.lastToken());996 if (is_multiline_string) ais.pushIndent();
984 // try renderToken(ais, tree, comma, Space.Newline); // ,
985 // try renderExtraNewline(tree, ais, next_node);
986 // } else {
987 // try renderExpression(ais, tree, param_node, Space.Comma);
988 // }
989 // }
990 // }
991 // return renderToken(ais, tree, call.rtoken, space);
992 // }
993997
994 // try renderToken(ais, tree, lparen, Space.None); // (998 try renderExtraNewline(ais, tree, params[i + 1]);
999 } else {
1000 try renderExpression(ais, tree, param_node, Space.Comma);
1001 }
1002 }
1003 ais.popIndent();
1004 return renderToken(ais, tree, after_last_param_tok + 1, space); // )
1005 }
9951006
996 // const params = call.params();1007 try renderToken(ais, tree, lparen, Space.None); // (
997 // for (params) |param_node, i| {
998 // const maybe_comment = param_node.firstToken() - 1;
999 // const maybe_multiline_string = param_node.firstToken();
1000 // if (tree.token_tags[maybe_multiline_string] == .MultilineStringLiteralLine or tree.token_tags[maybe_comment] == .LineComment) {
1001 // ais.pushIndentOneShot();
1002 // }
10031008
1004 // try renderExpression(ais, tree, param_node, Space.None);1009 for (params) |param_node, i| {
1010 try renderExpression(ais, tree, param_node, Space.None);
10051011
1006 // if (i + 1 < params.len) {1012 if (i + 1 < params.len) {
1007 // const comma = tree.nextToken(param_node.lastToken());1013 const comma = tree.lastToken(param_node) + 1;
1008 // try renderToken(ais, tree, comma, Space.Space);1014 try renderToken(ais, tree, comma, Space.Space);
1009 // }1015 }
1010 // }1016 }
1011 // return renderToken(ais, tree, call.rtoken, space); // )1017 return renderToken(ais, tree, after_last_param_tok, space); // )
1012 //},1018 },
10131019
1014 //.ArrayAccess => {1020 //.ArrayAccess => {
1015 // const suffix_op = base.castTag(.ArrayAccess).?;1021 // const suffix_op = base.castTag(.ArrayAccess).?;
...@@ -1118,14 +1124,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1118,14 +1124,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
1118 // }1124 // }
1119 //},1125 //},
11201126
1121 //.Payload => {
1122 // const payload = @fieldParentPtr(ast.Node.Payload, "base", base);
1123
1124 // try renderToken(ais, tree, payload.lpipe, Space.None);
1125 // try renderExpression(ais, tree, payload.error_symbol, Space.None);
1126 // return renderToken(ais, tree, payload.rpipe, space);
1127 //},
1128
1129 //.PointerPayload => {1127 //.PointerPayload => {
1130 // const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base);1128 // const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base);
11311129
...@@ -1264,7 +1262,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1264,7 +1262,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
1264 // try renderContainerDecl(allocator, ais, tree, decl, .Newline);1262 // try renderContainerDecl(allocator, ais, tree, decl, .Newline);
12651263
1266 // if (i + 1 < fields_and_decls.len) {1264 // if (i + 1 < fields_and_decls.len) {
1267 // try renderExtraNewline(tree, ais, fields_and_decls[i + 1]);1265 // try renderExtraNewline(ais, tree, fields_and_decls[i + 1]);
1268 // }1266 // }
1269 // }1267 // }
1270 // } else if (src_has_newline) {1268 // } else if (src_has_newline) {
...@@ -1338,7 +1336,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1338,7 +1336,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
1338 // try renderExpression(ais, tree, node, Space.None);1336 // try renderExpression(ais, tree, node, Space.None);
1339 // try renderToken(ais, tree, tree.nextToken(node.lastToken()), Space.Newline); // ,1337 // try renderToken(ais, tree, tree.nextToken(node.lastToken()), Space.Newline); // ,
13401338
1341 // try renderExtraNewline(tree, ais, decls[i + 1]);1339 // try renderExtraNewline(ais, tree, decls[i + 1]);
1342 // } else {1340 // } else {
1343 // try renderExpression(ais, tree, node, Space.Comma);1341 // try renderExpression(ais, tree, node, Space.Comma);
1344 // }1342 // }
...@@ -1357,7 +1355,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1357,7 +1355,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
1357 // const comma_token = tree.nextToken(node.lastToken());1355 // const comma_token = tree.nextToken(node.lastToken());
1358 // assert(tree.token_tags[comma_token] == .Comma);1356 // assert(tree.token_tags[comma_token] == .Comma);
1359 // try renderToken(ais, tree, comma_token, Space.Space); // ,1357 // try renderToken(ais, tree, comma_token, Space.Space); // ,
1360 // try renderExtraNewline(tree, ais, decls[i + 1]);1358 // try renderExtraNewline(ais, tree, decls[i + 1]);
1361 // } else {1359 // } else {
1362 // try renderExpression(ais, tree, node, Space.Space);1360 // try renderExpression(ais, tree, node, Space.Space);
1363 // }1361 // }
...@@ -1624,7 +1622,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1624,7 +1622,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
1624 // try renderExpression(ais, tree, node, Space.Comma);1622 // try renderExpression(ais, tree, node, Space.Comma);
16251623
1626 // if (i + 1 < cases.len) {1624 // if (i + 1 < cases.len) {
1627 // try renderExtraNewline(tree, ais, cases[i + 1]);1625 // try renderExtraNewline(ais, tree, cases[i + 1]);
1628 // }1626 // }
1629 // }1627 // }
1630 // }1628 // }
...@@ -1650,7 +1648,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1650,7 +1648,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
16501648
1651 // const comma_token = tree.nextToken(node.lastToken());1649 // const comma_token = tree.nextToken(node.lastToken());
1652 // try renderToken(ais, tree, comma_token, Space.Space); // ,1650 // try renderToken(ais, tree, comma_token, Space.Space); // ,
1653 // try renderExtraNewline(tree, ais, items[i + 1]);1651 // try renderExtraNewline(ais, tree, items[i + 1]);
1654 // } else {1652 // } else {
1655 // try renderExpression(ais, tree, node, Space.Space);1653 // try renderExpression(ais, tree, node, Space.Space);
1656 // }1654 // }
...@@ -1663,7 +1661,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1663,7 +1661,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
16631661
1664 // const comma_token = tree.nextToken(node.lastToken());1662 // const comma_token = tree.nextToken(node.lastToken());
1665 // try renderToken(ais, tree, comma_token, Space.Newline); // ,1663 // try renderToken(ais, tree, comma_token, Space.Newline); // ,
1666 // try renderExtraNewline(tree, ais, items[i + 1]);1664 // try renderExtraNewline(ais, tree, items[i + 1]);
1667 // } else {1665 // } else {
1668 // try renderExpression(ais, tree, node, Space.Comma);1666 // try renderExpression(ais, tree, node, Space.Comma);
1669 // }1667 // }
...@@ -1682,28 +1680,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1682,28 +1680,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
1682 // const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);1680 // const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);
1683 // return renderToken(ais, tree, switch_else.token, space);1681 // return renderToken(ais, tree, switch_else.token, space);
1684 //},1682 //},
1685 //.Else => {
1686 // const else_node = @fieldParentPtr(ast.Node.Else, "base", base);
1687
1688 // const body_is_block = nodeIsBlock(else_node.body);
1689 // const same_line = body_is_block or tree.tokensOnSameLine(else_node.else_token, else_node.body.lastToken());
1690
1691 // const after_else_space = if (same_line or else_node.payload != null) Space.Space else Space.Newline;
1692 // try renderToken(ais, tree, else_node.else_token, after_else_space);
1693
1694 // if (else_node.payload) |payload| {
1695 // const payload_space = if (same_line) Space.Space else Space.Newline;
1696 // try renderExpression(ais, tree, payload, payload_space);
1697 // }
1698
1699 // if (same_line) {
1700 // return renderExpression(ais, tree, else_node.body, space);
1701 // } else {
1702 // ais.pushIndent();
1703 // defer ais.popIndent();
1704 // return renderExpression(ais, tree, else_node.body, space);
1705 // }
1706 //},
17071683
1708 //.While => {1684 //.While => {
1709 // const while_node = @fieldParentPtr(ast.Node.While, "base", base);1685 // const while_node = @fieldParentPtr(ast.Node.While, "base", base);
...@@ -1824,111 +1800,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1824,111 +1800,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
1824 // }1800 // }
1825 //},1801 //},
18261802
1827 //.If => {1803 .IfSimple => return renderIf(ais, tree, tree.ifSimple(node), space),
1828 // const if_node = @fieldParentPtr(ast.Node.If, "base", base);1804 .If => return renderIf(ais, tree, tree.ifFull(node), space),
1829
1830 // const lparen = tree.nextToken(if_node.if_token);
1831 // const rparen = tree.nextToken(if_node.condition.lastToken());
1832
1833 // try renderToken(ais, tree, if_node.if_token, Space.Space); // if
1834 // try renderToken(ais, tree, lparen, Space.None); // (
1835
1836 // try renderExpression(ais, tree, if_node.condition, Space.None); // condition
1837
1838 // const body_is_if_block = if_node.body.tag == .If;
1839 // const body_is_block = nodeIsBlock(if_node.body);
1840
1841 // if (body_is_if_block) {
1842 // try renderExtraNewline(tree, ais, if_node.body);
1843 // } else if (body_is_block) {
1844 // const after_rparen_space = if (if_node.payload == null) Space.BlockStart else Space.Space;
1845 // try renderToken(ais, tree, rparen, after_rparen_space); // )
1846
1847 // if (if_node.payload) |payload| {
1848 // try renderExpression(ais, tree, payload, Space.BlockStart); // |x|
1849 // }
1850
1851 // if (if_node.@"else") |@"else"| {
1852 // try renderExpression(ais, tree, if_node.body, Space.SpaceOrOutdent);
1853 // return renderExpression(ais, tree, &@"else".base, space);
1854 // } else {
1855 // return renderExpression(ais, tree, if_node.body, space);
1856 // }
1857 // }
1858
1859 // const src_has_newline = !tree.tokensOnSameLine(rparen, if_node.body.lastToken());
1860
1861 // if (src_has_newline) {
1862 // const after_rparen_space = if (if_node.payload == null) Space.Newline else Space.Space;
1863
1864 // {
1865 // ais.pushIndent();
1866 // defer ais.popIndent();
1867 // try renderToken(ais, tree, rparen, after_rparen_space); // )
1868 // }
1869
1870 // if (if_node.payload) |payload| {
1871 // try renderExpression(ais, tree, payload, Space.Newline);
1872 // }
1873
1874 // if (if_node.@"else") |@"else"| {
1875 // const else_is_block = nodeIsBlock(@"else".body);
1876
1877 // {
1878 // ais.pushIndent();
1879 // defer ais.popIndent();
1880 // try renderExpression(ais, tree, if_node.body, Space.Newline);
1881 // }
1882
1883 // if (else_is_block) {
1884 // try renderToken(ais, tree, @"else".else_token, Space.Space); // else
1885
1886 // if (@"else".payload) |payload| {
1887 // try renderExpression(ais, tree, payload, Space.Space);
1888 // }
1889
1890 // return renderExpression(ais, tree, @"else".body, space);
1891 // } else {
1892 // const after_else_space = if (@"else".payload == null) Space.Newline else Space.Space;
1893 // try renderToken(ais, tree, @"else".else_token, after_else_space); // else
1894
1895 // if (@"else".payload) |payload| {
1896 // try renderExpression(ais, tree, payload, Space.Newline);
1897 // }
1898
1899 // ais.pushIndent();
1900 // defer ais.popIndent();
1901 // return renderExpression(ais, tree, @"else".body, space);
1902 // }
1903 // } else {
1904 // ais.pushIndent();
1905 // defer ais.popIndent();
1906 // return renderExpression(ais, tree, if_node.body, space);
1907 // }
1908 // }
1909
1910 // // Single line if statement
1911
1912 // try renderToken(ais, tree, rparen, Space.Space); // )
1913
1914 // if (if_node.payload) |payload| {
1915 // try renderExpression(ais, tree, payload, Space.Space);
1916 // }
1917
1918 // if (if_node.@"else") |@"else"| {
1919 // try renderExpression(ais, tree, if_node.body, Space.Space);
1920 // try renderToken(ais, tree, @"else".else_token, Space.Space);
1921
1922 // if (@"else".payload) |payload| {
1923 // try renderExpression(ais, tree, payload, Space.Space);
1924 // }
1925
1926 // return renderExpression(ais, tree, @"else".body, space);
1927 // } else {
1928 // return renderExpression(ais, tree, if_node.body, space);
1929 // }
1930 //},
1931
1932 //.Asm => {1805 //.Asm => {
1933 // const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base);1806 // const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base);
19341807
...@@ -1974,7 +1847,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1974,7 +1847,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
19741847
1975 // const comma = tree.prevToken(next_asm_output.firstToken());1848 // const comma = tree.prevToken(next_asm_output.firstToken());
1976 // try renderToken(ais, tree, comma, Space.Newline); // ,1849 // try renderToken(ais, tree, comma, Space.Newline); // ,
1977 // try renderExtraNewlineToken(tree, ais, next_asm_output.firstToken());1850 // try renderExtraNewlineToken(ais, tree, next_asm_output.firstToken());
1978 // } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {1851 // } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
1979 // try renderAsmOutput(allocator, ais, tree, asm_output, Space.Newline);1852 // try renderAsmOutput(allocator, ais, tree, asm_output, Space.Newline);
1980 // break :asmblk;1853 // break :asmblk;
...@@ -2004,7 +1877,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -2004,7 +1877,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
20041877
2005 // const comma = tree.prevToken(next_asm_input.firstToken());1878 // const comma = tree.prevToken(next_asm_input.firstToken());
2006 // try renderToken(ais, tree, comma, Space.Newline); // ,1879 // try renderToken(ais, tree, comma, Space.Newline); // ,
2007 // try renderExtraNewlineToken(tree, ais, next_asm_input.firstToken());1880 // try renderExtraNewlineToken(ais, tree, next_asm_input.firstToken());
2008 // } else if (asm_node.clobbers.len == 0) {1881 // } else if (asm_node.clobbers.len == 0) {
2009 // try renderAsmInput(allocator, ais, tree, asm_input, Space.Newline);1882 // try renderAsmInput(allocator, ais, tree, asm_input, Space.Newline);
2010 // break :asmblk;1883 // break :asmblk;
...@@ -2140,89 +2013,225 @@ fn renderAsmInput(...@@ -2140,89 +2013,225 @@ fn renderAsmInput(
2140 return renderToken(ais, tree, asm_input.lastToken(), space); // )2013 return renderToken(ais, tree, asm_input.lastToken(), space); // )
2141}2014}
21422015
2143fn renderVarDecl(2016fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.Full.VarDecl) Error!void {
2144 allocator: *mem.Allocator,2017 if (var_decl.visib_token) |visib_token| {
2145 ais: *Ais,
2146 tree: ast.Tree,
2147 var_decl: ast.Node.Index.VarDecl,
2148) Error!void {
2149 if (var_decl.getVisibToken()) |visib_token| {
2150 try renderToken(ais, tree, visib_token, Space.Space); // pub2018 try renderToken(ais, tree, visib_token, Space.Space); // pub
2151 }2019 }
21522020
2153 if (var_decl.getExternExportToken()) |extern_export_token| {2021 if (var_decl.extern_export_token) |extern_export_token| {
2154 try renderToken(ais, tree, extern_export_token, Space.Space); // extern2022 try renderToken(ais, tree, extern_export_token, Space.Space); // extern
21552023
2156 if (var_decl.getLibName()) |lib_name| {2024 if (var_decl.lib_name) |lib_name| {
2157 try renderExpression(ais, tree, lib_name, Space.Space); // "lib"2025 try renderExpression(ais, tree, lib_name, Space.Space); // "lib"
2158 }2026 }
2159 }2027 }
21602028
2161 if (var_decl.getComptimeToken()) |comptime_token| {2029 if (var_decl.threadlocal_token) |thread_local_token| {
2162 try renderToken(ais, tree, comptime_token, Space.Space); // comptime2030 try renderToken(ais, tree, thread_local_token, Space.Space); // threadlocal
2163 }2031 }
21642032
2165 if (var_decl.getThreadLocalToken()) |thread_local_token| {2033 if (var_decl.comptime_token) |comptime_token| {
2166 try renderToken(ais, tree, thread_local_token, Space.Space); // threadlocal2034 try renderToken(ais, tree, comptime_token, Space.Space); // comptime
2167 }2035 }
2168 try renderToken(ais, tree, var_decl.mut_token, Space.Space); // var
21692036
2170 const name_space = if (var_decl.getTypeNode() == null and2037 try renderToken(ais, tree, var_decl.ast.mut_token, .Space); // var
2171 (var_decl.getAlignNode() != null or2038
2172 var_decl.getSectionNode() != null or2039 const name_space = if (var_decl.ast.type_node == 0 and
2173 var_decl.getInitNode() != null))2040 (var_decl.ast.align_node != 0 or
2041 var_decl.ast.section_node != 0 or
2042 var_decl.ast.init_node != 0))
2174 Space.Space2043 Space.Space
2175 else2044 else
2176 Space.None;2045 Space.None;
2177 try renderToken(ais, tree, var_decl.name_token, name_space);2046 try renderToken(ais, tree, var_decl.ast.mut_token + 1, name_space); // name
21782047
2179 if (var_decl.getTypeNode()) |type_node| {2048 if (var_decl.ast.type_node != 0) {
2180 try renderToken(ais, tree, tree.nextToken(var_decl.name_token), Space.Space);2049 try renderToken(ais, tree, var_decl.ast.mut_token + 2, Space.Space); // :
2181 const s = if (var_decl.getAlignNode() != null or2050 if (var_decl.ast.align_node != 0 or var_decl.ast.section_node != 0 or
2182 var_decl.getSectionNode() != null or2051 var_decl.ast.init_node != 0)
2183 var_decl.getInitNode() != null) Space.Space else Space.None;2052 {
2184 try renderExpression(ais, tree, type_node, s);2053 try renderExpression(ais, tree, var_decl.ast.type_node, .Space);
2054 } else {
2055 try renderExpression(ais, tree, var_decl.ast.type_node, .None);
2056 const semicolon = tree.lastToken(var_decl.ast.type_node) + 1;
2057 return renderToken(ais, tree, semicolon, Space.Newline); // ;
2058 }
2185 }2059 }
21862060
2187 if (var_decl.getAlignNode()) |align_node| {2061 if (var_decl.ast.align_node != 0) {
2188 const lparen = tree.prevToken(align_node.firstToken());2062 const lparen = tree.firstToken(var_decl.ast.align_node) - 1;
2189 const align_kw = tree.prevToken(lparen);2063 const align_kw = lparen - 1;
2190 const rparen = tree.nextToken(align_node.lastToken());2064 const rparen = tree.lastToken(var_decl.ast.align_node) + 1;
2191 try renderToken(ais, tree, align_kw, Space.None); // align2065 try renderToken(ais, tree, align_kw, Space.None); // align
2192 try renderToken(ais, tree, lparen, Space.None); // (2066 try renderToken(ais, tree, lparen, Space.None); // (
2193 try renderExpression(ais, tree, align_node, Space.None);2067 try renderExpression(ais, tree, var_decl.ast.align_node, Space.None);
2194 const s = if (var_decl.getSectionNode() != null or var_decl.getInitNode() != null) Space.Space else Space.None;2068 if (var_decl.ast.section_node != 0 or var_decl.ast.init_node != 0) {
2195 try renderToken(ais, tree, rparen, s); // )2069 try renderToken(ais, tree, rparen, .Space); // )
2070 } else {
2071 try renderToken(ais, tree, rparen, .None); // )
2072 return renderToken(ais, tree, rparen + 1, Space.Newline); // ;
2073 }
2196 }2074 }
21972075
2198 if (var_decl.getSectionNode()) |section_node| {2076 if (var_decl.ast.section_node != 0) {
2199 const lparen = tree.prevToken(section_node.firstToken());2077 const lparen = tree.firstToken(var_decl.ast.section_node) - 1;
2200 const section_kw = tree.prevToken(lparen);2078 const section_kw = lparen - 1;
2201 const rparen = tree.nextToken(section_node.lastToken());2079 const rparen = tree.lastToken(var_decl.ast.section_node) + 1;
2202 try renderToken(ais, tree, section_kw, Space.None); // linksection2080 try renderToken(ais, tree, section_kw, Space.None); // linksection
2203 try renderToken(ais, tree, lparen, Space.None); // (2081 try renderToken(ais, tree, lparen, Space.None); // (
2204 try renderExpression(ais, tree, section_node, Space.None);2082 try renderExpression(ais, tree, var_decl.ast.section_node, Space.None);
2205 const s = if (var_decl.getInitNode() != null) Space.Space else Space.None;2083 if (var_decl.ast.init_node != 0) {
2206 try renderToken(ais, tree, rparen, s); // )2084 try renderToken(ais, tree, rparen, .Space); // )
2085 } else {
2086 try renderToken(ais, tree, rparen, .None); // )
2087 return renderToken(ais, tree, rparen + 1, Space.Newline); // ;
2088 }
2207 }2089 }
22082090
2209 if (var_decl.getInitNode()) |init_node| {2091 assert(var_decl.ast.init_node != 0);
2210 const eq_token = var_decl.getEqToken().?;2092 const eq_token = tree.firstToken(var_decl.ast.init_node) - 1;
2211 const eq_space = blk: {2093 const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .Space else .Newline;
2212 const loc = tree.tokenLocation(tree.token_locs[eq_token].end, tree.nextToken(eq_token));2094 {
2213 break :blk if (loc.line == 0) Space.Space else Space.Newline;2095 ais.pushIndent();
2214 };2096 try renderToken(ais, tree, eq_token, eq_space); // =
2097 ais.popIndent();
2098 }
2099 ais.pushIndentOneShot();
2100 try renderExpression(ais, tree, var_decl.ast.init_node, Space.None);
22152101
2216 {2102 const semicolon = tree.lastToken(var_decl.ast.init_node) + 1;
2103 return renderToken(ais, tree, semicolon, Space.Newline);
2104}
2105
2106fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.Full.If, space: Space) Error!void {
2107 const node_tags = tree.nodes.items(.tag);
2108 const token_tags = tree.tokens.items(.tag);
2109
2110 try renderToken(ais, tree, if_node.ast.if_token, .Space); // if
2111
2112 const lparen = if_node.ast.if_token + 1;
2113
2114 try renderToken(ais, tree, lparen, .None); // (
2115 try renderExpression(ais, tree, if_node.ast.cond_expr, .None); // condition
2116
2117 switch (node_tags[if_node.ast.then_expr]) {
2118 .If, .IfSimple => {
2119 try renderExtraNewline(ais, tree, if_node.ast.then_expr);
2120 },
2121 .Block, .For, .ForSimple, .While, .WhileSimple, .Switch => {
2122 if (if_node.payload_token) |payload_token| {
2123 try renderToken(ais, tree, payload_token - 2, .Space); // )
2124 try renderToken(ais, tree, payload_token - 1, .None); // |
2125 if (token_tags[payload_token] == .Asterisk) {
2126 try renderToken(ais, tree, payload_token, .None); // *
2127 try renderToken(ais, tree, payload_token + 1, .None); // identifier
2128 try renderToken(ais, tree, payload_token + 2, .BlockStart); // |
2129 } else {
2130 try renderToken(ais, tree, payload_token, .None); // identifier
2131 try renderToken(ais, tree, payload_token + 1, .BlockStart); // |
2132 }
2133 } else {
2134 const rparen = tree.lastToken(if_node.ast.cond_expr) + 1;
2135 try renderToken(ais, tree, rparen, .BlockStart); // )
2136 }
2137 if (if_node.ast.else_expr != 0) {
2138 try renderExpression(ais, tree, if_node.ast.then_expr, Space.SpaceOrOutdent);
2139 try renderToken(ais, tree, if_node.else_token, .Space); // else
2140 if (if_node.error_token) |error_token| {
2141 try renderToken(ais, tree, error_token - 1, .None); // |
2142 try renderToken(ais, tree, error_token, .None); // identifier
2143 try renderToken(ais, tree, error_token + 1, .Space); // |
2144 }
2145 return renderExpression(ais, tree, if_node.ast.else_expr, space);
2146 } else {
2147 return renderExpression(ais, tree, if_node.ast.then_expr, space);
2148 }
2149 },
2150 else => {},
2151 }
2152
2153 const rparen = tree.lastToken(if_node.ast.cond_expr) + 1;
2154 const last_then_token = tree.lastToken(if_node.ast.then_expr);
2155 const src_has_newline = !tree.tokensOnSameLine(rparen, last_then_token);
2156
2157 if (src_has_newline) {
2158 if (if_node.payload_token) |payload_token| {
2159 try renderToken(ais, tree, payload_token - 2, .Space); // )
2160 try renderToken(ais, tree, payload_token - 1, .None); // |
2161 try renderToken(ais, tree, payload_token, .None); // identifier
2162 try renderToken(ais, tree, payload_token + 1, .Newline); // |
2163 } else {
2217 ais.pushIndent();2164 ais.pushIndent();
2218 defer ais.popIndent();2165 try renderToken(ais, tree, rparen, .Newline); // )
2219 try renderToken(ais, tree, eq_token, eq_space); // =2166 ais.popIndent();
2167 }
2168 if (if_node.ast.else_expr != 0) {
2169 ais.pushIndent();
2170 try renderExpression(ais, tree, if_node.ast.then_expr, Space.Newline);
2171 ais.popIndent();
2172 const else_is_block = nodeIsBlock(node_tags[if_node.ast.else_expr]);
2173 if (else_is_block) {
2174 try renderToken(ais, tree, if_node.else_token, .Space); // else
2175 if (if_node.error_token) |error_token| {
2176 try renderToken(ais, tree, error_token - 1, .None); // |
2177 try renderToken(ais, tree, error_token, .None); // identifier
2178 try renderToken(ais, tree, error_token + 1, .Space); // |
2179 }
2180 return renderExpression(ais, tree, if_node.ast.else_expr, space);
2181 } else {
2182 if (if_node.error_token) |error_token| {
2183 try renderToken(ais, tree, if_node.else_token, .Space); // else
2184 try renderToken(ais, tree, error_token - 1, .None); // |
2185 try renderToken(ais, tree, error_token, .None); // identifier
2186 try renderToken(ais, tree, error_token + 1, .Space); // |
2187 } else {
2188 try renderToken(ais, tree, if_node.else_token, .Newline); // else
2189 }
2190 ais.pushIndent();
2191 try renderExpression(ais, tree, if_node.ast.else_expr, space);
2192 ais.popIndent();
2193 return;
2194 }
2195 } else {
2196 ais.pushIndent();
2197 try renderExpression(ais, tree, if_node.ast.then_expr, space);
2198 ais.popIndent();
2199 return;
2220 }2200 }
2221 ais.pushIndentOneShot();
2222 try renderExpression(ais, tree, init_node, Space.None);
2223 }2201 }
22242202
2225 try renderToken(ais, tree, var_decl.semicolon_token, Space.Newline);2203 // Single line if statement.
2204
2205 if (if_node.payload_token) |payload_token| {
2206 assert(payload_token - 2 == rparen);
2207 try renderToken(ais, tree, payload_token - 2, .Space); // )
2208 try renderToken(ais, tree, payload_token - 1, .None); // |
2209 if (token_tags[payload_token] == .Asterisk) {
2210 try renderToken(ais, tree, payload_token, .None); // *
2211 try renderToken(ais, tree, payload_token + 1, .None); // identifier
2212 try renderToken(ais, tree, payload_token + 2, .Space); // |
2213 } else {
2214 try renderToken(ais, tree, payload_token, .None); // identifier
2215 try renderToken(ais, tree, payload_token + 1, .Space); // |
2216 }
2217 } else {
2218 try renderToken(ais, tree, rparen, .Space); // )
2219 }
2220
2221 if (if_node.ast.else_expr != 0) {
2222 try renderExpression(ais, tree, if_node.ast.then_expr, .Space);
2223 try renderToken(ais, tree, if_node.else_token, .Space); // else
2224
2225 if (if_node.error_token) |error_token| {
2226 try renderToken(ais, tree, error_token - 1, .None); // |
2227 try renderToken(ais, tree, error_token, .None); // identifier
2228 try renderToken(ais, tree, error_token + 1, .Space); // |
2229 }
2230
2231 return renderExpression(ais, tree, if_node.ast.else_expr, space);
2232 } else {
2233 return renderExpression(ais, tree, if_node.ast.then_expr, space);
2234 }
2226}2235}
22272236
2228fn renderParamDecl(2237fn renderParamDecl(
...@@ -2249,27 +2258,6 @@ fn renderParamDecl(...@@ -2249,27 +2258,6 @@ fn renderParamDecl(
2249 }2258 }
2250}2259}
22512260
2252fn renderStatement(ais: *Ais, tree: ast.Tree, base: ast.Node.Index) Error!void {
2253 @panic("TODO render statement");
2254 //switch (base.tag) {
2255 // .VarDecl => {
2256 // const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
2257 // try renderVarDecl(allocator, ais, tree, var_decl);
2258 // },
2259 // else => {
2260 // if (base.requireSemiColon()) {
2261 // try renderExpression(ais, tree, base, Space.None);
2262
2263 // const semicolon_index = tree.nextToken(base.lastToken());
2264 // assert(tree.token_tags[semicolon_index] == .Semicolon);
2265 // try renderToken(ais, tree, semicolon_index, Space.Newline);
2266 // } else {
2267 // try renderExpression(ais, tree, base, Space.Newline);
2268 // }
2269 // },
2270 //}
2271}
2272
2273const Space = enum {2261const Space = enum {
2274 None,2262 None,
2275 Newline,2263 Newline,
...@@ -2367,13 +2355,15 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error...@@ -2367,13 +2355,15 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error
2367 }2355 }
2368}2356}
23692357
2370fn nodeIsBlock(base: *const ast.Node) bool {2358fn nodeIsBlock(tag: ast.Node.Tag) bool {
2371 return switch (base.tag) {2359 return switch (tag) {
2372 .Block,2360 .Block,
2373 .LabeledBlock,
2374 .If,2361 .If,
2362 .IfSimple,
2375 .For,2363 .For,
2364 .ForSimple,
2376 .While,2365 .While,
2366 .WhileSimple,
2377 .Switch,2367 .Switch,
2378 => true,2368 => true,
2379 else => false,2369 else => false,