diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/zig/Ast.zig | 31 | ||||
| -rw-r--r-- | lib/std/zig/parse.zig | 17 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 2 | ||||
| -rw-r--r-- | lib/std/zig/render.zig | 21 |
4 files changed, 56 insertions, 15 deletions
diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig index bfa73dc9ac..62a567387f 100644 --- a/lib/std/zig/Ast.zig +++ b/lib/std/zig/Ast.zig @@ -643,11 +643,23 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { n = datas[n].lhs; } }, + .switch_case_inline_one => { + if (datas[n].lhs == 0) { + return main_tokens[n] - 2 - end_offset; // else token + } else { + return firstToken(tree, datas[n].lhs) - 1; + } + }, .switch_case => { const extra = tree.extraData(datas[n].lhs, Node.SubRange); assert(extra.end - extra.start > 0); n = tree.extra_data[extra.start]; }, + .switch_case_inline => { + const extra = tree.extraData(datas[n].lhs, Node.SubRange); + assert(extra.end - extra.start > 0); + return firstToken(tree, tree.extra_data[extra.start]) - 1; + }, .asm_output, .asm_input => { assert(token_tags[main_tokens[n] - 1] == .l_bracket); @@ -763,7 +775,9 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { .ptr_type_bit_range, .array_type, .switch_case_one, + .switch_case_inline_one, .switch_case, + .switch_case_inline, .switch_range, => n = datas[n].rhs, @@ -1755,7 +1769,7 @@ pub fn switchCaseOne(tree: Ast, node: Node.Index) full.SwitchCase { .values = if (data.lhs == 0) values[0..0] else values[0..1], .arrow_token = tree.nodes.items(.main_token)[node], .target_expr = data.rhs, - }); + }, node); } pub fn switchCase(tree: Ast, node: Node.Index) full.SwitchCase { @@ -1765,7 +1779,7 @@ pub fn switchCase(tree: Ast, node: Node.Index) full.SwitchCase { .values = tree.extra_data[extra.start..extra.end], .arrow_token = tree.nodes.items(.main_token)[node], .target_expr = data.rhs, - }); + }, node); } pub fn asmSimple(tree: Ast, node: Node.Index) full.Asm { @@ -2038,15 +2052,21 @@ fn fullContainerDecl(tree: Ast, info: full.ContainerDecl.Components) full.Contai return result; } -fn fullSwitchCase(tree: Ast, info: full.SwitchCase.Components) full.SwitchCase { +fn fullSwitchCase(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); var result: full.SwitchCase = .{ .ast = info, .payload_token = null, + .inline_token = null, }; if (token_tags[info.arrow_token + 1] == .pipe) { result.payload_token = info.arrow_token + 2; } + switch (node_tags[node]) { + .switch_case_inline, .switch_case_inline_one => result.inline_token = firstToken(tree, node), + else => {}, + } return result; } @@ -2454,6 +2474,7 @@ pub const full = struct { }; pub const SwitchCase = struct { + inline_token: ?TokenIndex, /// Points to the first token after the `|`. Will either be an identifier or /// a `*` (with an identifier immediately after it). payload_token: ?TokenIndex, @@ -2847,9 +2868,13 @@ pub const Node = struct { /// `lhs => rhs`. If lhs is omitted it means `else`. /// main_token is the `=>` switch_case_one, + /// Same ast `switch_case_one` but the case is inline + switch_case_inline_one, /// `a, b, c => rhs`. `SubRange[lhs]`. /// main_token is the `=>` switch_case, + /// Same ast `switch_case` but the case is inline + switch_case_inline, /// `lhs...rhs`. switch_range, /// `while (lhs) rhs`. diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 43b6eda8e0..db56cef21e 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -3100,7 +3100,7 @@ const Parser = struct { return identifier; } - /// SwitchProng <- SwitchCase EQUALRARROW PtrPayload? AssignExpr + /// SwitchProng <- KEYWORD_inline? SwitchCase EQUALRARROW PtrIndexPayload? AssignExpr /// SwitchCase /// <- SwitchItem (COMMA SwitchItem)* COMMA? /// / KEYWORD_else @@ -3108,6 +3108,8 @@ const Parser = struct { const scratch_top = p.scratch.items.len; defer p.scratch.shrinkRetainingCapacity(scratch_top); + const is_inline = p.eatToken(.keyword_inline) != null; + if (p.eatToken(.keyword_else) == null) { while (true) { const item = try p.parseSwitchItem(); @@ -3115,15 +3117,18 @@ const Parser = struct { try p.scratch.append(p.gpa, item); if (p.eatToken(.comma) == null) break; } - if (scratch_top == p.scratch.items.len) return null_node; + if (scratch_top == p.scratch.items.len) { + if (is_inline) p.tok_i -= 1; + return null_node; + } } const arrow_token = try p.expectToken(.equal_angle_bracket_right); - _ = try p.parsePtrPayload(); + _ = try p.parsePtrIndexPayload(); const items = p.scratch.items[scratch_top..]; switch (items.len) { 0 => return p.addNode(.{ - .tag = .switch_case_one, + .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, .main_token = arrow_token, .data = .{ .lhs = 0, @@ -3131,7 +3136,7 @@ const Parser = struct { }, }), 1 => return p.addNode(.{ - .tag = .switch_case_one, + .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, .main_token = arrow_token, .data = .{ .lhs = items[0], @@ -3139,7 +3144,7 @@ const Parser = struct { }, }), else => return p.addNode(.{ - .tag = .switch_case, + .tag = if (is_inline) .switch_case_inline else .switch_case, .main_token = arrow_token, .data = .{ .lhs = try p.addExtra(try p.listToSpan(items)), diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 0e1817ffab..4e155df6d8 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -3276,6 +3276,8 @@ test "zig fmt: switch" { \\ switch (u) { \\ Union.Int => |int| {}, \\ Union.Float => |*float| unreachable, + \\ 1 => |a, b| unreachable, + \\ 2 => |*a, b| unreachable, \\ } \\} \\ diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 6ef0cfcd6f..ab009f8390 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -685,8 +685,8 @@ fn renderExpression(gpa: Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index, return renderToken(ais, tree, tree.lastToken(node), space); // rbrace }, - .switch_case_one => return renderSwitchCase(gpa, ais, tree, tree.switchCaseOne(node), space), - .switch_case => return renderSwitchCase(gpa, ais, tree, tree.switchCase(node), space), + .switch_case_one, .switch_case_inline_one => return renderSwitchCase(gpa, ais, tree, tree.switchCaseOne(node), space), + .switch_case, .switch_case_inline => return renderSwitchCase(gpa, ais, tree, tree.switchCase(node), space), .while_simple => return renderWhile(gpa, ais, tree, tree.whileSimple(node), space), .while_cont => return renderWhile(gpa, ais, tree, tree.whileCont(node), space), @@ -1509,6 +1509,11 @@ fn renderSwitchCase( break :blk hasComment(tree, tree.firstToken(switch_case.ast.values[0]), switch_case.ast.arrow_token); }; + // render inline keyword + if (switch_case.inline_token) |some| { + try renderToken(ais, tree, some, .space); + } + // Render everything before the arrow if (switch_case.ast.values.len == 0) { try renderToken(ais, tree, switch_case.ast.arrow_token - 1, .space); // else keyword @@ -1536,13 +1541,17 @@ fn renderSwitchCase( if (switch_case.payload_token) |payload_token| { try renderToken(ais, tree, payload_token - 1, .none); // pipe + const ident = payload_token + @boolToInt(token_tags[payload_token] == .asterisk); if (token_tags[payload_token] == .asterisk) { try renderToken(ais, tree, payload_token, .none); // asterisk - try renderToken(ais, tree, payload_token + 1, .none); // identifier - try renderToken(ais, tree, payload_token + 2, pre_target_space); // pipe + } + try renderToken(ais, tree, ident, .none); // identifier + if (token_tags[ident + 1] == .comma) { + try renderToken(ais, tree, ident + 1, .space); // , + try renderToken(ais, tree, ident + 2, .none); // identifier + try renderToken(ais, tree, ident + 3, pre_target_space); // pipe } else { - try renderToken(ais, tree, payload_token, .none); // identifier - try renderToken(ais, tree, payload_token + 1, pre_target_space); // pipe + try renderToken(ais, tree, ident + 1, pre_target_space); // pipe } } |
