authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-07 12:43:53+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-07 12:04:32-08:00
log0929fcbc34a2aa8cd69492c9437622d29a9a46b9
treebe23dd76a00a3b0d61f83642f4fc3878ceec6aff
parent33915cb1ed88417d3495c160ffd15c93f9197e5b

zig fmt: implement slices


3 files changed, 114 insertions(+), 36 deletions(-)

lib/std/zig/ast.zig+58-5
......@@ -688,6 +688,20 @@ pub const Tree = struct {
688688 return main_tokens[n] + end_offset;
689689 }
690690 },
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 },
691705
692706 // These are not supported by lastToken() because implementation would
693707 // require recursion due to the optional comma followed by rbrace.
......@@ -708,8 +722,6 @@ pub const Tree = struct {
708722 .ErrorSetDecl => unreachable, // TODO
709723 .AsmSimple => unreachable, // TODO
710724 .Asm => unreachable, // TODO
711 .SliceOpen => unreachable, // TODO
712 .Slice => unreachable, // TODO
713725 .SwitchCaseOne => unreachable, // TODO
714726 .SwitchRange => unreachable, // TODO
715727 .ArrayType => unreachable, // TODO
......@@ -1094,6 +1106,35 @@ pub const Tree = struct {
10941106 });
10951107 }
10961108
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
10971138 pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl {
10981139 assert(tree.nodes.items(.tag)[node] == .ContainerDeclTwo or
10991140 tree.nodes.items(.tag)[node] == .ContainerDeclTwoComma);
......@@ -1452,6 +1493,18 @@ pub const Full = struct {
14521493 };
14531494 };
14541495
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
14551508 pub const ContainerDecl = struct {
14561509 layout_token: ?TokenIndex,
14571510 ast: Ast,
......@@ -1860,10 +1913,10 @@ pub const Node = struct {
18601913 /// main_token is the asterisk if a pointer or the lbrace if a slice
18611914 PtrTypeBitRange,
18621915 /// `lhs[rhs..]`
1863 /// main_token is the `[`.
1916 /// main_token is the lbracket.
18641917 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.
18671920 Slice,
18681921 /// `lhs.*`. rhs is unused.
18691922 Deref,
lib/std/zig/parser_test.zig+18
......@@ -637,6 +637,24 @@ test "zig fmt: sentinel array literal 1 element" {
637637 );
638638}
639639
640test "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
649test "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
640658//test "zig fmt: async function" {
641659// try testCanonical(
642660// \\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
466466 return renderToken(ais, tree, rbracket, space); // ]
467467 },
468468
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),
497471
498472 .Deref => {
499473 try renderExpression(ais, tree, datas[node].lhs, .None);
......@@ -1142,6 +1116,40 @@ fn renderPtrType(
11421116 try renderExpression(ais, tree, ptr_type.ast.child_type, space);
11431117}
11441118
1119fn 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
11451153fn renderAsmOutput(
11461154 allocator: *mem.Allocator,
11471155 ais: *Ais,
......@@ -2099,8 +2107,8 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool {
20992107 };
21002108}
21012109
2102fn nodeCausesSliceOpSpace(base: ast.Node.Index) bool {
2103 return switch (base.tag) {
2110fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {
2111 return switch (tag) {
21042112 .Catch,
21052113 .Add,
21062114 .AddWrap,
......@@ -2139,7 +2147,6 @@ fn nodeCausesSliceOpSpace(base: ast.Node.Index) bool {
21392147 .Mod,
21402148 .Mul,
21412149 .MulWrap,
2142 .Range,
21432150 .Sub,
21442151 .SubWrap,
21452152 .OrElse,