diff --git a/parser.c b/parser.c index 4bcef636be..926e50d5c2 100644 --- a/parser.c +++ b/parser.c @@ -571,9 +571,49 @@ static AstNodeIndex parseSuffixOp(Parser* p, AstNodeIndex lhs) { .main_token = lbracket, .data = { .lhs = lhs, .rhs = index_expr }, }); - case TOKEN_ELLIPSIS2: - fprintf(stderr, "parseSuffixOp: slicing not implemented\n"); - exit(1); + case TOKEN_ELLIPSIS2: { + p->tok_i++; // consume .. + const AstNodeIndex end_expr = parseExpr(p); + if (eatToken(p, TOKEN_COLON) != null_token) { + const AstNodeIndex sentinel = expectExpr(p); + expectToken(p, TOKEN_R_BRACKET); + // end_expr 0 means "no end" — encode as ~0 for + // OptionalIndex.none + const AstNodeIndex opt_end + = end_expr == 0 ? ~(AstNodeIndex)0 : end_expr; + return addNode(&p->nodes, + (AstNodeItem) { + .tag = AST_NODE_SLICE_SENTINEL, + .main_token = lbracket, + .data = { + .lhs = lhs, + .rhs = addExtra(p, + (AstNodeIndex[]) { + index_expr, opt_end, sentinel }, + 3), + }, + }); + } + expectToken(p, TOKEN_R_BRACKET); + if (end_expr == 0) { + return addNode(&p->nodes, + (AstNodeItem) { + .tag = AST_NODE_SLICE_OPEN, + .main_token = lbracket, + .data = { .lhs = lhs, .rhs = index_expr }, + }); + } + return addNode(&p->nodes, + (AstNodeItem) { + .tag = AST_NODE_SLICE, + .main_token = lbracket, + .data = { + .lhs = lhs, + .rhs = addExtra(p, + (AstNodeIndex[]) { index_expr, end_expr }, 2), + }, + }); + } default: fprintf( stderr, "parseSuffixOp: expected ] or .. after index expr\n"); diff --git a/parser_test.zig b/parser_test.zig index 281d01bbab..a9f24cc9e1 100644 --- a/parser_test.zig +++ b/parser_test.zig @@ -1206,3 +1206,49 @@ test "zig fmt: array literal 3 element comma" { \\ ); } + +test "zig fmt: slices" { + try testCanonical( + \\const a = b[0..]; + \\const c = d[0..1]; + \\const d = f[0.. :0]; + \\const e = f[0..1 :0]; + \\ + ); +} + +test "zig fmt: tagged union with enum values" { + try testCanonical( + \\const MultipleChoice2 = union(enum(u32)) { + \\ Unspecified1: i32, + \\ A: f32 = 20, + \\ Unspecified2: void, + \\ B: bool = 40, + \\ Unspecified3: i32, + \\ C: i8 = 60, + \\ Unspecified4: void, + \\ D: void = 1000, + \\ Unspecified5: i32, + \\}; + \\ + ); +} + +test "zig fmt: tagged union enum tag last token" { + try testCanonical( + \\test { + \\ const U = union(enum(u32)) {}; + \\} + \\ + \\test { + \\ const U = union(enum(u32)) { foo }; + \\} + \\ + \\test { + \\ const U = union(enum(u32)) { + \\ foo, + \\ }; + \\} + \\ + ); +}