From edca1739975f69a695d1ee12ba88ebca1778fefb Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Thu, 29 Mar 2018 23:40:46 +0200 Subject: [PATCH] std.zig.parser now parses call expr --- std/zig/ast.zig | 31 ++++++++++++++++++++++++++++++ std/zig/parser.zig | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/std/zig/ast.zig b/std/zig/ast.zig index 36952ec3c3..0e41836f07 100644 --- a/std/zig/ast.zig +++ b/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, diff --git a/std/zig/parser.zig b/std/zig/parser.zig index a96277df04..33bcbaeda0 100644 --- a/std/zig/parser.zig +++ b/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); + \\} + \\ + ); }