diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-02-13 12:34:41 +0200 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-02-13 13:45:35 +0200 |
| commit | ddd6de86f7eb71814d3605d3e0ea9ed01d075613 (patch) | |
| tree | 4d6373402a99ed70eba6aa66dbcc3624036dbe30 /lib/std | |
| parent | 0b7347fd18eee7dd829cd9aaed3683123d84859b (diff) | |
| download | zig-ddd6de86f7eb71814d3605d3e0ea9ed01d075613.tar.gz zig-ddd6de86f7eb71814d3605d3e0ea9ed01d075613.zip | |
parser: make missing semicolon error point to the end of the previous token
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/zig/Ast.zig | 22 | ||||
| -rw-r--r-- | lib/std/zig/parse.zig | 19 |
2 files changed, 36 insertions, 5 deletions
diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig index 17da4f5315..16430fe9d4 100644 --- a/lib/std/zig/Ast.zig +++ b/lib/std/zig/Ast.zig @@ -64,6 +64,17 @@ pub fn renderToArrayList(tree: Ast, buffer: *std.ArrayList(u8)) RenderError!void return @import("./render.zig").renderTree(buffer, tree); } +/// Returns an extra offset for column and byte offset of errors that +/// should point after the token in the error message. +pub fn errorOffset(tree:Ast, error_tag: Error.Tag, token: TokenIndex) u32 { + return switch (error_tag) { + .expected_semi_after_decl, + .expected_semi_after_stmt, + => @intCast(u32, tree.tokenSlice(token).len), + else => 0, + }; +} + pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenIndex) Location { var loc = Location{ .line = 0, @@ -306,6 +317,13 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { return stream.writeAll("function prototype has parameter after varargs"); }, + .expected_semi_after_decl => { + return stream.writeAll("expected ';' after declaration"); + }, + .expected_semi_after_stmt => { + return stream.writeAll("expected ';' after statement"); + }, + .expected_token => { const found_tag = token_tags[parse_error.token]; const expected_symbol = parse_error.extra.expected_tag.symbol(); @@ -2495,6 +2513,10 @@ pub const Error = struct { unattached_doc_comment, varargs_nonfinal, + // these have `token` set to token after which a semicolon was expected + expected_semi_after_decl, + expected_semi_after_stmt, + /// `expected_tag` is populated. expected_token, }; diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index a70d0309e3..e818046ac5 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -586,7 +586,7 @@ const Parser = struct { const thread_local_token = p.eatToken(.keyword_threadlocal); const var_decl = try p.parseVarDecl(); if (var_decl != 0) { - _ = try p.expectToken(.semicolon); + try p.expectSemicolon(.expected_semi_after_decl, false); return var_decl; } if (thread_local_token != null) { @@ -614,7 +614,7 @@ const Parser = struct { fn expectUsingNamespace(p: *Parser) !Node.Index { const usingnamespace_token = p.assertToken(.keyword_usingnamespace); const expr = try p.expectExpr(); - _ = try p.expectToken(.semicolon); + try p.expectSemicolon(.expected_semi_after_decl, false); return p.addNode(.{ .tag = .@"usingnamespace", .main_token = usingnamespace_token, @@ -851,7 +851,7 @@ const Parser = struct { const var_decl = try p.parseVarDecl(); if (var_decl != 0) { - _ = try p.expectTokenRecoverable(.semicolon); + try p.expectSemicolon(.expected_semi_after_decl, true); return var_decl; } @@ -915,7 +915,7 @@ const Parser = struct { const assign_expr = try p.parseAssignExpr(); if (assign_expr != 0) { - _ = try p.expectTokenRecoverable(.semicolon); + try p.expectSemicolon(.expected_semi_after_stmt, true); return assign_expr; } @@ -1205,7 +1205,7 @@ const Parser = struct { } const assign_expr = try p.parseAssignExpr(); if (assign_expr != 0) { - _ = try p.expectTokenRecoverable(.semicolon); + try p.expectSemicolon(.expected_semi_after_stmt, true); return assign_expr; } return null_node; @@ -3664,6 +3664,15 @@ const Parser = struct { } } + fn expectSemicolon(p: *Parser, tag: AstError.Tag, recoverable: bool) Error!void { + if (p.token_tags[p.tok_i] == .semicolon) { + _ = p.nextToken(); + return; + } + try p.warnMsg(.{ .tag = tag, .token = p.tok_i - 1 }); + if (!recoverable) return error.ParseError; + } + fn nextToken(p: *Parser) TokenIndex { const result = p.tok_i; p.tok_i += 1; |
