authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-10 14:52:47+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-10 14:52:47+02:00
log3b80e665074cd56d9e24fb8ae0fb9d86e8cd841a
tree2a3ec2ead0bffe97adf4096b0906af1cd706979a
parentdb0812d4b7f856425e0bd26cd6f579468f3ac8ab

std.zig.parser now parses toplevel use


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};
290294
295pub 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
291pub const NodeErrorSetDecl = struct {320pub 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 {
30683091
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
5037test "zig fmt: use" {
5038 try testCanonical(
5039 \\use @import("std");
5040 \\pub use @import("std");
5041 \\
5042 );
5043}