| 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,6 +688,20 @@ pub const Tree = struct { |
| 688 | return main_tokens[n] + end_offset; | 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 | // These are not supported by lastToken() because implementation would | 706 | // These are not supported by lastToken() because implementation would |
| 693 | // require recursion due to the optional comma followed by rbrace. | 707 | // require recursion due to the optional comma followed by rbrace. |
| ... | @@ -708,8 +722,6 @@ pub const Tree = struct { | ... | @@ -708,8 +722,6 @@ pub const Tree = struct { |
| 708 | .ErrorSetDecl => unreachable, // TODO | 722 | .ErrorSetDecl => unreachable, // TODO |
| 709 | .AsmSimple => unreachable, // TODO | 723 | .AsmSimple => unreachable, // TODO |
| 710 | .Asm => unreachable, // TODO | 724 | .Asm => unreachable, // TODO |
| 711 | .SliceOpen => unreachable, // TODO | ||
| 712 | .Slice => unreachable, // TODO | ||
| 713 | .SwitchCaseOne => unreachable, // TODO | 725 | .SwitchCaseOne => unreachable, // TODO |
| 714 | .SwitchRange => unreachable, // TODO | 726 | .SwitchRange => unreachable, // TODO |
| 715 | .ArrayType => unreachable, // TODO | 727 | .ArrayType => unreachable, // TODO |
| ... | @@ -1094,6 +1106,35 @@ pub const Tree = struct { | ... | @@ -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 | pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl { | 1138 | pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl { |
| 1098 | assert(tree.nodes.items(.tag)[node] == .ContainerDeclTwo or | 1139 | assert(tree.nodes.items(.tag)[node] == .ContainerDeclTwo or |
| 1099 | tree.nodes.items(.tag)[node] == .ContainerDeclTwoComma); | 1140 | tree.nodes.items(.tag)[node] == .ContainerDeclTwoComma); |
| ... | @@ -1452,6 +1493,18 @@ pub const Full = struct { | ... | @@ -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 | pub const ContainerDecl = struct { | 1508 | pub const ContainerDecl = struct { |
| 1456 | layout_token: ?TokenIndex, | 1509 | layout_token: ?TokenIndex, |
| 1457 | ast: Ast, | 1510 | ast: Ast, |
| ... | @@ -1860,10 +1913,10 @@ pub const Node = struct { | ... | @@ -1860,10 +1913,10 @@ pub const Node = struct { |
| 1860 | /// main_token is the asterisk if a pointer or the lbrace if a slice | 1913 | /// main_token is the asterisk if a pointer or the lbrace if a slice |
| 1861 | PtrTypeBitRange, | 1914 | PtrTypeBitRange, |
| 1862 | /// `lhs[rhs..]` | 1915 | /// `lhs[rhs..]` |
| 1863 | /// main_token is the `[`. | 1916 | /// main_token is the lbracket. |
| 1864 | SliceOpen, | 1917 | SliceOpen, |
| 1865 | /// `lhs[b..c :d]`. `slice_list[rhs]`. | 1918 | /// `lhs[b..c :d]`. rhs is index into Slice |
| 1866 | /// main_token is the `[`. | 1919 | /// main_token is the lbracket. |
| 1867 | Slice, | 1920 | Slice, |
| 1868 | /// `lhs.*`. rhs is unused. | 1921 | /// `lhs.*`. rhs is unused. |
| 1869 | Deref, | 1922 | Deref, |
lib/std/zig/parser_test.zig+18| ... | @@ -637,6 +637,24 @@ test "zig fmt: sentinel array literal 1 element" { | ... | @@ -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 | //test "zig fmt: async function" { | 658 | //test "zig fmt: async function" { |
| 641 | // try testCanonical( | 659 | // try testCanonical( |
| 642 | // \\pub const Server = struct { | 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,34 +466,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 466 | return renderToken(ais, tree, rbracket, space); // ] | 466 | return renderToken(ais, tree, rbracket, space); // ] |
| 467 | }, | 467 | }, |
| 468 | 468 | ||
| 469 | .Slice => unreachable, // TODO | 469 | .SliceOpen => try renderSlice(ais, tree, tree.sliceOpen(node), space), |
| 470 | .SliceOpen => unreachable, // TODO | 470 | .Slice => try renderSlice(ais, tree, tree.slice(node), space), |
| 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 | //}, | ||
| 497 | 471 | ||
| 498 | .Deref => { | 472 | .Deref => { |
| 499 | try renderExpression(ais, tree, datas[node].lhs, .None); | 473 | try renderExpression(ais, tree, datas[node].lhs, .None); |
| ... | @@ -1142,6 +1116,40 @@ fn renderPtrType( | ... | @@ -1142,6 +1116,40 @@ fn renderPtrType( |
| 1142 | try renderExpression(ais, tree, ptr_type.ast.child_type, space); | 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 | fn renderAsmOutput( | 1153 | fn renderAsmOutput( |
| 1146 | allocator: *mem.Allocator, | 1154 | allocator: *mem.Allocator, |
| 1147 | ais: *Ais, | 1155 | ais: *Ais, |
| ... | @@ -2099,8 +2107,8 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool { | ... | @@ -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 { | 2110 | fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool { |
| 2103 | return switch (base.tag) { | 2111 | return switch (tag) { |
| 2104 | .Catch, | 2112 | .Catch, |
| 2105 | .Add, | 2113 | .Add, |
| 2106 | .AddWrap, | 2114 | .AddWrap, |
| ... | @@ -2139,7 +2147,6 @@ fn nodeCausesSliceOpSpace(base: ast.Node.Index) bool { | ... | @@ -2139,7 +2147,6 @@ fn nodeCausesSliceOpSpace(base: ast.Node.Index) bool { |
| 2139 | .Mod, | 2147 | .Mod, |
| 2140 | .Mul, | 2148 | .Mul, |
| 2141 | .MulWrap, | 2149 | .MulWrap, |
| 2142 | .Range, | ||
| 2143 | .Sub, | 2150 | .Sub, |
| 2144 | .SubWrap, | 2151 | .SubWrap, |
| 2145 | .OrElse, | 2152 | .OrElse, |