zig fmt: implement break

This commit is contained in:
Isaac Freund
2021-02-08 00:24:58 +01:00
committed by Andrew Kelley
parent 57cec38e61
commit aaf13a2bb3
3 changed files with 50 additions and 24 deletions

View File

@@ -438,7 +438,6 @@ pub const Tree = struct {
.OptionalType,
.Suspend,
.Resume,
.Break,
.Nosuspend,
.Comptime,
=> n = datas[n].lhs,
@@ -715,6 +714,16 @@ pub const Tree = struct {
n = extra.sentinel;
},
.Break => {
if (datas[n].rhs != 0) {
n = datas[n].rhs;
} else if (datas[n].lhs != 0) {
return datas[n].lhs + end_offset;
} else {
return main_tokens[n] + end_offset;
}
},
// These are not supported by lastToken() because implementation would
// require recursion due to the optional comma followed by rbrace.
// TODO follow the pattern set by StructInitDotTwoComma which will allow
@@ -2023,7 +2032,8 @@ pub const Node = struct {
Resume,
/// `continue`. lhs is token index of label if any. rhs is unused.
Continue,
/// `break rhs`. rhs can be omitted. lhs is label token index, if any.
/// `break :lhs rhs`
/// both lhs and rhs may be omitted.
Break,
/// `return lhs`. lhs can be omitted. rhs is unused.
Return,

View File

@@ -273,6 +273,24 @@ test "zig fmt: comptime struct field" {
);
}
test "zig fmt: break from block" {
try testCanonical(
\\const a = blk: {
\\ break :blk 42;
\\};
\\const b = blk: {
\\ break :blk;
\\};
\\const c = {
\\ break 42;
\\};
\\const d = {
\\ break;
\\};
\\
);
}
//test "zig fmt: c pointer type" {
// try testCanonical(
// \\pub extern fn repro() [*c]const u8;

View File

@@ -487,28 +487,26 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
return renderToken(ais, tree, datas[node].rhs, space);
},
.Break => unreachable, // TODO
//.Break => {
// const flow_expr = base.castTag(.Break).?;
// const maybe_rhs = flow_expr.getRHS();
// const maybe_label = flow_expr.getLabel();
// if (maybe_label == null and maybe_rhs == null) {
// return renderToken(ais, tree, flow_expr.ltoken, space); // break
// }
// try renderToken(ais, tree, flow_expr.ltoken, Space.Space); // break
// if (maybe_label) |label| {
// const colon = tree.nextToken(flow_expr.ltoken);
// try renderToken(ais, tree, colon, Space.None); // :
// if (maybe_rhs == null) {
// return renderToken(ais, tree, label, space); // label
// }
// try renderToken(ais, tree, label, Space.Space); // label
// }
// return renderExpression(ais, tree, maybe_rhs.?, space);
//},
.Break => {
const main_token = main_tokens[node];
const label_token = datas[node].lhs;
const target = datas[node].rhs;
if (label_token == 0 and target == 0) {
try renderToken(ais, tree, main_token, space); // break keyword
} else if (label_token == 0 and target != 0) {
try renderToken(ais, tree, main_token, .Space); // break keyword
try renderExpression(ais, tree, target, space);
} else if (label_token != 0 and target == 0) {
try renderToken(ais, tree, main_token, .Space); // break keyword
try renderToken(ais, tree, label_token - 1, .None); // colon
try renderToken(ais, tree, label_token, space); // identifier
} else if (label_token != 0 and target != 0) {
try renderToken(ais, tree, main_token, .Space); // break keyword
try renderToken(ais, tree, label_token - 1, .None); // colon
try renderToken(ais, tree, label_token, .Space); // identifier
try renderExpression(ais, tree, target, space);
}
},
.Continue => unreachable, // TODO
//.Continue => {