Skip to content

Commit

Permalink
Merge pull request #21257 from mlugg/computed-goto-3
Browse files Browse the repository at this point in the history
compiler: implement labeled switch/continue
  • Loading branch information
andrewrk authored Sep 5, 2024
2 parents 7e31804 + 289c704 commit 3929cac
Show file tree
Hide file tree
Showing 28 changed files with 2,690 additions and 824 deletions.
65 changes: 56 additions & 9 deletions lib/std/zig/Ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1184,14 +1184,7 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex {
n = extra.sentinel;
},

.@"continue" => {
if (datas[n].lhs != 0) {
return datas[n].lhs + end_offset;
} else {
return main_tokens[n] + end_offset;
}
},
.@"break" => {
.@"continue", .@"break" => {
if (datas[n].rhs != 0) {
n = datas[n].rhs;
} else if (datas[n].lhs != 0) {
Expand Down Expand Up @@ -1895,6 +1888,25 @@ pub fn taggedUnionEnumTag(tree: Ast, node: Node.Index) full.ContainerDecl {
});
}

pub fn switchFull(tree: Ast, node: Node.Index) full.Switch {
const data = &tree.nodes.items(.data)[node];
const main_token = tree.nodes.items(.main_token)[node];
const switch_token: TokenIndex, const label_token: ?TokenIndex = switch (tree.tokens.items(.tag)[main_token]) {
.identifier => .{ main_token + 2, main_token },
.keyword_switch => .{ main_token, null },
else => unreachable,
};
const extra = tree.extraData(data.rhs, Ast.Node.SubRange);
return .{
.ast = .{
.switch_token = switch_token,
.condition = data.lhs,
.cases = tree.extra_data[extra.start..extra.end],
},
.label_token = label_token,
};
}

pub fn switchCaseOne(tree: Ast, node: Node.Index) full.SwitchCase {
const data = &tree.nodes.items(.data)[node];
const values: *[1]Node.Index = &data.lhs;
Expand Down Expand Up @@ -2206,6 +2218,21 @@ fn fullContainerDeclComponents(tree: Ast, info: full.ContainerDecl.Components) f
return result;
}

fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch {
const token_tags = tree.tokens.items(.tag);
const tok_i = info.switch_token -| 1;
var result: full.Switch = .{
.ast = info,
.label_token = null,
};
if (token_tags[tok_i] == .colon and
token_tags[tok_i -| 1] == .identifier)
{
result.label_token = tok_i - 1;
}
return result;
}

fn fullSwitchCaseComponents(tree: Ast, info: full.SwitchCase.Components, node: Node.Index) full.SwitchCase {
const token_tags = tree.tokens.items(.tag);
const node_tags = tree.nodes.items(.tag);
Expand Down Expand Up @@ -2477,6 +2504,13 @@ pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index
};
}

pub fn fullSwitch(tree: Ast, node: Node.Index) ?full.Switch {
return switch (tree.nodes.items(.tag)[node]) {
.@"switch", .switch_comma => tree.switchFull(node),
else => null,
};
}

pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase {
return switch (tree.nodes.items(.tag)[node]) {
.switch_case_one, .switch_case_inline_one => tree.switchCaseOne(node),
Expand Down Expand Up @@ -2829,6 +2863,17 @@ pub const full = struct {
};
};

pub const Switch = struct {
ast: Components,
label_token: ?TokenIndex,

pub const Components = struct {
switch_token: TokenIndex,
condition: Node.Index,
cases: []const Node.Index,
};
};

pub const SwitchCase = struct {
inline_token: ?TokenIndex,
/// Points to the first token after the `|`. Will either be an identifier or
Expand Down Expand Up @@ -3243,6 +3288,7 @@ pub const Node = struct {
/// main_token is the `(`.
async_call_comma,
/// `switch(lhs) {}`. `SubRange[rhs]`.
/// `main_token` is the identifier of a preceding label, if any; otherwise `switch`.
@"switch",
/// Same as switch except there is known to be a trailing comma
/// before the final rbrace
Expand Down Expand Up @@ -3287,7 +3333,8 @@ pub const Node = struct {
@"suspend",
/// `resume lhs`. rhs is unused.
@"resume",
/// `continue`. lhs is token index of label if any. rhs is unused.
/// `continue :lhs rhs`
/// both lhs and rhs may be omitted.
@"continue",
/// `break :lhs rhs`
/// both lhs and rhs may be omitted.
Expand Down
Loading

0 comments on commit 3929cac

Please sign in to comment.