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