authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-01 22:02:51+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-01 22:02:51+02:00
logb9093185f748293064e7eeaaa07e7479099420ed
treea45b7d49eeb362bef91d78eff9f5e87e21183c18
parentdf09c01f7f141a384010d17ab23db3b36316f5b6

std.zig.parser now parses slicing and array access


3 files changed, 170 insertions(+), 0 deletions(-)

std/zig/ast.zig+66
......@@ -30,6 +30,8 @@ pub const Node = struct {
3030 ErrorType,
3131 BuiltinCall,
3232 Call,
33 ArrayAccess,
34 SliceExpression,
3335 LineComment,
3436 TestDecl,
3537 };
......@@ -57,6 +59,8 @@ pub const Node = struct {
5759 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).iterate(index),
5860 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),
5961 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),
6064 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).iterate(index),
6165 Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).iterate(index),
6266 };
......@@ -85,6 +89,8 @@ pub const Node = struct {
8589 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).firstToken(),
8690 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).firstToken(),
8791 Id.Call => @fieldParentPtr(NodeCall, "base", base).firstToken(),
92 Id.ArrayAccess => @fieldParentPtr(NodeArrayAccess, "base", base).firstToken(),
93 Id.SliceExpression => @fieldParentPtr(NodeSliceExpression, "base", base).firstToken(),
8894 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).firstToken(),
8995 Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).firstToken(),
9096 };
......@@ -113,6 +119,8 @@ pub const Node = struct {
113119 Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).lastToken(),
114120 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).lastToken(),
115121 Id.Call => @fieldParentPtr(NodeCall, "base", base).lastToken(),
122 Id.ArrayAccess => @fieldParentPtr(NodeArrayAccess, "base", base).lastToken(),
123 Id.SliceExpression => @fieldParentPtr(NodeSliceExpression, "base", base).lastToken(),
116124 Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).lastToken(),
117125 Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).lastToken(),
118126 };
......@@ -598,6 +606,64 @@ pub const NodeCall = struct {
598606 }
599607};
600608
609pub const NodeArrayAccess = struct {
610 base: Node,
611 expr: &Node,
612 index: &Node,
613 rbracket_token: Token,
614
615 pub fn iterate(self: &NodeArrayAccess, index: usize) ?&Node {
616 var i = index;
617
618 if (i < 1) return self.expr;
619 i -= 1;
620
621 if (i < 1) return self.index;
622 i -= 1;
623
624 return null;
625 }
626
627 pub fn firstToken(self: &NodeArrayAccess) Token {
628 return self.expr.firstToken();
629 }
630
631 pub fn lastToken(self: &NodeArrayAccess) Token {
632 return self.rbracket_token;
633 }
634};
635
636pub const NodeSliceExpression = struct {
637 base: Node,
638 expr: &Node,
639 start: &Node,
640 end: ?&Node,
641 rbracket_token: Token,
642
643 pub fn iterate(self: &NodeSliceExpression, index: usize) ?&Node {
644 var i = index;
645
646 if (i < 1) return self.callee;
647 i -= 1;
648
649 if (i < 1) return self.start;
650 i -= 1;
651
652 if (i < 1) return self.end;
653 i -= 1;
654
655 return null;
656 }
657
658 pub fn firstToken(self: &NodeSliceExpression) Token {
659 return self.expr.firstToken();
660 }
661
662 pub fn lastToken(self: &NodeSliceExpression) Token {
663 return self.rbracket_token;
664 }
665};
666
601667pub const NodeStringLiteral = struct {
602668 base: Node,
603669 token: Token,
std/zig/parser.zig+92
......@@ -88,6 +88,7 @@ pub const Parser = struct {
8888 InfixOp: &ast.NodeInfixOp,
8989 PrefixOp: &ast.NodePrefixOp,
9090 SuffixOp: &ast.Node,
91 SliceOrArrayAccess,
9192 AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
9293 TypeExpr: DestPtr,
9394 VarDecl: &ast.NodeVarDecl,
......@@ -590,6 +591,11 @@ pub const Parser = struct {
590591 });
591592 continue;
592593
594 } else if (token.id == Token.Id.LBracket) {
595 try stack.append(State.SliceOrArrayAccess);
596 try stack.append(State.ExpectOperand);
597 continue;
598
593599 // TODO: Parse postfix operator
594600 } else {
595601 // no postfix/infix operator after this operand.
......@@ -603,6 +609,53 @@ pub const Parser = struct {
603609 try dest_ptr.store(expression);
604610 break;
605611 },
612 State.SliceOrArrayAccess => {
613 var rbracket_or_ellipsis2_token = self.getNextToken();
614
615 switch (rbracket_or_ellipsis2_token.id) {
616 Token.Id.Ellipsis2 => {
617 const node = try arena.create(ast.NodeSliceExpression);
618 *node = ast.NodeSliceExpression {
619 .base = self.initNode(ast.Node.Id.SliceExpression),
620 .expr = undefined,
621 .start = expression,
622 .end = null,
623 .rbracket_token = undefined,
624 };
625
626 try stack.append(State { .SuffixOp = &node.base });
627 try stack.append(State.AfterOperand);
628
629 const rbracket_token = self.getNextToken();
630 if (rbracket_token.id != Token.Id.RBracket) {
631 self.putBackToken(rbracket_token);
632 try stack.append(State {
633 .ExpectTokenSave = ExpectTokenSave {
634 .id = Token.Id.RBracket,
635 .ptr = &node.rbracket_token,
636 }
637 });
638 try stack.append(State { .Expression = DestPtr { .NullableField = &node.end } });
639 } else {
640 node.rbracket_token = rbracket_token;
641 }
642 break;
643 },
644 Token.Id.RBracket => {
645 const node = try arena.create(ast.NodeArrayAccess);
646 *node = ast.NodeArrayAccess {
647 .base = self.initNode(ast.Node.Id.ArrayAccess),
648 .expr = undefined,
649 .index = expression,
650 .rbracket_token = token,
651 };
652 try stack.append(State { .SuffixOp = &node.base });
653 try stack.append(State.AfterOperand);
654 break;
655 },
656 else => return self.parseError(token, "expected ']' or '..', found {}", @tagName(token.id))
657 }
658 },
606659 State.InfixOp => |infix_op| {
607660 infix_op.rhs = expression;
608661 infix_op.lhs = popSuffixOp(&stack);
......@@ -857,6 +910,7 @@ pub const Parser = struct {
857910 State.PrefixOp => unreachable,
858911 State.SuffixOp => unreachable,
859912 State.Operand => unreachable,
913 State.SliceOrArrayAccess => unreachable,
860914 }
861915 }
862916 }
......@@ -874,6 +928,18 @@ pub const Parser = struct {
874928 left_leaf_ptr = &call.callee;
875929 continue;
876930 },
931 ast.Node.Id.ArrayAccess => {
932 const arr_access = @fieldParentPtr(ast.NodeArrayAccess, "base", suffix_op);
933 *left_leaf_ptr = &arr_access.base;
934 left_leaf_ptr = &arr_access.expr;
935 continue;
936 },
937 ast.Node.Id.SliceExpression => {
938 const slice_expr = @fieldParentPtr(ast.NodeSliceExpression, "base", suffix_op);
939 *left_leaf_ptr = &slice_expr.base;
940 left_leaf_ptr = &slice_expr.expr;
941 continue;
942 },
877943 else => unreachable,
878944 }
879945 },
......@@ -1594,6 +1660,24 @@ pub const Parser = struct {
15941660 try stack.append(RenderState { .Text = "("});
15951661 try stack.append(RenderState { .Expression = call.callee });
15961662 },
1663 ast.Node.Id.ArrayAccess => {
1664 const arr_access = @fieldParentPtr(ast.NodeArrayAccess, "base", base);
1665 try stack.append(RenderState { .Text = "]"});
1666 try stack.append(RenderState { .Expression = arr_access.index});
1667 try stack.append(RenderState { .Text = "["});
1668 try stack.append(RenderState { .Expression = arr_access.expr });
1669 },
1670 ast.Node.Id.SliceExpression => {
1671 const slice_expr = @fieldParentPtr(ast.NodeSliceExpression, "base", base);
1672 try stack.append(RenderState { .Text = "]"});
1673 if (slice_expr.end) |end| {
1674 try stack.append(RenderState { .Expression = end});
1675 }
1676 try stack.append(RenderState { .Text = ".."});
1677 try stack.append(RenderState { .Expression = slice_expr.start});
1678 try stack.append(RenderState { .Text = "["});
1679 try stack.append(RenderState { .Expression = slice_expr.expr});
1680 },
15971681 ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"),
15981682 ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"),
15991683
......@@ -1978,6 +2062,14 @@ test "zig fmt: indexing" {
19782062 \\ a[0 + 5];
19792063 \\ a[0..];
19802064 \\ a[0..5];
2065 \\ a[a[0]];
2066 \\ a[a[0..]];
2067 \\ a[a[0..5]];
2068 \\ a[a[0]..];
2069 \\ a[a[0..5]..];
2070 \\ a[a[0]..a[0]];
2071 \\ a[a[0..5]..a[0]];
2072 \\ a[a[0..5]..a[0..5]];
19812073 \\}
19822074 \\
19832075 );
std/zig/tokenizer.zig+12
......@@ -91,6 +91,8 @@ pub const Token = struct {
9191 PercentEqual,
9292 LBrace,
9393 RBrace,
94 LBracket,
95 RBracket,
9496 Period,
9597 Ellipsis2,
9698 Ellipsis3,
......@@ -327,6 +329,16 @@ pub const Tokenizer = struct {
327329 self.index += 1;
328330 break;
329331 },
332 '[' => {
333 result.id = Token.Id.LBracket;
334 self.index += 1;
335 break;
336 },
337 ']' => {
338 result.id = Token.Id.RBracket;
339 self.index += 1;
340 break;
341 },
330342 ';' => {
331343 result.id = Token.Id.Semicolon;
332344 self.index += 1;