| ... | @@ -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 stack | 457 | |
| 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 | } |
| 723 | | 723 | |
| | 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, |