| 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,6 +11,7 @@ pub const Node = struct { |
| 11 | pub const Id = enum { | 11 | pub const Id = enum { |
| 12 | Root, | 12 | Root, |
| 13 | VarDecl, | 13 | VarDecl, |
| 14 | Use, | ||
| 14 | ErrorSetDecl, | 15 | ErrorSetDecl, |
| 15 | ContainerDecl, | 16 | ContainerDecl, |
| 16 | StructField, | 17 | StructField, |
| ... | @@ -63,6 +64,7 @@ pub const Node = struct { | ... | @@ -63,6 +64,7 @@ pub const Node = struct { |
| 63 | return switch (base.id) { | 64 | return switch (base.id) { |
| 64 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index), | 65 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index), |
| 65 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index), | 66 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index), |
| 67 | Id.Use => @fieldParentPtr(NodeUse, "base", base).iterate(index), | ||
| 66 | Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index), | 68 | Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index), |
| 67 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index), | 69 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index), |
| 68 | Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index), | 70 | Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index), |
| ... | @@ -116,6 +118,7 @@ pub const Node = struct { | ... | @@ -116,6 +118,7 @@ pub const Node = struct { |
| 116 | return switch (base.id) { | 118 | return switch (base.id) { |
| 117 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(), | 119 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(), |
| 118 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(), | 120 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(), |
| 121 | Id.Use => @fieldParentPtr(NodeUse, "base", base).firstToken(), | ||
| 119 | Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(), | 122 | Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(), |
| 120 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(), | 123 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(), |
| 121 | Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(), | 124 | Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(), |
| ... | @@ -169,6 +172,7 @@ pub const Node = struct { | ... | @@ -169,6 +172,7 @@ pub const Node = struct { |
| 169 | return switch (base.id) { | 172 | return switch (base.id) { |
| 170 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(), | 173 | Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(), |
| 171 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(), | 174 | Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(), |
| 175 | Id.Use => @fieldParentPtr(NodeUse, "base", base).lastToken(), | ||
| 172 | Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(), | 176 | Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(), |
| 173 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(), | 177 | Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(), |
| 174 | Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(), | 178 | Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(), |
| ... | @@ -288,6 +292,31 @@ pub const NodeVarDecl = struct { | ... | @@ -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 | pub const NodeErrorSetDecl = struct { | 320 | pub const NodeErrorSetDecl = struct { |
| 292 | base: Node, | 321 | base: Node, |
| 293 | error_token: Token, | 322 | error_token: Token, |
std/zig/parser.zig+64-23| ... | @@ -348,31 +348,54 @@ pub const Parser = struct { | ... | @@ -348,31 +348,54 @@ pub const Parser = struct { |
| 348 | }, | 348 | }, |
| 349 | State.TopLevelExtern => |ctx| { | 349 | State.TopLevelExtern => |ctx| { |
| 350 | const token = self.getNextToken(); | 350 | const token = self.getNextToken(); |
| 351 | if (token.id == Token.Id.Keyword_extern) { | 351 | switch (token.id) { |
| 352 | const lib_name_token = self.getNextToken(); | 352 | Token.Id.Keyword_use => { |
| 353 | const lib_name = blk: { | 353 | const node = try arena.create(ast.NodeUse); |
| 354 | if (lib_name_token.id == Token.Id.StringLiteral) { | 354 | *node = ast.NodeUse { |
| 355 | const res = try self.createStringLiteral(arena, lib_name_token); | 355 | .base = self.initNode(ast.Node.Id.Use), |
| 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, | ||
| 366 | .visib_token = ctx.visib_token, | 356 | .visib_token = ctx.visib_token, |
| 367 | .extern_token = token, | 357 | .expr = undefined, |
| 368 | .lib_name = lib_name, | 358 | .semicolon_token = undefined, |
| 369 | }, | 359 | }; |
| 370 | }) catch unreachable; | 360 | try ctx.decls.append(&node.base); |
| 371 | continue; | 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 | State.TopLevelDecl => |ctx| { | 400 | State.TopLevelDecl => |ctx| { |
| 378 | const token = self.getNextToken(); | 401 | const token = self.getNextToken(); |
| ... | @@ -3068,6 +3091,15 @@ pub const Parser = struct { | ... | @@ -3068,6 +3091,15 @@ pub const Parser = struct { |
| 3068 | 3091 | ||
| 3069 | try stack.append(RenderState { .Expression = decl }); | 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 | ast.Node.Id.VarDecl => { | 3103 | ast.Node.Id.VarDecl => { |
| 3072 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl); | 3104 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl); |
| 3073 | try stack.append(RenderState { .VarDecl = var_decl}); | 3105 | try stack.append(RenderState { .VarDecl = var_decl}); |
| ... | @@ -4086,6 +4118,7 @@ pub const Parser = struct { | ... | @@ -4086,6 +4118,7 @@ pub const Parser = struct { |
| 4086 | ast.Node.Id.EnumTag, | 4118 | ast.Node.Id.EnumTag, |
| 4087 | ast.Node.Id.Root, | 4119 | ast.Node.Id.Root, |
| 4088 | ast.Node.Id.VarDecl, | 4120 | ast.Node.Id.VarDecl, |
| 4121 | ast.Node.Id.Use, | ||
| 4089 | ast.Node.Id.TestDecl, | 4122 | ast.Node.Id.TestDecl, |
| 4090 | ast.Node.Id.ParamDecl => unreachable, | 4123 | ast.Node.Id.ParamDecl => unreachable, |
| 4091 | }, | 4124 | }, |
| ... | @@ -5000,3 +5033,11 @@ test "zig fmt: Block after if" { | ... | @@ -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 | } |