Skip to content

Commit e6afea9

Browse files
committed
zig fmt: support aligned ptr with bit fields
1 parent b74dda3 commit e6afea9

File tree

4 files changed

+103
-24
lines changed

4 files changed

+103
-24
lines changed

std/zig/ast.zig

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ pub const Error = union(enum) {
9898
UnattachedDocComment: UnattachedDocComment,
9999
ExpectedEqOrSemi: ExpectedEqOrSemi,
100100
ExpectedSemiOrLBrace: ExpectedSemiOrLBrace,
101+
ExpectedColonOrRParen: ExpectedColonOrRParen,
101102
ExpectedLabelable: ExpectedLabelable,
102103
ExpectedInlinable: ExpectedInlinable,
103104
ExpectedAsmOutputReturnOrType: ExpectedAsmOutputReturnOrType,
@@ -120,6 +121,7 @@ pub const Error = union(enum) {
120121
@TagType(Error).UnattachedDocComment => |*x| return x.render(tokens, stream),
121122
@TagType(Error).ExpectedEqOrSemi => |*x| return x.render(tokens, stream),
122123
@TagType(Error).ExpectedSemiOrLBrace => |*x| return x.render(tokens, stream),
124+
@TagType(Error).ExpectedColonOrRParen => |*x| return x.render(tokens, stream),
123125
@TagType(Error).ExpectedLabelable => |*x| return x.render(tokens, stream),
124126
@TagType(Error).ExpectedInlinable => |*x| return x.render(tokens, stream),
125127
@TagType(Error).ExpectedAsmOutputReturnOrType => |*x| return x.render(tokens, stream),
@@ -144,6 +146,7 @@ pub const Error = union(enum) {
144146
@TagType(Error).UnattachedDocComment => |x| return x.token,
145147
@TagType(Error).ExpectedEqOrSemi => |x| return x.token,
146148
@TagType(Error).ExpectedSemiOrLBrace => |x| return x.token,
149+
@TagType(Error).ExpectedColonOrRParen => |x| return x.token,
147150
@TagType(Error).ExpectedLabelable => |x| return x.token,
148151
@TagType(Error).ExpectedInlinable => |x| return x.token,
149152
@TagType(Error).ExpectedAsmOutputReturnOrType => |x| return x.token,
@@ -164,6 +167,7 @@ pub const Error = union(enum) {
164167
pub const ExpectedAggregateKw = SingleTokenError("Expected " ++ @tagName(Token.Id.Keyword_struct) ++ ", " ++ @tagName(Token.Id.Keyword_union) ++ ", or " ++ @tagName(Token.Id.Keyword_enum) ++ ", found {}");
165168
pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found {}");
166169
pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found {}");
170+
pub const ExpectedColonOrRParen = SingleTokenError("Expected ':' or ')', found {}");
167171
pub const ExpectedLabelable = SingleTokenError("Expected 'while', 'for', 'inline', 'suspend', or '{{', found {}");
168172
pub const ExpectedInlinable = SingleTokenError("Expected 'while' or 'for', found {}");
169173
pub const ExpectedAsmOutputReturnOrType = SingleTokenError("Expected '->' or " ++ @tagName(Token.Id.Identifier) ++ ", found {}");
@@ -1487,7 +1491,7 @@ pub const Node = struct {
14871491
op: Op,
14881492
rhs: &Node,
14891493

1490-
const Op = union(enum) {
1494+
pub const Op = union(enum) {
14911495
AddrOf: AddrOfInfo,
14921496
ArrayType: &Node,
14931497
Await,
@@ -1504,12 +1508,20 @@ pub const Node = struct {
15041508
UnwrapMaybe,
15051509
};
15061510

1507-
const AddrOfInfo = struct {
1508-
align_expr: ?&Node,
1509-
bit_offset_start_token: ?TokenIndex,
1510-
bit_offset_end_token: ?TokenIndex,
1511+
pub const AddrOfInfo = struct {
1512+
align_info: ?Align,
15111513
const_token: ?TokenIndex,
15121514
volatile_token: ?TokenIndex,
1515+
1516+
pub const Align = struct {
1517+
node: &Node,
1518+
bit_range: ?BitRange,
1519+
1520+
pub const BitRange = struct {
1521+
start: &Node,
1522+
end: &Node,
1523+
};
1524+
};
15131525
};
15141526

15151527
pub fn iterate(self: &PrefixOp, index: usize) ?&Node {

std/zig/parse.zig

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,9 +1450,7 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
14501450
State.SliceOrArrayType => |node| {
14511451
if (eatToken(&tok_it, &tree, Token.Id.RBracket)) |_| {
14521452
node.op = ast.Node.PrefixOp.Op{ .SliceType = ast.Node.PrefixOp.AddrOfInfo{
1453-
.align_expr = null,
1454-
.bit_offset_start_token = null,
1455-
.bit_offset_end_token = null,
1453+
.align_info = null,
14561454
.const_token = null,
14571455
.volatile_token = null,
14581456
} };
@@ -1467,19 +1465,27 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
14671465
try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.op.ArrayType } });
14681466
continue;
14691467
},
1468+
14701469
State.AddrOfModifiers => |addr_of_info| {
14711470
const token = nextToken(&tok_it, &tree);
14721471
const token_index = token.index;
14731472
const token_ptr = token.ptr;
14741473
switch (token_ptr.id) {
14751474
Token.Id.Keyword_align => {
14761475
stack.append(state) catch unreachable;
1477-
if (addr_of_info.align_expr != null) {
1476+
if (addr_of_info.align_info != null) {
14781477
((try tree.errors.addOne())).* = Error{ .ExtraAlignQualifier = Error.ExtraAlignQualifier{ .token = token_index } };
14791478
return tree;
14801479
}
1481-
try stack.append(State{ .ExpectToken = Token.Id.RParen });
1482-
try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &addr_of_info.align_expr } });
1480+
addr_of_info.align_info = ast.Node.PrefixOp.AddrOfInfo.Align {
1481+
.node = undefined,
1482+
.bit_range = null,
1483+
};
1484+
// TODO https://github.com/ziglang/zig/issues/1022
1485+
const align_info = &??addr_of_info.align_info;
1486+
1487+
try stack.append(State{ .AlignBitRange = align_info });
1488+
try stack.append(State{ .Expression = OptionalCtx{ .Required = &align_info.node } });
14831489
try stack.append(State{ .ExpectToken = Token.Id.LParen });
14841490
continue;
14851491
},
@@ -1508,6 +1514,31 @@ pub fn parse(allocator: &mem.Allocator, source: []const u8) !ast.Tree {
15081514
}
15091515
},
15101516

1517+
State.AlignBitRange => |align_info| {
1518+
const token = nextToken(&tok_it, &tree);
1519+
switch (token.ptr.id) {
1520+
Token.Id.Colon => {
1521+
align_info.bit_range = ast.Node.PrefixOp.AddrOfInfo.Align.BitRange(undefined);
1522+
const bit_range = &??align_info.bit_range;
1523+
1524+
try stack.append(State{ .ExpectToken = Token.Id.RParen });
1525+
try stack.append(State{ .Expression = OptionalCtx{ .Required = &bit_range.end } });
1526+
try stack.append(State{ .ExpectToken = Token.Id.Colon });
1527+
try stack.append(State{ .Expression = OptionalCtx{ .Required = &bit_range.start } });
1528+
continue;
1529+
},
1530+
Token.Id.RParen => continue,
1531+
else => {
1532+
(try tree.errors.addOne()).* = Error{
1533+
.ExpectedColonOrRParen = Error.ExpectedColonOrRParen{
1534+
.token = token.index,
1535+
}
1536+
};
1537+
return tree;
1538+
},
1539+
}
1540+
},
1541+
15111542
State.Payload => |opt_ctx| {
15121543
const token = nextToken(&tok_it, &tree);
15131544
const token_index = token.index;
@@ -2801,6 +2832,7 @@ const State = union(enum) {
28012832
SliceOrArrayAccess: &ast.Node.SuffixOp,
28022833
SliceOrArrayType: &ast.Node.PrefixOp,
28032834
AddrOfModifiers: &ast.Node.PrefixOp.AddrOfInfo,
2835+
AlignBitRange: &ast.Node.PrefixOp.AddrOfInfo.Align,
28042836

28052837
Payload: OptionalCtx,
28062838
PointerPayload: OptionalCtx,
@@ -3120,9 +3152,7 @@ fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.Node.PrefixOp.Op {
31203152
Token.Id.Asterisk,
31213153
Token.Id.AsteriskAsterisk => ast.Node.PrefixOp.Op{ .PointerType = void{} },
31223154
Token.Id.Ampersand => ast.Node.PrefixOp.Op{ .AddrOf = ast.Node.PrefixOp.AddrOfInfo{
3123-
.align_expr = null,
3124-
.bit_offset_start_token = null,
3125-
.bit_offset_end_token = null,
3155+
.align_info = null,
31263156
.const_token = null,
31273157
.volatile_token = null,
31283158
} },

std/zig/parser_test.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
test "zig fmt: float literal with exponent" {
2+
try testCanonical(
3+
\\test "bit field alignment" {
4+
\\ assert(@typeOf(&blah.b) == &align(1:3:6) const u3);
5+
\\}
6+
\\
7+
);
8+
}
9+
110
test "zig fmt: float literal with exponent" {
211
try testCanonical(
312
\\test "aoeu" {

std/zig/render.zig

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -253,17 +253,30 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
253253
switch (prefix_op_node.op) {
254254
ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| {
255255
try renderToken(tree, stream, prefix_op_node.op_token, indent, Space.None); // &
256-
if (addr_of_info.align_expr) |align_expr| {
256+
if (addr_of_info.align_info) |align_info| {
257257
const align_token = tree.nextToken(prefix_op_node.op_token);
258258
try renderToken(tree, stream, align_token, indent, Space.None); // align
259259

260-
const lparen_token = tree.prevToken(align_expr.firstToken());
260+
const lparen_token = tree.prevToken(align_info.node.firstToken());
261261
try renderToken(tree, stream, lparen_token, indent, Space.None); // (
262262

263-
try renderExpression(allocator, stream, tree, indent, align_expr, Space.None);
263+
try renderExpression(allocator, stream, tree, indent, align_info.node, Space.None);
264264

265-
const rparen_token = tree.nextToken(align_expr.lastToken());
266-
try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
265+
if (align_info.bit_range) |bit_range| {
266+
const colon1 = tree.prevToken(bit_range.start.firstToken());
267+
const colon2 = tree.prevToken(bit_range.end.firstToken());
268+
269+
try renderToken(tree, stream, colon1, indent, Space.None); // :
270+
try renderExpression(allocator, stream, tree, indent, bit_range.start, Space.None);
271+
try renderToken(tree, stream, colon2, indent, Space.None); // :
272+
try renderExpression(allocator, stream, tree, indent, bit_range.end, Space.None);
273+
274+
const rparen_token = tree.nextToken(bit_range.end.lastToken());
275+
try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
276+
} else {
277+
const rparen_token = tree.nextToken(align_info.node.lastToken());
278+
try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
279+
}
267280
}
268281
if (addr_of_info.const_token) |const_token| {
269282
try renderToken(tree, stream, const_token, indent, Space.Space); // const
@@ -272,21 +285,35 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
272285
try renderToken(tree, stream, volatile_token, indent, Space.Space); // volatile
273286
}
274287
},
288+
275289
ast.Node.PrefixOp.Op.SliceType => |addr_of_info| {
276290
try renderToken(tree, stream, prefix_op_node.op_token, indent, Space.None); // [
277291
try renderToken(tree, stream, tree.nextToken(prefix_op_node.op_token), indent, Space.None); // ]
278292

279-
if (addr_of_info.align_expr) |align_expr| {
293+
if (addr_of_info.align_info) |align_info| {
280294
const align_token = tree.nextToken(prefix_op_node.op_token);
281295
try renderToken(tree, stream, align_token, indent, Space.None); // align
282296

283-
const lparen_token = tree.prevToken(align_expr.firstToken());
297+
const lparen_token = tree.prevToken(align_info.node.firstToken());
284298
try renderToken(tree, stream, lparen_token, indent, Space.None); // (
285299

286-
try renderExpression(allocator, stream, tree, indent, align_expr, Space.None);
300+
try renderExpression(allocator, stream, tree, indent, align_info.node, Space.None);
287301

288-
const rparen_token = tree.nextToken(align_expr.lastToken());
289-
try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
302+
if (align_info.bit_range) |bit_range| {
303+
const colon1 = tree.prevToken(bit_range.start.firstToken());
304+
const colon2 = tree.prevToken(bit_range.end.firstToken());
305+
306+
try renderToken(tree, stream, colon1, indent, Space.None); // :
307+
try renderExpression(allocator, stream, tree, indent, bit_range.start, Space.None);
308+
try renderToken(tree, stream, colon2, indent, Space.None); // :
309+
try renderExpression(allocator, stream, tree, indent, bit_range.end, Space.None);
310+
311+
const rparen_token = tree.nextToken(bit_range.end.lastToken());
312+
try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
313+
} else {
314+
const rparen_token = tree.nextToken(align_info.node.lastToken());
315+
try renderToken(tree, stream, rparen_token, indent, Space.Space); // )
316+
}
290317
}
291318
if (addr_of_info.const_token) |const_token| {
292319
try renderToken(tree, stream, const_token, indent, Space.Space);
@@ -295,6 +322,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
295322
try renderToken(tree, stream, volatile_token, indent, Space.Space);
296323
}
297324
},
325+
298326
ast.Node.PrefixOp.Op.ArrayType => |array_index| {
299327
try renderToken(tree, stream, prefix_op_node.op_token, indent, Space.None); // [
300328
try renderExpression(allocator, stream, tree, indent, array_index, Space.None);

0 commit comments

Comments
 (0)