Skip to content

Commit 0f92c2b

Browse files
committed
parser: Handle .{.{. ,. .el}}
1 parent fd47d6f commit 0f92c2b

File tree

1 file changed

+107
-98
lines changed

1 file changed

+107
-98
lines changed

Diff for: src/stage2/Parse.zig

+107-98
Original file line numberDiff line numberDiff line change
@@ -2811,33 +2811,103 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index {
28112811
},
28122812
.keyword_for => return p.parseFor(expectTypeExpr),
28132813
.keyword_while => return p.parseWhileTypeExpr(),
2814-
.period => switch (p.token_tags[p.tok_i + 1]) {
2815-
.identifier => return p.addNode(.{
2816-
.tag = .enum_literal,
2817-
.data = .{
2818-
.lhs = p.nextToken(), // dot
2819-
.rhs = undefined,
2820-
},
2821-
.main_token = p.nextToken(), // identifier
2822-
}),
2823-
.l_brace => {
2824-
const lbrace = p.tok_i + 1;
2825-
p.tok_i = lbrace + 1;
2814+
.period => {
2815+
// zls
2816+
// not strictly neccessary, but allows `.{.{. ,. .el}}`, ie
2817+
// when the dot precedes existing elems here^, ^-or here
2818+
if (p.token_tags[p.tok_i + 1] == .period or p.token_tags[p.tok_i + 1] == .comma) { // zls
2819+
try p.warn(.expected_expr);
2820+
p.tok_i += 1;
2821+
}
2822+
switch (p.token_tags[p.tok_i + 1]) {
2823+
.identifier => return p.addNode(.{
2824+
.tag = .enum_literal,
2825+
.data = .{
2826+
.lhs = p.nextToken(), // dot
2827+
.rhs = undefined,
2828+
},
2829+
.main_token = p.nextToken(), // identifier
2830+
}),
2831+
.l_brace => {
2832+
const lbrace = p.tok_i + 1;
2833+
p.tok_i = lbrace + 1;
28262834

2827-
if (p.token_tags[p.tok_i] == .period and p.token_tags[p.tok_i + 1] == .period) { // zls
2828-
try p.warn(.expected_initializer);
2829-
p.tok_i += 1;
2830-
}
2835+
if (p.token_tags[p.tok_i] == .period and p.token_tags[p.tok_i + 1] == .period) { // zls
2836+
try p.warn(.expected_initializer);
2837+
p.tok_i += 1;
2838+
}
28312839

2832-
// If there are 0, 1, or 2 items, we can use ArrayInitDotTwo/StructInitDotTwo;
2833-
// otherwise we use the full ArrayInitDot/StructInitDot.
2840+
// If there are 0, 1, or 2 items, we can use ArrayInitDotTwo/StructInitDotTwo;
2841+
// otherwise we use the full ArrayInitDot/StructInitDot.
2842+
2843+
const scratch_top = p.scratch.items.len;
2844+
defer p.scratch.shrinkRetainingCapacity(scratch_top);
2845+
const field_init = try p.parseFieldInit();
2846+
if (field_init != 0) {
2847+
try p.scratch.append(p.gpa, field_init);
2848+
while (true) {
2849+
switch (p.token_tags[p.tok_i]) {
2850+
.comma => p.tok_i += 1,
2851+
.r_brace => {
2852+
p.tok_i += 1;
2853+
break;
2854+
},
2855+
.colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
2856+
// Likely just a missing comma; give error but continue parsing.
2857+
else => try p.warn(.expected_comma_after_initializer),
2858+
}
2859+
if (p.token_tags[p.tok_i] == .period) { // zls
2860+
if (p.token_tags[p.tok_i + 1] == .period or p.token_tags[p.tok_i + 1] == .r_brace) {
2861+
try p.warn(.expected_initializer);
2862+
p.tok_i += 1;
2863+
}
2864+
}
2865+
if (p.eatToken(.r_brace)) |_| break;
2866+
const next = try p.expectFieldInit();
2867+
try p.scratch.append(p.gpa, next);
2868+
}
2869+
const comma = (p.token_tags[p.tok_i - 2] == .comma);
2870+
const inits = p.scratch.items[scratch_top..];
2871+
switch (inits.len) {
2872+
0 => unreachable,
2873+
1 => return p.addNode(.{
2874+
.tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two,
2875+
.main_token = lbrace,
2876+
.data = .{
2877+
.lhs = inits[0],
2878+
.rhs = 0,
2879+
},
2880+
}),
2881+
2 => return p.addNode(.{
2882+
.tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two,
2883+
.main_token = lbrace,
2884+
.data = .{
2885+
.lhs = inits[0],
2886+
.rhs = inits[1],
2887+
},
2888+
}),
2889+
else => {
2890+
const span = try p.listToSpan(inits);
2891+
return p.addNode(.{
2892+
.tag = if (comma) .struct_init_dot_comma else .struct_init_dot,
2893+
.main_token = lbrace,
2894+
.data = .{
2895+
.lhs = span.start,
2896+
.rhs = span.end,
2897+
},
2898+
});
2899+
},
2900+
}
2901+
}
28342902

2835-
const scratch_top = p.scratch.items.len;
2836-
defer p.scratch.shrinkRetainingCapacity(scratch_top);
2837-
const field_init = try p.parseFieldInit();
2838-
if (field_init != 0) {
2839-
try p.scratch.append(p.gpa, field_init);
28402903
while (true) {
2904+
if (p.token_tags[p.tok_i] == .period and p.token_tags[p.tok_i + 1] == .r_brace) { // zls
2905+
try p.warn(.expected_expr);
2906+
p.tok_i += 1;
2907+
}
2908+
if (p.eatToken(.r_brace)) |_| break;
2909+
const elem_init = try p.expectExpr();
2910+
try p.scratch.append(p.gpa, elem_init);
28412911
switch (p.token_tags[p.tok_i]) {
28422912
.comma => p.tok_i += 1,
28432913
.r_brace => {
@@ -2848,30 +2918,28 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index {
28482918
// Likely just a missing comma; give error but continue parsing.
28492919
else => try p.warn(.expected_comma_after_initializer),
28502920
}
2851-
if (p.token_tags[p.tok_i] == .period) { // zls
2852-
if (p.token_tags[p.tok_i + 1] == .period or p.token_tags[p.tok_i + 1] == .r_brace) {
2853-
try p.warn(.expected_initializer);
2854-
p.tok_i += 1;
2855-
}
2856-
}
2857-
if (p.eatToken(.r_brace)) |_| break;
2858-
const next = try p.expectFieldInit();
2859-
try p.scratch.append(p.gpa, next);
28602921
}
28612922
const comma = (p.token_tags[p.tok_i - 2] == .comma);
28622923
const inits = p.scratch.items[scratch_top..];
28632924
switch (inits.len) {
2864-
0 => unreachable,
2925+
0 => return p.addNode(.{
2926+
.tag = .struct_init_dot_two,
2927+
.main_token = lbrace,
2928+
.data = .{
2929+
.lhs = 0,
2930+
.rhs = 0,
2931+
},
2932+
}),
28652933
1 => return p.addNode(.{
2866-
.tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two,
2934+
.tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two,
28672935
.main_token = lbrace,
28682936
.data = .{
28692937
.lhs = inits[0],
28702938
.rhs = 0,
28712939
},
28722940
}),
28732941
2 => return p.addNode(.{
2874-
.tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two,
2942+
.tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two,
28752943
.main_token = lbrace,
28762944
.data = .{
28772945
.lhs = inits[0],
@@ -2881,7 +2949,7 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index {
28812949
else => {
28822950
const span = try p.listToSpan(inits);
28832951
return p.addNode(.{
2884-
.tag = if (comma) .struct_init_dot_comma else .struct_init_dot,
2952+
.tag = if (comma) .array_init_dot_comma else .array_init_dot,
28852953
.main_token = lbrace,
28862954
.data = .{
28872955
.lhs = span.start,
@@ -2890,68 +2958,9 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index {
28902958
});
28912959
},
28922960
}
2893-
}
2894-
2895-
while (true) {
2896-
if (p.token_tags[p.tok_i] == .period and p.token_tags[p.tok_i + 1] == .r_brace) { // zls
2897-
try p.warn(.expected_expr);
2898-
p.tok_i += 1;
2899-
}
2900-
if (p.eatToken(.r_brace)) |_| break;
2901-
const elem_init = try p.expectExpr();
2902-
try p.scratch.append(p.gpa, elem_init);
2903-
switch (p.token_tags[p.tok_i]) {
2904-
.comma => p.tok_i += 1,
2905-
.r_brace => {
2906-
p.tok_i += 1;
2907-
break;
2908-
},
2909-
.colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
2910-
// Likely just a missing comma; give error but continue parsing.
2911-
else => try p.warn(.expected_comma_after_initializer),
2912-
}
2913-
}
2914-
const comma = (p.token_tags[p.tok_i - 2] == .comma);
2915-
const inits = p.scratch.items[scratch_top..];
2916-
switch (inits.len) {
2917-
0 => return p.addNode(.{
2918-
.tag = .struct_init_dot_two,
2919-
.main_token = lbrace,
2920-
.data = .{
2921-
.lhs = 0,
2922-
.rhs = 0,
2923-
},
2924-
}),
2925-
1 => return p.addNode(.{
2926-
.tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two,
2927-
.main_token = lbrace,
2928-
.data = .{
2929-
.lhs = inits[0],
2930-
.rhs = 0,
2931-
},
2932-
}),
2933-
2 => return p.addNode(.{
2934-
.tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two,
2935-
.main_token = lbrace,
2936-
.data = .{
2937-
.lhs = inits[0],
2938-
.rhs = inits[1],
2939-
},
2940-
}),
2941-
else => {
2942-
const span = try p.listToSpan(inits);
2943-
return p.addNode(.{
2944-
.tag = if (comma) .array_init_dot_comma else .array_init_dot,
2945-
.main_token = lbrace,
2946-
.data = .{
2947-
.lhs = span.start,
2948-
.rhs = span.end,
2949-
},
2950-
});
2951-
},
2952-
}
2953-
},
2954-
else => return null_node,
2961+
},
2962+
else => return null_node,
2963+
}
29552964
},
29562965
.keyword_error => switch (p.token_tags[p.tok_i + 1]) {
29572966
.l_brace => {

0 commit comments

Comments
 (0)