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 {
1111 pub const Id = enum {
1212 Root,
1313 VarDecl,
14 Use,
1415 ErrorSetDecl,
1516 ContainerDecl,
1617 StructField,
......@@ -63,6 +64,7 @@ pub const Node = struct {
6364 return switch (base.id) {
6465 Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),
6566 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),
67 Id.Use => @fieldParentPtr(NodeUse, "base", base).iterate(index),
6668 Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index),
6769 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index),
6870 Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index),
......@@ -116,6 +118,7 @@ pub const Node = struct {
116118 return switch (base.id) {
117119 Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(),
118120 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(),
121 Id.Use => @fieldParentPtr(NodeUse, "base", base).firstToken(),
119122 Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(),
120123 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(),
121124 Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(),
......@@ -169,6 +172,7 @@ pub const Node = struct {
169172 return switch (base.id) {
170173 Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(),
171174 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(),
175 Id.Use => @fieldParentPtr(NodeUse, "base", base).lastToken(),
172176 Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(),
173177 Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(),
174178 Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(),
......@@ -288,6 +292,31 @@ pub const NodeVarDecl = struct {
288292 }
289293};
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
291320pub const NodeErrorSetDecl = struct {
292321 base: Node,
293322 error_token: Token,
std/zig/parser.zig+64-23
......@@ -348,31 +348,54 @@ pub const Parser = struct {
348348 },
349349 State.TopLevelExtern => |ctx| {
350350 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),
366356 .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 }
372398 }
373 self.putBackToken(token);
374 stack.append(State { .TopLevelDecl = ctx }) catch unreachable;
375 continue;
376399 },
377400 State.TopLevelDecl => |ctx| {
378401 const token = self.getNextToken();
......@@ -3068,6 +3091,15 @@ pub const Parser = struct {
30683091
30693092 try stack.append(RenderState { .Expression = decl });
30703093 },
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 },
30713103 ast.Node.Id.VarDecl => {
30723104 const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl);
30733105 try stack.append(RenderState { .VarDecl = var_decl});
......@@ -4086,6 +4118,7 @@ pub const Parser = struct {
40864118 ast.Node.Id.EnumTag,
40874119 ast.Node.Id.Root,
40884120 ast.Node.Id.VarDecl,
4121 ast.Node.Id.Use,
40894122 ast.Node.Id.TestDecl,
40904123 ast.Node.Id.ParamDecl => unreachable,
40914124 },
......@@ -5000,3 +5033,11 @@ test "zig fmt: Block after if" {
50005033 \\
50015034 );
50025035}
5036
5037test "zig fmt: use" {
5038 try testCanonical(
5039 \\use @import("std");
5040 \\pub use @import("std");
5041 \\
5042 );
5043}