aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-02-19 18:04:52 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-02-19 18:04:52 -0700
commit8fee41b1d528d598521525574206e200fd332c67 (patch)
tree2c5ad20494b34a9391474d06a7d1e97b6732612d
parent74878565e5112fed04336089ed769443e08e605b (diff)
downloadzig-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.zig529
-rw-r--r--lib/std/zig/parse.zig338
-rw-r--r--lib/std/zig/parser_test.zig127
-rw-r--r--src/Module.zig2
-rw-r--r--src/main.zig2
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);