authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-09 14:02:03+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-09 14:02:03+02:00
logaa552633cc0bc66d46f61ea2105f7a4392df37be
tree8784dc3cde57ffd8a66b18dc52d598cdc856e865
parent7d32c9521fff3d2a18293d38562636c5a0e3408e

std.zig.parser now parses fn types


1 files changed, 99 insertions(+), 35 deletions(-)

std/zig/parser.zig+99-35
......@@ -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 );