authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-22 10:04:05+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-22 10:04:05+02:00
log67dac2936cb1fc2ce1d3ea00a5c8e574921aded3
tree5b24fa50a184ef3ef4d6ae8f53c76eec4b1282ca
parent621ad241d6dfbde60ee8a5b1d0dcd7d9cf29f8f3
signaturelock-open Commit is signed but in an unrecognized format.

parser: warn on missing for loop payload, recover from invalid global error set access


3 files changed, 54 insertions(+), 12 deletions(-)

lib/std/zig/ast.zig+6
...@@ -253,6 +253,11 @@ pub const Tree = struct {...@@ -253,6 +253,11 @@ pub const Tree = struct {
253 token_tags[parse_error.token].symbol(),253 token_tags[parse_error.token].symbol(),
254 });254 });
255 },255 },
256 .expected_loop_payload => {
257 return stream.print("expected loop payload, found '{s}'", .{
258 token_tags[parse_error.token].symbol(),
259 });
260 },
256 .extra_align_qualifier => {261 .extra_align_qualifier => {
257 return stream.writeAll("extra align qualifier");262 return stream.writeAll("extra align qualifier");
258 },263 },
...@@ -2332,6 +2337,7 @@ pub const Error = struct {...@@ -2332,6 +2337,7 @@ pub const Error = struct {
2332 expected_type_expr,2337 expected_type_expr,
2333 expected_var_decl,2338 expected_var_decl,
2334 expected_var_decl_or_fn,2339 expected_var_decl_or_fn,
2340 expected_loop_payload,
2335 extra_align_qualifier,2341 extra_align_qualifier,
2336 extra_allowzero_qualifier,2342 extra_allowzero_qualifier,
2337 extra_const_qualifier,2343 extra_const_qualifier,
lib/std/zig/parse.zig+32-12
...@@ -1052,7 +1052,8 @@ const Parser = struct {...@@ -1052,7 +1052,8 @@ const Parser = struct {
1052 _ = try p.expectToken(.l_paren);1052 _ = try p.expectToken(.l_paren);
1053 const array_expr = try p.expectExpr();1053 const array_expr = try p.expectExpr();
1054 _ = try p.expectToken(.r_paren);1054 _ = try p.expectToken(.r_paren);
1055 _ = try p.parsePtrIndexPayload();1055 const found_payload = try p.parsePtrIndexPayload();
1056 if (found_payload == 0) try p.warn(.expected_loop_payload);
10561057
1057 // TODO propose to change the syntax so that semicolons are always required1058 // TODO propose to change the syntax so that semicolons are always required
1058 // inside while statements, even if there is an `else`.1059 // inside while statements, even if there is an `else`.
...@@ -2067,7 +2068,8 @@ const Parser = struct {...@@ -2067,7 +2068,8 @@ const Parser = struct {
2067 _ = try p.expectToken(.l_paren);2068 _ = try p.expectToken(.l_paren);
2068 const array_expr = try p.expectExpr();2069 const array_expr = try p.expectExpr();
2069 _ = try p.expectToken(.r_paren);2070 _ = try p.expectToken(.r_paren);
2070 _ = try p.parsePtrIndexPayload();2071 const found_payload = try p.parsePtrIndexPayload();
2072 if (found_payload == 0) try p.warn(.expected_loop_payload);
20712073
2072 const then_expr = try p.expectExpr();2074 const then_expr = try p.expectExpr();
2073 const else_token = p.eatToken(.keyword_else) orelse {2075 const else_token = p.eatToken(.keyword_else) orelse {
...@@ -2672,6 +2674,16 @@ const Parser = struct {...@@ -2672,6 +2674,16 @@ const Parser = struct {
2672 },2674 },
2673 }),2675 }),
2674 },2676 },
2677 .keyword_inline => {
2678 p.tok_i += 1;
2679 switch (p.token_tags[p.tok_i]) {
2680 .keyword_for => return p.parseForTypeExpr(),
2681 .keyword_while => return p.parseWhileTypeExpr(),
2682 else => return p.fail(.expected_inlinable),
2683 }
2684 },
2685 .keyword_for => return p.parseForTypeExpr(),
2686 .keyword_while => return p.parseWhileTypeExpr(),
2675 .period => switch (p.token_tags[p.tok_i + 1]) {2687 .period => switch (p.token_tags[p.tok_i + 1]) {
2676 .identifier => return p.addNode(.{2688 .identifier => return p.addNode(.{
2677 .tag = .enum_literal,2689 .tag = .enum_literal,
...@@ -2879,14 +2891,21 @@ const Parser = struct {...@@ -2879,14 +2891,21 @@ const Parser = struct {
2879 },2891 },
2880 });2892 });
2881 },2893 },
2882 else => return p.addNode(.{2894 else => {
2883 .tag = .error_value,2895 const main_token = p.nextToken();
2884 .main_token = p.nextToken(),2896 const period = p.eatToken(.period);
2885 .data = .{2897 if (period == null) try p.warnExpected(.period);
2886 .lhs = try p.expectToken(.period),2898 const identifier = p.eatToken(.identifier);
2887 .rhs = try p.expectToken(.identifier),2899 if (identifier == null) try p.warnExpected(.identifier);
2888 },2900 return p.addNode(.{
2889 }),2901 .tag = .error_value,
2902 .main_token = main_token,
2903 .data = .{
2904 .lhs = period orelse 0,
2905 .rhs = identifier orelse 0,
2906 },
2907 });
2908 },
2890 },2909 },
2891 .l_paren => return p.addNode(.{2910 .l_paren => return p.addNode(.{
2892 .tag = .grouped_expression,2911 .tag = .grouped_expression,
...@@ -2913,9 +2932,10 @@ const Parser = struct {...@@ -2913,9 +2932,10 @@ const Parser = struct {
2913 fn parseForTypeExpr(p: *Parser) !Node.Index {2932 fn parseForTypeExpr(p: *Parser) !Node.Index {
2914 const for_token = p.eatToken(.keyword_for) orelse return null_node;2933 const for_token = p.eatToken(.keyword_for) orelse return null_node;
2915 _ = try p.expectToken(.l_paren);2934 _ = try p.expectToken(.l_paren);
2916 const array_expr = try p.expectTypeExpr();2935 const array_expr = try p.expectExpr();
2917 _ = try p.expectToken(.r_paren);2936 _ = try p.expectToken(.r_paren);
2918 _ = try p.parsePtrIndexPayload();2937 const found_payload = try p.parsePtrIndexPayload();
2938 if (found_payload == 0) try p.warn(.expected_loop_payload);
29192939
2920 const then_expr = try p.expectExpr();2940 const then_expr = try p.expectExpr();
2921 const else_token = p.eatToken(.keyword_else) orelse {2941 const else_token = p.eatToken(.keyword_else) orelse {
lib/std/zig/parser_test.zig+16
...@@ -4215,6 +4215,8 @@ test "recovery: invalid global error set access" {...@@ -4215,6 +4215,8 @@ test "recovery: invalid global error set access" {
4215 \\}4215 \\}
4216 , &[_]Error{4216 , &[_]Error{
4217 .expected_token,4217 .expected_token,
4218 .expected_token,
4219 .invalid_and,
4218 });4220 });
4219}4221}
42204222
...@@ -4273,6 +4275,20 @@ test "recovery: missing block after for/while loops" {...@@ -4273,6 +4275,20 @@ test "recovery: missing block after for/while loops" {
4273 });4275 });
4274}4276}
42754277
4278test "recovery: missing for payload" {
4279 try testError(
4280 \\comptime {
4281 \\ const a = for(a) {};
4282 \\ const a: for(a) {};
4283 \\ for(a) {}
4284 \\}
4285 , &[_]Error{
4286 .expected_loop_payload,
4287 .expected_loop_payload,
4288 .expected_loop_payload,
4289 });
4290}
4291
4276const std = @import("std");4292const std = @import("std");
4277const mem = std.mem;4293const mem = std.mem;
4278const warn = std.debug.warn;4294const warn = std.debug.warn;