| author | |
| committer | |
| log | b988815bf0771dd86a345ce8ed8b0d3eb9d6f55e |
| tree | fed9a51f338b4ada0bbebf6314bba22482813361 |
| parent | d01bb211732f1d0aebf558c43825a52254d034ab |
The modification to the grammar in the comment is in line with the
grammar in the zig-spec repo.
Note: checking if the previous token is a colon is insufficent to tell
if a block has a label, the identifier must be checked for as well. This
can be seen in sentinel terminated slicing: `foo[0..1:{}]`5 files changed, 43 insertions(+), 37 deletions(-)
lib/std/zig/ast.zig+6-3| ... | ... | @@ -525,7 +525,9 @@ pub const Tree = struct { |
| 525 | 525 | => { |
| 526 | 526 | // Look for a label. |
| 527 | 527 | const lbrace = main_tokens[n]; |
| 528 | if (token_tags[lbrace - 1] == .colon) { | |
| 528 | if (token_tags[lbrace - 1] == .colon and | |
| 529 | token_tags[lbrace - 2] == .identifier) | |
| 530 | { | |
| 529 | 531 | end_offset += 2; |
| 530 | 532 | } |
| 531 | 533 | return lbrace - end_offset; |
| ... | ... | @@ -989,13 +991,13 @@ pub const Tree = struct { |
| 989 | 991 | }, |
| 990 | 992 | .slice => { |
| 991 | 993 | const extra = tree.extraData(datas[n].rhs, Node.Slice); |
| 992 | assert(extra.end != 0); // should have used SliceOpen | |
| 994 | assert(extra.end != 0); // should have used slice_open | |
| 993 | 995 | end_offset += 1; // rbracket |
| 994 | 996 | n = extra.end; |
| 995 | 997 | }, |
| 996 | 998 | .slice_sentinel => { |
| 997 | 999 | const extra = tree.extraData(datas[n].rhs, Node.SliceSentinel); |
| 998 | assert(extra.sentinel != 0); // should have used Slice | |
| 1000 | assert(extra.sentinel != 0); // should have used slice | |
| 999 | 1001 | end_offset += 1; // rbracket |
| 1000 | 1002 | n = extra.sentinel; |
| 1001 | 1003 | }, |
| ... | ... | @@ -2925,6 +2927,7 @@ pub const Node = struct { |
| 2925 | 2927 | |
| 2926 | 2928 | pub const SliceSentinel = struct { |
| 2927 | 2929 | start: Index, |
| 2930 | /// May be 0 if the slice is "open" | |
| 2928 | 2931 | end: Index, |
| 2929 | 2932 | sentinel: Index, |
| 2930 | 2933 | }; |
lib/std/zig/parse.zig+17-19| ... | ... | @@ -3441,7 +3441,7 @@ const Parser = struct { |
| 3441 | 3441 | } |
| 3442 | 3442 | |
| 3443 | 3443 | /// SuffixOp |
| 3444 | /// <- LBRACKET Expr (DOT2 (Expr (COLON Expr)?)?)? RBRACKET | |
| 3444 | /// <- LBRACKET Expr (DOT2 (Expr? (COLON Expr)?)?)? RBRACKET | |
| 3445 | 3445 | /// / DOT IDENTIFIER |
| 3446 | 3446 | /// / DOTASTERISK |
| 3447 | 3447 | /// / DOTQUESTIONMARK |
| ... | ... | @@ -3453,17 +3453,6 @@ const Parser = struct { |
| 3453 | 3453 | |
| 3454 | 3454 | if (p.eatToken(.ellipsis2)) |_| { |
| 3455 | 3455 | const end_expr = try p.parseExpr(); |
| 3456 | if (end_expr == 0) { | |
| 3457 | _ = try p.expectToken(.r_bracket); | |
| 3458 | return p.addNode(.{ | |
| 3459 | .tag = .slice_open, | |
| 3460 | .main_token = lbracket, | |
| 3461 | .data = .{ | |
| 3462 | .lhs = lhs, | |
| 3463 | .rhs = index_expr, | |
| 3464 | }, | |
| 3465 | }); | |
| 3466 | } | |
| 3467 | 3456 | if (p.eatToken(.colon)) |_| { |
| 3468 | 3457 | const sentinel = try p.parseExpr(); |
| 3469 | 3458 | _ = try p.expectToken(.r_bracket); |
| ... | ... | @@ -3479,20 +3468,29 @@ const Parser = struct { |
| 3479 | 3468 | }), |
| 3480 | 3469 | }, |
| 3481 | 3470 | }); |
| 3482 | } else { | |
| 3483 | _ = try p.expectToken(.r_bracket); | |
| 3471 | } | |
| 3472 | _ = try p.expectToken(.r_bracket); | |
| 3473 | if (end_expr == 0) { | |
| 3484 | 3474 | return p.addNode(.{ |
| 3485 | .tag = .slice, | |
| 3475 | .tag = .slice_open, | |
| 3486 | 3476 | .main_token = lbracket, |
| 3487 | 3477 | .data = .{ |
| 3488 | 3478 | .lhs = lhs, |
| 3489 | .rhs = try p.addExtra(Node.Slice{ | |
| 3490 | .start = index_expr, | |
| 3491 | .end = end_expr, | |
| 3492 | }), | |
| 3479 | .rhs = index_expr, | |
| 3493 | 3480 | }, |
| 3494 | 3481 | }); |
| 3495 | 3482 | } |
| 3483 | return p.addNode(.{ | |
| 3484 | .tag = .slice, | |
| 3485 | .main_token = lbracket, | |
| 3486 | .data = .{ | |
| 3487 | .lhs = lhs, | |
| 3488 | .rhs = try p.addExtra(Node.Slice{ | |
| 3489 | .start = index_expr, | |
| 3490 | .end = end_expr, | |
| 3491 | }), | |
| 3492 | }, | |
| 3493 | }); | |
| 3496 | 3494 | } |
| 3497 | 3495 | _ = try p.expectToken(.r_bracket); |
| 3498 | 3496 | return p.addNode(.{ |
lib/std/zig/parser_test.zig+2| ... | ... | @@ -852,6 +852,7 @@ test "zig fmt: slices" { |
| 852 | 852 | try testCanonical( |
| 853 | 853 | \\const a = b[0..]; |
| 854 | 854 | \\const c = d[0..1]; |
| 855 | \\const d = f[0.. :0]; | |
| 855 | 856 | \\const e = f[0..1 :0]; |
| 856 | 857 | \\ |
| 857 | 858 | ); |
| ... | ... | @@ -861,6 +862,7 @@ test "zig fmt: slices with spaces in bounds" { |
| 861 | 862 | try testCanonical( |
| 862 | 863 | \\const a = b[0 + 0 ..]; |
| 863 | 864 | \\const c = d[0 + 0 .. 1]; |
| 865 | \\const c = d[0 + 0 .. :0]; | |
| 864 | 866 | \\const e = f[0 .. 1 + 1 :0]; |
| 865 | 867 | \\ |
| 866 | 868 | ); |
lib/std/zig/render.zig+15-14| ... | ... | @@ -470,9 +470,9 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I |
| 470 | 470 | return renderToken(ais, tree, rbracket, space); // ] |
| 471 | 471 | }, |
| 472 | 472 | |
| 473 | .slice_open => return renderSlice(gpa, ais, tree, tree.sliceOpen(node), space), | |
| 474 | .slice => return renderSlice(gpa, ais, tree, tree.slice(node), space), | |
| 475 | .slice_sentinel => return renderSlice(gpa, ais, tree, tree.sliceSentinel(node), space), | |
| 473 | .slice_open => return renderSlice(gpa, ais, tree, node, tree.sliceOpen(node), space), | |
| 474 | .slice => return renderSlice(gpa, ais, tree, node, tree.slice(node), space), | |
| 475 | .slice_sentinel => return renderSlice(gpa, ais, tree, node, tree.sliceSentinel(node), space), | |
| 476 | 476 | |
| 477 | 477 | .deref => { |
| 478 | 478 | try renderExpression(gpa, ais, tree, datas[node].lhs, .none); |
| ... | ... | @@ -815,6 +815,7 @@ fn renderSlice( |
| 815 | 815 | gpa: *Allocator, |
| 816 | 816 | ais: *Ais, |
| 817 | 817 | tree: ast.Tree, |
| 818 | slice_node: ast.Node.Index, | |
| 818 | 819 | slice: ast.full.Slice, |
| 819 | 820 | space: Space, |
| 820 | 821 | ) Error!void { |
| ... | ... | @@ -822,7 +823,9 @@ fn renderSlice( |
| 822 | 823 | const after_start_space_bool = nodeCausesSliceOpSpace(node_tags[slice.ast.start]) or |
| 823 | 824 | if (slice.ast.end != 0) nodeCausesSliceOpSpace(node_tags[slice.ast.end]) else false; |
| 824 | 825 | const after_start_space = if (after_start_space_bool) Space.space else Space.none; |
| 825 | const after_dots_space = if (slice.ast.end != 0) after_start_space else Space.none; | |
| 826 | const after_dots_space = if (slice.ast.end != 0) | |
| 827 | after_start_space | |
| 828 | else if (slice.ast.sentinel != 0) Space.space else Space.none; | |
| 826 | 829 | |
| 827 | 830 | try renderExpression(gpa, ais, tree, slice.ast.sliced, .none); |
| 828 | 831 | try renderToken(ais, tree, slice.ast.lbracket, .none); // lbracket |
| ... | ... | @@ -830,20 +833,18 @@ fn renderSlice( |
| 830 | 833 | const start_last = tree.lastToken(slice.ast.start); |
| 831 | 834 | try renderExpression(gpa, ais, tree, slice.ast.start, after_start_space); |
| 832 | 835 | try renderToken(ais, tree, start_last + 1, after_dots_space); // ellipsis2 ("..") |
| 833 | if (slice.ast.end == 0) { | |
| 834 | return renderToken(ais, tree, start_last + 2, space); // rbracket | |
| 836 | ||
| 837 | if (slice.ast.end != 0) { | |
| 838 | const after_end_space = if (slice.ast.sentinel != 0) Space.space else Space.none; | |
| 839 | try renderExpression(gpa, ais, tree, slice.ast.end, after_end_space); | |
| 835 | 840 | } |
| 836 | 841 | |
| 837 | const end_last = tree.lastToken(slice.ast.end); | |
| 838 | const after_end_space = if (slice.ast.sentinel != 0) Space.space else Space.none; | |
| 839 | try renderExpression(gpa, ais, tree, slice.ast.end, after_end_space); | |
| 840 | if (slice.ast.sentinel == 0) { | |
| 841 | return renderToken(ais, tree, end_last + 1, space); // rbracket | |
| 842 | if (slice.ast.sentinel != 0) { | |
| 843 | try renderToken(ais, tree, tree.firstToken(slice.ast.sentinel) - 1, .none); // colon | |
| 844 | try renderExpression(gpa, ais, tree, slice.ast.sentinel, .none); | |
| 842 | 845 | } |
| 843 | 846 | |
| 844 | try renderToken(ais, tree, end_last + 1, .none); // colon | |
| 845 | try renderExpression(gpa, ais, tree, slice.ast.sentinel, .none); | |
| 846 | try renderToken(ais, tree, tree.lastToken(slice.ast.sentinel) + 1, space); // rbracket | |
| 847 | try renderToken(ais, tree, tree.lastToken(slice_node), space); // rbracket | |
| 847 | 848 | } |
| 848 | 849 | |
| 849 | 850 | fn renderAsmOutput( |
src/astgen.zig+3-1| ... | ... | @@ -848,7 +848,9 @@ pub fn blockExpr( |
| 848 | 848 | const token_tags = tree.tokens.items(.tag); |
| 849 | 849 | |
| 850 | 850 | const lbrace = main_tokens[block_node]; |
| 851 | if (token_tags[lbrace - 1] == .colon) { | |
| 851 | if (token_tags[lbrace - 1] == .colon and | |
| 852 | token_tags[lbrace - 2] == .identifier) | |
| 853 | { | |
| 852 | 854 | return labeledBlockExpr(mod, scope, rl, block_node, statements, .block); |
| 853 | 855 | } |
| 854 | 856 |