authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-09 12:51:18+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-09 12:51:18+02:00
logc19f5a2356b441e3dde95e85e029fec6ef4f836d
tree35c83611aec9775dc3018ac709f53fb726c38487
parent7dd55a8007c540415d3e704e490609dd86bea924

std.zig.parser now parses if statements


2 files changed, 137 insertions(+), 11 deletions(-)

std/zig/ast.zig+47
...@@ -29,6 +29,7 @@ pub const Node = struct {...@@ -29,6 +29,7 @@ pub const Node = struct {
29 SwitchElse,29 SwitchElse,
30 While,30 While,
31 For,31 For,
32 If,
32 InfixOp,33 InfixOp,
33 PrefixOp,34 PrefixOp,
34 SuffixOp,35 SuffixOp,
...@@ -73,6 +74,7 @@ pub const Node = struct {...@@ -73,6 +74,7 @@ pub const Node = struct {
73 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).iterate(index),74 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).iterate(index),
74 Id.While => @fieldParentPtr(NodeWhile, "base", base).iterate(index),75 Id.While => @fieldParentPtr(NodeWhile, "base", base).iterate(index),
75 Id.For => @fieldParentPtr(NodeFor, "base", base).iterate(index),76 Id.For => @fieldParentPtr(NodeFor, "base", base).iterate(index),
77 Id.If => @fieldParentPtr(NodeIf, "base", base).iterate(index),
76 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index),78 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index),
77 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),79 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
78 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),80 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
...@@ -118,6 +120,7 @@ pub const Node = struct {...@@ -118,6 +120,7 @@ pub const Node = struct {
118 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).firstToken(),120 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).firstToken(),
119 Id.While => @fieldParentPtr(NodeWhile, "base", base).firstToken(),121 Id.While => @fieldParentPtr(NodeWhile, "base", base).firstToken(),
120 Id.For => @fieldParentPtr(NodeFor, "base", base).firstToken(),122 Id.For => @fieldParentPtr(NodeFor, "base", base).firstToken(),
123 Id.If => @fieldParentPtr(NodeIf, "base", base).firstToken(),
121 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),124 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),
122 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),125 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
123 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),126 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
...@@ -163,6 +166,7 @@ pub const Node = struct {...@@ -163,6 +166,7 @@ pub const Node = struct {
163 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).lastToken(),166 Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).lastToken(),
164 Id.While => @fieldParentPtr(NodeWhile, "base", base).lastToken(),167 Id.While => @fieldParentPtr(NodeWhile, "base", base).lastToken(),
165 Id.For => @fieldParentPtr(NodeFor, "base", base).lastToken(),168 Id.For => @fieldParentPtr(NodeFor, "base", base).lastToken(),
169 Id.If => @fieldParentPtr(NodeIf, "base", base).lastToken(),
166 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),170 Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),
167 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),171 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
168 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),172 Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
...@@ -867,6 +871,49 @@ pub const NodeFor = struct {...@@ -867,6 +871,49 @@ pub const NodeFor = struct {
867 }871 }
868};872};
869873
874pub const NodeIf = struct {
875 base: Node,
876 if_token: Token,
877 condition: &Node,
878 payload: ?&NodeValuePayload,
879 body: &Node,
880 @"else": ?&NodeElse,
881
882 pub fn iterate(self: &NodeIf, index: usize) ?&Node {
883 var i = index;
884
885 if (i < 1) return self.condition;
886 i -= 1;
887
888 if (self.payload) |payload| {
889 if (i < 1) return &payload.base;
890 i -= 1;
891 }
892
893 if (i < 1) return self.body;
894 i -= 1;
895
896 if (self.@"else") |@"else"| {
897 if (i < 1) return &@"else".base;
898 i -= 1;
899 }
900
901 return null;
902 }
903
904 pub fn firstToken(self: &NodeIf) Token {
905 return self.if_token;
906 }
907
908 pub fn lastToken(self: &NodeIf) Token {
909 if (self.@"else") |@"else"| {
910 return @"else".body.lastToken();
911 }
912
913 return self.body.lastToken();
914 }
915};
916
870pub const NodeInfixOp = struct {917pub const NodeInfixOp = struct {
871 base: Node,918 base: Node,
872 op_token: Token,919 op_token: Token,
std/zig/parser.zig+90-11
...@@ -1449,7 +1449,24 @@ pub const Parser = struct {...@@ -1449,7 +1449,24 @@ pub const Parser = struct {
1449 @panic("TODO: inline asm");1449 @panic("TODO: inline asm");
1450 },1450 },
1451 Token.Id.Keyword_if => {1451 Token.Id.Keyword_if => {
1452 @panic("TODO: inline if");1452 const node = try arena.create(ast.NodeIf);
1453 *node = ast.NodeIf {
1454 .base = self.initNode(ast.Node.Id.If),
1455 .if_token = token,
1456 .condition = undefined,
1457 .payload = null,
1458 .body = undefined,
1459 .@"else" = null,
1460 };
1461 dest_ptr.store(&node.base);
1462
1463 stack.append(State { .Else = &node.@"else" }) catch unreachable;
1464 try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
1465 try stack.append(State { .ValuePayload = &node.payload });
1466 try stack.append(State { .ExpectToken = Token.Id.RParen });
1467 try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
1468 try stack.append(State { .ExpectToken = Token.Id.LParen });
1469 continue;
1453 },1470 },
1454 Token.Id.Keyword_inline => {1471 Token.Id.Keyword_inline => {
1455 stack.append(State {1472 stack.append(State {
...@@ -2188,6 +2205,15 @@ pub const Parser = struct {...@@ -2188,6 +2205,15 @@ pub const Parser = struct {
21882205
2189 n = for_node.body;2206 n = for_node.body;
2190 },2207 },
2208 ast.Node.Id.If => {
2209 const if_node = @fieldParentPtr(ast.NodeIf, "base", n);
2210 if (if_node.@"else") |@"else"| {
2211 n = @"else".base;
2212 continue;
2213 }
2214
2215 n = if_node.body;
2216 },
2191 ast.Node.Id.Else => {2217 ast.Node.Id.Else => {
2192 const else_node = @fieldParentPtr(ast.NodeElse, "base", n);2218 const else_node = @fieldParentPtr(ast.NodeElse, "base", n);
2193 n = else_node.body;2219 n = else_node.body;
...@@ -3363,14 +3389,19 @@ pub const Parser = struct {...@@ -3363,14 +3389,19 @@ pub const Parser = struct {
3363 const else_node = @fieldParentPtr(ast.NodeElse, "base", base);3389 const else_node = @fieldParentPtr(ast.NodeElse, "base", base);
3364 try stream.print("{} ", self.tokenizer.getTokenSlice(else_node.else_token));3390 try stream.print("{} ", self.tokenizer.getTokenSlice(else_node.else_token));
33653391
3366 if (else_node.body.id == ast.Node.Id.Block) {3392 switch (else_node.body.id) {
3367 try stack.append(RenderState { .Expression = else_node.body });3393 ast.Node.Id.Block, ast.Node.Id.If,
3368 } else {3394 ast.Node.Id.For, ast.Node.Id.While,
3369 try stack.append(RenderState { .Indent = indent });3395 ast.Node.Id.Switch => {
3370 try stack.append(RenderState { .Expression = else_node.body });3396 try stack.append(RenderState { .Expression = else_node.body });
3371 try stack.append(RenderState.PrintIndent);3397 },
3372 try stack.append(RenderState { .Indent = indent + indent_delta });3398 else => {
3373 try stack.append(RenderState { .Text = "\n" });3399 try stack.append(RenderState { .Indent = indent });
3400 try stack.append(RenderState { .Expression = else_node.body });
3401 try stack.append(RenderState.PrintIndent);
3402 try stack.append(RenderState { .Indent = indent + indent_delta });
3403 try stack.append(RenderState { .Text = "\n" });
3404 }
3374 }3405 }
33753406
3376 if (else_node.payload) |payload| {3407 if (else_node.payload) |payload| {
...@@ -3396,6 +3427,7 @@ pub const Parser = struct {...@@ -3396,6 +3427,7 @@ pub const Parser = struct {
3396 if (while_node.body.id == ast.Node.Id.Block) {3427 if (while_node.body.id == ast.Node.Id.Block) {
3397 try stack.append(RenderState { .Text = " " });3428 try stack.append(RenderState { .Text = " " });
3398 } else {3429 } else {
3430 try stack.append(RenderState.PrintIndent);
3399 try stack.append(RenderState { .Text = "\n" });3431 try stack.append(RenderState { .Text = "\n" });
3400 }3432 }
3401 }3433 }
...@@ -3445,6 +3477,7 @@ pub const Parser = struct {...@@ -3445,6 +3477,7 @@ pub const Parser = struct {
3445 if (for_node.body.id == ast.Node.Id.Block) {3477 if (for_node.body.id == ast.Node.Id.Block) {
3446 try stack.append(RenderState { .Text = " " });3478 try stack.append(RenderState { .Text = " " });
3447 } else {3479 } else {
3480 try stack.append(RenderState.PrintIndent);
3448 try stack.append(RenderState { .Text = "\n" });3481 try stack.append(RenderState { .Text = "\n" });
3449 }3482 }
3450 }3483 }
...@@ -3469,6 +3502,53 @@ pub const Parser = struct {...@@ -3469,6 +3502,53 @@ pub const Parser = struct {
3469 try stack.append(RenderState { .Expression = for_node.array_expr });3502 try stack.append(RenderState { .Expression = for_node.array_expr });
3470 try stack.append(RenderState { .Text = "(" });3503 try stack.append(RenderState { .Text = "(" });
3471 },3504 },
3505 ast.Node.Id.If => {
3506 const if_node = @fieldParentPtr(ast.NodeIf, "base", base);
3507 try stream.print("{} ", self.tokenizer.getTokenSlice(if_node.if_token));
3508
3509 switch (if_node.body.id) {
3510 ast.Node.Id.Block, ast.Node.Id.If,
3511 ast.Node.Id.For, ast.Node.Id.While,
3512 ast.Node.Id.Switch => {
3513 if (if_node.@"else") |@"else"| {
3514 try stack.append(RenderState { .Expression = &@"else".base });
3515
3516 if (if_node.body.id == ast.Node.Id.Block) {
3517 try stack.append(RenderState { .Text = " " });
3518 } else {
3519 try stack.append(RenderState.PrintIndent);
3520 try stack.append(RenderState { .Text = "\n" });
3521 }
3522 }
3523 },
3524 else => {
3525 if (if_node.@"else") |@"else"| {
3526 try stack.append(RenderState { .Expression = @"else".body });
3527
3528 if (@"else".payload) |payload| {
3529 try stack.append(RenderState { .Text = " " });
3530 try stack.append(RenderState { .Expression = &payload.base });
3531 }
3532
3533 try stack.append(RenderState { .Text = " " });
3534 try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(@"else".else_token) });
3535 try stack.append(RenderState { .Text = " " });
3536 }
3537 }
3538 }
3539
3540 try stack.append(RenderState { .Expression = if_node.body });
3541 try stack.append(RenderState { .Text = " " });
3542
3543 if (if_node.payload) |payload| {
3544 try stack.append(RenderState { .Expression = &payload.base });
3545 try stack.append(RenderState { .Text = " " });
3546 }
3547
3548 try stack.append(RenderState { .Text = ")" });
3549 try stack.append(RenderState { .Expression = if_node.condition });
3550 try stack.append(RenderState { .Text = "(" });
3551 },
34723552
3473 ast.Node.Id.StructField,3553 ast.Node.Id.StructField,
3474 ast.Node.Id.UnionTag,3554 ast.Node.Id.UnionTag,
...@@ -4210,8 +4290,7 @@ test "zig fmt: if" {...@@ -4210,8 +4290,7 @@ test "zig fmt: if" {
4210 \\ unreachable;4290 \\ unreachable;
4211 \\ }4291 \\ }
4212 \\4292 \\
4213 \\ if (10 < 0)4293 \\ if (10 < 0) unreachable;
4214 \\ unreachable;
4215 \\4294 \\
4216 \\ if (10 < 0) {4295 \\ if (10 < 0) {
4217 \\ unreachable;4296 \\ unreachable;