Commit c19f5a2356
Changed files (2)
std
std/zig/ast.zig
@@ -29,6 +29,7 @@ pub const Node = struct {
SwitchElse,
While,
For,
+ If,
InfixOp,
PrefixOp,
SuffixOp,
@@ -73,6 +74,7 @@ pub const Node = struct {
Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).iterate(index),
Id.While => @fieldParentPtr(NodeWhile, "base", base).iterate(index),
Id.For => @fieldParentPtr(NodeFor, "base", base).iterate(index),
+ Id.If => @fieldParentPtr(NodeIf, "base", base).iterate(index),
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
@@ -118,6 +120,7 @@ pub const Node = struct {
Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).firstToken(),
Id.While => @fieldParentPtr(NodeWhile, "base", base).firstToken(),
Id.For => @fieldParentPtr(NodeFor, "base", base).firstToken(),
+ Id.If => @fieldParentPtr(NodeIf, "base", base).firstToken(),
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
@@ -163,6 +166,7 @@ pub const Node = struct {
Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).lastToken(),
Id.While => @fieldParentPtr(NodeWhile, "base", base).lastToken(),
Id.For => @fieldParentPtr(NodeFor, "base", base).lastToken(),
+ Id.If => @fieldParentPtr(NodeIf, "base", base).lastToken(),
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
@@ -867,6 +871,49 @@ pub const NodeFor = struct {
}
};
+pub const NodeIf = struct {
+ base: Node,
+ if_token: Token,
+ condition: &Node,
+ payload: ?&NodeValuePayload,
+ body: &Node,
+ @"else": ?&NodeElse,
+
+ pub fn iterate(self: &NodeIf, index: usize) ?&Node {
+ var i = index;
+
+ if (i < 1) return self.condition;
+ i -= 1;
+
+ if (self.payload) |payload| {
+ if (i < 1) return &payload.base;
+ i -= 1;
+ }
+
+ if (i < 1) return self.body;
+ i -= 1;
+
+ if (self.@"else") |@"else"| {
+ if (i < 1) return &@"else".base;
+ i -= 1;
+ }
+
+ return null;
+ }
+
+ pub fn firstToken(self: &NodeIf) Token {
+ return self.if_token;
+ }
+
+ pub fn lastToken(self: &NodeIf) Token {
+ if (self.@"else") |@"else"| {
+ return @"else".body.lastToken();
+ }
+
+ return self.body.lastToken();
+ }
+};
+
pub const NodeInfixOp = struct {
base: Node,
op_token: Token,
std/zig/parser.zig
@@ -1449,7 +1449,24 @@ pub const Parser = struct {
@panic("TODO: inline asm");
},
Token.Id.Keyword_if => {
- @panic("TODO: inline if");
+ const node = try arena.create(ast.NodeIf);
+ *node = ast.NodeIf {
+ .base = self.initNode(ast.Node.Id.If),
+ .if_token = token,
+ .condition = undefined,
+ .payload = null,
+ .body = undefined,
+ .@"else" = null,
+ };
+ dest_ptr.store(&node.base);
+
+ stack.append(State { .Else = &node.@"else" }) catch unreachable;
+ try stack.append(State { .Expression = DestPtr { .Field = &node.body } });
+ try stack.append(State { .ValuePayload = &node.payload });
+ try stack.append(State { .ExpectToken = Token.Id.RParen });
+ try stack.append(State { .Expression = DestPtr { .Field = &node.condition } });
+ try stack.append(State { .ExpectToken = Token.Id.LParen });
+ continue;
},
Token.Id.Keyword_inline => {
stack.append(State {
@@ -2188,6 +2205,15 @@ pub const Parser = struct {
n = for_node.body;
},
+ ast.Node.Id.If => {
+ const if_node = @fieldParentPtr(ast.NodeIf, "base", n);
+ if (if_node.@"else") |@"else"| {
+ n = @"else".base;
+ continue;
+ }
+
+ n = if_node.body;
+ },
ast.Node.Id.Else => {
const else_node = @fieldParentPtr(ast.NodeElse, "base", n);
n = else_node.body;
@@ -3363,14 +3389,19 @@ pub const Parser = struct {
const else_node = @fieldParentPtr(ast.NodeElse, "base", base);
try stream.print("{} ", self.tokenizer.getTokenSlice(else_node.else_token));
- if (else_node.body.id == ast.Node.Id.Block) {
- try stack.append(RenderState { .Expression = else_node.body });
- } else {
- try stack.append(RenderState { .Indent = indent });
- try stack.append(RenderState { .Expression = else_node.body });
- try stack.append(RenderState.PrintIndent);
- try stack.append(RenderState { .Indent = indent + indent_delta });
- try stack.append(RenderState { .Text = "\n" });
+ switch (else_node.body.id) {
+ ast.Node.Id.Block, ast.Node.Id.If,
+ ast.Node.Id.For, ast.Node.Id.While,
+ ast.Node.Id.Switch => {
+ try stack.append(RenderState { .Expression = else_node.body });
+ },
+ else => {
+ try stack.append(RenderState { .Indent = indent });
+ try stack.append(RenderState { .Expression = else_node.body });
+ try stack.append(RenderState.PrintIndent);
+ try stack.append(RenderState { .Indent = indent + indent_delta });
+ try stack.append(RenderState { .Text = "\n" });
+ }
}
if (else_node.payload) |payload| {
@@ -3396,6 +3427,7 @@ pub const Parser = struct {
if (while_node.body.id == ast.Node.Id.Block) {
try stack.append(RenderState { .Text = " " });
} else {
+ try stack.append(RenderState.PrintIndent);
try stack.append(RenderState { .Text = "\n" });
}
}
@@ -3445,6 +3477,7 @@ pub const Parser = struct {
if (for_node.body.id == ast.Node.Id.Block) {
try stack.append(RenderState { .Text = " " });
} else {
+ try stack.append(RenderState.PrintIndent);
try stack.append(RenderState { .Text = "\n" });
}
}
@@ -3469,6 +3502,53 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = for_node.array_expr });
try stack.append(RenderState { .Text = "(" });
},
+ ast.Node.Id.If => {
+ const if_node = @fieldParentPtr(ast.NodeIf, "base", base);
+ try stream.print("{} ", self.tokenizer.getTokenSlice(if_node.if_token));
+
+ switch (if_node.body.id) {
+ ast.Node.Id.Block, ast.Node.Id.If,
+ ast.Node.Id.For, ast.Node.Id.While,
+ ast.Node.Id.Switch => {
+ if (if_node.@"else") |@"else"| {
+ try stack.append(RenderState { .Expression = &@"else".base });
+
+ if (if_node.body.id == ast.Node.Id.Block) {
+ try stack.append(RenderState { .Text = " " });
+ } else {
+ try stack.append(RenderState.PrintIndent);
+ try stack.append(RenderState { .Text = "\n" });
+ }
+ }
+ },
+ else => {
+ if (if_node.@"else") |@"else"| {
+ try stack.append(RenderState { .Expression = @"else".body });
+
+ if (@"else".payload) |payload| {
+ try stack.append(RenderState { .Text = " " });
+ try stack.append(RenderState { .Expression = &payload.base });
+ }
+
+ try stack.append(RenderState { .Text = " " });
+ try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(@"else".else_token) });
+ try stack.append(RenderState { .Text = " " });
+ }
+ }
+ }
+
+ try stack.append(RenderState { .Expression = if_node.body });
+ try stack.append(RenderState { .Text = " " });
+
+ if (if_node.payload) |payload| {
+ try stack.append(RenderState { .Expression = &payload.base });
+ try stack.append(RenderState { .Text = " " });
+ }
+
+ try stack.append(RenderState { .Text = ")" });
+ try stack.append(RenderState { .Expression = if_node.condition });
+ try stack.append(RenderState { .Text = "(" });
+ },
ast.Node.Id.StructField,
ast.Node.Id.UnionTag,
@@ -4210,8 +4290,7 @@ test "zig fmt: if" {
\\ unreachable;
\\ }
\\
- \\ if (10 < 0)
- \\ unreachable;
+ \\ if (10 < 0) unreachable;
\\
\\ if (10 < 0) {
\\ unreachable;