| author | |
| committer | |
| log | d04346d2ac04c079c1722db691d1536c3d717735 |
| tree | 9584bbcbf717c7960725f8a35dfb78809cb6af9a |
| parent | c19f5a2356b441e3dde95e85e029fec6ef4f836d |
3 files changed, 62 insertions(+), 0 deletions(-)
std/zig/ast.zig+33| ... | ... | @@ -20,6 +20,7 @@ pub const Node = struct { |
| 20 | 20 | FnProto, |
| 21 | 21 | ParamDecl, |
| 22 | 22 | Block, |
| 23 | Defer, | |
| 23 | 24 | ErrorPayload, |
| 24 | 25 | ValuePayload, |
| 25 | 26 | ValueIndexPayload, |
| ... | ... | @@ -65,6 +66,7 @@ pub const Node = struct { |
| 65 | 66 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index), |
| 66 | 67 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index), |
| 67 | 68 | Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index), |
| 69 | Id.Defer => @fieldParentPtr(NodeDefer, "base", base).iterate(index), | |
| 68 | 70 | Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).iterate(index), |
| 69 | 71 | Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).iterate(index), |
| 70 | 72 | Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).iterate(index), |
| ... | ... | @@ -111,6 +113,7 @@ pub const Node = struct { |
| 111 | 113 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(), |
| 112 | 114 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(), |
| 113 | 115 | Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(), |
| 116 | Id.Defer => @fieldParentPtr(NodeDefer, "base", base).firstToken(), | |
| 114 | 117 | Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).firstToken(), |
| 115 | 118 | Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).firstToken(), |
| 116 | 119 | Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).firstToken(), |
| ... | ... | @@ -157,6 +160,7 @@ pub const Node = struct { |
| 157 | 160 | Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(), |
| 158 | 161 | Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(), |
| 159 | 162 | Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(), |
| 163 | Id.Defer => @fieldParentPtr(NodeDefer, "base", base).lastToken(), | |
| 160 | 164 | Id.ErrorPayload => @fieldParentPtr(NodeErrorPayload, "base", base).lastToken(), |
| 161 | 165 | Id.ValuePayload => @fieldParentPtr(NodeValuePayload, "base", base).lastToken(), |
| 162 | 166 | Id.ValueIndexPayload => @fieldParentPtr(NodeValueIndexPayload, "base", base).lastToken(), |
| ... | ... | @@ -573,6 +577,35 @@ pub const NodeBlock = struct { |
| 573 | 577 | } |
| 574 | 578 | }; |
| 575 | 579 | |
| 580 | pub const NodeDefer = struct { | |
| 581 | base: Node, | |
| 582 | defer_token: Token, | |
| 583 | kind: Kind, | |
| 584 | expr: &Node, | |
| 585 | ||
| 586 | const Kind = enum { | |
| 587 | Error, | |
| 588 | Unconditional, | |
| 589 | }; | |
| 590 | ||
| 591 | pub fn iterate(self: &NodeDefer, index: usize) ?&Node { | |
| 592 | var i = index; | |
| 593 | ||
| 594 | if (i < 1) return self.expr; | |
| 595 | i -= 1; | |
| 596 | ||
| 597 | return null; | |
| 598 | } | |
| 599 | ||
| 600 | pub fn firstToken(self: &NodeDefer) Token { | |
| 601 | return self.defer_token; | |
| 602 | } | |
| 603 | ||
| 604 | pub fn lastToken(self: &NodeDefer) Token { | |
| 605 | return self.expr.lastToken(); | |
| 606 | } | |
| 607 | }; | |
| 608 | ||
| 576 | 609 | pub const NodeErrorPayload = struct { |
| 577 | 610 | base: Node, |
| 578 | 611 | lpipe: Token, |
std/zig/parser.zig+27| ... | ... | @@ -2140,6 +2140,24 @@ pub const Parser = struct { |
| 2140 | 2140 | stack.append(State { .VarDecl = var_decl }) catch unreachable; |
| 2141 | 2141 | continue; |
| 2142 | 2142 | }, |
| 2143 | Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => { | |
| 2144 | const node = try arena.create(ast.NodeDefer); | |
| 2145 | *node = ast.NodeDefer { | |
| 2146 | .base = self.initNode(ast.Node.Id.Defer), | |
| 2147 | .defer_token = next, | |
| 2148 | .kind = switch (next.id) { | |
| 2149 | Token.Id.Keyword_defer => ast.NodeDefer.Kind.Unconditional, | |
| 2150 | Token.Id.Keyword_errdefer => ast.NodeDefer.Kind.Error, | |
| 2151 | else => unreachable, | |
| 2152 | }, | |
| 2153 | .expr = undefined, | |
| 2154 | }; | |
| 2155 | try block.statements.append(&node.base); | |
| 2156 | ||
| 2157 | stack.append(State { .Semicolon = &node.base }) catch unreachable; | |
| 2158 | try stack.append(State { .Expression = DestPtr{.Field = &node.expr } }); | |
| 2159 | continue; | |
| 2160 | }, | |
| 2143 | 2161 | Token.Id.LBrace => { |
| 2144 | 2162 | const inner_block = try self.createBlock(arena, (?Token)(null), next); |
| 2145 | 2163 | try block.statements.append(&inner_block.base); |
| ... | ... | @@ -2218,6 +2236,10 @@ pub const Parser = struct { |
| 2218 | 2236 | const else_node = @fieldParentPtr(ast.NodeElse, "base", n); |
| 2219 | 2237 | n = else_node.body; |
| 2220 | 2238 | }, |
| 2239 | ast.Node.Id.Defer => { | |
| 2240 | const defer_node = @fieldParentPtr(ast.NodeDefer, "base", n); | |
| 2241 | n = defer_node.expr; | |
| 2242 | }, | |
| 2221 | 2243 | else => return true, |
| 2222 | 2244 | } |
| 2223 | 2245 | } |
| ... | ... | @@ -2912,6 +2934,11 @@ pub const Parser = struct { |
| 2912 | 2934 | } |
| 2913 | 2935 | } |
| 2914 | 2936 | }, |
| 2937 | ast.Node.Id.Defer => { | |
| 2938 | const defer_node = @fieldParentPtr(ast.NodeDefer, "base", base); | |
| 2939 | try stream.print("{} ", self.tokenizer.getTokenSlice(defer_node.defer_token)); | |
| 2940 | try stack.append(RenderState { .Expression = defer_node.expr }); | |
| 2941 | }, | |
| 2915 | 2942 | ast.Node.Id.InfixOp => { |
| 2916 | 2943 | const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base); |
| 2917 | 2944 | try stack.append(RenderState { .Expression = prefix_op_node.rhs }); |
std/zig/tokenizer.zig+2| ... | ... | @@ -26,6 +26,7 @@ pub const Token = struct { |
| 26 | 26 | KeywordId{.bytes="defer", .id = Id.Keyword_defer}, |
| 27 | 27 | KeywordId{.bytes="else", .id = Id.Keyword_else}, |
| 28 | 28 | KeywordId{.bytes="enum", .id = Id.Keyword_enum}, |
| 29 | KeywordId{.bytes="errdefer", .id = Id.Keyword_errdefer}, | |
| 29 | 30 | KeywordId{.bytes="error", .id = Id.Keyword_error}, |
| 30 | 31 | KeywordId{.bytes="export", .id = Id.Keyword_export}, |
| 31 | 32 | KeywordId{.bytes="extern", .id = Id.Keyword_extern}, |
| ... | ... | @@ -151,6 +152,7 @@ pub const Token = struct { |
| 151 | 152 | Keyword_defer, |
| 152 | 153 | Keyword_else, |
| 153 | 154 | Keyword_enum, |
| 155 | Keyword_errdefer, | |
| 154 | 156 | Keyword_error, |
| 155 | 157 | Keyword_export, |
| 156 | 158 | Keyword_extern, |