feature. See also
. The project being documented here (as the example) is the Zig library itself.
Parse.parseCurlySuffixExpr
fn parseCurlySuffixExpr(p: *Parse) !?Node.Index
File
Code
fn parseCurlySuffixExpr(p: *Parse) !?Node.Index {
const lhs = try p.parseTypeExpr() orelse return null;
const lbrace = p.eatToken(.l_brace) orelse return lhs;
// otherwise we use the full ArrayInit/StructInit.
const scratch_top = p.scratch.items.len;
defer p.scratch.shrinkRetainingCapacity(scratch_top);
const opt_field_init = try p.parseFieldInit();
if (opt_field_init) |field_init| {
try p.scratch.append(p.gpa, field_init);
while (true) {
switch (p.tokenTag(p.tok_i)) {
.comma => p.tok_i += 1,
.r_brace => {
p.tok_i += 1;
break;
},
.colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
else => try p.warn(.expected_comma_after_initializer),
}
if (p.eatToken(.r_brace)) |_| break;
const next = try p.expectFieldInit();
try p.scratch.append(p.gpa, next);
}
const comma = (p.tokenTag(p.tok_i - 2)) == .comma;
const inits = p.scratch.items[scratch_top..];
std.debug.assert(inits.len != 0);
if (inits.len <= 1) {
return try p.addNode(.{
.tag = if (comma) .struct_init_one_comma else .struct_init_one,
.main_token = lbrace,
.data = .{ .node_and_opt_node = .{
lhs,
inits[0].toOptional(),
} },
});
} else {
return try p.addNode(.{
.tag = if (comma) .struct_init_comma else .struct_init,
.main_token = lbrace,
.data = .{ .node_and_extra = .{
lhs,
try p.addExtra(try p.listToSpan(inits)),
} },
});
}
}
while (true) {
if (p.eatToken(.r_brace)) |_| break;
const elem_init = try p.expectExpr();
try p.scratch.append(p.gpa, elem_init);
switch (p.tokenTag(p.tok_i)) {
.comma => p.tok_i += 1,
.r_brace => {
p.tok_i += 1;
break;
},
.colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
else => try p.warn(.expected_comma_after_initializer),
}
}
const comma = (p.tokenTag(p.tok_i - 2)) == .comma;
const inits = p.scratch.items[scratch_top..];
switch (inits.len) {
0 => return try p.addNode(.{
.tag = .struct_init_one,
.main_token = lbrace,
.data = .{ .node_and_opt_node = .{
lhs,
.none,
} },
}),
1 => return try p.addNode(.{
.tag = if (comma) .array_init_one_comma else .array_init_one,
.main_token = lbrace,
.data = .{ .node_and_node = .{
lhs,
inits[0],
} },
}),
else => return try p.addNode(.{
.tag = if (comma) .array_init_comma else .array_init,
.main_token = lbrace,
.data = .{ .node_and_extra = .{
lhs,
try p.addExtra(try p.listToSpan(inits)),
} },
}),
}
}