| author | |
| committer | |
| log | 3b80e665074cd56d9e24fb8ae0fb9d86e8cd841a |
| tree | 2a3ec2ead0bffe97adf4096b0906af1cd706979a |
| parent | db0812d4b7f856425e0bd26cd6f579468f3ac8ab |
2 files changed, 93 insertions(+), 23 deletions(-)
std/zig/ast.zig+29| ... | ... | @@ -11,6 +11,7 @@ pub const Node = struct { |
| 11 | 11 | pub const Id = enum { |
| 12 | 12 | Root, |
| 13 | 13 | VarDecl, |
| 14 | Use, | |
| 14 | 15 | ErrorSetDecl, |
| 15 | 16 | ContainerDecl, |
| 16 | 17 | StructField, |
| ... | ... | @@ -63,6 +64,7 @@ pub const Node = struct { |
| 63 | 64 | return switch (base.id) { |
| 64 | 65 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index), |
| 65 | 66 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index), |
| 67 | Id.Use => @fieldParentPtr(NodeUse, "base", base).iterate(index), | |
| 66 | 68 | Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index), |
| 67 | 69 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index), |
| 68 | 70 | Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index), |
| ... | ... | @@ -116,6 +118,7 @@ pub const Node = struct { |
| 116 | 118 | return switch (base.id) { |
| 117 | 119 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(), |
| 118 | 120 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(), |
| 121 | Id.Use => @fieldParentPtr(NodeUse, "base", base).firstToken(), | |
| 119 | 122 | Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(), |
| 120 | 123 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(), |
| 121 | 124 | Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(), |
| ... | ... | @@ -169,6 +172,7 @@ pub const Node = struct { |
| 169 | 172 | return switch (base.id) { |
| 170 | 173 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(), |
| 171 | 174 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(), |
| 175 | Id.Use => @fieldParentPtr(NodeUse, "base", base).lastToken(), | |
| 172 | 176 | Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(), |
| 173 | 177 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(), |
| 174 | 178 | Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(), |
| ... | ... | @@ -288,6 +292,31 @@ pub const NodeVarDecl = struct { |
| 288 | 292 | } |
| 289 | 293 | }; |
| 290 | 294 | |
| 295 | pub const NodeUse = struct { | |
| 296 | base: Node, | |
| 297 | visib_token: ?Token, | |
| 298 | expr: &Node, | |
| 299 | semicolon_token: Token, | |
| 300 | ||
| 301 | pub fn iterate(self: &NodeUse, index: usize) ?&Node { | |
| 302 | var i = index; | |
| 303 | ||
| 304 | if (i < 1) return self.expr; | |
| 305 | i -= 1; | |
| 306 | ||
| 307 | return null; | |
| 308 | } | |
| 309 | ||
| 310 | pub fn firstToken(self: &NodeUse) Token { | |
| 311 | if (self.visib_token) |visib_token| return visib_token; | |
| 312 | return self.expr.firstToken(); | |
| 313 | } | |
| 314 | ||
| 315 | pub fn lastToken(self: &NodeUse) Token { | |
| 316 | return self.semicolon_token; | |
| 317 | } | |
| 318 | }; | |
| 319 | ||
| 291 | 320 | pub const NodeErrorSetDecl = struct { |
| 292 | 321 | base: Node, |
| 293 | 322 | error_token: Token, |
std/zig/parser.zig+64-23| ... | ... | @@ -348,31 +348,54 @@ pub const Parser = struct { |
| 348 | 348 | }, |
| 349 | 349 | State.TopLevelExtern => |ctx| { |
| 350 | 350 | const token = self.getNextToken(); |
| 351 | if (token.id == Token.Id.Keyword_extern) { | |
| 352 | const lib_name_token = self.getNextToken(); | |
| 353 | const lib_name = blk: { | |
| 354 | if (lib_name_token.id == Token.Id.StringLiteral) { | |
| 355 | const res = try self.createStringLiteral(arena, lib_name_token); | |
| 356 | break :blk &res.base; | |
| 357 | } else { | |
| 358 | self.putBackToken(lib_name_token); | |
| 359 | break :blk null; | |
| 360 | } | |
| 361 | }; | |
| 362 | ||
| 363 | stack.append(State { | |
| 364 | .TopLevelDecl = TopLevelDeclCtx { | |
| 365 | .decls = ctx.decls, | |
| 351 | switch (token.id) { | |
| 352 | Token.Id.Keyword_use => { | |
| 353 | const node = try arena.create(ast.NodeUse); | |
| 354 | *node = ast.NodeUse { | |
| 355 | .base = self.initNode(ast.Node.Id.Use), | |
| 366 | 356 | .visib_token = ctx.visib_token, |
| 367 | .extern_token = token, | |
| 368 | .lib_name = lib_name, | |
| 369 | }, | |
| 370 | }) catch unreachable; | |
| 371 | continue; | |
| 357 | .expr = undefined, | |
| 358 | .semicolon_token = undefined, | |
| 359 | }; | |
| 360 | try ctx.decls.append(&node.base); | |
| 361 | ||
| 362 | stack.append(State { | |
| 363 | .ExpectTokenSave = ExpectTokenSave { | |
| 364 | .id = Token.Id.Semicolon, | |
| 365 | .ptr = &node.semicolon_token, | |
| 366 | } | |
| 367 | }) catch unreachable; | |
| 368 | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); | |
| 369 | continue; | |
| 370 | }, | |
| 371 | Token.Id.Keyword_extern => { | |
| 372 | const lib_name_token = self.getNextToken(); | |
| 373 | const lib_name = blk: { | |
| 374 | if (lib_name_token.id == Token.Id.StringLiteral) { | |
| 375 | const res = try self.createStringLiteral(arena, lib_name_token); | |
| 376 | break :blk &res.base; | |
| 377 | } else { | |
| 378 | self.putBackToken(lib_name_token); | |
| 379 | break :blk null; | |
| 380 | } | |
| 381 | }; | |
| 382 | ||
| 383 | stack.append(State { | |
| 384 | .TopLevelDecl = TopLevelDeclCtx { | |
| 385 | .decls = ctx.decls, | |
| 386 | .visib_token = ctx.visib_token, | |
| 387 | .extern_token = token, | |
| 388 | .lib_name = lib_name, | |
| 389 | }, | |
| 390 | }) catch unreachable; | |
| 391 | continue; | |
| 392 | }, | |
| 393 | else => { | |
| 394 | self.putBackToken(token); | |
| 395 | stack.append(State { .TopLevelDecl = ctx }) catch unreachable; | |
| 396 | continue; | |
| 397 | } | |
| 372 | 398 | } |
| 373 | self.putBackToken(token); | |
| 374 | stack.append(State { .TopLevelDecl = ctx }) catch unreachable; | |
| 375 | continue; | |
| 376 | 399 | }, |
| 377 | 400 | State.TopLevelDecl => |ctx| { |
| 378 | 401 | const token = self.getNextToken(); |
| ... | ... | @@ -3068,6 +3091,15 @@ pub const Parser = struct { |
| 3068 | 3091 | |
| 3069 | 3092 | try stack.append(RenderState { .Expression = decl }); |
| 3070 | 3093 | }, |
| 3094 | ast.Node.Id.Use => { | |
| 3095 | const use_decl = @fieldParentPtr(ast.NodeUse, "base", decl); | |
| 3096 | if (use_decl.visib_token) |visib_token| { | |
| 3097 | try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token)); | |
| 3098 | } | |
| 3099 | try stream.print("use "); | |
| 3100 | try stack.append(RenderState { .Text = ";" }); | |
| 3101 | try stack.append(RenderState { .Expression = use_decl.expr }); | |
| 3102 | }, | |
| 3071 | 3103 | ast.Node.Id.VarDecl => { |
| 3072 | 3104 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl); |
| 3073 | 3105 | try stack.append(RenderState { .VarDecl = var_decl}); |
| ... | ... | @@ -4086,6 +4118,7 @@ pub const Parser = struct { |
| 4086 | 4118 | ast.Node.Id.EnumTag, |
| 4087 | 4119 | ast.Node.Id.Root, |
| 4088 | 4120 | ast.Node.Id.VarDecl, |
| 4121 | ast.Node.Id.Use, | |
| 4089 | 4122 | ast.Node.Id.TestDecl, |
| 4090 | 4123 | ast.Node.Id.ParamDecl => unreachable, |
| 4091 | 4124 | }, |
| ... | ... | @@ -5000,3 +5033,11 @@ test "zig fmt: Block after if" { |
| 5000 | 5033 | \\ |
| 5001 | 5034 | ); |
| 5002 | 5035 | } |
| 5036 | ||
| 5037 | test "zig fmt: use" { | |
| 5038 | try testCanonical( | |
| 5039 | \\use @import("std"); | |
| 5040 | \\pub use @import("std"); | |
| 5041 | \\ | |
| 5042 | ); | |
| 5043 | } |