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 {
1616 tag: Token.Tag,
1717 start: ByteOffset,
1818});
19pub const NodeList = std.MultiArrayList(struct {
20 tag: Node.Tag,
21 main_token: TokenIndex,
22 data: Node.Data,
23});
19pub const NodeList = std.MultiArrayList(Node);
2420
2521pub const Tree = struct {
2622 /// Reference to externally-owned data.
......@@ -76,6 +72,16 @@ pub const Tree = struct {
7672 return loc;
7773 }
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
7985 pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {
8086 const tokens = tree.tokens.items(.tag);
8187 switch (parse_error) {
......@@ -189,7 +195,8 @@ pub const Tree = struct {
189195 const tags = tree.nodes.items(.tag);
190196 const datas = tree.nodes.items(.data);
191197 const main_tokens = tree.nodes.items(.main_token);
192 switch (tags[node]) {
198 var n = node;
199 while (true) switch (tags[n]) {
193200 .Root => return 0,
194201
195202 .UsingNamespace,
......@@ -210,20 +217,25 @@ pub const Tree = struct {
210217 .StructInitDot,
211218 .Switch,
212219 .IfSimple,
213 .IfSimpleOptional,
214220 .If,
215 .IfOptional,
216 .IfError,
217221 .Suspend,
218222 .Resume,
219223 .Continue,
220224 .Break,
221225 .Return,
222226 .AnyFrameType,
223 .OneToken,
224227 .Identifier,
228 .AnyFrameLiteral,
229 .CharLiteral,
230 .IntegerLiteral,
231 .FloatLiteral,
232 .FalseLiteral,
233 .TrueLiteral,
234 .NullLiteral,
235 .UndefinedLiteral,
236 .UnreachableLiteral,
225237 .EnumLiteral,
226 .MultilineStringLiteral,
238 .StringLiteral,
227239 .GroupedExpression,
228240 .BuiltinCallTwo,
229241 .BuiltinCall,
......@@ -234,7 +246,7 @@ pub const Tree = struct {
234246 .Block,
235247 .AsmSimple,
236248 .Asm,
237 => return main_tokens[node],
249 => return main_tokens[n],
238250
239251 .Catch,
240252 .FieldAccess,
......@@ -290,7 +302,7 @@ pub const Tree = struct {
290302 .SwitchCaseOne,
291303 .SwitchRange,
292304 .FnDecl,
293 => return tree.firstToken(datas[node].lhs),
305 => n = datas[n].lhs,
294306
295307 .GlobalVarDecl,
296308 .LocalVarDecl,
......@@ -305,12 +317,8 @@ pub const Tree = struct {
305317 .StructInit,
306318 .SwitchCaseMulti,
307319 .WhileSimple,
308 .WhileSimpleOptional,
309320 .WhileCont,
310 .WhileContOptional,
311321 .While,
312 .WhileOptional,
313 .WhileError,
314322 .ForSimple,
315323 .For,
316324 .FnProtoSimple,
......@@ -329,19 +337,19 @@ pub const Tree = struct {
329337 .ErrorValue,
330338 .ErrorUnion,
331339 => @panic("TODO finish implementing firstToken"),
332 }
340 };
333341 }
334342
335343 pub fn lastToken(tree: Tree, node: Node.Index) TokenIndex {
336344 const tags = tree.nodes.items(.tag);
337345 const datas = tree.nodes.items(.data);
338346 const main_tokens = tree.nodes.items(.main_token);
339 switch (tags[node]) {
340 .Root,
347 var n = node;
348 var end_offset: TokenIndex = 0;
349 while (true) switch (tags[n]) {
350 .Root => return @intCast(TokenIndex, tree.tokens.len - 1),
351
341352 .UsingNamespace,
342 .TestDecl,
343 .ErrDefer,
344 .Defer,
345353 .BoolNot,
346354 .Negation,
347355 .BitNot,
......@@ -350,39 +358,16 @@ pub const Tree = struct {
350358 .Try,
351359 .Await,
352360 .OptionalType,
353 .ArrayInitDotTwo,
354 .ArrayInitDot,
355 .StructInitDotTwo,
356 .StructInitDot,
357 .Switch,
358 .IfSimple,
359 .IfSimpleOptional,
360 .If,
361 .IfOptional,
362 .IfError,
363361 .Suspend,
364362 .Resume,
365 .Continue,
366363 .Break,
367364 .Return,
368 .AnyFrameType,
369 .OneToken,
370 .Identifier,
371 .EnumLiteral,
372 .MultilineStringLiteral,
373 .GroupedExpression,
374 .BuiltinCallTwo,
375 .BuiltinCall,
376 .ErrorSetDecl,
377 .AnyType,
378 .Comptime,
379 .Nosuspend,
380 .Block,
381 .AsmSimple,
382 .Asm,
365 => n = datas[n].lhs,
366
367 .TestDecl,
368 .ErrDefer,
369 .Defer,
383370 .Catch,
384 .FieldAccess,
385 .UnwrapOptional,
386371 .EqualEqual,
387372 .BangEqual,
388373 .LessThan,
......@@ -422,6 +407,63 @@ pub const Tree = struct {
422407 .OrElse,
423408 .BoolAnd,
424409 .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,
425467 .SliceOpen,
426468 .Slice,
427469 .Deref,
......@@ -429,8 +471,6 @@ pub const Tree = struct {
429471 .ArrayInitOne,
430472 .ArrayInit,
431473 .StructInitOne,
432 .CallOne,
433 .Call,
434474 .SwitchCaseOne,
435475 .SwitchRange,
436476 .FnDecl,
......@@ -446,13 +486,8 @@ pub const Tree = struct {
446486 .SliceType,
447487 .StructInit,
448488 .SwitchCaseMulti,
449 .WhileSimple,
450 .WhileSimpleOptional,
451489 .WhileCont,
452 .WhileContOptional,
453490 .While,
454 .WhileOptional,
455 .WhileError,
456491 .ForSimple,
457492 .For,
458493 .FnProtoSimple,
......@@ -469,12 +504,178 @@ pub const Tree = struct {
469504 .AsmOutput,
470505 .AsmInput,
471506 .ErrorValue,
472 .ErrorUnion,
473507 => @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 }
474636 }
637 return result;
475638 }
476639};
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
478679pub const Error = union(enum) {
479680 InvalidToken: InvalidToken,
480681 ExpectedContainerMembers: ExpectedContainerMembers,
......@@ -706,7 +907,9 @@ pub const Error = union(enum) {
706907};
707908
708909pub const Node = struct {
709 index: Index,
910 tag: Tag,
911 main_token: TokenIndex,
912 data: Data,
710913
711914 pub const Index = u32;
712915
......@@ -718,22 +921,26 @@ pub const Node = struct {
718921 pub const Tag = enum {
719922 /// sub_list[lhs...rhs]
720923 Root,
721 /// lhs is the sub-expression. rhs is unused.
924 /// `usingnamespace lhs;`. rhs unused. main_token is `usingnamespace`.
722925 UsingNamespace,
723926 /// lhs is test name token (must be string literal), if any.
724927 /// rhs is the body node.
725928 TestDecl,
726929 /// lhs is the index into extra_data.
727930 /// rhs is the initialization expression, if any.
931 /// main_token is `var` or `const`.
728932 GlobalVarDecl,
729933 /// `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`.
731936 LocalVarDecl,
732937 /// `var a: lhs = rhs`. lhs and rhs may be unused.
733938 /// Can be local or global.
939 /// main_token is `var` or `const`.
734940 SimpleVarDecl,
735941 /// `var a align(lhs) = rhs`. lhs and rhs may be unused.
736942 /// Can be local or global.
943 /// main_token is `var` or `const`.
737944 AlignedVarDecl,
738945 /// lhs is the identifier token payload if any,
739946 /// rhs is the deferred expression.
......@@ -901,33 +1108,26 @@ pub const Node = struct {
9011108 /// `lhs...rhs`.
9021109 SwitchRange,
9031110 /// `while (lhs) rhs`.
904 WhileSimple,
9051111 /// `while (lhs) |x| rhs`.
906 WhileSimpleOptional,
1112 WhileSimple,
9071113 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
908 WhileCont,
9091114 /// `while (lhs) : (a) b`. `WhileCont[rhs]`.
910 WhileContOptional,
1115 WhileCont,
9111116 /// `while (lhs) : (a) b else c`. `While[rhs]`.
912 While,
9131117 /// `while (lhs) |x| : (a) b else c`. `While[rhs]`.
914 WhileOptional,
9151118 /// `while (lhs) |x| : (a) b else |y| c`. `While[rhs]`.
916 WhileError,
1119 While,
9171120 /// `for (lhs) rhs`.
9181121 ForSimple,
9191122 /// `for (lhs) a else b`. `if_list[rhs]`.
9201123 For,
9211124 /// `if (lhs) rhs`.
922 IfSimple,
9231125 /// `if (lhs) |a| rhs`.
924 IfSimpleOptional,
1126 IfSimple,
9251127 /// `if (lhs) a else b`. `if_list[rhs]`.
926 If,
9271128 /// `if (lhs) |x| a else b`. `if_list[rhs]`.
928 IfOptional,
9291129 /// `if (lhs) |x| a else |y| b`. `if_list[rhs]`.
930 IfError,
1130 If,
9311131 /// `suspend lhs`. lhs can be omitted. rhs is unused.
9321132 Suspend,
9331133 /// `resume lhs`. rhs is unused.
......@@ -955,10 +1155,24 @@ pub const Node = struct {
9551155 FnDecl,
9561156 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
9571157 AnyFrameType,
958 /// Could be integer literal, float literal, char literal, bool literal,
959 /// null literal, undefined literal, unreachable, depending on the token.
9601158 /// 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,
9621176 /// Both lhs and rhs unused.
9631177 /// Most identifiers will not have explicit AST nodes, however for expressions
9641178 /// which could be one of many different kinds of AST nodes, there will be an
......@@ -966,8 +1180,11 @@ pub const Node = struct {
9661180 Identifier,
9671181 /// lhs is the dot token index, rhs unused, main_token is the identifier.
9681182 EnumLiteral,
969 /// Both lhs and rhs unused.
970 MultilineStringLiteral,
1183 /// main_token is the first token index (redundant with lhs)
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,
9711188 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
9721189 GroupedExpression,
9731190 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
lib/std/zig/parse.zig+119-109
......@@ -832,7 +832,7 @@ const Parser = struct {
832832 }
833833 if (p.eatToken(.Semicolon)) |_| {
834834 return p.addNode(.{
835 .tag = if (then_payload == 0) .IfSimple else .IfSimpleOptional,
835 .tag = .IfSimple,
836836 .main_token = if_token,
837837 .data = .{
838838 .lhs = condition,
......@@ -848,7 +848,7 @@ const Parser = struct {
848848 return p.fail(.{ .ExpectedSemiOrElse = .{ .token = p.tok_i } });
849849 }
850850 return p.addNode(.{
851 .tag = if (then_payload == 0) .IfSimple else .IfSimpleOptional,
851 .tag = .IfSimple,
852852 .main_token = if_token,
853853 .data = .{
854854 .lhs = condition,
......@@ -858,14 +858,8 @@ const Parser = struct {
858858 };
859859 const else_payload = try p.parsePayload();
860860 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;
867861 return p.addNode(.{
868 .tag = tag,
862 .tag = .If,
869863 .main_token = if_token,
870864 .data = .{
871865 .lhs = condition,
......@@ -994,7 +988,7 @@ const Parser = struct {
994988 if (p.eatToken(.Semicolon)) |_| {
995989 if (continue_expr == 0) {
996990 return p.addNode(.{
997 .tag = if (then_payload == 0) .WhileSimple else .WhileSimpleOptional,
991 .tag = .WhileSimple,
998992 .main_token = while_token,
999993 .data = .{
1000994 .lhs = condition,
......@@ -1003,7 +997,7 @@ const Parser = struct {
1003997 });
1004998 } else {
1005999 return p.addNode(.{
1006 .tag = if (then_payload == 0) .WhileCont else .WhileContOptional,
1000 .tag = .WhileCont,
10071001 .main_token = while_token,
10081002 .data = .{
10091003 .lhs = condition,
......@@ -1024,7 +1018,7 @@ const Parser = struct {
10241018 }
10251019 if (continue_expr == 0) {
10261020 return p.addNode(.{
1027 .tag = if (then_payload == 0) .WhileSimple else .WhileSimpleOptional,
1021 .tag = .WhileSimple,
10281022 .main_token = while_token,
10291023 .data = .{
10301024 .lhs = condition,
......@@ -1033,7 +1027,7 @@ const Parser = struct {
10331027 });
10341028 } else {
10351029 return p.addNode(.{
1036 .tag = if (then_payload == 0) .WhileCont else .WhileContOptional,
1030 .tag = .WhileCont,
10371031 .main_token = while_token,
10381032 .data = .{
10391033 .lhs = condition,
......@@ -1047,14 +1041,8 @@ const Parser = struct {
10471041 };
10481042 const else_payload = try p.parsePayload();
10491043 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;
10561044 return p.addNode(.{
1057 .tag = tag,
1045 .tag = .While,
10581046 .main_token = while_token,
10591047 .data = .{
10601048 .lhs = condition,
......@@ -1948,7 +1936,7 @@ const Parser = struct {
19481936 const else_token = p.eatToken(.Keyword_else) orelse {
19491937 if (continue_expr == 0) {
19501938 return p.addNode(.{
1951 .tag = if (then_payload == 0) .WhileSimple else .WhileSimpleOptional,
1939 .tag = .WhileSimple,
19521940 .main_token = while_token,
19531941 .data = .{
19541942 .lhs = condition,
......@@ -1957,7 +1945,7 @@ const Parser = struct {
19571945 });
19581946 } else {
19591947 return p.addNode(.{
1960 .tag = if (then_payload == 0) .WhileCont else .WhileContOptional,
1948 .tag = .WhileCont,
19611949 .main_token = while_token,
19621950 .data = .{
19631951 .lhs = condition,
......@@ -1971,14 +1959,8 @@ const Parser = struct {
19711959 };
19721960 const else_payload = try p.parsePayload();
19731961 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;
19801962 return p.addNode(.{
1981 .tag = tag,
1963 .tag = .While,
19821964 .main_token = while_token,
19831965 .data = .{
19841966 .lhs = condition,
......@@ -2229,24 +2211,89 @@ const Parser = struct {
22292211 /// LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr)
22302212 fn parsePrimaryTypeExpr(p: *Parser) !Node.Index {
22312213 switch (p.token_tags[p.tok_i]) {
2232 .CharLiteral,
2233 .IntegerLiteral,
2234 .FloatLiteral,
2235 .StringLiteral,
2236 .Keyword_false,
2237 .Keyword_true,
2238 .Keyword_null,
2239 .Keyword_undefined,
2240 .Keyword_unreachable,
2241 .Keyword_anyframe,
2242 => return p.addNode(.{
2243 .tag = .OneToken,
2214 .CharLiteral => return p.addNode(.{
2215 .tag = .CharLiteral,
2216 .main_token = p.nextToken(),
2217 .data = .{
2218 .lhs = undefined,
2219 .rhs = undefined,
2220 },
2221 }),
2222 .IntegerLiteral => return p.addNode(.{
2223 .tag = .IntegerLiteral,
2224 .main_token = p.nextToken(),
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,
22442280 .main_token = p.nextToken(),
22452281 .data = .{
22462282 .lhs = undefined,
22472283 .rhs = undefined,
22482284 },
22492285 }),
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
22512298 .Builtin => return p.parseBuiltinCall(),
22522299 .Keyword_fn => return p.parseFnProto(),
......@@ -2280,11 +2327,11 @@ const Parser = struct {
22802327 p.tok_i += 1;
22812328 }
22822329 return p.addNode(.{
2283 .tag = .OneToken,
2330 .tag = .StringLiteral,
22842331 .main_token = first_line,
22852332 .data = .{
2286 .lhs = undefined,
2287 .rhs = undefined,
2333 .lhs = first_line,
2334 .rhs = p.tok_i - 1,
22882335 },
22892336 });
22902337 },
......@@ -2641,7 +2688,7 @@ const Parser = struct {
26412688 const else_token = p.eatToken(.Keyword_else) orelse {
26422689 if (continue_expr == 0) {
26432690 return p.addNode(.{
2644 .tag = if (then_payload == 0) .WhileSimple else .WhileSimpleOptional,
2691 .tag = .WhileSimple,
26452692 .main_token = while_token,
26462693 .data = .{
26472694 .lhs = condition,
......@@ -2650,7 +2697,7 @@ const Parser = struct {
26502697 });
26512698 } else {
26522699 return p.addNode(.{
2653 .tag = if (then_payload == 0) .WhileCont else .WhileContOptional,
2700 .tag = .WhileCont,
26542701 .main_token = while_token,
26552702 .data = .{
26562703 .lhs = condition,
......@@ -2664,14 +2711,8 @@ const Parser = struct {
26642711 };
26652712 const else_payload = try p.parsePayload();
26662713 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;
26732714 return p.addNode(.{
2674 .tag = tag,
2715 .tag = .While,
26752716 .main_token = while_token,
26762717 .data = .{
26772718 .lhs = condition,
......@@ -3450,7 +3491,7 @@ const Parser = struct {
34503491 });
34513492 // Pretend this was an identifier so we can continue parsing.
34523493 return p.addNode(.{
3453 .tag = .OneToken,
3494 .tag = .Identifier,
34543495 .main_token = builtin_token,
34553496 .data = .{
34563497 .lhs = undefined,
......@@ -3470,59 +3511,31 @@ const Parser = struct {
34703511 });
34713512 }
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
35043514 // string literal or multiline string literal
35053515 fn parseStringLiteral(p: *Parser) !Node.Index {
35063516 switch (p.token_tags[p.tok_i]) {
3507 .StringLiteral => return p.addNode(.{
3508 .tag = .OneToken,
3509 .main_token = p.nextToken(),
3510 .data = .{
3511 .lhs = undefined,
3512 .rhs = undefined,
3513 },
3514 }),
3517 .StringLiteral => {
3518 const main_token = p.nextToken();
3519 return p.addNode(.{
3520 .tag = .StringLiteral,
3521 .main_token = main_token,
3522 .data = .{
3523 .lhs = main_token,
3524 .rhs = main_token,
3525 },
3526 });
3527 },
35153528 .MultilineStringLiteralLine => {
35163529 const first_line = p.nextToken();
35173530 while (p.token_tags[p.tok_i] == .MultilineStringLiteralLine) {
35183531 p.tok_i += 1;
35193532 }
35203533 return p.addNode(.{
3521 .tag = .OneToken,
3534 .tag = .StringLiteral,
35223535 .main_token = first_line,
35233536 .data = .{
3524 .lhs = undefined,
3525 .rhs = undefined,
3537 .lhs = first_line,
3538 .rhs = p.tok_i - 1,
35263539 },
35273540 });
35283541 },
......@@ -3539,11 +3552,14 @@ const Parser = struct {
35393552 }
35403553
35413554 fn expectIntegerLiteral(p: *Parser) !Node.Index {
3542 const node = p.parseOneToken(.IntegerLiteral);
3543 if (node != 0) {
3544 return p.fail(.{ .ExpectedIntegerLiteral = .{ .token = p.tok_i } });
3545 }
3546 return node;
3555 return p.addNode(.{
3556 .tag = .IntegerLiteral,
3557 .main_token = try p.expectToken(.IntegerLiteral),
3558 .data = .{
3559 .lhs = undefined,
3560 .rhs = undefined,
3561 },
3562 });
35473563 }
35483564
35493565 /// KEYWORD_if LPAREN Expr RPAREN PtrPayload? Body (KEYWORD_else Payload? Body)?
......@@ -3558,7 +3574,7 @@ const Parser = struct {
35583574 if (then_expr == 0) return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });
35593575
35603576 const else_token = p.eatToken(.Keyword_else) orelse return p.addNode(.{
3561 .tag = if (then_payload == 0) .IfSimple else .IfSimpleOptional,
3577 .tag = .IfSimple,
35623578 .main_token = if_token,
35633579 .data = .{
35643580 .lhs = condition,
......@@ -3569,14 +3585,8 @@ const Parser = struct {
35693585 const else_expr = try bodyParseFn(p);
35703586 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;
35783588 return p.addNode(.{
3579 .tag = tag,
3589 .tag = .If,
35803590 .main_token = if_token,
35813591 .data = .{
35823592 .lhs = condition,
lib/std/zig/parser_test.zig+10-10
......@@ -81,16 +81,16 @@ test "zig fmt: doc comments on test" {
8181 );
8282}
8383
84//test "zig fmt: if statment" {
85// try testCanonical(
86// \\test "" {
87// \\ if (optional()) |some|
88// \\ bar = some.foo();
89// \\}
90// \\
91// );
92//}
93//
84test "zig fmt: if statment" {
85 try testCanonical(
86 \\test "" {
87 \\ if (optional()) |some|
88 \\ bar = some.foo();
89 \\}
90 \\
91 );
92}
93
9494//test "zig fmt: top-level fields" {
9595// try testCanonical(
9696// \\a: did_you_know,
lib/std/zig/render.zig+373-383
......@@ -69,15 +69,15 @@ fn renderRoot(ais: *Ais, tree: ast.Tree) Error!void {
6969 if (root_decls.len == 0) return;
7070
7171 for (root_decls) |decl| {
72 try renderTopLevelDecl(ais, tree, decl);
72 return renderContainerDecl(ais, tree, decl, .Newline);
7373 }
7474}
7575
76fn renderExtraNewline(tree: ast.Tree, ais: *Ais, node: ast.Node.Index) Error!void {
77 return renderExtraNewlineToken(tree, ais, tree.firstToken(node));
76fn renderExtraNewline(ais: *Ais, tree: ast.Tree, node: ast.Node.Index) Error!void {
77 return renderExtraNewlineToken(ais, tree, tree.firstToken(node));
7878}
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 {
8181 @panic("TODO implement renderExtraNewlineToken");
8282 //var prev_token = first_token;
8383 //if (prev_token == 0) return;
......@@ -96,14 +96,11 @@ fn renderExtraNewlineToken(tree: ast.Tree, ais: *Ais, first_token: ast.TokenInde
9696 //}
9797}
9898
99fn renderTopLevelDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index) Error!void {
100 return renderContainerDecl(ais, tree, decl, .Newline);
101}
102
10399fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) Error!void {
104100 const token_tags = tree.tokens.items(.tag);
105101 const main_tokens = tree.nodes.items(.main_token);
106102 const datas = tree.nodes.items(.data);
103 try renderDocComments(ais, tree, tree.firstToken(decl));
107104 switch (tree.nodes.items(.tag)[decl]) {
108105 .UsingNamespace,
109106 .FnProtoSimple,
......@@ -111,10 +108,6 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S
111108 .FnProtoOne,
112109 .FnProto,
113110 .FnDecl,
114 .GlobalVarDecl,
115 .LocalVarDecl,
116 .SimpleVarDecl,
117 .AlignedVarDecl,
118111 .ContainerFieldInit,
119112 .ContainerFieldAlign,
120113 .ContainerField,
......@@ -145,16 +138,13 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S
145138 // try renderToken(ais, tree, use_decl.semicolon_token, space); // ;
146139 // },
147140
148 // .VarDecl => {
149 // const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl);
150
151 // try renderDocComments(ais, tree, var_decl, var_decl.getDocComments());
152 // try renderVarDecl(allocator, ais, tree, var_decl);
153 // },
141 .GlobalVarDecl => return renderVarDecl(ais, tree, tree.globalVarDecl(decl)),
142 .LocalVarDecl => return renderVarDecl(ais, tree, tree.localVarDecl(decl)),
143 .SimpleVarDecl => return renderVarDecl(ais, tree, tree.simpleVarDecl(decl)),
144 .AlignedVarDecl => return renderVarDecl(ais, tree, tree.alignedVarDecl(decl)),
154145
155146 .TestDecl => {
156147 const test_token = main_tokens[decl];
157 try renderDocComments(ais, tree, test_token);
158148 try renderToken(ais, tree, test_token, .Space);
159149 if (token_tags[test_token + 1] == .StringLiteral) {
160150 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
251241fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
252242 const token_tags = tree.tokens.items(.tag);
253243 const main_tokens = tree.nodes.items(.main_token);
254 switch (tree.nodes.items(.tag)[node]) {
255 //.Identifier,
256 //.IntegerLiteral,
257 //.FloatLiteral,
258 //.StringLiteral,
259 //.CharLiteral,
260 //.BoolLiteral,
261 //.NullLiteral,
262 //.Unreachable,
263 //.ErrorType,
264 //.UndefinedLiteral,
265 //=> {
266 // const casted_node = base.cast(ast.Node.OneToken).?;
267 // return renderToken(ais, tree, casted_node.token, space);
268 //},
244 const node_tags = tree.nodes.items(.tag);
245 const datas = tree.nodes.items(.data);
246 switch (node_tags[node]) {
247 .Identifier,
248 .IntegerLiteral,
249 .FloatLiteral,
250 .StringLiteral,
251 .CharLiteral,
252 .TrueLiteral,
253 .FalseLiteral,
254 .NullLiteral,
255 .UnreachableLiteral,
256 .UndefinedLiteral,
257 => return renderToken(ais, tree, main_tokens[node], space),
269258
270259 //.AnyType => {
271260 // const any_type = base.castTag(.AnyType).?;
......@@ -299,16 +288,37 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
299288
300289 try renderToken(ais, tree, lbrace, .Newline);
301290
302 for (statements) |statement, i| {
303 try renderStatement(ais, tree, statement);
291 for (statements) |stmt, i| {
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
305308 if (i + 1 < statements.len) {
306 try renderExtraNewline(tree, ais, statements[i + 1]);
309 try renderExtraNewline(ais, tree, statements[i + 1]);
307310 }
308311 }
309312 ais.popIndent();
310 const rbrace = tree.lastToken(statements[statements.len - 1]) + 1;
311 return renderToken(ais, tree, rbrace, space);
313 // The rbrace could be +1 or +2 from the last token of the last
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 }
312322 }
313323 },
314324
......@@ -322,8 +332,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
322332 // return renderExpression(ais, tree, defer_node.expr, space);
323333 //},
324334 .Comptime => {
325 const comptime_token = tree.nodes.items(.main_token)[node];
326 const block = tree.nodes.items(.data)[node].lhs;
335 const comptime_token = main_tokens[node];
336 const block = datas[node].lhs;
327337 try renderToken(ais, tree, comptime_token, .Space);
328338 return renderExpression(ais, tree, block, space);
329339 },
......@@ -369,71 +379,78 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
369379 // ais.pushIndentOneShot();
370380 // return renderExpression(ais, tree, infix_op_node.rhs, space);
371381 //},
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,
374 //.AddWrap,
375 //.ArrayCat,
376 //.ArrayMult,
377 //.Assign,
378 //.AssignBitAnd,
379 //.AssignBitOr,
380 //.AssignBitShiftLeft,
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 // };
389 .ErrorUnion,
390 .SwitchRange,
391 => {
392 const infix = datas[node];
393 try renderExpression(ais, tree, infix.lhs, .None);
394 try renderToken(ais, tree, main_tokens[node], .None);
395 return renderExpression(ais, tree, infix.rhs, space);
396 },
428397
429 // {
430 // ais.pushIndent();
431 // defer ais.popIndent();
432 // try renderToken(ais, tree, infix_op_node.op_token, after_op_space);
433 // }
434 // ais.pushIndentOneShot();
435 // return renderExpression(ais, tree, infix_op_node.rhs, space);
436 //},
398 .Add,
399 .AddWrap,
400 .ArrayCat,
401 .ArrayMult,
402 .Assign,
403 .AssignBitAnd,
404 .AssignBitOr,
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
438455 //.BitNot,
439456 //.BoolNot,
......@@ -769,7 +786,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
769786
770787 // column_counter = 0;
771788 // try renderToken(ais, tree, comma, Space.Newline); // ,
772 // try renderExtraNewline(tree, ais, next_expr);
789 // try renderExtraNewline(ais, tree, next_expr);
773790 // } else {
774791 // const maybe_comma = tree.nextToken(expr.*.lastToken());
775792 // if (tree.token_tags[maybe_comma] == .Comma) {
......@@ -932,7 +949,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
932949 // const comma = tree.nextToken(field_init.lastToken());
933950 // try renderToken(ais, tree, comma, Space.Newline);
934951
935 // try renderExtraNewline(tree, ais, next_field_init);
952 // try renderExtraNewline(ais, tree, next_field_init);
936953 // } else {
937954 // try renderExpression(ais, tree, field_init, Space.Comma);
938955 // }
......@@ -942,74 +959,63 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
942959 // return renderToken(ais, tree, rtoken, space);
943960 //},
944961
945 //.Call => {
946 // const call = @fieldParentPtr(ast.Node.Call, "base", base);
947 // if (call.async_token) |async_token| {
948 // try renderToken(ais, tree, async_token, Space.Space);
949 // }
950
951 // try renderExpression(ais, tree, call.lhs, Space.None);
952
953 // const lparen = tree.nextToken(call.lhs.lastToken());
962 .Call => {
963 const call = datas[node];
964 const params_range = tree.extraData(call.rhs, ast.Node.SubRange);
965 const params = tree.extra_data[params_range.start..params_range.end];
966 const async_token = tree.firstToken(call.lhs) - 1;
967 if (token_tags[async_token] == .Keyword_async) {
968 try renderToken(ais, tree, async_token, .Space);
969 }
970 try renderExpression(ais, tree, call.lhs, .None);
954971
955 // if (call.params_len == 0) {
956 // try renderToken(ais, tree, lparen, Space.None);
957 // return renderToken(ais, tree, call.rtoken, space);
958 // }
972 const lparen = main_tokens[node];
959973
960 // const src_has_trailing_comma = blk: {
961 // const maybe_comma = tree.prevToken(call.rtoken);
962 // break :blk tree.token_tags[maybe_comma] == .Comma;
963 // };
974 if (params.len == 0) {
975 try renderToken(ais, tree, lparen, .None);
976 return renderToken(ais, tree, lparen + 1, space); // )
977 }
964978
965 // if (src_has_trailing_comma) {
966 // {
967 // ais.pushIndent();
968 // defer ais.popIndent();
979 const last_param = params[params.len - 1];
980 const after_last_param_tok = tree.lastToken(last_param) + 1;
981 if (token_tags[after_last_param_tok] == .Comma) {
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); // (
971 // const params = call.params();
972 // for (params) |param_node, i| {
973 // if (i + 1 < params.len) {
974 // const next_node = params[i + 1];
975 // try renderExpression(ais, tree, param_node, Space.None);
988 // Unindent the comma for multiline string literals
989 const is_multiline_string = node_tags[param_node] == .StringLiteral and
990 token_tags[main_tokens[param_node]] == .MultilineStringLiteralLine;
991 if (is_multiline_string) ais.popIndent();
976992
977 // // Unindent the comma for multiline string literals
978 // const maybe_multiline_string = param_node.firstToken();
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();
993 const comma = tree.lastToken(param_node) + 1;
994 try renderToken(ais, tree, comma, Space.Newline); // ,
982995
983 // const comma = tree.nextToken(param_node.lastToken());
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 // }
996 if (is_multiline_string) ais.pushIndent();
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();
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 // }
1007 try renderToken(ais, tree, lparen, Space.None); // (
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) {
1007 // const comma = tree.nextToken(param_node.lastToken());
1008 // try renderToken(ais, tree, comma, Space.Space);
1009 // }
1010 // }
1011 // return renderToken(ais, tree, call.rtoken, space); // )
1012 //},
1012 if (i + 1 < params.len) {
1013 const comma = tree.lastToken(param_node) + 1;
1014 try renderToken(ais, tree, comma, Space.Space);
1015 }
1016 }
1017 return renderToken(ais, tree, after_last_param_tok, space); // )
1018 },
10131019
10141020 //.ArrayAccess => {
10151021 // const suffix_op = base.castTag(.ArrayAccess).?;
......@@ -1118,14 +1124,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
11181124 // }
11191125 //},
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
11291127 //.PointerPayload => {
11301128 // 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
12641262 // try renderContainerDecl(allocator, ais, tree, decl, .Newline);
12651263
12661264 // 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]);
12681266 // }
12691267 // }
12701268 // } else if (src_has_newline) {
......@@ -1338,7 +1336,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
13381336 // try renderExpression(ais, tree, node, Space.None);
13391337 // 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]);
13421340 // } else {
13431341 // try renderExpression(ais, tree, node, Space.Comma);
13441342 // }
......@@ -1357,7 +1355,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
13571355 // const comma_token = tree.nextToken(node.lastToken());
13581356 // assert(tree.token_tags[comma_token] == .Comma);
13591357 // try renderToken(ais, tree, comma_token, Space.Space); // ,
1360 // try renderExtraNewline(tree, ais, decls[i + 1]);
1358 // try renderExtraNewline(ais, tree, decls[i + 1]);
13611359 // } else {
13621360 // try renderExpression(ais, tree, node, Space.Space);
13631361 // }
......@@ -1624,7 +1622,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
16241622 // try renderExpression(ais, tree, node, Space.Comma);
16251623
16261624 // if (i + 1 < cases.len) {
1627 // try renderExtraNewline(tree, ais, cases[i + 1]);
1625 // try renderExtraNewline(ais, tree, cases[i + 1]);
16281626 // }
16291627 // }
16301628 // }
......@@ -1650,7 +1648,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
16501648
16511649 // const comma_token = tree.nextToken(node.lastToken());
16521650 // try renderToken(ais, tree, comma_token, Space.Space); // ,
1653 // try renderExtraNewline(tree, ais, items[i + 1]);
1651 // try renderExtraNewline(ais, tree, items[i + 1]);
16541652 // } else {
16551653 // try renderExpression(ais, tree, node, Space.Space);
16561654 // }
......@@ -1663,7 +1661,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
16631661
16641662 // const comma_token = tree.nextToken(node.lastToken());
16651663 // try renderToken(ais, tree, comma_token, Space.Newline); // ,
1666 // try renderExtraNewline(tree, ais, items[i + 1]);
1664 // try renderExtraNewline(ais, tree, items[i + 1]);
16671665 // } else {
16681666 // try renderExpression(ais, tree, node, Space.Comma);
16691667 // }
......@@ -1682,28 +1680,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
16821680 // const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);
16831681 // return renderToken(ais, tree, switch_else.token, space);
16841682 //},
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
17081684 //.While => {
17091685 // 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
18241800 // }
18251801 //},
18261802
1827 //.If => {
1828 // const if_node = @fieldParentPtr(ast.Node.If, "base", base);
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
1803 .IfSimple => return renderIf(ais, tree, tree.ifSimple(node), space),
1804 .If => return renderIf(ais, tree, tree.ifFull(node), space),
19321805 //.Asm => {
19331806 // 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
19741847
19751848 // const comma = tree.prevToken(next_asm_output.firstToken());
19761849 // 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());
19781851 // } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
19791852 // try renderAsmOutput(allocator, ais, tree, asm_output, Space.Newline);
19801853 // break :asmblk;
......@@ -2004,7 +1877,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
20041877
20051878 // const comma = tree.prevToken(next_asm_input.firstToken());
20061879 // 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());
20081881 // } else if (asm_node.clobbers.len == 0) {
20091882 // try renderAsmInput(allocator, ais, tree, asm_input, Space.Newline);
20101883 // break :asmblk;
......@@ -2140,89 +2013,225 @@ fn renderAsmInput(
21402013 return renderToken(ais, tree, asm_input.lastToken(), space); // )
21412014}
21422015
2143fn renderVarDecl(
2144 allocator: *mem.Allocator,
2145 ais: *Ais,
2146 tree: ast.Tree,
2147 var_decl: ast.Node.Index.VarDecl,
2148) Error!void {
2149 if (var_decl.getVisibToken()) |visib_token| {
2016fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.Full.VarDecl) Error!void {
2017 if (var_decl.visib_token) |visib_token| {
21502018 try renderToken(ais, tree, visib_token, Space.Space); // pub
21512019 }
21522020
2153 if (var_decl.getExternExportToken()) |extern_export_token| {
2021 if (var_decl.extern_export_token) |extern_export_token| {
21542022 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| {
21572025 try renderExpression(ais, tree, lib_name, Space.Space); // "lib"
21582026 }
21592027 }
21602028
2161 if (var_decl.getComptimeToken()) |comptime_token| {
2162 try renderToken(ais, tree, comptime_token, Space.Space); // comptime
2029 if (var_decl.threadlocal_token) |thread_local_token| {
2030 try renderToken(ais, tree, thread_local_token, Space.Space); // threadlocal
21632031 }
21642032
2165 if (var_decl.getThreadLocalToken()) |thread_local_token| {
2166 try renderToken(ais, tree, thread_local_token, Space.Space); // threadlocal
2033 if (var_decl.comptime_token) |comptime_token| {
2034 try renderToken(ais, tree, comptime_token, Space.Space); // comptime
21672035 }
2168 try renderToken(ais, tree, var_decl.mut_token, Space.Space); // var
21692036
2170 const name_space = if (var_decl.getTypeNode() == null and
2171 (var_decl.getAlignNode() != null or
2172 var_decl.getSectionNode() != null or
2173 var_decl.getInitNode() != null))
2037 try renderToken(ais, tree, var_decl.ast.mut_token, .Space); // var
2038
2039 const name_space = if (var_decl.ast.type_node == 0 and
2040 (var_decl.ast.align_node != 0 or
2041 var_decl.ast.section_node != 0 or
2042 var_decl.ast.init_node != 0))
21742043 Space.Space
21752044 else
21762045 Space.None;
2177 try renderToken(ais, tree, var_decl.name_token, name_space);
2178
2179 if (var_decl.getTypeNode()) |type_node| {
2180 try renderToken(ais, tree, tree.nextToken(var_decl.name_token), Space.Space);
2181 const s = if (var_decl.getAlignNode() != null or
2182 var_decl.getSectionNode() != null or
2183 var_decl.getInitNode() != null) Space.Space else Space.None;
2184 try renderExpression(ais, tree, type_node, s);
2046 try renderToken(ais, tree, var_decl.ast.mut_token + 1, name_space); // name
2047
2048 if (var_decl.ast.type_node != 0) {
2049 try renderToken(ais, tree, var_decl.ast.mut_token + 2, Space.Space); // :
2050 if (var_decl.ast.align_node != 0 or var_decl.ast.section_node != 0 or
2051 var_decl.ast.init_node != 0)
2052 {
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 }
21852059 }
21862060
2187 if (var_decl.getAlignNode()) |align_node| {
2188 const lparen = tree.prevToken(align_node.firstToken());
2189 const align_kw = tree.prevToken(lparen);
2190 const rparen = tree.nextToken(align_node.lastToken());
2061 if (var_decl.ast.align_node != 0) {
2062 const lparen = tree.firstToken(var_decl.ast.align_node) - 1;
2063 const align_kw = lparen - 1;
2064 const rparen = tree.lastToken(var_decl.ast.align_node) + 1;
21912065 try renderToken(ais, tree, align_kw, Space.None); // align
21922066 try renderToken(ais, tree, lparen, Space.None); // (
2193 try renderExpression(ais, tree, align_node, Space.None);
2194 const s = if (var_decl.getSectionNode() != null or var_decl.getInitNode() != null) Space.Space else Space.None;
2195 try renderToken(ais, tree, rparen, s); // )
2067 try renderExpression(ais, tree, var_decl.ast.align_node, Space.None);
2068 if (var_decl.ast.section_node != 0 or var_decl.ast.init_node != 0) {
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 }
21962074 }
21972075
2198 if (var_decl.getSectionNode()) |section_node| {
2199 const lparen = tree.prevToken(section_node.firstToken());
2200 const section_kw = tree.prevToken(lparen);
2201 const rparen = tree.nextToken(section_node.lastToken());
2076 if (var_decl.ast.section_node != 0) {
2077 const lparen = tree.firstToken(var_decl.ast.section_node) - 1;
2078 const section_kw = lparen - 1;
2079 const rparen = tree.lastToken(var_decl.ast.section_node) + 1;
22022080 try renderToken(ais, tree, section_kw, Space.None); // linksection
22032081 try renderToken(ais, tree, lparen, Space.None); // (
2204 try renderExpression(ais, tree, section_node, Space.None);
2205 const s = if (var_decl.getInitNode() != null) Space.Space else Space.None;
2206 try renderToken(ais, tree, rparen, s); // )
2082 try renderExpression(ais, tree, var_decl.ast.section_node, Space.None);
2083 if (var_decl.ast.init_node != 0) {
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 }
22072089 }
22082090
2209 if (var_decl.getInitNode()) |init_node| {
2210 const eq_token = var_decl.getEqToken().?;
2211 const eq_space = blk: {
2212 const loc = tree.tokenLocation(tree.token_locs[eq_token].end, tree.nextToken(eq_token));
2213 break :blk if (loc.line == 0) Space.Space else Space.Newline;
2214 };
2091 assert(var_decl.ast.init_node != 0);
2092 const eq_token = tree.firstToken(var_decl.ast.init_node) - 1;
2093 const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .Space else .Newline;
2094 {
2095 ais.pushIndent();
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 {
22172164 ais.pushIndent();
2218 defer ais.popIndent();
2219 try renderToken(ais, tree, eq_token, eq_space); // =
2165 try renderToken(ais, tree, rparen, .Newline); // )
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;
22202200 }
2221 ais.pushIndentOneShot();
2222 try renderExpression(ais, tree, init_node, Space.None);
22232201 }
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 }
22262235}
22272236
22282237fn renderParamDecl(
......@@ -2249,27 +2258,6 @@ fn renderParamDecl(
22492258 }
22502259}
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
22732261const Space = enum {
22742262 None,
22752263 Newline,
......@@ -2367,13 +2355,15 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error
23672355 }
23682356}
23692357
2370fn nodeIsBlock(base: *const ast.Node) bool {
2371 return switch (base.tag) {
2358fn nodeIsBlock(tag: ast.Node.Tag) bool {
2359 return switch (tag) {
23722360 .Block,
2373 .LabeledBlock,
23742361 .If,
2362 .IfSimple,
23752363 .For,
2364 .ForSimple,
23762365 .While,
2366 .WhileSimple,
23772367 .Switch,
23782368 => true,
23792369 else => false,