Commit 4708fb23c0

Benjamin Feng <benjamin.feng@glassdoor.com>
2019-06-21 05:06:20
Generate parse error from &&
1 parent d4ff271
Changed files (2)
std/zig/ast.zig
@@ -113,6 +113,7 @@ pub const Tree = struct {
 
 pub const Error = union(enum) {
     InvalidToken: InvalidToken,
+    InvalidAmpersandAmpersand: InvalidAmpersandAmpersand,
     ExpectedContainerMembers: ExpectedContainerMembers,
     ExpectedStringLiteral: ExpectedStringLiteral,
     ExpectedIntegerLiteral: ExpectedIntegerLiteral,
@@ -161,6 +162,7 @@ pub const Error = union(enum) {
         switch (self.*) {
             // TODO https://github.com/ziglang/zig/issues/683
             @TagType(Error).InvalidToken => |*x| return x.render(tokens, stream),
+            @TagType(Error).InvalidAmpersandAmpersand => |*x| return x.render(tokens, stream),
             @TagType(Error).ExpectedContainerMembers => |*x| return x.render(tokens, stream),
             @TagType(Error).ExpectedStringLiteral => |*x| return x.render(tokens, stream),
             @TagType(Error).ExpectedIntegerLiteral => |*x| return x.render(tokens, stream),
@@ -211,6 +213,7 @@ pub const Error = union(enum) {
         switch (self.*) {
             // TODO https://github.com/ziglang/zig/issues/683
             @TagType(Error).InvalidToken => |x| return x.token,
+            @TagType(Error).InvalidAmpersandAmpersand => |x| return x.token,
             @TagType(Error).ExpectedContainerMembers => |x| return x.token,
             @TagType(Error).ExpectedStringLiteral => |x| return x.token,
             @TagType(Error).ExpectedIntegerLiteral => |x| return x.token,
@@ -291,6 +294,7 @@ pub const Error = union(enum) {
     pub const ExpectedDerefOrUnwrap = SingleTokenError("Expected pointer dereference or optional unwrap, found {}");
     pub const ExpectedSuffixOp = SingleTokenError("Expected pointer dereference, optional unwrap, or field access, found {}");
 
+    pub const InvalidAmpersandAmpersand = SimpleError("Invalid token '&&', 'and' performs boolean AND");
     pub const ExpectedParamType = SimpleError("Expected parameter type");
     pub const ExpectedPubItem = SimpleError("Pub must be followed by fn decl, var decl, or container member");
     pub const UnattachedDocComment = SimpleError("Unattached documentation comment");
std/zig/parse.zig
@@ -774,7 +774,7 @@ fn parseBoolAndExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
         arena,
         it,
         tree,
-        SimpleBinOpParseFn(.Keyword_and, Node.InfixOp.Op.BoolAnd),
+        parseAmpersandAmpersandOp,
         parseCompareExpr,
         .Infinitely,
     );
@@ -2687,6 +2687,18 @@ fn SimpleBinOpParseFn(comptime token: Token.Id, comptime op: Node.InfixOp.Op) No
 
 // Helper parsers not included in the grammar
 
+fn parseAmpersandAmpersandOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
+    const op_parse_and = SimpleBinOpParseFn(.Keyword_and, Node.InfixOp.Op.BoolAnd);
+    const op_token = eatToken(it, .AmpersandAmpersand);
+    if (op_token != null) {
+        try tree.errors.push(AstError{
+            .InvalidAmpersandAmpersand = AstError.InvalidAmpersandAmpersand{ .token = it.index },
+        });
+        return error.ParseError;
+    }
+    return op_parse_and(arena, it, tree);
+}
+
 fn parseBuiltinCall(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
     const token = eatToken(it, .Builtin) orelse return null;
     const params = (try parseFnCallArguments(arena, it, tree)) orelse {