| author | |
| committer | |
| log | 0929fcbc34a2aa8cd69492c9437622d29a9a46b9 |
| tree | be23dd76a00a3b0d61f83642f4fc3878ceec6aff |
| parent | 33915cb1ed88417d3495c160ffd15c93f9197e5b |
3 files changed, 114 insertions(+), 36 deletions(-)
lib/std/zig/ast.zig+58-5| ... | ... | @@ -688,6 +688,20 @@ pub const Tree = struct { |
| 688 | 688 | return main_tokens[n] + end_offset; |
| 689 | 689 | } |
| 690 | 690 | }, |
| 691 | .SliceOpen => { | |
| 692 | end_offset += 2; // ellipsis2 and rbracket | |
| 693 | n = datas[n].rhs; | |
| 694 | }, | |
| 695 | .Slice => { | |
| 696 | const extra = tree.extraData(datas[n].rhs, Node.Slice); | |
| 697 | if (extra.sentinel != 0) { | |
| 698 | n = extra.sentinel; | |
| 699 | } else { | |
| 700 | assert(extra.end != 0); // should have used SliceOpen if end and sentinel are 0 | |
| 701 | n = extra.end; | |
| 702 | } | |
| 703 | end_offset += 1; // rbracket | |
| 704 | }, | |
| 691 | 705 | |
| 692 | 706 | // These are not supported by lastToken() because implementation would |
| 693 | 707 | // require recursion due to the optional comma followed by rbrace. |
| ... | ... | @@ -708,8 +722,6 @@ pub const Tree = struct { |
| 708 | 722 | .ErrorSetDecl => unreachable, // TODO |
| 709 | 723 | .AsmSimple => unreachable, // TODO |
| 710 | 724 | .Asm => unreachable, // TODO |
| 711 | .SliceOpen => unreachable, // TODO | |
| 712 | .Slice => unreachable, // TODO | |
| 713 | 725 | .SwitchCaseOne => unreachable, // TODO |
| 714 | 726 | .SwitchRange => unreachable, // TODO |
| 715 | 727 | .ArrayType => unreachable, // TODO |
| ... | ... | @@ -1094,6 +1106,35 @@ pub const Tree = struct { |
| 1094 | 1106 | }); |
| 1095 | 1107 | } |
| 1096 | 1108 | |
| 1109 | pub fn sliceOpen(tree: Tree, node: Node.Index) Full.Slice { | |
| 1110 | assert(tree.nodes.items(.tag)[node] == .SliceOpen); | |
| 1111 | const data = tree.nodes.items(.data)[node]; | |
| 1112 | return .{ | |
| 1113 | .ast = .{ | |
| 1114 | .sliced = data.lhs, | |
| 1115 | .lbracket = tree.nodes.items(.main_token)[node], | |
| 1116 | .start = data.rhs, | |
| 1117 | .end = 0, | |
| 1118 | .sentinel = 0, | |
| 1119 | }, | |
| 1120 | }; | |
| 1121 | } | |
| 1122 | ||
| 1123 | pub fn slice(tree: Tree, node: Node.Index) Full.Slice { | |
| 1124 | assert(tree.nodes.items(.tag)[node] == .Slice); | |
| 1125 | const data = tree.nodes.items(.data)[node]; | |
| 1126 | const extra = tree.extraData(data.rhs, Node.Slice); | |
| 1127 | return .{ | |
| 1128 | .ast = .{ | |
| 1129 | .sliced = data.lhs, | |
| 1130 | .lbracket = tree.nodes.items(.main_token)[node], | |
| 1131 | .start = extra.start, | |
| 1132 | .end = extra.end, | |
| 1133 | .sentinel = extra.sentinel, | |
| 1134 | }, | |
| 1135 | }; | |
| 1136 | } | |
| 1137 | ||
| 1097 | 1138 | pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl { |
| 1098 | 1139 | assert(tree.nodes.items(.tag)[node] == .ContainerDeclTwo or |
| 1099 | 1140 | tree.nodes.items(.tag)[node] == .ContainerDeclTwoComma); |
| ... | ... | @@ -1452,6 +1493,18 @@ pub const Full = struct { |
| 1452 | 1493 | }; |
| 1453 | 1494 | }; |
| 1454 | 1495 | |
| 1496 | pub const Slice = struct { | |
| 1497 | ast: Ast, | |
| 1498 | ||
| 1499 | pub const Ast = struct { | |
| 1500 | sliced: Node.Index, | |
| 1501 | lbracket: TokenIndex, | |
| 1502 | start: Node.Index, | |
| 1503 | end: Node.Index, | |
| 1504 | sentinel: Node.Index, | |
| 1505 | }; | |
| 1506 | }; | |
| 1507 | ||
| 1455 | 1508 | pub const ContainerDecl = struct { |
| 1456 | 1509 | layout_token: ?TokenIndex, |
| 1457 | 1510 | ast: Ast, |
| ... | ... | @@ -1860,10 +1913,10 @@ pub const Node = struct { |
| 1860 | 1913 | /// main_token is the asterisk if a pointer or the lbrace if a slice |
| 1861 | 1914 | PtrTypeBitRange, |
| 1862 | 1915 | /// `lhs[rhs..]` |
| 1863 | /// main_token is the `[`. | |
| 1916 | /// main_token is the lbracket. | |
| 1864 | 1917 | SliceOpen, |
| 1865 | /// `lhs[b..c :d]`. `slice_list[rhs]`. | |
| 1866 | /// main_token is the `[`. | |
| 1918 | /// `lhs[b..c :d]`. rhs is index into Slice | |
| 1919 | /// main_token is the lbracket. | |
| 1867 | 1920 | Slice, |
| 1868 | 1921 | /// `lhs.*`. rhs is unused. |
| 1869 | 1922 | Deref, |
lib/std/zig/parser_test.zig+18| ... | ... | @@ -637,6 +637,24 @@ test "zig fmt: sentinel array literal 1 element" { |
| 637 | 637 | ); |
| 638 | 638 | } |
| 639 | 639 | |
| 640 | test "zig fmt: slices" { | |
| 641 | try testCanonical( | |
| 642 | \\const a = b[0..]; | |
| 643 | \\const c = d[0..1]; | |
| 644 | \\const e = f[0..1 :0]; | |
| 645 | \\ | |
| 646 | ); | |
| 647 | } | |
| 648 | ||
| 649 | test "zig fmt: slices with spaces in bounds" { | |
| 650 | try testCanonical( | |
| 651 | \\const a = b[0 + 0 ..]; | |
| 652 | \\const c = d[0 + 0 .. 1]; | |
| 653 | \\const e = f[0 .. 1 + 1 :0]; | |
| 654 | \\ | |
| 655 | ); | |
| 656 | } | |
| 657 | ||
| 640 | 658 | //test "zig fmt: async function" { |
| 641 | 659 | // try testCanonical( |
| 642 | 660 | // \\pub const Server = struct { |
lib/std/zig/render.zig+38-31| ... | ... | @@ -466,34 +466,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 466 | 466 | return renderToken(ais, tree, rbracket, space); // ] |
| 467 | 467 | }, |
| 468 | 468 | |
| 469 | .Slice => unreachable, // TODO | |
| 470 | .SliceOpen => unreachable, // TODO | |
| 471 | //.Slice => { | |
| 472 | // const suffix_op = base.castTag(.Slice).?; | |
| 473 | // try renderExpression(ais, tree, suffix_op.lhs, Space.None); | |
| 474 | ||
| 475 | // const lbracket = tree.prevToken(suffix_op.start.firstToken()); | |
| 476 | // const dotdot = tree.nextToken(suffix_op.start.lastToken()); | |
| 477 | ||
| 478 | // const after_start_space_bool = nodeCausesSliceOpSpace(suffix_op.start) or | |
| 479 | // (if (suffix_op.end) |end| nodeCausesSliceOpSpace(end) else false); | |
| 480 | // const after_start_space = if (after_start_space_bool) Space.Space else Space.None; | |
| 481 | // const after_op_space = if (suffix_op.end != null) after_start_space else Space.None; | |
| 482 | ||
| 483 | // try renderToken(ais, tree, lbracket, Space.None); // [ | |
| 484 | // try renderExpression(ais, tree, suffix_op.start, after_start_space); | |
| 485 | // try renderToken(ais, tree, dotdot, after_op_space); // .. | |
| 486 | // if (suffix_op.end) |end| { | |
| 487 | // const after_end_space = if (suffix_op.sentinel != null) Space.Space else Space.None; | |
| 488 | // try renderExpression(ais, tree, end, after_end_space); | |
| 489 | // } | |
| 490 | // if (suffix_op.sentinel) |sentinel| { | |
| 491 | // const colon = tree.prevToken(sentinel.firstToken()); | |
| 492 | // try renderToken(ais, tree, colon, Space.None); // : | |
| 493 | // try renderExpression(ais, tree, sentinel, Space.None); | |
| 494 | // } | |
| 495 | // return renderToken(ais, tree, suffix_op.rtoken, space); // ] | |
| 496 | //}, | |
| 469 | .SliceOpen => try renderSlice(ais, tree, tree.sliceOpen(node), space), | |
| 470 | .Slice => try renderSlice(ais, tree, tree.slice(node), space), | |
| 497 | 471 | |
| 498 | 472 | .Deref => { |
| 499 | 473 | try renderExpression(ais, tree, datas[node].lhs, .None); |
| ... | ... | @@ -1142,6 +1116,40 @@ fn renderPtrType( |
| 1142 | 1116 | try renderExpression(ais, tree, ptr_type.ast.child_type, space); |
| 1143 | 1117 | } |
| 1144 | 1118 | |
| 1119 | fn renderSlice( | |
| 1120 | ais: *Ais, | |
| 1121 | tree: ast.Tree, | |
| 1122 | slice: ast.Full.Slice, | |
| 1123 | space: Space, | |
| 1124 | ) Error!void { | |
| 1125 | const node_tags = tree.nodes.items(.tag); | |
| 1126 | const after_start_space_bool = nodeCausesSliceOpSpace(node_tags[slice.ast.start]) or | |
| 1127 | if (slice.ast.end != 0) nodeCausesSliceOpSpace(node_tags[slice.ast.end]) else false; | |
| 1128 | const after_start_space = if (after_start_space_bool) Space.Space else Space.None; | |
| 1129 | const after_dots_space = if (slice.ast.end != 0) after_start_space else Space.None; | |
| 1130 | ||
| 1131 | try renderExpression(ais, tree, slice.ast.sliced, .None); | |
| 1132 | try renderToken(ais, tree, slice.ast.lbracket, .None); // lbracket | |
| 1133 | ||
| 1134 | const start_last = tree.lastToken(slice.ast.start); | |
| 1135 | try renderExpression(ais, tree, slice.ast.start, after_start_space); | |
| 1136 | try renderToken(ais, tree, start_last + 1, after_dots_space); // ellipsis2 ("..") | |
| 1137 | if (slice.ast.end == 0) { | |
| 1138 | return renderToken(ais, tree, start_last + 2, space); // rbracket | |
| 1139 | } | |
| 1140 | ||
| 1141 | const end_last = tree.lastToken(slice.ast.end); | |
| 1142 | const after_end_space = if (slice.ast.sentinel != 0) Space.Space else Space.None; | |
| 1143 | try renderExpression(ais, tree, slice.ast.end, after_end_space); | |
| 1144 | if (slice.ast.sentinel == 0) { | |
| 1145 | return renderToken(ais, tree, end_last + 1, space); // rbracket | |
| 1146 | } | |
| 1147 | ||
| 1148 | try renderToken(ais, tree, end_last + 1, .None); // colon | |
| 1149 | try renderExpression(ais, tree, slice.ast.sentinel, .None); | |
| 1150 | try renderToken(ais, tree, tree.lastToken(slice.ast.sentinel) + 1, space); // rbracket | |
| 1151 | } | |
| 1152 | ||
| 1145 | 1153 | fn renderAsmOutput( |
| 1146 | 1154 | allocator: *mem.Allocator, |
| 1147 | 1155 | ais: *Ais, |
| ... | ... | @@ -2099,8 +2107,8 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool { |
| 2099 | 2107 | }; |
| 2100 | 2108 | } |
| 2101 | 2109 | |
| 2102 | fn nodeCausesSliceOpSpace(base: ast.Node.Index) bool { | |
| 2103 | return switch (base.tag) { | |
| 2110 | fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool { | |
| 2111 | return switch (tag) { | |
| 2104 | 2112 | .Catch, |
| 2105 | 2113 | .Add, |
| 2106 | 2114 | .AddWrap, |
| ... | ... | @@ -2139,7 +2147,6 @@ fn nodeCausesSliceOpSpace(base: ast.Node.Index) bool { |
| 2139 | 2147 | .Mod, |
| 2140 | 2148 | .Mul, |
| 2141 | 2149 | .MulWrap, |
| 2142 | .Range, | |
| 2143 | 2150 | .Sub, |
| 2144 | 2151 | .SubWrap, |
| 2145 | 2152 | .OrElse, |