Skip to content

Commit aa55263

Browse files
committed
std.zig.parser now parses fn types
1 parent 7d32c95 commit aa55263

File tree

1 file changed

+99
-35
lines changed

1 file changed

+99
-35
lines changed

std/zig/parser.zig

Lines changed: 99 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,17 @@ pub const Parser = struct {
14131413
}) catch unreachable;
14141414
},
14151415
Token.Id.Keyword_extern => {
1416+
const next = self.getNextToken();
1417+
if (next.id == Token.Id.Keyword_fn) {
1418+
// TODO shouldn't need this cast
1419+
const fn_proto = try self.createFnProto(arena, next,
1420+
(?Token)(token), (?&ast.Node)(null), (?Token)(null), (?Token)(null), (?Token)(null));
1421+
dest_ptr.store(&fn_proto.base);
1422+
stack.append(State { .FnProto = fn_proto }) catch unreachable;
1423+
continue;
1424+
}
1425+
1426+
self.putBackToken(next);
14161427
stack.append(State {
14171428
.ContainerExtern = ContainerExternCtx {
14181429
.dest_ptr = dest_ptr,
@@ -1455,7 +1466,26 @@ pub const Parser = struct {
14551466
continue;
14561467
},
14571468
Token.Id.Keyword_fn => {
1458-
@panic("TODO: fn proto");
1469+
// TODO shouldn't need these casts
1470+
const fn_proto = try self.createFnProto(arena, token,
1471+
(?Token)(null), (?&ast.Node)(null), (?Token)(null), (?Token)(null), (?Token)(null));
1472+
dest_ptr.store(&fn_proto.base);
1473+
stack.append(State { .FnProto = fn_proto }) catch unreachable;
1474+
continue;
1475+
},
1476+
Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
1477+
// TODO shouldn't need this cast
1478+
const fn_proto = try self.createFnProto(arena, undefined,
1479+
(?Token)(null), (?&ast.Node)(null), (?Token)(token), (?Token)(null), (?Token)(null));
1480+
dest_ptr.store(&fn_proto.base);
1481+
stack.append(State { .FnProto = fn_proto }) catch unreachable;
1482+
try stack.append(State {
1483+
.ExpectTokenSave = ExpectTokenSave {
1484+
.id = Token.Id.Keyword_fn,
1485+
.ptr = &fn_proto.fn_token,
1486+
}
1487+
});
1488+
continue;
14591489
},
14601490
Token.Id.Keyword_asm => {
14611491
@panic("TODO: inline asm");
@@ -2781,41 +2811,14 @@ pub const Parser = struct {
27812811
ast.Node.Id.FnProto => {
27822812
const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", decl);
27832813

2784-
if (fn_proto.body_node == null) {
2785-
try stack.append(RenderState { .Text = ";" });
2786-
}
2787-
2788-
try stack.append(RenderState { .FnProtoRParen = fn_proto});
2789-
var i = fn_proto.params.len;
2790-
while (i != 0) {
2791-
i -= 1;
2792-
const param_decl_node = fn_proto.params.items[i];
2793-
try stack.append(RenderState { .ParamDecl = param_decl_node});
2794-
if (i != 0) {
2795-
try stack.append(RenderState { .Text = ", " });
2796-
}
2797-
}
2798-
2799-
try stack.append(RenderState { .Text = "(" });
2800-
if (fn_proto.name_token) |name_token| {
2801-
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(name_token) });
2802-
}
2803-
2804-
try stack.append(RenderState { .Text = "fn " });
2805-
if (fn_proto.lib_name) |lib_name| {
2806-
try stack.append(RenderState { .Text = " " });
2807-
try stack.append(RenderState { .Expression = lib_name });
2808-
}
2809-
if (fn_proto.extern_token) |extern_token| {
2810-
try stack.append(RenderState { .Text = " " });
2811-
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) });
2814+
if (fn_proto.body_node) |body_node| {
2815+
stack.append(RenderState { .Expression = body_node}) catch unreachable;
2816+
try stack.append(RenderState { .Text = " "});
2817+
} else {
2818+
stack.append(RenderState { .Text = ";" }) catch unreachable;
28122819
}
28132820

2814-
if (fn_proto.visib_token) |visib_token| {
2815-
assert(visib_token.id == Token.Id.Keyword_pub or visib_token.id == Token.Id.Keyword_export);
2816-
try stack.append(RenderState { .Text = " " });
2817-
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(visib_token) });
2818-
}
2821+
try stack.append(RenderState { .Expression = decl });
28192822
},
28202823
ast.Node.Id.VarDecl => {
28212824
const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl);
@@ -3386,7 +3389,65 @@ pub const Parser = struct {
33863389
}
33873390
}
33883391
},
3389-
ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"),
3392+
ast.Node.Id.FnProto => {
3393+
const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", base);
3394+
3395+
switch (fn_proto.return_type) {
3396+
ast.NodeFnProto.ReturnType.Explicit => |node| {
3397+
try stack.append(RenderState { .Expression = node});
3398+
},
3399+
ast.NodeFnProto.ReturnType.Infer => {
3400+
try stack.append(RenderState { .Text = "var"});
3401+
},
3402+
ast.NodeFnProto.ReturnType.InferErrorSet => |node| {
3403+
try stack.append(RenderState { .Expression = node});
3404+
try stack.append(RenderState { .Text = "!"});
3405+
},
3406+
}
3407+
3408+
if (fn_proto.align_expr != null) {
3409+
@panic("TODO");
3410+
}
3411+
3412+
try stack.append(RenderState { .Text = ") " });
3413+
var i = fn_proto.params.len;
3414+
while (i != 0) {
3415+
i -= 1;
3416+
const param_decl_node = fn_proto.params.items[i];
3417+
try stack.append(RenderState { .ParamDecl = param_decl_node});
3418+
if (i != 0) {
3419+
try stack.append(RenderState { .Text = ", " });
3420+
}
3421+
}
3422+
3423+
try stack.append(RenderState { .Text = "(" });
3424+
if (fn_proto.name_token) |name_token| {
3425+
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(name_token) });
3426+
try stack.append(RenderState { .Text = " " });
3427+
}
3428+
3429+
try stack.append(RenderState { .Text = "fn" });
3430+
3431+
if (fn_proto.cc_token) |cc_token| {
3432+
try stack.append(RenderState { .Text = " " });
3433+
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(cc_token) });
3434+
}
3435+
3436+
if (fn_proto.lib_name) |lib_name| {
3437+
try stack.append(RenderState { .Text = " " });
3438+
try stack.append(RenderState { .Expression = lib_name });
3439+
}
3440+
if (fn_proto.extern_token) |extern_token| {
3441+
try stack.append(RenderState { .Text = " " });
3442+
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) });
3443+
}
3444+
3445+
if (fn_proto.visib_token) |visib_token| {
3446+
assert(visib_token.id == Token.Id.Keyword_pub or visib_token.id == Token.Id.Keyword_export);
3447+
try stack.append(RenderState { .Text = " " });
3448+
try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(visib_token) });
3449+
}
3450+
},
33903451
ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"),
33913452
ast.Node.Id.Switch => {
33923453
const switch_node = @fieldParentPtr(ast.NodeSwitch, "base", base);
@@ -4461,6 +4522,9 @@ test "zig fmt: fn type" {
44614522
\\ return i + 1;
44624523
\\}
44634524
\\
4525+
\\const a: fn(u8) u8 = undefined;
4526+
\\const b: extern fn(u8) u8 = undefined;
4527+
\\const c: nakedcc fn(u8) u8 = undefined;
44644528
\\const ap: fn(u8) u8 = a;
44654529
\\
44664530
);

0 commit comments

Comments
 (0)