diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-02-19 18:04:52 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-02-19 18:04:52 -0700 |
| commit | 8fee41b1d528d598521525574206e200fd332c67 (patch) | |
| tree | 2c5ad20494b34a9391474d06a7d1e97b6732612d | |
| parent | 74878565e5112fed04336089ed769443e08e605b (diff) | |
| download | zig-8fee41b1d528d598521525574206e200fd332c67.tar.gz zig-8fee41b1d528d598521525574206e200fd332c67.zip | |
stage2: AST: clean up parse errors
* struct instead of tagged union
* delete dead code
* simplify parser code
* remove unnecessary metaprogramming
| -rw-r--r-- | lib/std/zig/ast.zig | 529 | ||||
| -rw-r--r-- | lib/std/zig/parse.zig | 338 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 127 | ||||
| -rw-r--r-- | src/Module.zig | 2 | ||||
| -rw-r--r-- | src/main.zig | 2 |
5 files changed, 390 insertions, 608 deletions
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index 2042f07cf6..fda2916af4 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -132,113 +132,160 @@ pub const Tree = struct { } pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void { - const tokens = tree.tokens.items(.tag); - switch (parse_error) { - .InvalidToken => |*x| return x.render(tokens, stream), - .ExpectedContainerMembers => |*x| return x.render(tokens, stream), - .ExpectedStringLiteral => |*x| return x.render(tokens, stream), - .ExpectedIntegerLiteral => |*x| return x.render(tokens, stream), - .ExpectedPubItem => |*x| return x.render(tokens, stream), - .ExpectedIdentifier => |*x| return x.render(tokens, stream), - .ExpectedStatement => |*x| return x.render(tokens, stream), - .ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream), - .ExpectedVarDecl => |*x| return x.render(tokens, stream), - .ExpectedFn => |*x| return x.render(tokens, stream), - .ExpectedReturnType => |*x| return x.render(tokens, stream), - .ExpectedAggregateKw => |*x| return x.render(tokens, stream), - .SameLineDocComment => |*x| return x.render(tokens, stream), - .UnattachedDocComment => |*x| return x.render(tokens, stream), - .ExpectedEqOrSemi => |*x| return x.render(tokens, stream), - .ExpectedSemiOrLBrace => |*x| return x.render(tokens, stream), - .ExpectedSemiOrElse => |*x| return x.render(tokens, stream), - .ExpectedLabelOrLBrace => |*x| return x.render(tokens, stream), - .ExpectedLBrace => |*x| return x.render(tokens, stream), - .ExpectedColonOrRParen => |*x| return x.render(tokens, stream), - .ExpectedLabelable => |*x| return x.render(tokens, stream), - .ExpectedInlinable => |*x| return x.render(tokens, stream), - .ExpectedAsmOutputReturnOrType => |*x| return x.render(tokens, stream), - .ExpectedCall => |x| return x.render(tree, stream), - .ExpectedCallOrFnProto => |x| return x.render(tree, stream), - .ExpectedSliceOrRBracket => |*x| return x.render(tokens, stream), - .ExtraAlignQualifier => |*x| return x.render(tokens, stream), - .ExtraConstQualifier => |*x| return x.render(tokens, stream), - .ExtraVolatileQualifier => |*x| return x.render(tokens, stream), - .ExtraAllowZeroQualifier => |*x| return x.render(tokens, stream), - .ExpectedTypeExpr => |*x| return x.render(tokens, stream), - .ExpectedPrimaryTypeExpr => |*x| return x.render(tokens, stream), - .ExpectedParamType => |*x| return x.render(tokens, stream), - .ExpectedExpr => |*x| return x.render(tokens, stream), - .ExpectedPrimaryExpr => |*x| return x.render(tokens, stream), - .ExpectedToken => |*x| return x.render(tokens, stream), - .ExpectedCommaOrEnd => |*x| return x.render(tokens, stream), - .ExpectedParamList => |*x| return x.render(tokens, stream), - .ExpectedPayload => |*x| return x.render(tokens, stream), - .ExpectedBlockOrAssignment => |*x| return x.render(tokens, stream), - .ExpectedBlockOrExpression => |*x| return x.render(tokens, stream), - .ExpectedExprOrAssignment => |*x| return x.render(tokens, stream), - .ExpectedPrefixExpr => |*x| return x.render(tokens, stream), - .ExpectedLoopExpr => |*x| return x.render(tokens, stream), - .ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream), - .ExpectedSuffixOp => |*x| return x.render(tokens, stream), - .ExpectedBlockOrField => |*x| return x.render(tokens, stream), - .DeclBetweenFields => |*x| return x.render(tokens, stream), - .InvalidAnd => |*x| return x.render(tokens, stream), - .AsteriskAfterPointerDereference => |*x| return x.render(tokens, stream), - } - } + const token_tags = tree.tokens.items(.tag); + switch (parse_error.tag) { + .asterisk_after_ptr_deref => { + return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?"); + }, + .decl_between_fields => { + return stream.writeAll("declarations are not allowed between container fields"); + }, + .expected_block => { + return stream.print("expected block or field, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_block_or_assignment => { + return stream.print("expected block or assignment, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_block_or_expr => { + return stream.print("expected block or expression, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_block_or_field => { + return stream.print("expected block or field, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_container_members => { + return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_expr => { + return stream.print("expected expression, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_expr_or_assignment => { + return stream.print("expected expression or assignment, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_fn => { + return stream.print("expected function, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_inlinable => { + return stream.print("expected 'while' or 'for', found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_labelable => { + return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_param_list => { + return stream.print("expected parameter list, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_prefix_expr => { + return stream.print("expected prefix expression, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_primary_type_expr => { + return stream.print("expected primary type expression, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_return_type => { + return stream.print("expected return type expression, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_semi_or_else => { + return stream.print("expected ';' or 'else', found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_semi_or_lbrace => { + return stream.print("expected ';' or '{{', found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_statement => { + return stream.print("expected statement, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_string_literal => { + return stream.print("expected string literal, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_suffix_op => { + return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_type_expr => { + return stream.print("expected type expression, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_var_decl => { + return stream.print("expected variable declaration, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .expected_var_decl_or_fn => { + return stream.print("expected variable declaration or function, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .extra_align_qualifier => { + return stream.writeAll("extra align qualifier"); + }, + .extra_allowzero_qualifier => { + return stream.writeAll("extra allowzero qualifier"); + }, + .extra_const_qualifier => { + return stream.writeAll("extra const qualifier"); + }, + .extra_volatile_qualifier => { + return stream.writeAll("extra volatile qualifier"); + }, + .invalid_token => { + return stream.print("invalid token '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, + .same_line_doc_comment => { + return stream.writeAll("same line documentation comment"); + }, + .unattached_doc_comment => { + return stream.writeAll("unattached documentation comment"); + }, - pub fn errorToken(tree: Tree, parse_error: Error) TokenIndex { - switch (parse_error) { - .InvalidToken => |x| return x.token, - .ExpectedContainerMembers => |x| return x.token, - .ExpectedStringLiteral => |x| return x.token, - .ExpectedIntegerLiteral => |x| return x.token, - .ExpectedPubItem => |x| return x.token, - .ExpectedIdentifier => |x| return x.token, - .ExpectedStatement => |x| return x.token, - .ExpectedVarDeclOrFn => |x| return x.token, - .ExpectedVarDecl => |x| return x.token, - .ExpectedFn => |x| return x.token, - .ExpectedReturnType => |x| return x.token, - .ExpectedAggregateKw => |x| return x.token, - .SameLineDocComment => |x| return x.token, - .UnattachedDocComment => |x| return x.token, - .ExpectedEqOrSemi => |x| return x.token, - .ExpectedSemiOrLBrace => |x| return x.token, - .ExpectedSemiOrElse => |x| return x.token, - .ExpectedLabelOrLBrace => |x| return x.token, - .ExpectedLBrace => |x| return x.token, - .ExpectedColonOrRParen => |x| return x.token, - .ExpectedLabelable => |x| return x.token, - .ExpectedInlinable => |x| return x.token, - .ExpectedAsmOutputReturnOrType => |x| return x.token, - .ExpectedCall => |x| return tree.nodes.items(.main_token)[x.node], - .ExpectedCallOrFnProto => |x| return tree.nodes.items(.main_token)[x.node], - .ExpectedSliceOrRBracket => |x| return x.token, - .ExtraAlignQualifier => |x| return x.token, - .ExtraConstQualifier => |x| return x.token, - .ExtraVolatileQualifier => |x| return x.token, - .ExtraAllowZeroQualifier => |x| return x.token, - .ExpectedTypeExpr => |x| return x.token, - .ExpectedPrimaryTypeExpr => |x| return x.token, - .ExpectedParamType => |x| return x.token, - .ExpectedExpr => |x| return x.token, - .ExpectedPrimaryExpr => |x| return x.token, - .ExpectedToken => |x| return x.token, - .ExpectedCommaOrEnd => |x| return x.token, - .ExpectedParamList => |x| return x.token, - .ExpectedPayload => |x| return x.token, - .ExpectedBlockOrAssignment => |x| return x.token, - .ExpectedBlockOrExpression => |x| return x.token, - .ExpectedExprOrAssignment => |x| return x.token, - .ExpectedPrefixExpr => |x| return x.token, - .ExpectedLoopExpr => |x| return x.token, - .ExpectedDerefOrUnwrap => |x| return x.token, - .ExpectedSuffixOp => |x| return x.token, - .ExpectedBlockOrField => |x| return x.token, - .DeclBetweenFields => |x| return x.token, - .InvalidAnd => |x| return x.token, - .AsteriskAfterPointerDereference => |x| return x.token, + .expected_token => { + const found_tag = token_tags[parse_error.token]; + const expected_symbol = parse_error.extra.expected_tag.symbol(); + switch (found_tag) { + .invalid => return stream.print("expected '{s}', found invalid bytes", .{ + expected_symbol, + }), + else => return stream.print("expected '{s}', found '{s}'", .{ + expected_symbol, found_tag.symbol(), + }), + } + }, } } @@ -2239,236 +2286,50 @@ pub const full = struct { }; }; -pub const Error = union(enum) { - InvalidToken: InvalidToken, - ExpectedContainerMembers: ExpectedContainerMembers, - ExpectedStringLiteral: ExpectedStringLiteral, - ExpectedIntegerLiteral: ExpectedIntegerLiteral, - ExpectedPubItem: ExpectedPubItem, - ExpectedIdentifier: ExpectedIdentifier, - ExpectedStatement: ExpectedStatement, - ExpectedVarDeclOrFn: ExpectedVarDeclOrFn, - ExpectedVarDecl: ExpectedVarDecl, - ExpectedFn: ExpectedFn, - ExpectedReturnType: ExpectedReturnType, - ExpectedAggregateKw: ExpectedAggregateKw, - SameLineDocComment: SameLineDocComment, - UnattachedDocComment: UnattachedDocComment, - ExpectedEqOrSemi: ExpectedEqOrSemi, - ExpectedSemiOrLBrace: ExpectedSemiOrLBrace, - ExpectedSemiOrElse: ExpectedSemiOrElse, - ExpectedLabelOrLBrace: ExpectedLabelOrLBrace, - ExpectedLBrace: ExpectedLBrace, - ExpectedColonOrRParen: ExpectedColonOrRParen, - ExpectedLabelable: ExpectedLabelable, - ExpectedInlinable: ExpectedInlinable, - ExpectedAsmOutputReturnOrType: ExpectedAsmOutputReturnOrType, - ExpectedCall: ExpectedCall, - ExpectedCallOrFnProto: ExpectedCallOrFnProto, - ExpectedSliceOrRBracket: ExpectedSliceOrRBracket, - ExtraAlignQualifier: ExtraAlignQualifier, - ExtraConstQualifier: ExtraConstQualifier, - ExtraVolatileQualifier: ExtraVolatileQualifier, - ExtraAllowZeroQualifier: ExtraAllowZeroQualifier, - ExpectedTypeExpr: ExpectedTypeExpr, - ExpectedPrimaryTypeExpr: ExpectedPrimaryTypeExpr, - ExpectedParamType: ExpectedParamType, - ExpectedExpr: ExpectedExpr, - ExpectedPrimaryExpr: ExpectedPrimaryExpr, - ExpectedToken: ExpectedToken, - ExpectedCommaOrEnd: ExpectedCommaOrEnd, - ExpectedParamList: ExpectedParamList, - ExpectedPayload: ExpectedPayload, - ExpectedBlockOrAssignment: ExpectedBlockOrAssignment, - ExpectedBlockOrExpression: ExpectedBlockOrExpression, - ExpectedExprOrAssignment: ExpectedExprOrAssignment, - ExpectedPrefixExpr: ExpectedPrefixExpr, - ExpectedLoopExpr: ExpectedLoopExpr, - ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap, - ExpectedSuffixOp: ExpectedSuffixOp, - ExpectedBlockOrField: ExpectedBlockOrField, - DeclBetweenFields: DeclBetweenFields, - InvalidAnd: InvalidAnd, - AsteriskAfterPointerDereference: AsteriskAfterPointerDereference, - - pub const InvalidToken = SingleTokenError("Invalid token '{s}'"); - pub const ExpectedContainerMembers = SingleTokenError("Expected test, comptime, var decl, or container field, found '{s}'"); - pub const ExpectedStringLiteral = SingleTokenError("Expected string literal, found '{s}'"); - pub const ExpectedIntegerLiteral = SingleTokenError("Expected integer literal, found '{s}'"); - pub const ExpectedIdentifier = SingleTokenError("Expected identifier, found '{s}'"); - pub const ExpectedStatement = SingleTokenError("Expected statement, found '{s}'"); - pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{s}'"); - pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{s}'"); - pub const ExpectedFn = SingleTokenError("Expected function, found '{s}'"); - pub const ExpectedReturnType = SingleTokenError("Expected return type expression, found '{s}'"); - pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Tag.keyword_struct.symbol() ++ "', '" ++ Token.Tag.keyword_union.symbol() ++ "', '" ++ Token.Tag.keyword_enum.symbol() ++ "', or '" ++ Token.Tag.keyword_opaque.symbol() ++ "', found '{s}'"); - pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{s}'"); - pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found '{s}'"); - pub const ExpectedSemiOrElse = SingleTokenError("Expected ';' or 'else', found '{s}'"); - pub const ExpectedLBrace = SingleTokenError("Expected '{{', found '{s}'"); - pub const ExpectedLabelOrLBrace = SingleTokenError("Expected label or '{{', found '{s}'"); - pub const ExpectedColonOrRParen = SingleTokenError("Expected ':' or ')', found '{s}'"); - pub const ExpectedLabelable = SingleTokenError("Expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'"); - pub const ExpectedInlinable = SingleTokenError("Expected 'while' or 'for', found '{s}'"); - pub const ExpectedAsmOutputReturnOrType = SingleTokenError("Expected '->' or '" ++ Token.Tag.identifier.symbol() ++ "', found '{s}'"); - pub const ExpectedSliceOrRBracket = SingleTokenError("Expected ']' or '..', found '{s}'"); - pub const ExpectedTypeExpr = SingleTokenError("Expected type expression, found '{s}'"); - pub const ExpectedPrimaryTypeExpr = SingleTokenError("Expected primary type expression, found '{s}'"); - pub const ExpectedExpr = SingleTokenError("Expected expression, found '{s}'"); - pub const ExpectedPrimaryExpr = SingleTokenError("Expected primary expression, found '{s}'"); - pub const ExpectedParamList = SingleTokenError("Expected parameter list, found '{s}'"); - pub const ExpectedPayload = SingleTokenError("Expected loop payload, found '{s}'"); - pub const ExpectedBlockOrAssignment = SingleTokenError("Expected block or assignment, found '{s}'"); - pub const ExpectedBlockOrExpression = SingleTokenError("Expected block or expression, found '{s}'"); - pub const ExpectedExprOrAssignment = SingleTokenError("Expected expression or assignment, found '{s}'"); - pub const ExpectedPrefixExpr = SingleTokenError("Expected prefix expression, found '{s}'"); - pub const ExpectedLoopExpr = SingleTokenError("Expected loop expression, found '{s}'"); - pub const ExpectedDerefOrUnwrap = SingleTokenError("Expected pointer dereference or optional unwrap, found '{s}'"); - pub const ExpectedSuffixOp = SingleTokenError("Expected pointer dereference, optional unwrap, or field access, found '{s}'"); - pub const ExpectedBlockOrField = SingleTokenError("Expected block or field, found '{s}'"); - - pub const ExpectedParamType = SimpleError("Expected parameter type"); - pub const ExpectedPubItem = SimpleError("Expected function or variable declaration after pub"); - pub const SameLineDocComment = SimpleError("Same line documentation comment"); - pub const UnattachedDocComment = SimpleError("Unattached documentation comment"); - pub const ExtraAlignQualifier = SimpleError("Extra align qualifier"); - pub const ExtraConstQualifier = SimpleError("Extra const qualifier"); - pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier"); - pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier"); - pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields"); - pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND."); - pub const AsteriskAfterPointerDereference = SimpleError("`.*` can't be followed by `*`. Are you missing a space?"); - - pub const ExpectedCall = struct { - node: Node.Index, - - pub fn render(self: ExpectedCall, tree: Tree, stream: anytype) !void { - const node_tag = tree.nodes.items(.tag)[self.node]; - return stream.print("expected " ++ @tagName(Node.Tag.call) ++ ", found {s}", .{ - @tagName(node_tag), - }); - } - }; - - pub const ExpectedCallOrFnProto = struct { - node: Node.Index, - - pub fn render(self: ExpectedCallOrFnProto, tree: Tree, stream: anytype) !void { - const node_tag = tree.nodes.items(.tag)[self.node]; - return stream.print("expected " ++ @tagName(Node.Tag.call) ++ " or " ++ - @tagName(Node.Tag.fn_proto) ++ ", found {s}", .{@tagName(node_tag)}); - } - }; - - pub const ExpectedToken = struct { - token: TokenIndex, - expected_id: Token.Tag, - - pub fn render(self: *const ExpectedToken, tokens: []const Token.Tag, stream: anytype) !void { - const found_token = tokens[self.token]; - switch (found_token) { - .invalid => { - return stream.print("expected '{s}', found invalid bytes", .{self.expected_id.symbol()}); - }, - else => { - const token_name = found_token.symbol(); - return stream.print("expected '{s}', found '{s}'", .{ self.expected_id.symbol(), token_name }); - }, - } - } - }; - - pub const ExpectedCommaOrEnd = struct { - token: TokenIndex, - end_id: Token.Tag, +pub const Error = struct { + tag: Tag, + token: TokenIndex, + extra: union { + none: void, + expected_tag: Token.Tag, + } = .{ .none = {} }, - pub fn render(self: *const ExpectedCommaOrEnd, tokens: []const Token.Tag, stream: anytype) !void { - const actual_token = tokens[self.token]; - return stream.print("expected ',' or '{s}', found '{s}'", .{ - self.end_id.symbol(), - actual_token.symbol(), - }); - } + pub const Tag = enum { + asterisk_after_ptr_deref, + decl_between_fields, + expected_block, + expected_block_or_assignment, + expected_block_or_expr, + expected_block_or_field, + expected_container_members, + expected_expr, + expected_expr_or_assignment, + expected_fn, + expected_inlinable, + expected_labelable, + expected_param_list, + expected_prefix_expr, + expected_primary_type_expr, + expected_return_type, + expected_semi_or_else, + expected_semi_or_lbrace, + expected_statement, + expected_string_literal, + expected_suffix_op, + expected_type_expr, + expected_var_decl, + expected_var_decl_or_fn, + extra_align_qualifier, + extra_allowzero_qualifier, + extra_const_qualifier, + extra_volatile_qualifier, + invalid_token, + same_line_doc_comment, + unattached_doc_comment, + + /// `expected_tag` is populated. + expected_token, }; - - fn SingleTokenError(comptime msg: []const u8) type { - return struct { - const ThisError = @This(); - - token: TokenIndex, - - pub fn render(self: *const ThisError, tokens: []const Token.Tag, stream: anytype) !void { - const actual_token = tokens[self.token]; - return stream.print(msg, .{actual_token.symbol()}); - } - }; - } - - fn SimpleError(comptime msg: []const u8) type { - return struct { - const ThisError = @This(); - - token: TokenIndex, - - pub fn render(self: *const ThisError, tokens: []const Token.Tag, stream: anytype) !void { - return stream.writeAll(msg); - } - }; - } - - pub fn loc(self: Error) TokenIndex { - switch (self) { - .InvalidToken => |x| return x.token, - .ExpectedContainerMembers => |x| return x.token, - .ExpectedStringLiteral => |x| return x.token, - .ExpectedIntegerLiteral => |x| return x.token, - .ExpectedPubItem => |x| return x.token, - .ExpectedIdentifier => |x| return x.token, - .ExpectedStatement => |x| return x.token, - .ExpectedVarDeclOrFn => |x| return x.token, - .ExpectedVarDecl => |x| return x.token, - .ExpectedFn => |x| return x.token, - .ExpectedReturnType => |x| return x.token, - .ExpectedAggregateKw => |x| return x.token, - .UnattachedDocComment => |x| return x.token, - .ExpectedEqOrSemi => |x| return x.token, - .ExpectedSemiOrLBrace => |x| return x.token, - .ExpectedSemiOrElse => |x| return x.token, - .ExpectedLabelOrLBrace => |x| return x.token, - .ExpectedLBrace => |x| return x.token, - .ExpectedColonOrRParen => |x| return x.token, - .ExpectedLabelable => |x| return x.token, - .ExpectedInlinable => |x| return x.token, - .ExpectedAsmOutputReturnOrType => |x| return x.token, - .ExpectedCall => |x| @panic("TODO redo ast errors"), - .ExpectedCallOrFnProto => |x| @panic("TODO redo ast errors"), - .ExpectedSliceOrRBracket => |x| return x.token, - .ExtraAlignQualifier => |x| return x.token, - .ExtraConstQualifier => |x| return x.token, - .ExtraVolatileQualifier => |x| return x.token, - .ExtraAllowZeroQualifier => |x| return x.token, - .ExpectedTypeExpr => |x| return x.token, - .ExpectedPrimaryTypeExpr => |x| return x.token, - .ExpectedParamType => |x| return x.token, - .ExpectedExpr => |x| return x.token, - .ExpectedPrimaryExpr => |x| return x.token, - .ExpectedToken => |x| return x.token, - .ExpectedCommaOrEnd => |x| return x.token, - .ExpectedParamList => |x| return x.token, - .ExpectedPayload => |x| return x.token, - .ExpectedBlockOrAssignment => |x| return x.token, - .ExpectedBlockOrExpression => |x| return x.token, - .ExpectedExprOrAssignment => |x| return x.token, - .ExpectedPrefixExpr => |x| return x.token, - .ExpectedLoopExpr => |x| return x.token, - .ExpectedDerefOrUnwrap => |x| return x.token, - .ExpectedSuffixOp => |x| return x.token, - .ExpectedBlockOrField => |x| return x.token, - .DeclBetweenFields => |x| return x.token, - .InvalidAnd => |x| return x.token, - .AsteriskAfterPointerDereference => |x| return x.token, - } - } }; pub const Node = struct { diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index f6545c0f13..a557b57ad4 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -150,14 +150,41 @@ const Parser = struct { return result; } - fn warn(p: *Parser, msg: ast.Error) error{OutOfMemory}!void { + fn warn(p: *Parser, tag: ast.Error.Tag) error{OutOfMemory}!void { + @setCold(true); + try p.warnMsg(.{ .tag = tag, .token = p.tok_i }); + } + + fn warnExpected(p: *Parser, expected_token: Token.Tag) error{OutOfMemory}!void { + @setCold(true); + try p.warnMsg(.{ + .tag = .expected_token, + .token = p.tok_i, + .extra = .{ .expected_tag = expected_token }, + }); + } + fn warnMsg(p: *Parser, msg: ast.Error) error{OutOfMemory}!void { @setCold(true); try p.errors.append(p.gpa, msg); } - fn fail(p: *Parser, msg: ast.Error) error{ ParseError, OutOfMemory } { + fn fail(p: *Parser, tag: ast.Error.Tag) error{ ParseError, OutOfMemory } { + @setCold(true); + return p.failMsg(.{ .tag = tag, .token = p.tok_i }); + } + + fn failExpected(p: *Parser, expected_token: Token.Tag) error{ ParseError, OutOfMemory } { @setCold(true); - try p.warn(msg); + return p.failMsg(.{ + .tag = .expected_token, + .token = p.tok_i, + .extra = .{ .expected_tag = expected_token }, + }); + } + + fn failMsg(p: *Parser, msg: ast.Error) error{ ParseError, OutOfMemory } { + @setCold(true); + try p.warnMsg(msg); return error.ParseError; } @@ -190,7 +217,7 @@ const Parser = struct { var trailing_comma = false; while (true) { - const doc_comment = try p.eatDocComments (); + const doc_comment = try p.eatDocComments(); switch (p.token_tags[p.tok_i]) { .keyword_test => { @@ -212,8 +239,9 @@ const Parser = struct { .none => field_state = .seen, .err, .seen => {}, .end => |node| { - try p.warn(.{ - .DeclBetweenFields = .{ .token = p.nodes.items(.main_token)[node] }, + try p.warnMsg(.{ + .tag = .decl_between_fields, + .token = p.nodes.items(.main_token)[node], }); // Continue parsing; error will be reported later. field_state = .err; @@ -234,9 +262,7 @@ const Parser = struct { } // There is not allowed to be a decl after a field with no comma. // Report error but recover parser. - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); p.findNextContainerMember(); } }, @@ -267,7 +293,7 @@ const Parser = struct { }, else => { p.tok_i += 1; - try p.warn(.{ .ExpectedBlockOrField = .{ .token = p.tok_i } }); + try p.warn(.expected_block_or_field); }, }, .keyword_pub => { @@ -316,8 +342,9 @@ const Parser = struct { .none => field_state = .seen, .err, .seen => {}, .end => |node| { - try p.warn(.{ - .DeclBetweenFields = .{ .token = p.nodes.items(.main_token)[node] }, + try p.warnMsg(.{ + .tag = .decl_between_fields, + .token = p.nodes.items(.main_token)[node], }); // Continue parsing; error will be reported later. field_state = .err; @@ -338,20 +365,21 @@ const Parser = struct { } // There is not allowed to be a decl after a field with no comma. // Report error but recover parser. - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); p.findNextContainerMember(); } }, .eof, .r_brace => { if (doc_comment) |tok| { - try p.warn(.{ .UnattachedDocComment = .{ .token = tok } }); + try p.warnMsg(.{ + .tag = .unattached_doc_comment, + .token = tok, + }); } break; }, else => { - try p.warn(.{ .ExpectedContainerMembers = .{ .token = p.tok_i } }); + try p.warn(.expected_container_members); // This was likely not supposed to end yet; try to find the next declaration. p.findNextContainerMember(); }, @@ -475,7 +503,7 @@ const Parser = struct { const test_token = p.assertToken(.keyword_test); const name_token = p.eatToken(.string_literal); const block_node = try p.parseBlock(); - if (block_node == 0) return p.fail(.{ .ExpectedLBrace = .{ .token = p.tok_i } }); + if (block_node == 0) return p.fail(.expected_block); return p.addNode(.{ .tag = .test_decl, .main_token = test_token, @@ -540,15 +568,13 @@ const Parser = struct { // Since parseBlock only return error.ParseError on // a missing '}' we can assume this function was // supposed to end here. - try p.warn(.{ .ExpectedSemiOrLBrace = .{ .token = p.tok_i } }); + try p.warn(.expected_semi_or_lbrace); return null_node; }, } } if (expect_fn) { - try p.warn(.{ - .ExpectedFn = .{ .token = p.tok_i }, - }); + try p.warn(.expected_fn); return error.ParseError; } @@ -559,11 +585,11 @@ const Parser = struct { return var_decl; } if (thread_local_token != null) { - return p.fail(.{ .ExpectedVarDecl = .{ .token = p.tok_i } }); + return p.fail(.expected_var_decl); } if (exported) { - return p.fail(.{ .ExpectedVarDeclOrFn = .{ .token = p.tok_i } }); + return p.fail(.expected_var_decl_or_fn); } return p.expectUsingNamespace(); @@ -618,7 +644,7 @@ const Parser = struct { if (return_type_expr == 0) { // most likely the user forgot to specify the return type. // Mark return type as invalid and try to continue. - try p.warn(.{ .ExpectedReturnType = .{ .token = p.tok_i } }); + try p.warn(.expected_return_type); } if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) { @@ -901,7 +927,7 @@ const Parser = struct { fn expectStatement(p: *Parser) !Node.Index { const statement = try p.parseStatement(); if (statement == 0) { - return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + return p.fail(.expected_statement); } return statement; } @@ -940,7 +966,7 @@ const Parser = struct { if (block_expr != 0) break :blk block_expr; const assign_expr = try p.parseAssignExpr(); if (assign_expr == 0) { - return p.fail(.{ .ExpectedBlockOrAssignment = .{ .token = p.tok_i } }); + return p.fail(.expected_block_or_assignment); } if (p.eatToken(.semicolon)) |_| { return p.addNode(.{ @@ -957,7 +983,7 @@ const Parser = struct { }; const else_token = p.eatToken(.keyword_else) orelse { if (else_required) { - return p.fail(.{ .ExpectedSemiOrElse = .{ .token = p.tok_i } }); + return p.fail(.expected_semi_or_else); } return p.addNode(.{ .tag = .if_simple, @@ -993,7 +1019,7 @@ const Parser = struct { if (loop_stmt != 0) return loop_stmt; if (label_token != 0) { - return p.fail(.{ .ExpectedLabelable = .{ .token = p.tok_i } }); + return p.fail(.expected_labelable); } return null_node; @@ -1012,7 +1038,7 @@ const Parser = struct { if (inline_token == null) return null_node; // If we've seen "inline", there should have been a "for" or "while" - return p.fail(.{ .ExpectedInlinable = .{ .token = p.tok_i } }); + return p.fail(.expected_inlinable); } /// ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload @@ -1034,7 +1060,7 @@ const Parser = struct { if (block_expr != 0) break :blk block_expr; const assign_expr = try p.parseAssignExpr(); if (assign_expr == 0) { - return p.fail(.{ .ExpectedBlockOrAssignment = .{ .token = p.tok_i } }); + return p.fail(.expected_block_or_assignment); } if (p.eatToken(.semicolon)) |_| { return p.addNode(.{ @@ -1051,7 +1077,7 @@ const Parser = struct { }; const else_token = p.eatToken(.keyword_else) orelse { if (else_required) { - return p.fail(.{ .ExpectedSemiOrElse = .{ .token = p.tok_i } }); + return p.fail(.expected_semi_or_else); } return p.addNode(.{ .tag = .for_simple, @@ -1095,7 +1121,7 @@ const Parser = struct { if (block_expr != 0) break :blk block_expr; const assign_expr = try p.parseAssignExpr(); if (assign_expr == 0) { - return p.fail(.{ .ExpectedBlockOrAssignment = .{ .token = p.tok_i } }); + return p.fail(.expected_block_or_assignment); } if (p.eatToken(.semicolon)) |_| { if (cont_expr == 0) { @@ -1126,7 +1152,7 @@ const Parser = struct { }; const else_token = p.eatToken(.keyword_else) orelse { if (else_required) { - return p.fail(.{ .ExpectedSemiOrElse = .{ .token = p.tok_i } }); + return p.fail(.expected_semi_or_else); } if (cont_expr == 0) { return p.addNode(.{ @@ -1186,7 +1212,7 @@ const Parser = struct { fn expectBlockExprStatement(p: *Parser) !Node.Index { const node = try p.parseBlockExprStatement(); if (node == 0) { - return p.fail(.{ .ExpectedBlockOrExpression = .{ .token = p.tok_i } }); + return p.fail(.expected_block_or_expr); } return node; } @@ -1259,7 +1285,7 @@ const Parser = struct { fn expectAssignExpr(p: *Parser) !Node.Index { const expr = try p.parseAssignExpr(); if (expr == 0) { - return p.fail(.{ .ExpectedExprOrAssignment = .{ .token = p.tok_i } }); + return p.fail(.expected_expr_or_assignment); } return expr; } @@ -1272,7 +1298,7 @@ const Parser = struct { fn expectExpr(p: *Parser) Error!Node.Index { const node = try p.parseExpr(); if (node == 0) { - return p.fail(.{ .ExpectedExpr = .{ .token = p.tok_i } }); + return p.fail(.expected_expr); } else { return node; } @@ -1289,7 +1315,7 @@ const Parser = struct { const or_token = p.nextToken(); const rhs = try p.parseBoolAndExpr(); if (rhs == 0) { - return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + return p.fail(.invalid_token); } res = try p.addNode(.{ .tag = .bool_or, @@ -1316,7 +1342,7 @@ const Parser = struct { const and_token = p.nextToken(); const rhs = try p.parseCompareExpr(); if (rhs == 0) { - return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + return p.fail(.invalid_token); } res = try p.addNode(.{ .tag = .bool_and, @@ -1385,7 +1411,7 @@ const Parser = struct { _ = try p.parsePayload(); const rhs = try p.parseBitShiftExpr(); if (rhs == 0) { - return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + return p.fail(.invalid_token); } res = try p.addNode(.{ .tag = .@"catch", @@ -1413,7 +1439,7 @@ const Parser = struct { fn expectBitwiseExpr(p: *Parser) Error!Node.Index { const node = try p.parseBitwiseExpr(); if (node == 0) { - return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + return p.fail(.invalid_token); } else { return node; } @@ -1447,7 +1473,7 @@ const Parser = struct { fn expectBitShiftExpr(p: *Parser) Error!Node.Index { const node = try p.parseBitShiftExpr(); if (node == 0) { - return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + return p.fail(.invalid_token); } else { return node; } @@ -1487,7 +1513,7 @@ const Parser = struct { fn expectAdditionExpr(p: *Parser) Error!Node.Index { const node = try p.parseAdditionExpr(); if (node == 0) { - return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + return p.fail(.invalid_token); } return node; } @@ -1528,7 +1554,7 @@ const Parser = struct { fn expectMultiplyExpr(p: *Parser) Error!Node.Index { const node = try p.parseMultiplyExpr(); if (node == 0) { - return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + return p.fail(.invalid_token); } return node; } @@ -1566,7 +1592,7 @@ const Parser = struct { fn expectPrefixExpr(p: *Parser) Error!Node.Index { const node = try p.parsePrefixExpr(); if (node == 0) { - return p.fail(.{ .ExpectedPrefixExpr = .{ .token = p.tok_i } }); + return p.fail(.expected_prefix_expr); } return node; } @@ -1827,7 +1853,7 @@ const Parser = struct { fn expectTypeExpr(p: *Parser) Error!Node.Index { const node = try p.parseTypeExpr(); if (node == 0) { - return p.fail(.{ .ExpectedTypeExpr = .{ .token = p.tok_i } }); + return p.fail(.expected_type_expr); } return node; } @@ -1922,9 +1948,7 @@ const Parser = struct { switch (p.token_tags[p.tok_i]) { .keyword_for => return p.parseForExpr(), .keyword_while => return p.parseWhileExpr(), - else => return p.fail(.{ - .ExpectedInlinable = .{ .token = p.tok_i }, - }), + else => return p.fail(.expected_inlinable), } }, .keyword_for => { @@ -1950,9 +1974,7 @@ const Parser = struct { switch (p.token_tags[p.tok_i]) { .keyword_for => return p.parseForExpr(), .keyword_while => return p.parseWhileExpr(), - else => return p.fail(.{ - .ExpectedInlinable = .{ .token = p.tok_i }, - }), + else => return p.fail(.expected_inlinable), } }, .keyword_for => return p.parseForExpr(), @@ -2170,20 +2192,13 @@ const Parser = struct { .r_brace => break, .colon, .r_paren, .r_bracket => { p.tok_i -= 1; - return p.fail(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .r_brace, - }, - }); + return p.failExpected(.r_brace); }, else => { // This is likely just a missing comma; // give an error but continue parsing this list. p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } @@ -2214,9 +2229,7 @@ const Parser = struct { }); } if (comma_one == null) { - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); } var init_list = std.ArrayList(Node.Index).init(p.gpa); @@ -2278,7 +2291,7 @@ const Parser = struct { res = node; } const lparen = (try p.expectTokenRecoverable(.l_paren)) orelse { - try p.warn(.{ .ExpectedParamList = .{ .token = p.tok_i } }); + try p.warn(.expected_param_list); return res; }; if (p.eatToken(.r_paren)) |_| { @@ -2304,9 +2317,7 @@ const Parser = struct { }); } if (comma_one == null) { - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); } var param_list = std.ArrayList(Node.Index).init(p.gpa); @@ -2352,21 +2363,11 @@ const Parser = struct { }, .colon, .r_brace, .r_bracket => { p.tok_i -= 1; - return p.fail(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .r_paren, - }, - }); + return p.failExpected(.r_paren); }, else => { p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .comma, - }, - }); + try p.warnExpected(.comma); }, } } @@ -2405,9 +2406,7 @@ const Parser = struct { }); } if (comma_one == null) { - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); } var param_list = std.ArrayList(Node.Index).init(p.gpa); @@ -2453,21 +2452,11 @@ const Parser = struct { }, .colon, .r_brace, .r_bracket => { p.tok_i -= 1; - return p.fail(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .r_paren, - }, - }); + return p.failExpected(.r_paren); }, else => { p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .comma, - }, - }); + try p.warnExpected(.comma); }, } } @@ -2645,9 +2634,7 @@ const Parser = struct { switch (p.token_tags[p.tok_i]) { .keyword_for => return p.parseForTypeExpr(), .keyword_while => return p.parseWhileTypeExpr(), - else => return p.fail(.{ - .ExpectedInlinable = .{ .token = p.tok_i }, - }), + else => return p.fail(.expected_inlinable), } }, .keyword_for => { @@ -2716,9 +2703,7 @@ const Parser = struct { }); } if (comma_one == null) { - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); } const field_init_two = try p.expectFieldInit(); const comma_two = p.eatToken(.comma); @@ -2733,9 +2718,7 @@ const Parser = struct { }); } if (comma_two == null) { - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); } var init_list = std.ArrayList(Node.Index).init(p.gpa); defer init_list.deinit(); @@ -2754,21 +2737,11 @@ const Parser = struct { .r_brace => break, .colon, .r_paren, .r_bracket => { p.tok_i -= 1; - return p.fail(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .r_brace, - }, - }); + return p.failExpected(.r_brace); }, else => { p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .comma, - }, - }); + try p.warnExpected(.comma); }, } } @@ -2797,9 +2770,7 @@ const Parser = struct { }); } if (comma_one == null) { - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); } const elem_init_two = try p.expectExpr(); const comma_two = p.eatToken(.comma); @@ -2814,9 +2785,7 @@ const Parser = struct { }); } if (comma_two == null) { - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); } var init_list = std.ArrayList(Node.Index).init(p.gpa); defer init_list.deinit(); @@ -2835,21 +2804,11 @@ const Parser = struct { .r_brace => break, .colon, .r_paren, .r_bracket => { p.tok_i -= 1; - return p.fail(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .r_brace, - }, - }); + return p.failExpected(.r_brace); }, else => { p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .comma, - }, - }); + try p.warnExpected(.comma); }, } } @@ -2892,20 +2851,13 @@ const Parser = struct { .r_brace => break, .colon, .r_paren, .r_bracket => { p.tok_i -= 1; - return p.fail(.{ - .ExpectedToken = .{ - .token = p.tok_i, - .expected_id = .r_brace, - }, - }); + return p.failExpected(.r_brace); }, else => { // This is likely just a missing comma; // give an error but continue parsing this list. p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } @@ -2942,7 +2894,7 @@ const Parser = struct { fn expectPrimaryTypeExpr(p: *Parser) !Node.Index { const node = try p.parsePrimaryTypeExpr(); if (node == 0) { - return p.fail(.{ .ExpectedPrimaryTypeExpr = .{ .token = p.tok_i } }); + return p.fail(.expected_primary_type_expr); } return node; } @@ -3095,9 +3047,7 @@ const Parser = struct { else => { // This is likely just a missing comma; // give an error but continue parsing this list. - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } @@ -3112,9 +3062,7 @@ const Parser = struct { else => { // This is likely just a missing comma; // give an error but continue parsing this list. - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } @@ -3126,9 +3074,7 @@ const Parser = struct { else => { // This is likely just a missing comma; // give an error but continue parsing this list. - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } @@ -3238,7 +3184,7 @@ const Parser = struct { _ = p.eatToken(.colon) orelse return null_node; _ = try p.expectToken(.l_paren); const node = try p.parseAssignExpr(); - if (node == 0) return p.fail(.{ .ExpectedExprOrAssignment = .{ .token = p.tok_i } }); + if (node == 0) return p.fail(.expected_expr_or_assignment); _ = try p.expectToken(.r_paren); return node; } @@ -3418,9 +3364,7 @@ const Parser = struct { switch (p.token_tags[p.tok_i]) { .keyword_align => { if (result.align_node != 0) { - try p.warn(.{ - .ExtraAlignQualifier = .{ .token = p.tok_i }, - }); + try p.warn(.extra_align_qualifier); } p.tok_i += 1; _ = try p.expectToken(.l_paren); @@ -3436,27 +3380,21 @@ const Parser = struct { }, .keyword_const => { if (saw_const) { - try p.warn(.{ - .ExtraConstQualifier = .{ .token = p.tok_i }, - }); + try p.warn(.extra_const_qualifier); } p.tok_i += 1; saw_const = true; }, .keyword_volatile => { if (saw_volatile) { - try p.warn(.{ - .ExtraVolatileQualifier = .{ .token = p.tok_i }, - }); + try p.warn(.extra_volatile_qualifier); } p.tok_i += 1; saw_volatile = true; }, .keyword_allowzero => { if (saw_allowzero) { - try p.warn(.{ - .ExtraAllowZeroQualifier = .{ .token = p.tok_i }, - }); + try p.warn(.extra_allowzero_qualifier); } p.tok_i += 1; saw_allowzero = true; @@ -3539,11 +3477,10 @@ const Parser = struct { }, }), .invalid_periodasterisks => { - const period_asterisk = p.nextToken(); - try p.warn(.{ .AsteriskAfterPointerDereference = .{ .token = period_asterisk } }); + try p.warn(.asterisk_after_ptr_deref); return p.addNode(.{ .tag = .deref, - .main_token = period_asterisk, + .main_token = p.nextToken(), .data = .{ .lhs = lhs, .rhs = undefined, @@ -3569,7 +3506,7 @@ const Parser = struct { }), else => { p.tok_i += 1; - try p.warn(.{ .ExpectedSuffixOp = .{ .token = p.tok_i } }); + try p.warn(.expected_suffix_op); return null_node; }, }, @@ -3743,9 +3680,7 @@ const Parser = struct { // This is likely just a missing comma; // give an error but continue parsing this list. p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } else unreachable; @@ -3763,17 +3698,13 @@ const Parser = struct { .r_paren => return SmallSpan{ .zero_or_one = param_one }, .colon, .r_brace, .r_bracket => { p.tok_i -= 1; - return p.fail(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .r_paren }, - }); + return p.failExpected(.r_paren); }, else => { // This is likely just a missing comma; // give an error but continue parsing this list. p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } else unreachable; @@ -3799,17 +3730,13 @@ const Parser = struct { .r_paren => return SmallSpan{ .multi = list.toOwnedSlice() }, .colon, .r_brace, .r_bracket => { p.tok_i -= 1; - return p.fail(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .r_paren }, - }); + return p.failExpected(.r_paren); }, else => { // This is likely just a missing comma; // give an error but continue parsing this list. p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } @@ -3836,9 +3763,7 @@ const Parser = struct { else => { // This is likely just a missing comma; // give an error but continue parsing this list. - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } @@ -3852,9 +3777,7 @@ const Parser = struct { fn parseBuiltinCall(p: *Parser) !Node.Index { const builtin_token = p.assertToken(.builtin); _ = (try p.expectTokenRecoverable(.l_paren)) orelse { - try p.warn(.{ - .ExpectedParamList = .{ .token = p.tok_i }, - }); + try p.warn(.expected_param_list); // Pretend this was an identifier so we can continue parsing. return p.addNode(.{ .tag = .identifier, @@ -3901,9 +3824,7 @@ const Parser = struct { // This is likely just a missing comma; // give an error but continue parsing this list. p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } const param_two = try p.expectExpr(); @@ -3932,9 +3853,7 @@ const Parser = struct { // This is likely just a missing comma; // give an error but continue parsing this list. p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } @@ -3976,9 +3895,7 @@ const Parser = struct { // This is likely just a missing comma; // give an error but continue parsing this list. p.tok_i -= 1; - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma }, - }); + try p.warnExpected(.comma); }, } } @@ -4019,7 +3936,7 @@ const Parser = struct { fn expectStringLiteral(p: *Parser) !Node.Index { const node = try p.parseStringLiteral(); if (node == 0) { - return p.fail(.{ .ExpectedStringLiteral = .{ .token = p.tok_i } }); + return p.fail(.expected_string_literal); } return node; } @@ -4044,7 +3961,7 @@ const Parser = struct { const then_payload = try p.parsePtrPayload(); const then_expr = try bodyParseFn(p); - if (then_expr == 0) return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + if (then_expr == 0) return p.fail(.invalid_token); const else_token = p.eatToken(.keyword_else) orelse return p.addNode(.{ .tag = .if_simple, @@ -4056,7 +3973,7 @@ const Parser = struct { }); const else_payload = try p.parsePayload(); const else_expr = try bodyParseFn(p); - if (else_expr == 0) return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } }); + if (else_expr == 0) return p.fail(.invalid_token); return p.addNode(.{ .tag = .@"if", @@ -4076,7 +3993,10 @@ const Parser = struct { if (p.eatToken(.doc_comment)) |tok| { var first_line = tok; if (tok > 0 and tokensOnSameLine(p, tok - 1, tok)) { - try p.warn(.{ .SameLineDocComment = .{ .token = tok } }); + try p.warnMsg(.{ + .tag = .same_line_doc_comment, + .token = tok, + }); first_line = p.eatToken(.doc_comment) orelse return null; } while (p.eatToken(.doc_comment)) |_| {} @@ -4102,16 +4022,18 @@ const Parser = struct { fn expectToken(p: *Parser, tag: Token.Tag) Error!TokenIndex { const token = p.nextToken(); if (p.token_tags[token] != tag) { - return p.fail(.{ .ExpectedToken = .{ .token = token, .expected_id = tag } }); + return p.failMsg(.{ + .tag = .expected_token, + .token = token, + .extra = .{ .expected_tag = tag }, + }); } return token; } fn expectTokenRecoverable(p: *Parser, tag: Token.Tag) !?TokenIndex { if (p.token_tags[p.tok_i] != tag) { - try p.warn(.{ - .ExpectedToken = .{ .token = p.tok_i, .expected_id = tag }, - }); + try p.warnExpected(tag); return null; } else { return p.nextToken(); diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index f8e992bb2e..dc653047df 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -127,7 +127,7 @@ test "zig fmt: decl between fields" { \\ b: usize, \\}; , &[_]Error{ - .DeclBetweenFields, + .decl_between_fields, }); } @@ -135,7 +135,7 @@ test "zig fmt: eof after missing comma" { try testError( \\foo() , &[_]Error{ - .ExpectedToken, + .expected_token, }); } @@ -3578,7 +3578,7 @@ test "zig fmt: file ends with struct field" { // \\const container = extern {}; // \\ // , &[_]Error{ -// .ExpectedExpr, +// .expected_expr, // .ExpectedVarDeclOrFn, // }); //} @@ -3598,12 +3598,12 @@ test "zig fmt: same line doc comment returns error" { \\/// comment \\ , &[_]Error{ - .SameLineDocComment, - .SameLineDocComment, - .UnattachedDocComment, - .SameLineDocComment, - .SameLineDocComment, - .UnattachedDocComment, + .same_line_doc_comment, + .same_line_doc_comment, + .unattached_doc_comment, + .same_line_doc_comment, + .same_line_doc_comment, + .unattached_doc_comment, }); } @@ -3678,10 +3678,10 @@ test "zig fmt: hexadeciaml float literals with underscore separators" { } test "zig fmt: C var args" { - try testCanonical( - \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; - \\ - ); + try testCanonical( + \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; + \\ + ); } //test "zig fmt: Only indent multiline string literals in function calls" { @@ -4037,8 +4037,8 @@ test "recovery: top level" { \\test "" {inline} \\test "" {inline} , &[_]Error{ - .ExpectedInlinable, - .ExpectedInlinable, + .expected_inlinable, + .expected_inlinable, }); } @@ -4049,8 +4049,8 @@ test "recovery: block statements" { \\ inline; \\} , &[_]Error{ - .InvalidToken, - .ExpectedInlinable, + .invalid_token, + .expected_inlinable, }); } @@ -4066,10 +4066,10 @@ test "recovery: block statements" { // \\ } // \\} // , &[_]Error{ -// .ExpectedToken, -// .ExpectedToken, -// .InvalidAnd, -// .InvalidToken, +// .expected_token, +// .expected_token, +// .invalid_and, +// .invalid_token, // }); //} @@ -4078,8 +4078,8 @@ test "recovery: extra qualifier" { \\const a: *const const u8; \\test "" , &[_]Error{ - .ExtraConstQualifier, - .ExpectedLBrace, + .extra_const_qualifier, + .expected_block, }); } @@ -4091,8 +4091,8 @@ test "recovery: extra qualifier" { // \\test "" // , &[_]Error{ // .ExpectedReturnType, -// .InvalidAnd, -// .ExpectedLBrace, +// .invalid_and, +// .expected_block, // }); //} @@ -4105,10 +4105,10 @@ test "recovery: extra qualifier" { // \\ async a && b; // \\} // , &[_]Error{ -// .ExpectedToken, +// .expected_token, // .ExpectedPubItem, // .ExpectedParamList, -// .InvalidAnd, +// .invalid_and, // }); // try testError( // \\threadlocal test "" { @@ -4117,7 +4117,7 @@ test "recovery: extra qualifier" { // , &[_]Error{ // .ExpectedVarDecl, // .ExpectedParamList, -// .InvalidAnd, +// .invalid_and, // }); //} @@ -4126,13 +4126,13 @@ test "recovery: extra qualifier" { // \\inline test "" { a && b; } // , &[_]Error{ // .ExpectedFn, -// .InvalidAnd, +// .invalid_and, // }); // try testError( // \\extern "" test "" { a && b; } // , &[_]Error{ // .ExpectedVarDeclOrFn, -// .InvalidAnd, +// .invalid_and, // }); //} @@ -4144,12 +4144,12 @@ test "recovery: extra qualifier" { // \\ @foo // \\} // , &[_]Error{ -// .InvalidAnd, -// .ExpectedToken, -// .InvalidAnd, -// .ExpectedToken, +// .invalid_and, +// .expected_token, +// .invalid_and, +// .expected_token, // .ExpectedParamList, -// .ExpectedToken, +// .expected_token, // }); //} @@ -4163,12 +4163,12 @@ test "recovery: extra qualifier" { // \\ a && b // \\} // , &[_]Error{ -// .ExpectedExpr, -// .ExpectedToken, -// .ExpectedToken, -// .ExpectedContainerMembers, -// .InvalidAnd, -// .ExpectedToken, +// .expected_expr, +// .expected_token, +// .expected_token, +// .expected_container_members, +// .invalid_and, +// .expected_token, // }); //} @@ -4178,7 +4178,7 @@ test "recovery: extra qualifier" { // \\ a(comptime T: type) // \\} // , &[_]Error{ -// .ExpectedToken, +// .expected_token, // }); //} @@ -4189,10 +4189,10 @@ test "recovery: extra qualifier" { // \\ a && b; // \\} // , &[_]Error{ -// .ExpectedContainerMembers, -// .ExpectedContainerMembers, -// .ExpectedContainerMembers, -// .InvalidAnd, +// .expected_container_members, +// .expected_container_members, +// .expected_container_members, +// .invalid_and, // }); //} // @@ -4202,7 +4202,7 @@ test "recovery: mismatched bracket at top level" { \\ arr: 128]?G \\}; , &[_]Error{ - .ExpectedToken, + .expected_token, }); } @@ -4212,9 +4212,9 @@ test "recovery: mismatched bracket at top level" { // \\ error && foo; // \\} // , &[_]Error{ -// .ExpectedToken, +// .expected_token, // .ExpectedIdentifier, -// .InvalidAnd, +// .invalid_and, // }); //} @@ -4224,15 +4224,15 @@ test "recovery: mismatched bracket at top level" { // \\ var sequence = "repeat".*** 10; // \\} // , &[_]Error{ -// .AsteriskAfterPointerDereference, +// .asterisk_after_ptr_deref, // }); // try testError( // \\test "" { // \\ var sequence = "repeat".** 10&&a; // \\} // , &[_]Error{ -// .AsteriskAfterPointerDereference, -// .InvalidAnd, +// .asterisk_after_ptr_deref, +// .invalid_and, // }); //} @@ -4245,10 +4245,10 @@ test "recovery: mismatched bracket at top level" { // \\ a && b; // \\} // , &[_]Error{ -// .ExpectedSemiOrElse, -// .ExpectedSemiOrElse, -// .ExpectedSemiOrElse, -// .InvalidAnd, +// .expected_semi_or_else, +// .expected_semi_or_else, +// .expected_semi_or_else, +// .invalid_and, // }); //} @@ -4256,7 +4256,7 @@ test "recovery: invalid comptime" { try testError( \\comptime , &[_]Error{ - .ExpectedBlockOrField, + .expected_block_or_field, }); } @@ -4264,12 +4264,12 @@ test "recovery: missing block after for/while loops" { try testError( \\test "" { while (foo) } , &[_]Error{ - .ExpectedBlockOrAssignment, + .expected_block_or_assignment, }); try testError( \\test "" { for (foo) |bar| } , &[_]Error{ - .ExpectedBlockOrAssignment, + .expected_block_or_assignment, }); } @@ -4288,9 +4288,8 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b defer tree.deinit(allocator); for (tree.errors) |parse_error| { - const error_token = tree.errorToken(parse_error); - const token_start = tree.tokens.items(.start)[error_token]; - const loc = tree.tokenLocation(0, error_token); + const token_start = tree.tokens.items(.start)[parse_error.token]; + const loc = tree.tokenLocation(0, parse_error.token); try stderr.print("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 }); try tree.renderError(parse_error, stderr); try stderr.print("\n{s}\n", .{source[loc.line_start..loc.line_end]}); @@ -4362,7 +4361,7 @@ fn testCanonical(source: []const u8) !void { return testTransform(source, source); } -const Error = std.meta.Tag(std.zig.ast.Error); +const Error = std.zig.ast.Error.Tag; fn testError(source: []const u8, expected_errors: []const Error) !void { var tree = try std.zig.parse(std.testing.allocator, source); @@ -4370,6 +4369,6 @@ fn testError(source: []const u8, expected_errors: []const Error) !void { std.testing.expect(tree.errors.len == expected_errors.len); for (expected_errors) |expected, i| { - std.testing.expectEqual(expected, tree.errors[i]); + std.testing.expectEqual(expected, tree.errors[i].tag); } } diff --git a/src/Module.zig b/src/Module.zig index 35819c5d44..8f2ac3721e 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1723,7 +1723,7 @@ pub fn getAstTree(self: *Module, root_scope: *Scope.File) !*const ast.Tree { err_msg.* = .{ .src_loc = .{ .file_scope = root_scope, - .byte_offset = tree.tokens.items(.start)[parse_err.loc()], + .byte_offset = tree.tokens.items(.start)[parse_err.token], }, .msg = msg.toOwnedSlice(), }; diff --git a/src/main.zig b/src/main.zig index c0ac41d9bf..09d791cfb5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2898,7 +2898,7 @@ fn printErrMsgToFile( .on => true, .off => false, }; - const lok_token = parse_error.loc(); + const lok_token = parse_error.token; const token_starts = tree.tokens.items(.start); const token_tags = tree.tokens.items(.tag); |
