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 {...@@ -86,6 +86,7 @@ pub const Parser = struct {
86 AfterOperand,86 AfterOperand,
87 InfixOp: &ast.NodeInfixOp,87 InfixOp: &ast.NodeInfixOp,
88 PrefixOp: &ast.NodePrefixOp,88 PrefixOp: &ast.NodePrefixOp,
89 SuffixOp: &ast.Node,
89 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,90 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
90 TypeExpr: DestPtr,91 TypeExpr: DestPtr,
91 VarDecl: &ast.NodeVarDecl,92 VarDecl: &ast.NodeVarDecl,
...@@ -434,13 +435,11 @@ pub const Parser = struct {...@@ -434,13 +435,11 @@ pub const Parser = struct {
434 const node = try arena.create(ast.NodeCall);435 const node = try arena.create(ast.NodeCall);
435 *node = ast.NodeCall {436 *node = ast.NodeCall {
436 .base = self.initNode(ast.Node.Id.Call),437 .base = self.initNode(ast.Node.Id.Call),
437 .callee = stack.pop().Operand,438 .callee = undefined,
438 .params = ArrayList(&ast.Node).init(arena),439 .params = ArrayList(&ast.Node).init(arena),
439 .rparen_token = undefined,440 .rparen_token = undefined,
440 };441 };
441 try stack.append(State {442 try stack.append(State { .SuffixOp = &node.base });
442 .Operand = &node.base
443 });
444 try stack.append(State.AfterOperand);443 try stack.append(State.AfterOperand);
445 try stack.append(State {.ExprListItemOrEnd = &node.params });444 try stack.append(State {.ExprListItemOrEnd = &node.params });
446 try stack.append(State {445 try stack.append(State {
...@@ -455,8 +454,8 @@ pub const Parser = struct {...@@ -455,8 +454,8 @@ pub const Parser = struct {
455 } else {454 } else {
456 // no postfix/infix operator after this operand.455 // no postfix/infix operator after this operand.
457 self.putBackToken(token);456 self.putBackToken(token);
458 // reduce the stack457
459 var expression: &ast.Node = stack.pop().Operand;458 var expression = popSuffixOp(&stack);
460 while (true) {459 while (true) {
461 switch (stack.pop()) {460 switch (stack.pop()) {
462 State.Expression => |dest_ptr| {461 State.Expression => |dest_ptr| {
...@@ -466,7 +465,7 @@ pub const Parser = struct {...@@ -466,7 +465,7 @@ pub const Parser = struct {
466 },465 },
467 State.InfixOp => |infix_op| {466 State.InfixOp => |infix_op| {
468 infix_op.rhs = expression;467 infix_op.rhs = expression;
469 infix_op.lhs = stack.pop().Operand;468 infix_op.lhs = popSuffixOp(&stack);
470 expression = &infix_op.base;469 expression = &infix_op.base;
471 continue;470 continue;
472 },471 },
...@@ -716,11 +715,39 @@ pub const Parser = struct {...@@ -716,11 +715,39 @@ pub const Parser = struct {
716 // These are data, not control flow.715 // These are data, not control flow.
717 State.InfixOp => unreachable,716 State.InfixOp => unreachable,
718 State.PrefixOp => unreachable,717 State.PrefixOp => unreachable,
718 State.SuffixOp => unreachable,
719 State.Operand => unreachable,719 State.Operand => unreachable,
720 }720 }
721 }721 }
722 }722 }
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
724 fn tokenIdToInfixOp(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {751 fn tokenIdToInfixOp(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
725 return switch (*id) {752 return switch (*id) {
726 Token.Id.Ampersand => ast.NodeInfixOp.InfixOp.BitAnd,753 Token.Id.Ampersand => ast.NodeInfixOp.InfixOp.BitAnd,