AST: use fn_proto not fn_decl for extern decls

saves a few bytes per extern function declaration
This commit is contained in:
Andrew Kelley 2021-02-21 16:01:22 -07:00
parent 88d0e77b97
commit 15603f403c
3 changed files with 40 additions and 18 deletions

View File

@ -2642,20 +2642,29 @@ pub const Node = struct {
@"return",
/// `fn(a: lhs) rhs`. lhs can be omitted.
/// anytype and ... parameters are omitted from the AST tree.
/// main_token is the `fn` keyword.
/// extern function declarations use this tag.
fn_proto_simple,
/// `fn(a: b, c: d) rhs`. `sub_range_list[lhs]`.
/// anytype and ... parameters are omitted from the AST tree.
/// main_token is the `fn` keyword.
/// extern function declarations use this tag.
fn_proto_multi,
/// `fn(a: b) rhs linksection(e) callconv(f)`. `FnProtoOne[lhs]`.
/// zero or one parameters.
/// anytype and ... parameters are omitted from the AST tree.
/// main_token is the `fn` keyword.
/// extern function declarations use this tag.
fn_proto_one,
/// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`.
/// anytype and ... parameters are omitted from the AST tree.
/// main_token is the `fn` keyword.
/// extern function declarations use this tag.
fn_proto,
/// lhs is the fn_proto.
/// rhs is the function body block if non-zero.
/// if rhs is zero, the function decl has no body (e.g. an extern function)
/// rhs is the function body block.
/// Note that extern function declarations use the fn_proto tags rather
/// than this one.
fn_decl,
/// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
anyframe_type,

View File

@ -542,15 +542,8 @@ const Parser = struct {
if (fn_proto != 0) {
switch (p.token_tags[p.tok_i]) {
.semicolon => {
const semicolon_token = p.nextToken();
return p.addNode(.{
.tag = .fn_decl,
.main_token = p.nodes.items(.main_token)[fn_proto],
.data = .{
.lhs = fn_proto,
.rhs = 0,
},
});
p.tok_i += 1;
return fn_proto;
},
.l_brace => {
const body_block = try p.parseBlock();

View File

@ -81,19 +81,39 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
while (i < fn_token) : (i += 1) {
try renderToken(ais, tree, i, .space);
}
if (datas[decl].rhs != 0) {
try renderExpression(ais, tree, fn_proto, .space);
return renderExpression(ais, tree, datas[decl].rhs, space);
} else {
try renderExpression(ais, tree, fn_proto, .none);
return renderToken(ais, tree, tree.lastToken(fn_proto) + 1, space); // semicolon
}
assert(datas[decl].rhs != 0);
try renderExpression(ais, tree, fn_proto, .space);
return renderExpression(ais, tree, datas[decl].rhs, space);
},
.fn_proto_simple,
.fn_proto_multi,
.fn_proto_one,
.fn_proto,
=> {
// Extern function prototypes are parsed as these tags.
// Go back to the first token we should render here.
const fn_token = main_tokens[decl];
var i = fn_token;
while (i > 0) {
i -= 1;
switch (token_tags[i]) {
.keyword_extern,
.keyword_export,
.keyword_pub,
.string_literal,
.keyword_inline,
.keyword_noinline,
=> continue,
else => {
i += 1;
break;
},
}
}
while (i < fn_token) : (i += 1) {
try renderToken(ais, tree, i, .space);
}
try renderExpression(ais, tree, decl, .none);
return renderToken(ais, tree, tree.lastToken(decl) + 1, space); // semicolon
},