| ... | ... | @@ -55,7 +55,7 @@ pub const Parser = struct { |
| 55 | 55 | const TopLevelDeclCtx = struct { |
| 56 | 56 | decls: &ArrayList(&ast.Node), |
| 57 | 57 | visib_token: ?Token, |
| 58 | | extern_token: ?Token, |
| 58 | extern_export_inline_token: ?Token, |
| 59 | 59 | lib_name: ?&ast.Node, |
| 60 | 60 | }; |
| 61 | 61 | |
| ... | ... | @@ -142,6 +142,7 @@ pub const Parser = struct { |
| 142 | 142 | const State = union(enum) { |
| 143 | 143 | TopLevel, |
| 144 | 144 | TopLevelExtern: TopLevelDeclCtx, |
| 145 | TopLevelLibname: TopLevelDeclCtx, |
| 145 | 146 | TopLevelDecl: TopLevelDeclCtx, |
| 146 | 147 | ContainerExtern: ContainerExternCtx, |
| 147 | 148 | ContainerDecl: &ast.NodeContainerDecl, |
| ... | ... | @@ -332,13 +333,13 @@ pub const Parser = struct { |
| 332 | 333 | root_node.eof_token = token; |
| 333 | 334 | return Tree {.root_node = root_node, .arena_allocator = arena_allocator}; |
| 334 | 335 | }, |
| 335 | | Token.Id.Keyword_pub, Token.Id.Keyword_export => { |
| 336 | Token.Id.Keyword_pub => { |
| 336 | 337 | stack.append(State.TopLevel) catch unreachable; |
| 337 | 338 | try stack.append(State { |
| 338 | 339 | .TopLevelExtern = TopLevelDeclCtx { |
| 339 | 340 | .decls = &root_node.decls, |
| 340 | 341 | .visib_token = token, |
| 341 | | .extern_token = null, |
| 342 | .extern_export_inline_token = null, |
| 342 | 343 | .lib_name = null, |
| 343 | 344 | } |
| 344 | 345 | }); |
| ... | ... | @@ -363,7 +364,7 @@ pub const Parser = struct { |
| 363 | 364 | .TopLevelExtern = TopLevelDeclCtx { |
| 364 | 365 | .decls = &root_node.decls, |
| 365 | 366 | .visib_token = null, |
| 366 | | .extern_token = null, |
| 367 | .extern_export_inline_token = null, |
| 367 | 368 | .lib_name = null, |
| 368 | 369 | } |
| 369 | 370 | }); |
| ... | ... | @@ -374,39 +375,24 @@ pub const Parser = struct { |
| 374 | 375 | State.TopLevelExtern => |ctx| { |
| 375 | 376 | const token = self.getNextToken(); |
| 376 | 377 | switch (token.id) { |
| 377 | | Token.Id.Keyword_use => { |
| 378 | | const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse, |
| 379 | | ast.NodeUse { |
| 380 | | .base = undefined, |
| 381 | | .visib_token = ctx.visib_token, |
| 382 | | .expr = undefined, |
| 383 | | .semicolon_token = undefined, |
| 384 | | } |
| 385 | | ); |
| 378 | Token.Id.Keyword_export, Token.Id.Keyword_inline => { |
| 386 | 379 | stack.append(State { |
| 387 | | .ExpectTokenSave = ExpectTokenSave { |
| 388 | | .id = Token.Id.Semicolon, |
| 389 | | .ptr = &node.semicolon_token, |
| 390 | | } |
| 380 | .TopLevelDecl = TopLevelDeclCtx { |
| 381 | .decls = ctx.decls, |
| 382 | .visib_token = ctx.visib_token, |
| 383 | .extern_export_inline_token = token, |
| 384 | .lib_name = null, |
| 385 | }, |
| 391 | 386 | }) catch unreachable; |
| 392 | | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| 393 | 387 | continue; |
| 394 | 388 | }, |
| 395 | 389 | Token.Id.Keyword_extern => { |
| 396 | | const lib_name = blk: { |
| 397 | | const lib_name_token = self.getNextToken(); |
| 398 | | break :blk (try self.parseStringLiteral(arena, lib_name_token)) ?? { |
| 399 | | self.putBackToken(lib_name_token); |
| 400 | | break :blk null; |
| 401 | | }; |
| 402 | | }; |
| 403 | | |
| 404 | 390 | stack.append(State { |
| 405 | | .TopLevelDecl = TopLevelDeclCtx { |
| 391 | .TopLevelLibname = TopLevelDeclCtx { |
| 406 | 392 | .decls = ctx.decls, |
| 407 | 393 | .visib_token = ctx.visib_token, |
| 408 | | .extern_token = token, |
| 409 | | .lib_name = lib_name, |
| 394 | .extern_export_inline_token = token, |
| 395 | .lib_name = null, |
| 410 | 396 | }, |
| 411 | 397 | }) catch unreachable; |
| 412 | 398 | continue; |
| ... | ... | @@ -418,17 +404,67 @@ pub const Parser = struct { |
| 418 | 404 | } |
| 419 | 405 | } |
| 420 | 406 | }, |
| 407 | |
| 408 | State.TopLevelLibname => |ctx| { |
| 409 | const lib_name = blk: { |
| 410 | const lib_name_token = self.getNextToken(); |
| 411 | break :blk (try self.parseStringLiteral(arena, lib_name_token)) ?? { |
| 412 | self.putBackToken(lib_name_token); |
| 413 | break :blk null; |
| 414 | }; |
| 415 | }; |
| 416 | |
| 417 | stack.append(State { |
| 418 | .TopLevelDecl = TopLevelDeclCtx { |
| 419 | .decls = ctx.decls, |
| 420 | .visib_token = ctx.visib_token, |
| 421 | .extern_export_inline_token = ctx.extern_export_inline_token, |
| 422 | .lib_name = lib_name, |
| 423 | }, |
| 424 | }) catch unreachable; |
| 425 | }, |
| 426 | |
| 421 | 427 | State.TopLevelDecl => |ctx| { |
| 422 | 428 | const token = self.getNextToken(); |
| 423 | 429 | switch (token.id) { |
| 430 | Token.Id.Keyword_use => { |
| 431 | if (ctx.extern_export_inline_token != null) { |
| 432 | try self.parseError(&stack, token, "Invalid token {}", @tagName((??ctx.extern_export_inline_token).id)); |
| 433 | continue; |
| 434 | } |
| 435 | |
| 436 | const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse, |
| 437 | ast.NodeUse { |
| 438 | .base = undefined, |
| 439 | .visib_token = ctx.visib_token, |
| 440 | .expr = undefined, |
| 441 | .semicolon_token = undefined, |
| 442 | } |
| 443 | ); |
| 444 | stack.append(State { |
| 445 | .ExpectTokenSave = ExpectTokenSave { |
| 446 | .id = Token.Id.Semicolon, |
| 447 | .ptr = &node.semicolon_token, |
| 448 | } |
| 449 | }) catch unreachable; |
| 450 | try stack.append(State { .Expression = DestPtr { .Field = &node.expr } }); |
| 451 | continue; |
| 452 | }, |
| 424 | 453 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 454 | if (ctx.extern_export_inline_token) |extern_export_inline_token| { |
| 455 | if (extern_export_inline_token.id == Token.Id.Keyword_inline) { |
| 456 | try self.parseError(&stack, token, "Invalid token {}", @tagName(extern_export_inline_token.id)); |
| 457 | continue; |
| 458 | } |
| 459 | } |
| 460 | |
| 425 | 461 | const var_decl_node = try self.createAttachNode(arena, ctx.decls, ast.NodeVarDecl, |
| 426 | 462 | ast.NodeVarDecl { |
| 427 | 463 | .base = undefined, |
| 428 | 464 | .visib_token = ctx.visib_token, |
| 429 | 465 | .mut_token = token, |
| 430 | 466 | .comptime_token = null, |
| 431 | | .extern_token = ctx.extern_token, |
| 467 | .extern_export_token = ctx.extern_export_inline_token, |
| 432 | 468 | .type_node = null, |
| 433 | 469 | .align_node = null, |
| 434 | 470 | .init_node = null, |
| ... | ... | @@ -452,8 +488,7 @@ pub const Parser = struct { |
| 452 | 488 | .params = ArrayList(&ast.Node).init(arena), |
| 453 | 489 | .return_type = undefined, |
| 454 | 490 | .var_args_token = null, |
| 455 | | .extern_token = ctx.extern_token, |
| 456 | | .inline_token = null, |
| 491 | .extern_export_inline_token = ctx.extern_export_inline_token, |
| 457 | 492 | .cc_token = null, |
| 458 | 493 | .async_attr = null, |
| 459 | 494 | .body_node = null, |
| ... | ... | @@ -475,8 +510,7 @@ pub const Parser = struct { |
| 475 | 510 | .params = ArrayList(&ast.Node).init(arena), |
| 476 | 511 | .return_type = undefined, |
| 477 | 512 | .var_args_token = null, |
| 478 | | .extern_token = ctx.extern_token, |
| 479 | | .inline_token = null, |
| 513 | .extern_export_inline_token = ctx.extern_export_inline_token, |
| 480 | 514 | .cc_token = token, |
| 481 | 515 | .async_attr = null, |
| 482 | 516 | .body_node = null, |
| ... | ... | @@ -513,8 +547,7 @@ pub const Parser = struct { |
| 513 | 547 | .params = ArrayList(&ast.Node).init(arena), |
| 514 | 548 | .return_type = undefined, |
| 515 | 549 | .var_args_token = null, |
| 516 | | .extern_token = ctx.extern_token, |
| 517 | | .inline_token = null, |
| 550 | .extern_export_inline_token = ctx.extern_export_inline_token, |
| 518 | 551 | .cc_token = null, |
| 519 | 552 | .async_attr = async_node, |
| 520 | 553 | .body_node = null, |
| ... | ... | @@ -752,7 +785,7 @@ pub const Parser = struct { |
| 752 | 785 | .TopLevelExtern = TopLevelDeclCtx { |
| 753 | 786 | .decls = &container_decl.fields_and_decls, |
| 754 | 787 | .visib_token = token, |
| 755 | | .extern_token = null, |
| 788 | .extern_export_inline_token = null, |
| 756 | 789 | .lib_name = null, |
| 757 | 790 | } |
| 758 | 791 | }); |
| ... | ... | @@ -764,7 +797,7 @@ pub const Parser = struct { |
| 764 | 797 | .TopLevelExtern = TopLevelDeclCtx { |
| 765 | 798 | .decls = &container_decl.fields_and_decls, |
| 766 | 799 | .visib_token = token, |
| 767 | | .extern_token = null, |
| 800 | .extern_export_inline_token = null, |
| 768 | 801 | .lib_name = null, |
| 769 | 802 | } |
| 770 | 803 | }); |
| ... | ... | @@ -781,7 +814,7 @@ pub const Parser = struct { |
| 781 | 814 | .TopLevelExtern = TopLevelDeclCtx { |
| 782 | 815 | .decls = &container_decl.fields_and_decls, |
| 783 | 816 | .visib_token = null, |
| 784 | | .extern_token = null, |
| 817 | .extern_export_inline_token = null, |
| 785 | 818 | .lib_name = null, |
| 786 | 819 | } |
| 787 | 820 | }); |
| ... | ... | @@ -1659,8 +1692,7 @@ pub const Parser = struct { |
| 1659 | 1692 | .params = ArrayList(&ast.Node).init(arena), |
| 1660 | 1693 | .return_type = undefined, |
| 1661 | 1694 | .var_args_token = null, |
| 1662 | | .extern_token = token, |
| 1663 | | .inline_token = null, |
| 1695 | .extern_export_inline_token = token, |
| 1664 | 1696 | .cc_token = null, |
| 1665 | 1697 | .async_attr = null, |
| 1666 | 1698 | .body_node = null, |
| ... | ... | @@ -1717,8 +1749,7 @@ pub const Parser = struct { |
| 1717 | 1749 | .params = ArrayList(&ast.Node).init(arena), |
| 1718 | 1750 | .return_type = undefined, |
| 1719 | 1751 | .var_args_token = null, |
| 1720 | | .extern_token = null, |
| 1721 | | .inline_token = null, |
| 1752 | .extern_export_inline_token = null, |
| 1722 | 1753 | .cc_token = null, |
| 1723 | 1754 | .async_attr = null, |
| 1724 | 1755 | .body_node = null, |
| ... | ... | @@ -1740,8 +1771,7 @@ pub const Parser = struct { |
| 1740 | 1771 | .params = ArrayList(&ast.Node).init(arena), |
| 1741 | 1772 | .return_type = undefined, |
| 1742 | 1773 | .var_args_token = null, |
| 1743 | | .extern_token = null, |
| 1744 | | .inline_token = null, |
| 1774 | .extern_export_inline_token = null, |
| 1745 | 1775 | .cc_token = token, |
| 1746 | 1776 | .async_attr = null, |
| 1747 | 1777 | .body_node = null, |
| ... | ... | @@ -2573,7 +2603,7 @@ pub const Parser = struct { |
| 2573 | 2603 | .visib_token = null, |
| 2574 | 2604 | .mut_token = mut_token, |
| 2575 | 2605 | .comptime_token = next, |
| 2576 | | .extern_token = null, |
| 2606 | .extern_export_token = null, |
| 2577 | 2607 | .type_node = null, |
| 2578 | 2608 | .align_node = null, |
| 2579 | 2609 | .init_node = null, |
| ... | ... | @@ -2601,7 +2631,7 @@ pub const Parser = struct { |
| 2601 | 2631 | .visib_token = null, |
| 2602 | 2632 | .mut_token = next, |
| 2603 | 2633 | .comptime_token = null, |
| 2604 | | .extern_token = null, |
| 2634 | .extern_export_token = null, |
| 2605 | 2635 | .type_node = null, |
| 2606 | 2636 | .align_node = null, |
| 2607 | 2637 | .init_node = null, |
| ... | ... | @@ -3281,13 +3311,13 @@ pub const Parser = struct { |
| 3281 | 3311 | try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(comptime_token) }); |
| 3282 | 3312 | } |
| 3283 | 3313 | |
| 3284 | | if (var_decl.extern_token) |extern_token| { |
| 3314 | if (var_decl.extern_export_token) |extern_export_token| { |
| 3285 | 3315 | if (var_decl.lib_name != null) { |
| 3286 | 3316 | try stack.append(RenderState { .Text = " " }); |
| 3287 | 3317 | try stack.append(RenderState { .Expression = ??var_decl.lib_name }); |
| 3288 | 3318 | } |
| 3289 | 3319 | try stack.append(RenderState { .Text = " " }); |
| 3290 | | try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) }); |
| 3320 | try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_export_token) }); |
| 3291 | 3321 | } |
| 3292 | 3322 | |
| 3293 | 3323 | if (var_decl.visib_token) |visib_token| { |
| ... | ... | @@ -3865,9 +3895,9 @@ pub const Parser = struct { |
| 3865 | 3895 | try stack.append(RenderState { .Text = " " }); |
| 3866 | 3896 | try stack.append(RenderState { .Expression = lib_name }); |
| 3867 | 3897 | } |
| 3868 | | if (fn_proto.extern_token) |extern_token| { |
| 3898 | if (fn_proto.extern_export_inline_token) |extern_export_inline_token| { |
| 3869 | 3899 | try stack.append(RenderState { .Text = " " }); |
| 3870 | | try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_token) }); |
| 3900 | try stack.append(RenderState { .Text = self.tokenizer.getTokenSlice(extern_export_inline_token) }); |
| 3871 | 3901 | } |
| 3872 | 3902 | |
| 3873 | 3903 | if (fn_proto.visib_token) |visib_token| { |
| ... | ... | @@ -4608,6 +4638,8 @@ test "zig fmt: extern function" { |
| 4608 | 4638 | try testCanonical( |
| 4609 | 4639 | \\extern fn puts(s: &const u8) c_int; |
| 4610 | 4640 | \\extern "c" fn puts(s: &const u8) c_int; |
| 4641 | \\export fn puts(s: &const u8) c_int; |
| 4642 | \\inline fn puts(s: &const u8) c_int; |
| 4611 | 4643 | \\ |
| 4612 | 4644 | ); |
| 4613 | 4645 | } |