Commit aaf13a2bb3
Changed files (3)
lib
lib/std/zig/ast.zig
@@ -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,
lib/std/zig/parser_test.zig
@@ -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;
lib/std/zig/render.zig
@@ -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 => {