std.zig.parser now parses toplevel use

master
Jimmi Holst Christensen 2018-04-10 14:52:47 +02:00
parent db0812d4b7
commit 3b80e66507
2 changed files with 93 additions and 23 deletions

View File

@ -11,6 +11,7 @@ pub const Node = struct {
pub const Id = enum { pub const Id = enum {
Root, Root,
VarDecl, VarDecl,
Use,
ErrorSetDecl, ErrorSetDecl,
ContainerDecl, ContainerDecl,
StructField, StructField,
@ -63,6 +64,7 @@ pub const Node = struct {
return switch (base.id) { return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index), Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index), Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),
Id.Use => @fieldParentPtr(NodeUse, "base", base).iterate(index),
Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index), Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index),
Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index), Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index),
Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index), Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index),
@ -116,6 +118,7 @@ pub const Node = struct {
return switch (base.id) { return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(), Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(), Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(),
Id.Use => @fieldParentPtr(NodeUse, "base", base).firstToken(),
Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(), Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(),
Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(), Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(),
Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(), Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(),
@ -169,6 +172,7 @@ pub const Node = struct {
return switch (base.id) { return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(), Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(), Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(),
Id.Use => @fieldParentPtr(NodeUse, "base", base).lastToken(),
Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(), Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(),
Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(), Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(),
Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(), Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(),
@ -288,6 +292,31 @@ pub const NodeVarDecl = struct {
} }
}; };
pub const NodeUse = struct {
base: Node,
visib_token: ?Token,
expr: &Node,
semicolon_token: Token,
pub fn iterate(self: &NodeUse, index: usize) ?&Node {
var i = index;
if (i < 1) return self.expr;
i -= 1;
return null;
}
pub fn firstToken(self: &NodeUse) Token {
if (self.visib_token) |visib_token| return visib_token;
return self.expr.firstToken();
}
pub fn lastToken(self: &NodeUse) Token {
return self.semicolon_token;
}
};
pub const NodeErrorSetDecl = struct { pub const NodeErrorSetDecl = struct {
base: Node, base: Node,
error_token: Token, error_token: Token,

View File

@ -348,31 +348,54 @@ pub const Parser = struct {
}, },
State.TopLevelExtern => |ctx| { State.TopLevelExtern => |ctx| {
const token = self.getNextToken(); const token = self.getNextToken();
if (token.id == Token.Id.Keyword_extern) { switch (token.id) {
const lib_name_token = self.getNextToken(); Token.Id.Keyword_use => {
const lib_name = blk: { const node = try arena.create(ast.NodeUse);
if (lib_name_token.id == Token.Id.StringLiteral) { *node = ast.NodeUse {
const res = try self.createStringLiteral(arena, lib_name_token); .base = self.initNode(ast.Node.Id.Use),
break :blk &res.base;
} else {
self.putBackToken(lib_name_token);
break :blk null;
}
};
stack.append(State {
.TopLevelDecl = TopLevelDeclCtx {
.decls = ctx.decls,
.visib_token = ctx.visib_token, .visib_token = ctx.visib_token,
.extern_token = token, .expr = undefined,
.lib_name = lib_name, .semicolon_token = undefined,
}, };
}) catch unreachable; try ctx.decls.append(&node.base);
continue;
stack.append(State {
.ExpectTokenSave = ExpectTokenSave {
.id = Token.Id.Semicolon,
.ptr = &node.semicolon_token,
}
}) catch unreachable;
try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
continue;
},
Token.Id.Keyword_extern => {
const lib_name_token = self.getNextToken();
const lib_name = blk: {
if (lib_name_token.id == Token.Id.StringLiteral) {
const res = try self.createStringLiteral(arena, lib_name_token);
break :blk &res.base;
} else {
self.putBackToken(lib_name_token);
break :blk null;
}
};
stack.append(State {
.TopLevelDecl = TopLevelDeclCtx {
.decls = ctx.decls,
.visib_token = ctx.visib_token,
.extern_token = token,
.lib_name = lib_name,
},
}) catch unreachable;
continue;
},
else => {
self.putBackToken(token);
stack.append(State { .TopLevelDecl = ctx }) catch unreachable;
continue;
}
} }
self.putBackToken(token);
stack.append(State { .TopLevelDecl = ctx }) catch unreachable;
continue;
}, },
State.TopLevelDecl => |ctx| { State.TopLevelDecl => |ctx| {
const token = self.getNextToken(); const token = self.getNextToken();
@ -3068,6 +3091,15 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = decl }); try stack.append(RenderState { .Expression = decl });
}, },
ast.Node.Id.Use => {
const use_decl = @fieldParentPtr(ast.NodeUse, "base", decl);
if (use_decl.visib_token) |visib_token| {
try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
}
try stream.print("use ");
try stack.append(RenderState { .Text = ";" });
try stack.append(RenderState { .Expression = use_decl.expr });
},
ast.Node.Id.VarDecl => { ast.Node.Id.VarDecl => {
const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl); const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl);
try stack.append(RenderState { .VarDecl = var_decl}); try stack.append(RenderState { .VarDecl = var_decl});
@ -4086,6 +4118,7 @@ pub const Parser = struct {
ast.Node.Id.EnumTag, ast.Node.Id.EnumTag,
ast.Node.Id.Root, ast.Node.Id.Root,
ast.Node.Id.VarDecl, ast.Node.Id.VarDecl,
ast.Node.Id.Use,
ast.Node.Id.TestDecl, ast.Node.Id.TestDecl,
ast.Node.Id.ParamDecl => unreachable, ast.Node.Id.ParamDecl => unreachable,
}, },
@ -5000,3 +5033,11 @@ test "zig fmt: Block after if" {
\\ \\
); );
} }
test "zig fmt: use" {
try testCanonical(
\\use @import("std");
\\pub use @import("std");
\\
);
}