Commit 9d69e94bba

Jimmi Holst Christensen <jhc@liab.dk>
2018-04-03 15:16:32
std.zig.parser now parses grouped expressions * I also moved some tests down, as they fail in ways I can't fix yet
1 parent 5c82ed2
Changed files (2)
std/zig/ast.zig
@@ -18,6 +18,7 @@ pub const Node = struct {
         InfixOp,
         PrefixOp,
         SuffixOp,
+        GroupedExpression,
         FieldInitializer,
         IntegerLiteral,
         FloatLiteral,
@@ -46,6 +47,7 @@ pub const Node = struct {
             Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index),
             Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
             Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
+            Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).iterate(index),
             Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).iterate(index),
             Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
             Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
@@ -75,6 +77,7 @@ pub const Node = struct {
             Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),
             Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
             Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
+            Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).firstToken(),
             Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).firstToken(),
             Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),
             Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),
@@ -104,6 +107,7 @@ pub const Node = struct {
             Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),
             Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
             Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
+            Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).lastToken(),
             Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).lastToken(),
             Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),
             Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),
@@ -624,6 +628,30 @@ pub const NodeSuffixOp = struct {
     }
 };
 
+pub const NodeGroupedExpression = struct {
+    base: Node,
+    lparen: Token,
+    expr: &Node,
+    rparen: Token,
+
+    pub fn iterate(self: &NodeGroupedExpression, index: usize) ?&Node {
+        var i = index;
+
+        if (i < 1) return self.expr;
+        i -= 1;
+
+        return null;
+    }
+
+    pub fn firstToken(self: &NodeGroupedExpression) Token {
+        return self.lparen;
+    }
+
+    pub fn lastToken(self: &NodeGroupedExpression) Token {
+        return self.rparen;
+    }
+};
+
 pub const NodeIntegerLiteral = struct {
     base: Node,
     token: Token,
std/zig/parser.zig
@@ -594,6 +594,27 @@ pub const Parser = struct {
                             try stack.append(State.AfterOperand);
                             continue;
                         },
+                        Token.Id.LParen => {
+                            const node = try arena.create(ast.NodeGroupedExpression);
+                            *node = ast.NodeGroupedExpression {
+                                .base = self.initNode(ast.Node.Id.GroupedExpression),
+                                .lparen = token,
+                                .expr = undefined,
+                                .rparen = undefined,
+                            };
+                            try stack.append(State {
+                                .Operand = &node.base
+                            });
+                            try stack.append(State.AfterOperand);
+                            try stack.append(State {
+                                .ExpectTokenSave = ExpectTokenSave {
+                                    .id = Token.Id.RParen,
+                                    .ptr = &node.rparen,
+                                }
+                            });
+                            try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
+                            continue;
+                        },
 
                         else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)),
                     }
@@ -1770,6 +1791,12 @@ pub const Parser = struct {
 
                         try stack.append(RenderState { .Expression = suffix_op.lhs });
                     },
+                    ast.Node.Id.GroupedExpression => {
+                        const grouped_expr = @fieldParentPtr(ast.NodeGroupedExpression, "base", base);
+                        try stack.append(RenderState { .Text = ")"});
+                        try stack.append(RenderState { .Expression = grouped_expr.expr });
+                        try stack.append(RenderState { .Text = "("});
+                    },
                     ast.Node.Id.FieldInitializer => {
                         const field_init = @fieldParentPtr(ast.NodeFieldInitializer, "base", base);
                         try stream.print(".{} = ", self.tokenizer.getTokenSlice(field_init.name_token));
@@ -2240,50 +2267,6 @@ test "zig fmt: indexing" {
     );
 }
 
-test "zig fmt: arrays" {
-    try testCanonical(
-        \\test "test array" {
-        \\    const a: [2]u8 = [2]u8{ 1, 2 };
-        \\    const a: [2]u8 = []u8{ 1, 2 };
-        \\    const a: [0]u8 = []u8{};
-        \\}
-        \\
-    );
-}
-
-test "zig fmt: precedence" {
-    try testCanonical(
-        \\test "precedence" {
-        \\    a!b();
-        \\    (a!b)();
-        \\    !a!b;
-        \\    !(a!b);
-        \\    !a{};
-        \\    !(a{});
-        \\    a + b{};
-        \\    (a + b){};
-        \\    a << b + c;
-        \\    (a << b) + c;
-        \\    a & b << c;
-        \\    (a & b) << c;
-        \\    a ^ b & c;
-        \\    (a ^ b) & c;
-        \\    a | b ^ c;
-        \\    (a | b) ^ c;
-        \\    a == b | c;
-        \\    (a == b) | c;
-        \\    a and b == c;
-        \\    (a and b) == c;
-        \\    a or b and c;
-        \\    (a or b) and c;
-        \\    (a or b) and c;
-        \\    a = b or c;
-        \\    (a = b) or c;
-        \\}
-        \\
-    );
-}
-
 test "zig fmt: struct declaration" {
     try testCanonical(
         \\const S = struct {
@@ -2682,6 +2665,50 @@ test "zig fmt: coroutines" {
     );
 }
 
+test "zig fmt: arrays" {
+    try testCanonical(
+        \\test "test array" {
+        \\    const a: [2]u8 = [2]u8{ 1, 2 };
+        \\    const a: [2]u8 = []u8{ 1, 2 };
+        \\    const a: [0]u8 = []u8{};
+        \\}
+        \\
+    );
+}
+
+test "zig fmt: precedence" {
+    try testCanonical(
+        \\test "precedence" {
+        \\    a!b();
+        \\    (a!b)();
+        \\    !a!b;
+        \\    !(a!b);
+        \\    !a{};
+        \\    !(a{});
+        \\    a + b{};
+        \\    (a + b){};
+        \\    a << b + c;
+        \\    (a << b) + c;
+        \\    a & b << c;
+        \\    (a & b) << c;
+        \\    a ^ b & c;
+        \\    (a ^ b) & c;
+        \\    a | b ^ c;
+        \\    (a | b) ^ c;
+        \\    a == b | c;
+        \\    (a == b) | c;
+        \\    a and b == c;
+        \\    (a and b) == c;
+        \\    a or b and c;
+        \\    (a or b) and c;
+        \\    (a or b) and c;
+        \\    a = b or c;
+        \\    (a = b) or c;
+        \\}
+        \\
+    );
+}
+
 test "zig fmt: zig fmt" {
     try testCanonical(@embedFile("ast.zig"));
     try testCanonical(@embedFile("index.zig"));