authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-03 12:33:06+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-03 12:33:06+02:00
logb424cd75ab9df69f44fe47c10ded3fd25c2d27bb
treef20265bfb9229bce4f25aac0fc791a5ac0b2586b
parent22e38ffb54775c2e523665ac739f2a895d8757ad

std.zig.parser refactored call, slice and array access to be suffix op


2 files changed, 161 insertions(+), 185 deletions(-)

std/zig/ast.zig+84-99
......@@ -17,6 +17,7 @@ pub const Node = struct {
1717 Block,
1818 InfixOp,
1919 PrefixOp,
20 SuffixOp,
2021 IntegerLiteral,
2122 FloatLiteral,
2223 StringLiteral,
......@@ -29,9 +30,6 @@ pub const Node = struct {
2930 Unreachable,
3031 ErrorType,
3132 BuiltinCall,
32 Call,
33 ArrayAccess,
34 SliceExpression,
3533 LineComment,
3634 TestDecl,
3735 };
......@@ -46,6 +44,7 @@ pub const Node = struct {
4644 Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index),
4745 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index),
4846 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
47 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
4948 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
5049 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
5150 Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).iterate(index),
......@@ -58,9 +57,6 @@ pub const Node = struct {
5857 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).iterate(index),
5958 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).iterate(index),
6059 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),
61 Id.Call => @fieldParentPtr(NodeCall, "base", base).iterate(index),
62 Id.ArrayAccess => @fieldParentPtr(NodeArrayAccess, "base", base).iterate(index),
63 Id.SliceExpression => @fieldParentPtr(NodeSliceExpression, "base", base).iterate(index),
6460 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).iterate(index),
6561 Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).iterate(index),
6662 };
......@@ -76,6 +72,7 @@ pub const Node = struct {
7672 Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(),
7773 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),
7874 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
75 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
7976 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),
8077 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),
8178 Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).firstToken(),
......@@ -88,9 +85,6 @@ pub const Node = struct {
8885 Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).firstToken(),
8986 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).firstToken(),
9087 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).firstToken(),
91 Id.Call => @fieldParentPtr(NodeCall, "base", base).firstToken(),
92 Id.ArrayAccess => @fieldParentPtr(NodeArrayAccess, "base", base).firstToken(),
93 Id.SliceExpression => @fieldParentPtr(NodeSliceExpression, "base", base).firstToken(),
9488 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).firstToken(),
9589 Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).firstToken(),
9690 };
......@@ -106,6 +100,7 @@ pub const Node = struct {
106100 Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(),
107101 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),
108102 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
103 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
109104 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),
110105 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),
111106 Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).lastToken(),
......@@ -118,9 +113,6 @@ pub const Node = struct {
118113 Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).lastToken(),
119114 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).lastToken(),
120115 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).lastToken(),
121 Id.Call => @fieldParentPtr(NodeCall, "base", base).lastToken(),
122 Id.ArrayAccess => @fieldParentPtr(NodeArrayAccess, "base", base).lastToken(),
123 Id.SliceExpression => @fieldParentPtr(NodeSliceExpression, "base", base).lastToken(),
124116 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).lastToken(),
125117 Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).lastToken(),
126118 };
......@@ -493,20 +485,28 @@ pub const NodePrefixOp = struct {
493485 var i = index;
494486
495487 switch (self.op) {
488 PrefixOp.SliceType => |addr_of_info| {
489 if (addr_of_info.align_expr) |align_expr| {
490 if (i < 1) return align_expr;
491 i -= 1;
492 }
493 },
496494 PrefixOp.AddrOf => |addr_of_info| {
497495 if (addr_of_info.align_expr) |align_expr| {
498496 if (i < 1) return align_expr;
499497 i -= 1;
500498 }
501499 },
500 PrefixOp.ArrayType => |size_expr| {
501 if (i < 1) return size_expr;
502 i -= 1;
503 },
502504 PrefixOp.BitNot,
503505 PrefixOp.BoolNot,
504506 PrefixOp.Deref,
505507 PrefixOp.Negation,
506508 PrefixOp.NegationWrap,
507509 PrefixOp.Return,
508 PrefixOp.ArrayType,
509 PrefixOp.SliceType,
510510 PrefixOp.Try,
511511 PrefixOp.UnwrapMaybe => {},
512512 }
......@@ -526,6 +526,76 @@ pub const NodePrefixOp = struct {
526526 }
527527};
528528
529pub const NodeSuffixOp = struct {
530 base: Node,
531 lhs: &Node,
532 op: SuffixOp,
533 rtoken: Token,
534
535 const SuffixOp = union(enum) {
536 Call: CallInfo,
537 ArrayAccess: &Node,
538 Slice: SliceRange,
539 ArrayInitializer: ArrayList(&Node),
540 StructInitializer: ArrayList(&Node),
541 };
542
543 const CallInfo = struct {
544 params: ArrayList(&Node),
545 is_async: bool,
546 };
547
548 const SliceRange = struct {
549 start: &Node,
550 end: ?&Node,
551 };
552
553 pub fn iterate(self: &NodeSuffixOp, index: usize) ?&Node {
554 var i = index;
555
556 if (i < 1) return self.lhs;
557 i -= 1;
558
559 switch (self.op) {
560 SuffixOp.Call => |call_info| {
561 if (i < call_info.params.len) return call_info.params.at(i);
562 i -= call_info.params.len;
563 },
564 SuffixOp.ArrayAccess => |index_expr| {
565 if (i < 1) return index_expr;
566 i -= 1;
567 },
568 SuffixOp.Slice => |range| {
569 if (i < 1) return range.start;
570 i -= 1;
571
572 if (range.end) |end| {
573 if (i < 1) return end;
574 i -= 1;
575 }
576 },
577 SuffixOp.ArrayInitializer => |exprs| {
578 if (i < exprs.len) return exprs.at(i);
579 i -= exprs.len;
580 },
581 SuffixOp.StructInitializer => |fields| {
582 if (i < fields.len) return fields.at(i);
583 i -= fields.len;
584 },
585 }
586
587 return null;
588 }
589
590 pub fn firstToken(self: &NodeSuffixOp) Token {
591 return self.lhs.firstToken();
592 }
593
594 pub fn lastToken(self: &NodeSuffixOp) Token {
595 return self.rtoken;
596 }
597};
598
529599pub const NodeIntegerLiteral = struct {
530600 base: Node,
531601 token: Token,
......@@ -584,91 +654,6 @@ pub const NodeBuiltinCall = struct {
584654 }
585655};
586656
587pub const NodeCall = struct {
588 base: Node,
589 callee: &Node,
590 params: ArrayList(&Node),
591 rparen_token: Token,
592
593 pub fn iterate(self: &NodeCall, index: usize) ?&Node {
594 var i = index;
595
596 if (i < 1) return self.callee;
597 i -= 1;
598
599 if (i < self.params.len) return self.params.at(i);
600 i -= self.params.len;
601
602 return null;
603 }
604
605 pub fn firstToken(self: &NodeCall) Token {
606 return self.callee.firstToken();
607 }
608
609 pub fn lastToken(self: &NodeCall) Token {
610 return self.rparen_token;
611 }
612};
613
614pub const NodeArrayAccess = struct {
615 base: Node,
616 expr: &Node,
617 index: &Node,
618 rbracket_token: Token,
619
620 pub fn iterate(self: &NodeArrayAccess, index: usize) ?&Node {
621 var i = index;
622
623 if (i < 1) return self.expr;
624 i -= 1;
625
626 if (i < 1) return self.index;
627 i -= 1;
628
629 return null;
630 }
631
632 pub fn firstToken(self: &NodeArrayAccess) Token {
633 return self.expr.firstToken();
634 }
635
636 pub fn lastToken(self: &NodeArrayAccess) Token {
637 return self.rbracket_token;
638 }
639};
640
641pub const NodeSliceExpression = struct {
642 base: Node,
643 expr: &Node,
644 start: &Node,
645 end: ?&Node,
646 rbracket_token: Token,
647
648 pub fn iterate(self: &NodeSliceExpression, index: usize) ?&Node {
649 var i = index;
650
651 if (i < 1) return self.callee;
652 i -= 1;
653
654 if (i < 1) return self.start;
655 i -= 1;
656
657 if (i < 1) return self.end;
658 i -= 1;
659
660 return null;
661 }
662
663 pub fn firstToken(self: &NodeSliceExpression) Token {
664 return self.expr.firstToken();
665 }
666
667 pub fn lastToken(self: &NodeSliceExpression) Token {
668 return self.rbracket_token;
669 }
670};
671
672657pub const NodeStringLiteral = struct {
673658 base: Node,
674659 token: Token,
std/zig/parser.zig+77-86
......@@ -87,7 +87,7 @@ pub const Parser = struct {
8787 AfterOperand,
8888 InfixOp: &ast.NodeInfixOp,
8989 PrefixOp: &ast.NodePrefixOp,
90 SuffixOp: &ast.Node,
90 SuffixOp: &ast.NodeSuffixOp,
9191 SliceOrArrayAccess,
9292 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
9393 TypeExpr: DestPtr,
......@@ -602,20 +602,19 @@ pub const Parser = struct {
602602 } else if (token.id == Token.Id.LParen) {
603603 self.putBackToken(token);
604604
605 const node = try arena.create(ast.NodeCall);
606 *node = ast.NodeCall {
607 .base = self.initNode(ast.Node.Id.Call),
608 .callee = undefined,
609 .params = ArrayList(&ast.Node).init(arena),
610 .rparen_token = undefined,
611 };
612 try stack.append(State { .SuffixOp = &node.base });
605 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
606 .Call = ast.NodeSuffixOp.CallInfo {
607 .params = ArrayList(&ast.Node).init(arena),
608 .is_async = false, // TODO: ASYNC
609 }
610 });
611 try stack.append(State { .SuffixOp = node });
613612 try stack.append(State.AfterOperand);
614 try stack.append(State {.ExprListItemOrEnd = &node.params });
613 try stack.append(State {.ExprListItemOrEnd = &node.op.Call.params });
615614 try stack.append(State {
616615 .ExpectTokenSave = ExpectTokenSave {
617616 .id = Token.Id.LParen,
618 .ptr = &node.rparen_token,
617 .ptr = &node.rtoken,
619618 },
620619 });
621620 continue;
......@@ -643,16 +642,14 @@ pub const Parser = struct {
643642
644643 switch (rbracket_or_ellipsis2_token.id) {
645644 Token.Id.Ellipsis2 => {
646 const node = try arena.create(ast.NodeSliceExpression);
647 *node = ast.NodeSliceExpression {
648 .base = self.initNode(ast.Node.Id.SliceExpression),
649 .expr = undefined,
650 .start = expression,
651 .end = null,
652 .rbracket_token = undefined,
653 };
654
655 try stack.append(State { .SuffixOp = &node.base });
645 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
646 .Slice = ast.NodeSuffixOp.SliceRange {
647 .start = expression,
648 .end = null,
649 }
650 });
651
652 try stack.append(State { .SuffixOp = node });
656653 try stack.append(State.AfterOperand);
657654
658655 const rbracket_token = self.getNextToken();
......@@ -661,24 +658,21 @@ pub const Parser = struct {
661658 try stack.append(State {
662659 .ExpectTokenSave = ExpectTokenSave {
663660 .id = Token.Id.RBracket,
664 .ptr = &node.rbracket_token,
661 .ptr = &node.rtoken,
665662 }
666663 });
667 try stack.append(State { .Expression = DestPtr { .NullableField = &node.end } });
664 try stack.append(State { .Expression = DestPtr { .NullableField = &node.op.Slice.end } });
668665 } else {
669 node.rbracket_token = rbracket_token;
666 node.rtoken = rbracket_token;
670667 }
671668 break;
672669 },
673670 Token.Id.RBracket => {
674 const node = try arena.create(ast.NodeArrayAccess);
675 *node = ast.NodeArrayAccess {
676 .base = self.initNode(ast.Node.Id.ArrayAccess),
677 .expr = undefined,
678 .index = expression,
679 .rbracket_token = token,
680 };
681 try stack.append(State { .SuffixOp = &node.base });
671 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
672 .ArrayAccess = expression
673 });
674 node.rtoken = token;
675 try stack.append(State { .SuffixOp = node });
682676 try stack.append(State.AfterOperand);
683677 break;
684678 },
......@@ -950,27 +944,8 @@ pub const Parser = struct {
950944 while (true) {
951945 switch (stack.pop()) {
952946 State.SuffixOp => |suffix_op| {
953 switch (suffix_op.id) {
954 ast.Node.Id.Call => {
955 const call = @fieldParentPtr(ast.NodeCall, "base", suffix_op);
956 *left_leaf_ptr = &call.base;
957 left_leaf_ptr = &call.callee;
958 continue;
959 },
960 ast.Node.Id.ArrayAccess => {
961 const arr_access = @fieldParentPtr(ast.NodeArrayAccess, "base", suffix_op);
962 *left_leaf_ptr = &arr_access.base;
963 left_leaf_ptr = &arr_access.expr;
964 continue;
965 },
966 ast.Node.Id.SliceExpression => {
967 const slice_expr = @fieldParentPtr(ast.NodeSliceExpression, "base", suffix_op);
968 *left_leaf_ptr = &slice_expr.base;
969 left_leaf_ptr = &slice_expr.expr;
970 continue;
971 },
972 else => unreachable,
973 }
947 *left_leaf_ptr = &suffix_op.base;
948 left_leaf_ptr = &suffix_op.lhs;
974949 },
975950 State.Operand => |operand| {
976951 *left_leaf_ptr = operand;
......@@ -1172,6 +1147,18 @@ pub const Parser = struct {
11721147 return node;
11731148 }
11741149
1150 fn createSuffixOp(self: &Parser, arena: &mem.Allocator, op: &const ast.NodeSuffixOp.SuffixOp) !&ast.NodeSuffixOp {
1151 const node = try arena.create(ast.NodeSuffixOp);
1152
1153 *node = ast.NodeSuffixOp {
1154 .base = self.initNode(ast.Node.Id.SuffixOp),
1155 .lhs = undefined,
1156 .op = *op,
1157 .rtoken = undefined,
1158 };
1159 return node;
1160 }
1161
11751162 fn createIdentifier(self: &Parser, arena: &mem.Allocator, name_token: &const Token) !&ast.NodeIdentifier {
11761163 const node = try arena.create(ast.NodeIdentifier);
11771164
......@@ -1625,6 +1612,43 @@ pub const Parser = struct {
16251612 ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"),
16261613 }
16271614 },
1615 ast.Node.Id.SuffixOp => {
1616 const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", base);
1617
1618 switch (suffix_op.op) {
1619 ast.NodeSuffixOp.SuffixOp.Call => |call_info| {
1620 try stack.append(RenderState { .Text = ")"});
1621 var i = call_info.params.len;
1622 while (i != 0) {
1623 i -= 1;
1624 const param_node = call_info.params.at(i);
1625 try stack.append(RenderState { .Expression = param_node});
1626 if (i != 0) {
1627 try stack.append(RenderState { .Text = ", " });
1628 }
1629 }
1630 try stack.append(RenderState { .Text = "("});
1631 },
1632 ast.NodeSuffixOp.SuffixOp.ArrayAccess => |index_expr| {
1633 try stack.append(RenderState { .Text = "]"});
1634 try stack.append(RenderState { .Expression = index_expr});
1635 try stack.append(RenderState { .Text = "["});
1636 },
1637 ast.NodeSuffixOp.SuffixOp.Slice => |range| {
1638 try stack.append(RenderState { .Text = "]"});
1639 if (range.end) |end| {
1640 try stack.append(RenderState { .Expression = end});
1641 }
1642 try stack.append(RenderState { .Text = ".."});
1643 try stack.append(RenderState { .Expression = range.start});
1644 try stack.append(RenderState { .Text = "["});
1645 },
1646 ast.NodeSuffixOp.SuffixOp.StructInitializer => @panic("TODO: StructInitializer"),
1647 ast.NodeSuffixOp.SuffixOp.ArrayInitializer => @panic("TODO: ArrayInitializer"),
1648 }
1649
1650 try stack.append(RenderState { .Expression = suffix_op.lhs });
1651 },
16281652 ast.Node.Id.IntegerLiteral => {
16291653 const integer_literal = @fieldParentPtr(ast.NodeIntegerLiteral, "base", base);
16301654 try stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token));
......@@ -1693,39 +1717,6 @@ pub const Parser = struct {
16931717 }
16941718 }
16951719 },
1696 ast.Node.Id.Call => {
1697 const call = @fieldParentPtr(ast.NodeCall, "base", base);
1698 try stack.append(RenderState { .Text = ")"});
1699 var i = call.params.len;
1700 while (i != 0) {
1701 i -= 1;
1702 const param_node = call.params.at(i);
1703 try stack.append(RenderState { .Expression = param_node});
1704 if (i != 0) {
1705 try stack.append(RenderState { .Text = ", " });
1706 }
1707 }
1708 try stack.append(RenderState { .Text = "("});
1709 try stack.append(RenderState { .Expression = call.callee });
1710 },
1711 ast.Node.Id.ArrayAccess => {
1712 const arr_access = @fieldParentPtr(ast.NodeArrayAccess, "base", base);
1713 try stack.append(RenderState { .Text = "]"});
1714 try stack.append(RenderState { .Expression = arr_access.index});
1715 try stack.append(RenderState { .Text = "["});
1716 try stack.append(RenderState { .Expression = arr_access.expr });
1717 },
1718 ast.Node.Id.SliceExpression => {
1719 const slice_expr = @fieldParentPtr(ast.NodeSliceExpression, "base", base);
1720 try stack.append(RenderState { .Text = "]"});
1721 if (slice_expr.end) |end| {
1722 try stack.append(RenderState { .Expression = end});
1723 }
1724 try stack.append(RenderState { .Text = ".."});
1725 try stack.append(RenderState { .Expression = slice_expr.start});
1726 try stack.append(RenderState { .Text = "["});
1727 try stack.append(RenderState { .Expression = slice_expr.expr});
1728 },
17291720 ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"),
17301721 ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"),
17311722