std.zig.parser now parses inline fn proto

Related #909
Allows parsing of `std/os/zen.zig`.
master
Jimmi Holst Christensen 2018-04-11 15:17:51 +02:00
parent fe7146277d
commit df4c575525
2 changed files with 91 additions and 61 deletions

View File

@ -214,7 +214,7 @@ pub const NodeVarDecl = struct {
eq_token: Token, eq_token: Token,
mut_token: Token, mut_token: Token,
comptime_token: ?Token, comptime_token: ?Token,
extern_token: ?Token, extern_export_token: ?Token,
lib_name: ?&Node, lib_name: ?&Node,
type_node: ?&Node, type_node: ?&Node,
align_node: ?&Node, align_node: ?&Node,
@ -245,7 +245,7 @@ pub const NodeVarDecl = struct {
pub fn firstToken(self: &NodeVarDecl) Token { pub fn firstToken(self: &NodeVarDecl) Token {
if (self.visib_token) |visib_token| return visib_token; if (self.visib_token) |visib_token| return visib_token;
if (self.comptime_token) |comptime_token| return comptime_token; if (self.comptime_token) |comptime_token| return comptime_token;
if (self.extern_token) |extern_token| return extern_token; if (self.extern_export_token) |extern_export_token| return extern_export_token;
assert(self.lib_name == null); assert(self.lib_name == null);
return self.mut_token; return self.mut_token;
} }
@ -496,8 +496,7 @@ pub const NodeFnProto = struct {
params: ArrayList(&Node), params: ArrayList(&Node),
return_type: ReturnType, return_type: ReturnType,
var_args_token: ?Token, var_args_token: ?Token,
extern_token: ?Token, extern_export_inline_token: ?Token,
inline_token: ?Token,
cc_token: ?Token, cc_token: ?Token,
async_attr: ?&NodeAsyncAttribute, async_attr: ?&NodeAsyncAttribute,
body_node: ?&Node, body_node: ?&Node,
@ -547,9 +546,8 @@ pub const NodeFnProto = struct {
pub fn firstToken(self: &NodeFnProto) Token { pub fn firstToken(self: &NodeFnProto) Token {
if (self.visib_token) |visib_token| return visib_token; if (self.visib_token) |visib_token| return visib_token;
if (self.extern_token) |extern_token| return extern_token; if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
assert(self.lib_name == null); assert(self.lib_name == null);
if (self.inline_token) |inline_token| return inline_token;
if (self.cc_token) |cc_token| return cc_token; if (self.cc_token) |cc_token| return cc_token;
return self.fn_token; return self.fn_token;
} }

View File

@ -55,7 +55,7 @@ pub const Parser = struct {
const TopLevelDeclCtx = struct { const TopLevelDeclCtx = struct {
decls: &ArrayList(&ast.Node), decls: &ArrayList(&ast.Node),
visib_token: ?Token, visib_token: ?Token,
extern_token: ?Token, extern_export_inline_token: ?Token,
lib_name: ?&ast.Node, lib_name: ?&ast.Node,
}; };
@ -142,6 +142,7 @@ pub const Parser = struct {
const State = union(enum) { const State = union(enum) {
TopLevel, TopLevel,
TopLevelExtern: TopLevelDeclCtx, TopLevelExtern: TopLevelDeclCtx,
TopLevelLibname: TopLevelDeclCtx,
TopLevelDecl: TopLevelDeclCtx, TopLevelDecl: TopLevelDeclCtx,
ContainerExtern: ContainerExternCtx, ContainerExtern: ContainerExternCtx,
ContainerDecl: &ast.NodeContainerDecl, ContainerDecl: &ast.NodeContainerDecl,
@ -332,13 +333,13 @@ pub const Parser = struct {
root_node.eof_token = token; root_node.eof_token = token;
return Tree {.root_node = root_node, .arena_allocator = arena_allocator}; return Tree {.root_node = root_node, .arena_allocator = arena_allocator};
}, },
Token.Id.Keyword_pub, Token.Id.Keyword_export => { Token.Id.Keyword_pub => {
stack.append(State.TopLevel) catch unreachable; stack.append(State.TopLevel) catch unreachable;
try stack.append(State { try stack.append(State {
.TopLevelExtern = TopLevelDeclCtx { .TopLevelExtern = TopLevelDeclCtx {
.decls = &root_node.decls, .decls = &root_node.decls,
.visib_token = token, .visib_token = token,
.extern_token = null, .extern_export_inline_token = null,
.lib_name = null, .lib_name = null,
} }
}); });
@ -363,7 +364,7 @@ pub const Parser = struct {
.TopLevelExtern = TopLevelDeclCtx { .TopLevelExtern = TopLevelDeclCtx {
.decls = &root_node.decls, .decls = &root_node.decls,
.visib_token = null, .visib_token = null,
.extern_token = null, .extern_export_inline_token = null,
.lib_name = null, .lib_name = null,
} }
}); });
@ -372,9 +373,66 @@ pub const Parser = struct {
} }
}, },
State.TopLevelExtern => |ctx| { State.TopLevelExtern => |ctx| {
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_export, Token.Id.Keyword_inline => {
stack.append(State {
.TopLevelDecl = TopLevelDeclCtx {
.decls = ctx.decls,
.visib_token = ctx.visib_token,
.extern_export_inline_token = token,
.lib_name = null,
},
}) catch unreachable;
continue;
},
Token.Id.Keyword_extern => {
stack.append(State {
.TopLevelLibname = TopLevelDeclCtx {
.decls = ctx.decls,
.visib_token = ctx.visib_token,
.extern_export_inline_token = token,
.lib_name = null,
},
}) catch unreachable;
continue;
},
else => {
self.putBackToken(token);
stack.append(State { .TopLevelDecl = ctx }) catch unreachable;
continue;
}
}
},
State.TopLevelLibname => |ctx| {
const lib_name = blk: {
const lib_name_token = self.getNextToken();
break :blk (try self.parseStringLiteral(arena, lib_name_token)) ?? {
self.putBackToken(lib_name_token);
break :blk null;
};
};
stack.append(State {
.TopLevelDecl = TopLevelDeclCtx {
.decls = ctx.decls,
.visib_token = ctx.visib_token,
.extern_export_inline_token = ctx.extern_export_inline_token,
.lib_name = lib_name,
},
}) catch unreachable;
},
State.TopLevelDecl => |ctx| {
const token = self.getNextToken(); const token = self.getNextToken();
switch (token.id) { switch (token.id) {
Token.Id.Keyword_use => { Token.Id.Keyword_use => {
if (ctx.extern_export_inline_token != null) {
try self.parseError(&stack, token, "Invalid token {}", @tagName((??ctx.extern_export_inline_token).id));
continue;
}
const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse, const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse,
ast.NodeUse { ast.NodeUse {
.base = undefined, .base = undefined,
@ -392,43 +450,21 @@ pub const Parser = struct {
try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); try stack.append(State { .Expression = DestPtr { .Field = &node.expr } });
continue; continue;
}, },
Token.Id.Keyword_extern => {
const lib_name = blk: {
const lib_name_token = self.getNextToken();
break :blk (try self.parseStringLiteral(arena, lib_name_token)) ?? {
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;
}
}
},
State.TopLevelDecl => |ctx| {
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_var, Token.Id.Keyword_const => { Token.Id.Keyword_var, Token.Id.Keyword_const => {
if (ctx.extern_export_inline_token) |extern_export_inline_token| {
if (extern_export_inline_token.id == Token.Id.Keyword_inline) {
try self.parseError(&stack, token, "Invalid token {}", @tagName(extern_export_inline_token.id));
continue;
}
}
const var_decl_node = try self.createAttachNode(arena, ctx.decls, ast.NodeVarDecl, const var_decl_node = try self.createAttachNode(arena, ctx.decls, ast.NodeVarDecl,
ast.NodeVarDecl { ast.NodeVarDecl {
.base = undefined, .base = undefined,
.visib_token = ctx.visib_token, .visib_token = ctx.visib_token,
.mut_token = token, .mut_token = token,
.comptime_token = null, .comptime_token = null,
.extern_token = ctx.extern_token, .extern_export_token = ctx.extern_export_inline_token,
.type_node = null, .type_node = null,
.align_node = null, .align_node = null,
.init_node = null, .init_node = null,
@ -452,8 +488,7 @@ pub const Parser = struct {
.params = ArrayList(&ast.Node).init(arena), .params = ArrayList(&ast.Node).init(arena),
.return_type = undefined, .return_type = undefined,
.var_args_token = null, .var_args_token = null,
.extern_token = ctx.extern_token, .extern_export_inline_token = ctx.extern_export_inline_token,
.inline_token = null,
.cc_token = null, .cc_token = null,
.async_attr = null, .async_attr = null,
.body_node = null, .body_node = null,
@ -475,8 +510,7 @@ pub const Parser = struct {
.params = ArrayList(&ast.Node).init(arena), .params = ArrayList(&ast.Node).init(arena),
.return_type = undefined, .return_type = undefined,
.var_args_token = null, .var_args_token = null,
.extern_token = ctx.extern_token, .extern_export_inline_token = ctx.extern_export_inline_token,
.inline_token = null,
.cc_token = token, .cc_token = token,
.async_attr = null, .async_attr = null,
.body_node = null, .body_node = null,
@ -513,8 +547,7 @@ pub const Parser = struct {
.params = ArrayList(&ast.Node).init(arena), .params = ArrayList(&ast.Node).init(arena),
.return_type = undefined, .return_type = undefined,
.var_args_token = null, .var_args_token = null,
.extern_token = ctx.extern_token, .extern_export_inline_token = ctx.extern_export_inline_token,
.inline_token = null,
.cc_token = null, .cc_token = null,
.async_attr = async_node, .async_attr = async_node,
.body_node = null, .body_node = null,
@ -752,7 +785,7 @@ pub const Parser = struct {
.TopLevelExtern = TopLevelDeclCtx { .TopLevelExtern = TopLevelDeclCtx {
.decls = &container_decl.fields_and_decls, .decls = &container_decl.fields_and_decls,
.visib_token = token, .visib_token = token,
.extern_token = null, .extern_export_inline_token = null,
.lib_name = null, .lib_name = null,
} }
}); });
@ -764,7 +797,7 @@ pub const Parser = struct {
.TopLevelExtern = TopLevelDeclCtx { .TopLevelExtern = TopLevelDeclCtx {
.decls = &container_decl.fields_and_decls, .decls = &container_decl.fields_and_decls,
.visib_token = token, .visib_token = token,
.extern_token = null, .extern_export_inline_token = null,
.lib_name = null, .lib_name = null,
} }
}); });
@ -781,7 +814,7 @@ pub const Parser = struct {
.TopLevelExtern = TopLevelDeclCtx { .TopLevelExtern = TopLevelDeclCtx {
.decls = &container_decl.fields_and_decls, .decls = &container_decl.fields_and_decls,
.visib_token = null, .visib_token = null,
.extern_token = null, .extern_export_inline_token = null,
.lib_name = null, .lib_name = null,
} }
}); });
@ -1659,8 +1692,7 @@ pub const Parser = struct {
.params = ArrayList(&ast.Node).init(arena), .params = ArrayList(&ast.Node).init(arena),
.return_type = undefined, .return_type = undefined,
.var_args_token = null, .var_args_token = null,
.extern_token = token, .extern_export_inline_token = token,
.inline_token = null,
.cc_token = null, .cc_token = null,
.async_attr = null, .async_attr = null,
.body_node = null, .body_node = null,
@ -1717,8 +1749,7 @@ pub const Parser = struct {
.params = ArrayList(&ast.Node).init(arena), .params = ArrayList(&ast.Node).init(arena),
.return_type = undefined, .return_type = undefined,
.var_args_token = null, .var_args_token = null,
.extern_token = null, .extern_export_inline_token = null,
.inline_token = null,
.cc_token = null, .cc_token = null,
.async_attr = null, .async_attr = null,
.body_node = null, .body_node = null,
@ -1740,8 +1771,7 @@ pub const Parser = struct {
.params = ArrayList(&ast.Node).init(arena), .params = ArrayList(&ast.Node).init(arena),
.return_type = undefined, .return_type = undefined,
.var_args_token = null, .var_args_token = null,
.extern_token = null, .extern_export_inline_token = null,
.inline_token = null,
.cc_token = token, .cc_token = token,
.async_attr = null, .async_attr = null,
.body_node = null, .body_node = null,
@ -2573,7 +2603,7 @@ pub const Parser = struct {
.visib_token = null, .visib_token = null,
.mut_token = mut_token, .mut_token = mut_token,
.comptime_token = next, .comptime_token = next,
.extern_token = null, .extern_export_token = null,
.type_node = null, .type_node = null,
.align_node = null, .align_node = null,
.init_node = null, .init_node = null,
@ -2601,7 +2631,7 @@ pub const Parser = struct {
.visib_token = null, .visib_token = null,
.mut_token = next, .mut_token = next,
.comptime_token = null, .comptime_token = null,
.extern_token = null, .extern_export_token = null,
.type_node = null, .type_node = null,
.align_node = null, .align_node = null,
.init_node = null, .init_node = null,
@ -3281,13 +3311,13 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(comptime_token) }); try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(comptime_token) });
} }
if (var_decl.extern_token) |extern_token| { if (var_decl.extern_export_token) |extern_export_token| {
if (var_decl.lib_name != null) { if (var_decl.lib_name != null) {
try stack.append(RenderState { .Text = " " }); try stack.append(RenderState { .Text = " " });
try stack.append(RenderState { .Expression = ??var_decl.lib_name }); try stack.append(RenderState { .Expression = ??var_decl.lib_name });
} }
try stack.append(RenderState { .Text = " " }); try stack.append(RenderState { .Text = " " });
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) }); try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_export_token) });
} }
if (var_decl.visib_token) |visib_token| { if (var_decl.visib_token) |visib_token| {
@ -3865,9 +3895,9 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = " " }); try stack.append(RenderState { .Text = " " });
try stack.append(RenderState { .Expression = lib_name }); try stack.append(RenderState { .Expression = lib_name });
} }
if (fn_proto.extern_token) |extern_token| { if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
try stack.append(RenderState { .Text = " " }); try stack.append(RenderState { .Text = " " });
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) }); try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_export_inline_token) });
} }
if (fn_proto.visib_token) |visib_token| { if (fn_proto.visib_token) |visib_token| {
@ -4608,6 +4638,8 @@ test "zig fmt: extern function" {
try testCanonical( try testCanonical(
\\extern fn puts(s: &const u8) c_int; \\extern fn puts(s: &const u8) c_int;
\\extern "c" fn puts(s: &const u8) c_int; \\extern "c" fn puts(s: &const u8) c_int;
\\export fn puts(s: &const u8) c_int;
\\inline fn puts(s: &const u8) c_int;
\\ \\
); );
} }