authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-03 14:53:27+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-03 14:53:27+02:00
log5c82ed2ea9360ea0931ba789a4ffb73d689b6a72
treebb1c50ed56c5276b682ac39782688d9c11e55f71
parent0b9247fb636a47add80f7c4ec194df436629df91

std.zig.parser now parses initializers... Or, it would, if it worked


2 files changed, 125 insertions(+), 28 deletions(-)

std/zig/ast.zig+2-2
...@@ -532,7 +532,7 @@ pub const NodePrefixOp = struct {...@@ -532,7 +532,7 @@ pub const NodePrefixOp = struct {
532532
533pub const NodeFieldInitializer = struct {533pub const NodeFieldInitializer = struct {
534 base: Node,534 base: Node,
535 dot_token: Token,535 period_token: Token,
536 name_token: Token,536 name_token: Token,
537 expr: &Node,537 expr: &Node,
538538
...@@ -546,7 +546,7 @@ pub const NodeFieldInitializer = struct {...@@ -546,7 +546,7 @@ pub const NodeFieldInitializer = struct {
546 }546 }
547547
548 pub fn firstToken(self: &NodeFieldInitializer) Token {548 pub fn firstToken(self: &NodeFieldInitializer) Token {
549 return self.dot_token;549 return self.period_token;
550 }550 }
551551
552 pub fn lastToken(self: &NodeFieldInitializer) Token {552 pub fn lastToken(self: &NodeFieldInitializer) Token {
std/zig/parser.zig+123-26
...@@ -75,14 +75,17 @@ pub const Parser = struct {...@@ -75,14 +75,17 @@ pub const Parser = struct {
75 const ExpectTokenSave = struct {75 const ExpectTokenSave = struct {
76 id: Token.Id,76 id: Token.Id,
77 ptr: &Token,77 ptr: &Token,
78 };
7978
80 const ExprListState = struct {
81 list: &ArrayList(&ast.Node),
82 end: Token.Id,
83 ptr: &Token,
84 };79 };
8580
81 fn ListState(comptime T: type) type {
82 return struct {
83 list: &ArrayList(T),
84 end: Token.Id,
85 ptr: &Token,
86 };
87 }
88
86 const State = union(enum) {89 const State = union(enum) {
87 TopLevel,90 TopLevel,
88 TopLevelExtern: ?Token,91 TopLevelExtern: ?Token,
...@@ -110,8 +113,10 @@ pub const Parser = struct {...@@ -110,8 +113,10 @@ pub const Parser = struct {
110 FnDef: &ast.NodeFnProto,113 FnDef: &ast.NodeFnProto,
111 Block: &ast.NodeBlock,114 Block: &ast.NodeBlock,
112 Statement: &ast.NodeBlock,115 Statement: &ast.NodeBlock,
113 ExprListItemOrEnd: ExprListState,116 ExprListItemOrEnd: ListState(&ast.Node),
114 ExprListCommaOrEnd: ExprListState,117 ExprListCommaOrEnd: ListState(&ast.Node),
118 FieldInitListItemOrEnd: ListState(&ast.NodeFieldInitializer),
119 FieldInitListCommaOrEnd: ListState(&ast.NodeFieldInitializer),
115 };120 };
116121
117 /// Returns an AST tree, allocated with the parser's allocator.122 /// Returns an AST tree, allocated with the parser's allocator.
...@@ -536,7 +541,7 @@ pub const Parser = struct {...@@ -536,7 +541,7 @@ pub const Parser = struct {
536 });541 });
537 try stack.append(State.AfterOperand);542 try stack.append(State.AfterOperand);
538 try stack.append(State {543 try stack.append(State {
539 .ExprListItemOrEnd = ExprListState {544 .ExprListItemOrEnd = ListState(&ast.Node) {
540 .list = &node.params,545 .list = &node.params,
541 .end = Token.Id.RParen,546 .end = Token.Id.RParen,
542 .ptr = &node.rparen_token,547 .ptr = &node.rparen_token,
...@@ -647,8 +652,6 @@ pub const Parser = struct {...@@ -647,8 +652,6 @@ pub const Parser = struct {
647 continue;652 continue;
648653
649 } else if (token.id == Token.Id.LParen) {654 } else if (token.id == Token.Id.LParen) {
650 self.putBackToken(token);
651
652 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {655 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
653 .Call = ast.NodeSuffixOp.CallInfo {656 .Call = ast.NodeSuffixOp.CallInfo {
654 .params = ArrayList(&ast.Node).init(arena),657 .params = ArrayList(&ast.Node).init(arena),
...@@ -658,18 +661,12 @@ pub const Parser = struct {...@@ -658,18 +661,12 @@ pub const Parser = struct {
658 try stack.append(State { .SuffixOp = node });661 try stack.append(State { .SuffixOp = node });
659 try stack.append(State.AfterOperand);662 try stack.append(State.AfterOperand);
660 try stack.append(State {663 try stack.append(State {
661 .ExprListItemOrEnd = ExprListState {664 .ExprListItemOrEnd = ListState(&ast.Node) {
662 .list = &node.op.Call.params,665 .list = &node.op.Call.params,
663 .end = Token.Id.RParen,666 .end = Token.Id.RParen,
664 .ptr = &node.rtoken,667 .ptr = &node.rtoken,
665 }668 }
666 });669 });
667 try stack.append(State {
668 .ExpectTokenSave = ExpectTokenSave {
669 .id = Token.Id.LParen,
670 .ptr = &node.rtoken,
671 },
672 });
673 continue;670 continue;
674671
675 } else if (token.id == Token.Id.LBracket) {672 } else if (token.id == Token.Id.LBracket) {
...@@ -686,6 +683,47 @@ pub const Parser = struct {...@@ -686,6 +683,47 @@ pub const Parser = struct {
686 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayAccess }});683 try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayAccess }});
687 continue;684 continue;
688685
686 // TODO: This is the initializer parsing code. It doesn't work because of
687 // the ambiguity between function bodies and initializers:
688 // fn main() void {} or fn main() (void {})
689 } else if (false) { //(token.id == Token.Id.LBrace) {
690 const next = self.getNextToken();
691
692 switch (next.id) {
693 Token.Id.Period => {
694 self.putBackToken(token);
695
696 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
697 .StructInitializer = ArrayList(&ast.NodeFieldInitializer).init(arena),
698 });
699
700 try stack.append(State {
701 .FieldInitListItemOrEnd = ListState(&ast.NodeFieldInitializer) {
702 .list = &node.op.StructInitializer,
703 .end = Token.Id.RBrace,
704 .ptr = &node.rtoken,
705 }
706 });
707 continue;
708 },
709 else => {
710 self.putBackToken(token);
711
712 const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
713 .ArrayInitializer = ArrayList(&ast.Node).init(arena),
714 });
715
716 try stack.append(State {
717 .ExprListItemOrEnd = ListState(&ast.Node) {
718 .list = &node.op.ArrayInitializer,
719 .end = Token.Id.RBrace,
720 .ptr = &node.rtoken,
721 }
722 });
723 continue;
724 },
725 }
726
689 // TODO: Parse postfix operator727 // TODO: Parse postfix operator
690 } else {728 } else {
691 // no postfix/infix operator after this operand.729 // no postfix/infix operator after this operand.
...@@ -717,30 +755,89 @@ pub const Parser = struct {...@@ -717,30 +755,89 @@ pub const Parser = struct {
717 }755 }
718 },756 },
719757
720 State.ExprListItemOrEnd => |expr_list_state| {758 State.ExprListItemOrEnd => |list_state| {
759 var token = self.getNextToken();
760
761 const IdTag = @TagType(Token.Id);
762 if (IdTag(list_state.end) == token.id) {
763 *list_state.ptr = token;
764 continue;
765 }
766
767 self.putBackToken(token);
768 stack.append(State { .ExprListCommaOrEnd = list_state }) catch unreachable;
769 try stack.append(State { .Expression = DestPtr{.List = list_state.list} });
770 },
771
772 State.ExprListCommaOrEnd => |list_state| {
721 var token = self.getNextToken();773 var token = self.getNextToken();
722 switch (token.id) {774 switch (token.id) {
723 Token.Id.RParen => continue,775 Token.Id.Comma => {
776 stack.append(State { .ExprListItemOrEnd = list_state }) catch unreachable;
777 },
724 else => {778 else => {
725 self.putBackToken(token);779 const IdTag = @TagType(Token.Id);
726 stack.append(State { .ExprListCommaOrEnd = expr_list_state }) catch unreachable;780 if (IdTag(list_state.end) == token.id) {
727 try stack.append(State { .Expression = DestPtr{.List = expr_list_state.list} });781 *list_state.ptr = token;
782 continue;
783 }
784
785 return self.parseError(token, "expected ',' or {}, found {}", @tagName(list_state.end), @tagName(token.id));
728 },786 },
729 }787 }
730 },788 },
731789
732 State.ExprListCommaOrEnd => |expr_list_state| {790 State.FieldInitListItemOrEnd => |list_state| {
791 var token = self.getNextToken();
792
793 const IdTag = @TagType(Token.Id);
794 if (IdTag(list_state.end) == token.id){
795 *list_state.ptr = token;
796 continue;
797 }
798
799 self.putBackToken(token);
800
801 const node = try arena.create(ast.NodeFieldInitializer);
802 *node = ast.NodeFieldInitializer {
803 .base = self.initNode(ast.Node.Id.FieldInitializer),
804 .period_token = undefined,
805 .name_token = undefined,
806 .expr = undefined,
807 };
808 try list_state.list.append(node);
809
810 stack.append(State { .FieldInitListCommaOrEnd = list_state }) catch unreachable;
811 try stack.append(State { .Expression = DestPtr{.Field = &node.expr} });
812 try stack.append(State { .ExpectToken = Token.Id.Equal });
813 try stack.append(State {
814 .ExpectTokenSave = ExpectTokenSave {
815 .id = Token.Id.Identifier,
816 .ptr = &node.name_token,
817 }
818 });
819 try stack.append(State {
820 .ExpectTokenSave = ExpectTokenSave {
821 .id = Token.Id.Period,
822 .ptr = &node.period_token,
823 }
824 });
825 },
826
827 State.FieldInitListCommaOrEnd => |list_state| {
733 var token = self.getNextToken();828 var token = self.getNextToken();
734 switch (token.id) {829 switch (token.id) {
735 Token.Id.Comma => {830 Token.Id.Comma => {
736 stack.append(State { .ExprListItemOrEnd = expr_list_state }) catch unreachable;831 stack.append(State { .FieldInitListItemOrEnd = list_state }) catch unreachable;
737 },832 },
738 else => {833 else => {
739 const IdTag = @TagType(Token.Id);834 const IdTag = @TagType(Token.Id);
740 if (IdTag(expr_list_state.end) == token.id)835 if (IdTag(list_state.end) == token.id) {
836 *list_state.ptr = token;
741 continue;837 continue;
838 }
742839
743 return self.parseError(token, "expected ',' or {}, found {}", @tagName(expr_list_state.end), @tagName(token.id));840 return self.parseError(token, "expected ',' or {}, found {}", @tagName(list_state.end), @tagName(token.id));
744 },841 },
745 }842 }
746 },843 },