Skip to content

Commit 1dfa927

Browse files
committedMar 30, 2018
std.zig.parser now treats call expr as a suffix operator
1 parent f586aca commit 1dfa927

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed
 

‎std/zig/parser.zig

+34-7
Original file line numberDiff line numberDiff line change
@@ -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,

0 commit comments

Comments
 (0)
Please sign in to comment.