authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-03-30 20:47:09+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-03-30 20:47:09+02:00
log1dfa927a67566a043e0c1d2982333904d18c3b3a
treecfddf17a6c926ad1963719a04de8fb771333cc2c
parentf586acabdcc4adaeda7bc278463c20e4033e8cc9

std.zig.parser now treats call expr as a suffix operator


1 files changed, 34 insertions(+), 7 deletions(-)

std/zig/parser.zig+34-7
......@@ -86,6 +86,7 @@ pub const Parser = struct {
8686 AfterOperand,
8787 InfixOp: &ast.NodeInfixOp,
8888 PrefixOp: &ast.NodePrefixOp,
89 SuffixOp: &ast.Node,
8990 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
9091 TypeExpr: DestPtr,
9192 VarDecl: &ast.NodeVarDecl,
......@@ -434,13 +435,11 @@ pub const Parser = struct {
434435 const node = try arena.create(ast.NodeCall);
435436 *node = ast.NodeCall {
436437 .base = self.initNode(ast.Node.Id.Call),
437 .callee = stack.pop().Operand,
438 .callee = undefined,
438439 .params = ArrayList(&ast.Node).init(arena),
439440 .rparen_token = undefined,
440441 };
441 try stack.append(State {
442 .Operand = &node.base
443 });
442 try stack.append(State { .SuffixOp = &node.base });
444443 try stack.append(State.AfterOperand);
445444 try stack.append(State {.ExprListItemOrEnd = &node.params });
446445 try stack.append(State {
......@@ -455,8 +454,8 @@ pub const Parser = struct {
455454 } else {
456455 // no postfix/infix operator after this operand.
457456 self.putBackToken(token);
458 // reduce the stack
459 var expression: &ast.Node = stack.pop().Operand;
457
458 var expression = popSuffixOp(&stack);
460459 while (true) {
461460 switch (stack.pop()) {
462461 State.Expression => |dest_ptr| {
......@@ -466,7 +465,7 @@ pub const Parser = struct {
466465 },
467466 State.InfixOp => |infix_op| {
468467 infix_op.rhs = expression;
469 infix_op.lhs = stack.pop().Operand;
468 infix_op.lhs = popSuffixOp(&stack);
470469 expression = &infix_op.base;
471470 continue;
472471 },
......@@ -716,11 +715,39 @@ pub const Parser = struct {
716715 // These are data, not control flow.
717716 State.InfixOp => unreachable,
718717 State.PrefixOp => unreachable,
718 State.SuffixOp => unreachable,
719719 State.Operand => unreachable,
720720 }
721721 }
722722 }
723723
724 fn popSuffixOp(stack: &ArrayList(State)) &ast.Node {
725 var expression: &ast.Node = undefined;
726 var left_leaf_ptr: &&ast.Node = &expression;
727 while (true) {
728 switch (stack.pop()) {
729 State.SuffixOp => |suffix_op| {
730 switch (suffix_op.id) {
731 ast.Node.Id.Call => {
732 const call = @fieldParentPtr(ast.NodeCall, "base", suffix_op);
733 *left_leaf_ptr = &call.base;
734 left_leaf_ptr = &call.callee;
735 continue;
736 },
737 else => unreachable,
738 }
739 },
740 State.Operand => |operand| {
741 *left_leaf_ptr = operand;
742 break;
743 },
744 else => unreachable,
745 }
746 }
747
748 return expression;
749 }
750
724751 fn tokenIdToInfixOp(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
725752 return switch (*id) {
726753 Token.Id.Ampersand => ast.NodeInfixOp.InfixOp.BitAnd,