Commit edca173997

Jimmi Holst Christensen <jimmiholstchristensen@gmail.com>
2018-03-29 23:40:46
std.zig.parser now parses call expr
1 parent 8ada030
Changed files (2)
std/zig/ast.zig
@@ -22,6 +22,7 @@ pub const Node = struct {
         StringLiteral,
         UndefinedLiteral,
         BuiltinCall,
+        Call,
         LineComment,
         TestDecl,
     };
@@ -41,6 +42,7 @@ pub const Node = struct {
             Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).iterate(index),
             Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).iterate(index),
             Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),
+            Id.Call => @fieldParentPtr(NodeCall, "base", base).iterate(index),
             Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).iterate(index),
             Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).iterate(index),
         };
@@ -61,6 +63,7 @@ pub const Node = struct {
             Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).firstToken(),
             Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).firstToken(),
             Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).firstToken(),
+            Id.Call => @fieldParentPtr(NodeCall, "base", base).firstToken(),
             Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).firstToken(),
             Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).firstToken(),
         };
@@ -81,6 +84,7 @@ pub const Node = struct {
             Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).lastToken(),
             Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).lastToken(),
             Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).lastToken(),
+            Id.Call => @fieldParentPtr(NodeCall, "base", base).lastToken(),
             Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).lastToken(),
             Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).lastToken(),
         };
@@ -527,6 +531,33 @@ pub const NodeBuiltinCall = struct {
     }
 };
 
+pub const NodeCall = struct {
+    base: Node,
+    callee: &Node,
+    params: ArrayList(&Node),
+    rparen_token: Token,
+
+    pub fn iterate(self: &NodeCall, index: usize) ?&Node {
+        var i = index;
+
+        if (i < 1) return self.callee;
+        i -= 1;
+
+        if (i < self.params.len) return self.params.at(i);
+        i -= self.params.len;
+
+        return null;
+    }
+
+    pub fn firstToken(self: &NodeCall) Token {
+        return self.callee.firstToken();
+    }
+
+    pub fn lastToken(self: &NodeCall) Token {
+        return self.rparen_token;
+    }
+};
+
 pub const NodeStringLiteral = struct {
     base: Node,
     token: Token,
std/zig/parser.zig
@@ -428,6 +428,29 @@ pub const Parser = struct {
                             try stack.append(State.ExpectOperand);
                             continue;
 
+                    } else if (token.id == Token.Id.LParen) {
+                        self.putBackToken(token);
+
+                        const node = try arena.create(ast.NodeCall);
+                        *node = ast.NodeCall {
+                            .base = self.initNode(ast.Node.Id.Call),
+                            .callee = stack.pop().Operand,
+                            .params = ArrayList(&ast.Node).init(arena),
+                            .rparen_token = undefined,
+                        };
+                        try stack.append(State {
+                            .Operand = &node.base
+                        });
+                        try stack.append(State.AfterOperand);
+                        try stack.append(State {.ExprListItemOrEnd = &node.params });
+                        try stack.append(State {
+                            .ExpectTokenSave = ExpectTokenSave {
+                                .id = Token.Id.LParen,
+                                .ptr = &node.rparen_token,
+                            },
+                        });
+                        continue;
+
                     // TODO: Parse postfix operator
                     } else {
                         // no postfix/infix operator after this operand.
@@ -1325,6 +1348,21 @@ pub const Parser = struct {
                             }
                         }
                     },
+                    ast.Node.Id.Call => {
+                        const call = @fieldParentPtr(ast.NodeCall, "base", base);
+                        try stack.append(RenderState { .Text = ")"});
+                        var i = call.params.len;
+                        while (i != 0) {
+                            i -= 1;
+                            const param_node = call.params.at(i);
+                            try stack.append(RenderState { .Expression = param_node});
+                            if (i != 0) {
+                                try stack.append(RenderState { .Text = ", " });
+                            }
+                        }
+                        try stack.append(RenderState { .Text = "("});
+                        try stack.append(RenderState { .Expression = call.callee });
+                    },
                     ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"),
                     ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"),
 
@@ -1610,4 +1648,14 @@ test "zig fmt" {
         \\}
         \\
     );
+
+    try testCanonical(
+        \\test "test calls" {
+        \\    a();
+        \\    a(1);
+        \\    a(1, 2);
+        \\    a(1, 2) + a(1, 2);
+        \\}
+        \\
+    );
 }