| ... | ... | @@ -169,7 +169,7 @@ const Tokenizer = struct { |
| 169 | 169 | if (c == '\n') { |
| 170 | 170 | loc.line += 1; |
| 171 | 171 | loc.column = 0; |
| 172 | | loc.line_start = i; |
| 172 | loc.line_start = i + 1; |
| 173 | 173 | } else { |
| 174 | 174 | loc.column += 1; |
| 175 | 175 | } |
| ... | ... | @@ -520,6 +520,7 @@ const AstNode = struct { |
| 520 | 520 | FnProto, |
| 521 | 521 | ParamDecl, |
| 522 | 522 | AddrOfExpr, |
| 523 | Block, |
| 523 | 524 | }; |
| 524 | 525 | |
| 525 | 526 | fn iterate(base: &AstNode, index: usize) -> ?&AstNode { |
| ... | ... | @@ -530,6 +531,7 @@ const AstNode = struct { |
| 530 | 531 | Id.FnProto => @fieldParentPtr(AstNodeFnProto, "base", base).iterate(index), |
| 531 | 532 | Id.ParamDecl => @fieldParentPtr(AstNodeParamDecl, "base", base).iterate(index), |
| 532 | 533 | Id.AddrOfExpr => @fieldParentPtr(AstNodeAddrOfExpr, "base", base).iterate(index), |
| 534 | Id.Block => @fieldParentPtr(AstNodeBlock, "base", base).iterate(index), |
| 533 | 535 | }; |
| 534 | 536 | } |
| 535 | 537 | |
| ... | ... | @@ -541,6 +543,7 @@ const AstNode = struct { |
| 541 | 543 | Id.FnProto => allocator.destroy(@fieldParentPtr(AstNodeFnProto, "base", base)), |
| 542 | 544 | Id.ParamDecl => allocator.destroy(@fieldParentPtr(AstNodeParamDecl, "base", base)), |
| 543 | 545 | Id.AddrOfExpr => allocator.destroy(@fieldParentPtr(AstNodeAddrOfExpr, "base", base)), |
| 546 | Id.Block => allocator.destroy(@fieldParentPtr(AstNodeBlock, "base", base)), |
| 544 | 547 | }; |
| 545 | 548 | } |
| 546 | 549 | }; |
| ... | ... | @@ -551,7 +554,7 @@ const AstNodeRoot = struct { |
| 551 | 554 | |
| 552 | 555 | fn iterate(self: &AstNodeRoot, index: usize) -> ?&AstNode { |
| 553 | 556 | if (index < self.decls.len) { |
| 554 | | return self.decls.items[index]; |
| 557 | return self.decls.items[self.decls.len - index - 1]; |
| 555 | 558 | } |
| 556 | 559 | return null; |
| 557 | 560 | } |
| ... | ... | @@ -612,36 +615,36 @@ const AstNodeFnProto = struct { |
| 612 | 615 | extern_token: ?Token, |
| 613 | 616 | inline_token: ?Token, |
| 614 | 617 | cc_token: ?Token, |
| 615 | | fn_def_node: ?&AstNode, |
| 618 | body_node: ?&AstNode, |
| 616 | 619 | lib_name: ?&AstNode, // populated if this is an extern declaration |
| 617 | 620 | align_expr: ?&AstNode, // populated if align(A) is present |
| 618 | 621 | |
| 619 | 622 | fn iterate(self: &AstNodeFnProto, index: usize) -> ?&AstNode { |
| 620 | 623 | var i = index; |
| 621 | 624 | |
| 622 | | if (i < self.params.len) return self.params.items[i]; |
| 623 | | i -= self.params.len; |
| 625 | if (self.body_node) |body_node| { |
| 626 | if (i < 1) return body_node; |
| 627 | i -= 1; |
| 628 | } |
| 624 | 629 | |
| 625 | 630 | if (self.return_type) |return_type| { |
| 626 | 631 | if (i < 1) return return_type; |
| 627 | 632 | i -= 1; |
| 628 | 633 | } |
| 629 | 634 | |
| 630 | | if (self.fn_def_node) |fn_def_node| { |
| 631 | | if (i < 1) return fn_def_node; |
| 635 | if (self.align_expr) |align_expr| { |
| 636 | if (i < 1) return align_expr; |
| 632 | 637 | i -= 1; |
| 633 | 638 | } |
| 634 | 639 | |
| 640 | if (i < self.params.len) return self.params.items[self.params.len - i - 1]; |
| 641 | i -= self.params.len; |
| 642 | |
| 635 | 643 | if (self.lib_name) |lib_name| { |
| 636 | 644 | if (i < 1) return lib_name; |
| 637 | 645 | i -= 1; |
| 638 | 646 | } |
| 639 | 647 | |
| 640 | | if (self.align_expr) |align_expr| { |
| 641 | | if (i < 1) return align_expr; |
| 642 | | i -= 1; |
| 643 | | } |
| 644 | | |
| 645 | 648 | return null; |
| 646 | 649 | } |
| 647 | 650 | }; |
| ... | ... | @@ -689,6 +692,22 @@ const AstNodeAddrOfExpr = struct { |
| 689 | 692 | } |
| 690 | 693 | }; |
| 691 | 694 | |
| 695 | const AstNodeBlock = struct { |
| 696 | base: AstNode, |
| 697 | begin_token: Token, |
| 698 | end_token: Token, |
| 699 | statements: ArrayList(&AstNode), |
| 700 | |
| 701 | fn iterate(self: &AstNodeBlock, index: usize) -> ?&AstNode { |
| 702 | var i = index; |
| 703 | |
| 704 | if (i < self.statements.len) return self.statements.items[i]; |
| 705 | i -= self.statements.len; |
| 706 | |
| 707 | return null; |
| 708 | } |
| 709 | }; |
| 710 | |
| 692 | 711 | error ParseError; |
| 693 | 712 | |
| 694 | 713 | const Parser = struct { |
| ... | ... | @@ -734,27 +753,41 @@ const Parser = struct { |
| 734 | 753 | extern_token: ?Token, |
| 735 | 754 | }; |
| 736 | 755 | |
| 756 | const DestPtr = union(enum) { |
| 757 | Field: &&AstNode, |
| 758 | NullableField: &?&AstNode, |
| 759 | List: &ArrayList(&AstNode), |
| 760 | |
| 761 | pub fn store(self: &const DestPtr, value: &AstNode) -> %void { |
| 762 | switch (*self) { |
| 763 | DestPtr.Field => |ptr| *ptr = value, |
| 764 | DestPtr.NullableField => |ptr| *ptr = value, |
| 765 | DestPtr.List => |list| %return list.append(value), |
| 766 | } |
| 767 | } |
| 768 | }; |
| 769 | |
| 737 | 770 | const State = union(enum) { |
| 738 | 771 | TopLevel, |
| 739 | 772 | TopLevelExtern: ?Token, |
| 740 | 773 | TopLevelDecl: TopLevelDeclCtx, |
| 741 | | Expression: &&AstNode, |
| 742 | | GroupedExpression: &&AstNode, |
| 743 | | UnwrapExpression: &&AstNode, |
| 744 | | BoolOrExpression: &&AstNode, |
| 745 | | BoolAndExpression: &&AstNode, |
| 746 | | ComparisonExpression: &&AstNode, |
| 747 | | BinaryOrExpression: &&AstNode, |
| 748 | | BinaryXorExpression: &&AstNode, |
| 749 | | BinaryAndExpression: &&AstNode, |
| 750 | | BitShiftExpression: &&AstNode, |
| 751 | | AdditionExpression: &&AstNode, |
| 752 | | MultiplyExpression: &&AstNode, |
| 753 | | BraceSuffixExpression: &&AstNode, |
| 754 | | PrefixOpExpression: &&AstNode, |
| 755 | | SuffixOpExpression: &&AstNode, |
| 756 | | PrimaryExpression: &&AstNode, |
| 757 | | TypeExpr: &&AstNode, |
| 774 | Expression: DestPtr, |
| 775 | GroupedExpression: DestPtr, |
| 776 | UnwrapExpression: DestPtr, |
| 777 | BoolOrExpression: DestPtr, |
| 778 | BoolAndExpression: DestPtr, |
| 779 | ComparisonExpression: DestPtr, |
| 780 | BinaryOrExpression: DestPtr, |
| 781 | BinaryXorExpression: DestPtr, |
| 782 | BinaryAndExpression: DestPtr, |
| 783 | BitShiftExpression: DestPtr, |
| 784 | AdditionExpression: DestPtr, |
| 785 | MultiplyExpression: DestPtr, |
| 786 | BraceSuffixExpression: DestPtr, |
| 787 | PrefixOpExpression: DestPtr, |
| 788 | SuffixOpExpression: DestPtr, |
| 789 | PrimaryExpression: DestPtr, |
| 790 | TypeExpr: DestPtr, |
| 758 | 791 | VarDecl: &AstNodeVarDecl, |
| 759 | 792 | VarDeclAlign: &AstNodeVarDecl, |
| 760 | 793 | VarDeclEq: &AstNodeVarDecl, |
| ... | ... | @@ -763,6 +796,9 @@ const Parser = struct { |
| 763 | 796 | FnProtoAlign: &AstNodeFnProto, |
| 764 | 797 | ParamDecl: &AstNodeFnProto, |
| 765 | 798 | ParamDeclComma, |
| 799 | FnDef: &AstNodeFnProto, |
| 800 | Block: &AstNodeBlock, |
| 801 | Statement: &AstNodeBlock, |
| 766 | 802 | }; |
| 767 | 803 | |
| 768 | 804 | pub fn freeAst(self: &Parser, root_node: &AstNodeRoot) { |
| ... | ... | @@ -797,6 +833,18 @@ const Parser = struct { |
| 797 | 833 | %defer self.freeAst(root_node); |
| 798 | 834 | |
| 799 | 835 | while (true) { |
| 836 | //{ |
| 837 | // const token = self.getNextToken(); |
| 838 | // warn("{} ", @tagName(token.id)); |
| 839 | // self.putBackToken(token); |
| 840 | // var i: usize = stack.len; |
| 841 | // while (i != 0) { |
| 842 | // i -= 1; |
| 843 | // warn("{} ", @tagName(stack.items[i])); |
| 844 | // } |
| 845 | // warn("\n"); |
| 846 | //} |
| 847 | |
| 800 | 848 | // This gives us 1 free append that can't fail |
| 801 | 849 | const state = stack.pop(); |
| 802 | 850 | |
| ... | ... | @@ -850,11 +898,11 @@ const Parser = struct { |
| 850 | 898 | }, |
| 851 | 899 | Token.Id.Keyword_fn => { |
| 852 | 900 | stack.append(State.TopLevel) %% unreachable; |
| 853 | | %return stack.append(State { .ExpectToken = Token.Id.Semicolon }); |
| 854 | 901 | // TODO shouldn't need these casts |
| 855 | | const fn_proto_node = %return self.createAttachFnProto(&root_node.decls, token, |
| 902 | const fn_proto = %return self.createAttachFnProto(&root_node.decls, token, |
| 856 | 903 | ctx.extern_token, (?Token)(null), (?Token)(null), (?Token)(null)); |
| 857 | | %return stack.append(State { .FnProto = fn_proto_node }); |
| 904 | %return stack.append(State { .FnDef = fn_proto }); |
| 905 | %return stack.append(State { .FnProto = fn_proto }); |
| 858 | 906 | continue; |
| 859 | 907 | }, |
| 860 | 908 | Token.Id.StringLiteral => { |
| ... | ... | @@ -862,12 +910,12 @@ const Parser = struct { |
| 862 | 910 | }, |
| 863 | 911 | Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => { |
| 864 | 912 | stack.append(State.TopLevel) %% unreachable; |
| 865 | | %return stack.append(State { .ExpectToken = Token.Id.Semicolon }); |
| 866 | 913 | const fn_token = %return self.eatToken(Token.Id.Keyword_fn); |
| 867 | 914 | // TODO shouldn't need this cast |
| 868 | | const fn_proto_node = %return self.createAttachFnProto(&root_node.decls, fn_token, |
| 915 | const fn_proto = %return self.createAttachFnProto(&root_node.decls, fn_token, |
| 869 | 916 | ctx.extern_token, (?Token)(token), (?Token)(null), (?Token)(null)); |
| 870 | | %return stack.append(State { .FnProto = fn_proto_node }); |
| 917 | %return stack.append(State { .FnDef = fn_proto }); |
| 918 | %return stack.append(State { .FnProto = fn_proto }); |
| 871 | 919 | continue; |
| 872 | 920 | }, |
| 873 | 921 | else => return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)), |
| ... | ... | @@ -879,7 +927,7 @@ const Parser = struct { |
| 879 | 927 | |
| 880 | 928 | const next_token = self.getNextToken(); |
| 881 | 929 | if (next_token.id == Token.Id.Colon) { |
| 882 | | %return stack.append(State { .TypeExpr = removeNullCast(&var_decl.type_node) }); |
| 930 | %return stack.append(State { .TypeExpr = DestPtr {.NullableField = &var_decl.type_node} }); |
| 883 | 931 | continue; |
| 884 | 932 | } |
| 885 | 933 | |
| ... | ... | @@ -891,7 +939,11 @@ const Parser = struct { |
| 891 | 939 | |
| 892 | 940 | const next_token = self.getNextToken(); |
| 893 | 941 | if (next_token.id == Token.Id.Keyword_align) { |
| 894 | | %return stack.append(State { .GroupedExpression = removeNullCast(&var_decl.align_node) }); |
| 942 | %return stack.append(State { |
| 943 | .GroupedExpression = DestPtr { |
| 944 | .NullableField = &var_decl.align_node |
| 945 | } |
| 946 | }); |
| 895 | 947 | continue; |
| 896 | 948 | } |
| 897 | 949 | |
| ... | ... | @@ -904,7 +956,7 @@ const Parser = struct { |
| 904 | 956 | var_decl.eq_token = token; |
| 905 | 957 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable; |
| 906 | 958 | %return stack.append(State { |
| 907 | | .Expression = removeNullCast(&var_decl.init_node), |
| 959 | .Expression = DestPtr {.NullableField = &var_decl.init_node}, |
| 908 | 960 | }); |
| 909 | 961 | continue; |
| 910 | 962 | } |
| ... | ... | @@ -917,70 +969,70 @@ const Parser = struct { |
| 917 | 969 | _ = %return self.eatToken(token_id); |
| 918 | 970 | continue; |
| 919 | 971 | }, |
| 920 | | State.Expression => |result_ptr| { |
| 921 | | stack.append(State {.UnwrapExpression = result_ptr}) %% unreachable; |
| 972 | State.Expression => |dest_ptr| { |
| 973 | stack.append(State {.UnwrapExpression = dest_ptr}) %% unreachable; |
| 922 | 974 | continue; |
| 923 | 975 | }, |
| 924 | 976 | |
| 925 | | State.UnwrapExpression => |result_ptr| { |
| 926 | | stack.append(State {.BoolOrExpression = result_ptr}) %% unreachable; |
| 977 | State.UnwrapExpression => |dest_ptr| { |
| 978 | stack.append(State {.BoolOrExpression = dest_ptr}) %% unreachable; |
| 927 | 979 | continue; |
| 928 | 980 | }, |
| 929 | 981 | |
| 930 | | State.BoolOrExpression => |result_ptr| { |
| 931 | | stack.append(State {.BoolAndExpression = result_ptr}) %% unreachable; |
| 982 | State.BoolOrExpression => |dest_ptr| { |
| 983 | stack.append(State {.BoolAndExpression = dest_ptr}) %% unreachable; |
| 932 | 984 | continue; |
| 933 | 985 | }, |
| 934 | 986 | |
| 935 | | State.BoolAndExpression => |result_ptr| { |
| 936 | | stack.append(State {.ComparisonExpression = result_ptr}) %% unreachable; |
| 987 | State.BoolAndExpression => |dest_ptr| { |
| 988 | stack.append(State {.ComparisonExpression = dest_ptr}) %% unreachable; |
| 937 | 989 | continue; |
| 938 | 990 | }, |
| 939 | 991 | |
| 940 | | State.ComparisonExpression => |result_ptr| { |
| 941 | | stack.append(State {.BinaryOrExpression = result_ptr}) %% unreachable; |
| 992 | State.ComparisonExpression => |dest_ptr| { |
| 993 | stack.append(State {.BinaryOrExpression = dest_ptr}) %% unreachable; |
| 942 | 994 | continue; |
| 943 | 995 | }, |
| 944 | 996 | |
| 945 | | State.BinaryOrExpression => |result_ptr| { |
| 946 | | stack.append(State {.BinaryXorExpression = result_ptr}) %% unreachable; |
| 997 | State.BinaryOrExpression => |dest_ptr| { |
| 998 | stack.append(State {.BinaryXorExpression = dest_ptr}) %% unreachable; |
| 947 | 999 | continue; |
| 948 | 1000 | }, |
| 949 | 1001 | |
| 950 | | State.BinaryXorExpression => |result_ptr| { |
| 951 | | stack.append(State {.BinaryAndExpression = result_ptr}) %% unreachable; |
| 1002 | State.BinaryXorExpression => |dest_ptr| { |
| 1003 | stack.append(State {.BinaryAndExpression = dest_ptr}) %% unreachable; |
| 952 | 1004 | continue; |
| 953 | 1005 | }, |
| 954 | 1006 | |
| 955 | | State.BinaryAndExpression => |result_ptr| { |
| 956 | | stack.append(State {.BitShiftExpression = result_ptr}) %% unreachable; |
| 1007 | State.BinaryAndExpression => |dest_ptr| { |
| 1008 | stack.append(State {.BitShiftExpression = dest_ptr}) %% unreachable; |
| 957 | 1009 | continue; |
| 958 | 1010 | }, |
| 959 | 1011 | |
| 960 | | State.BitShiftExpression => |result_ptr| { |
| 961 | | stack.append(State {.AdditionExpression = result_ptr}) %% unreachable; |
| 1012 | State.BitShiftExpression => |dest_ptr| { |
| 1013 | stack.append(State {.AdditionExpression = dest_ptr}) %% unreachable; |
| 962 | 1014 | continue; |
| 963 | 1015 | }, |
| 964 | 1016 | |
| 965 | | State.AdditionExpression => |result_ptr| { |
| 966 | | stack.append(State {.MultiplyExpression = result_ptr}) %% unreachable; |
| 1017 | State.AdditionExpression => |dest_ptr| { |
| 1018 | stack.append(State {.MultiplyExpression = dest_ptr}) %% unreachable; |
| 967 | 1019 | continue; |
| 968 | 1020 | }, |
| 969 | 1021 | |
| 970 | | State.MultiplyExpression => |result_ptr| { |
| 971 | | stack.append(State {.BraceSuffixExpression = result_ptr}) %% unreachable; |
| 1022 | State.MultiplyExpression => |dest_ptr| { |
| 1023 | stack.append(State {.BraceSuffixExpression = dest_ptr}) %% unreachable; |
| 972 | 1024 | continue; |
| 973 | 1025 | }, |
| 974 | 1026 | |
| 975 | | State.BraceSuffixExpression => |result_ptr| { |
| 976 | | stack.append(State {.PrefixOpExpression = result_ptr}) %% unreachable; |
| 1027 | State.BraceSuffixExpression => |dest_ptr| { |
| 1028 | stack.append(State {.PrefixOpExpression = dest_ptr}) %% unreachable; |
| 977 | 1029 | continue; |
| 978 | 1030 | }, |
| 979 | 1031 | |
| 980 | | State.PrefixOpExpression => |result_ptr| { |
| 1032 | State.PrefixOpExpression => |dest_ptr| { |
| 981 | 1033 | const first_token = self.getNextToken(); |
| 982 | 1034 | if (first_token.id == Token.Id.Ampersand) { |
| 983 | | const addr_of_expr = %return self.createAttachAddrOfExpr(result_ptr, first_token); |
| 1035 | const addr_of_expr = %return self.createAttachAddrOfExpr(dest_ptr, first_token); |
| 984 | 1036 | var token = self.getNextToken(); |
| 985 | 1037 | if (token.id == Token.Id.Keyword_align) { |
| 986 | 1038 | @panic("TODO align"); |
| ... | ... | @@ -994,40 +1046,42 @@ const Parser = struct { |
| 994 | 1046 | token = self.getNextToken(); |
| 995 | 1047 | } |
| 996 | 1048 | self.putBackToken(token); |
| 997 | | stack.append(State { .PrefixOpExpression = &addr_of_expr.op_expr }) %% unreachable; |
| 1049 | stack.append(State { |
| 1050 | .PrefixOpExpression = DestPtr { .Field = &addr_of_expr.op_expr}, |
| 1051 | }) %% unreachable; |
| 998 | 1052 | continue; |
| 999 | 1053 | } |
| 1000 | 1054 | |
| 1001 | 1055 | self.putBackToken(first_token); |
| 1002 | | stack.append(State { .SuffixOpExpression = result_ptr }) %% unreachable; |
| 1056 | stack.append(State { .SuffixOpExpression = dest_ptr }) %% unreachable; |
| 1003 | 1057 | continue; |
| 1004 | 1058 | }, |
| 1005 | 1059 | |
| 1006 | | State.SuffixOpExpression => |result_ptr| { |
| 1007 | | stack.append(State { .PrimaryExpression = result_ptr }) %% unreachable; |
| 1060 | State.SuffixOpExpression => |dest_ptr| { |
| 1061 | stack.append(State { .PrimaryExpression = dest_ptr }) %% unreachable; |
| 1008 | 1062 | continue; |
| 1009 | 1063 | }, |
| 1010 | 1064 | |
| 1011 | | State.PrimaryExpression => |result_ptr| { |
| 1065 | State.PrimaryExpression => |dest_ptr| { |
| 1012 | 1066 | const token = self.getNextToken(); |
| 1013 | 1067 | switch (token.id) { |
| 1014 | 1068 | Token.Id.Identifier => { |
| 1015 | 1069 | const identifier = %return self.createIdentifier(token); |
| 1016 | | *result_ptr = &identifier.base; |
| 1070 | %return dest_ptr.store(&identifier.base); |
| 1017 | 1071 | continue; |
| 1018 | 1072 | }, |
| 1019 | 1073 | else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)), |
| 1020 | 1074 | } |
| 1021 | 1075 | }, |
| 1022 | 1076 | |
| 1023 | | State.TypeExpr => |result_ptr| { |
| 1077 | State.TypeExpr => |dest_ptr| { |
| 1024 | 1078 | const token = self.getNextToken(); |
| 1025 | 1079 | if (token.id == Token.Id.Keyword_var) { |
| 1026 | 1080 | @panic("TODO param with type var"); |
| 1027 | 1081 | } |
| 1028 | 1082 | self.putBackToken(token); |
| 1029 | 1083 | |
| 1030 | | stack.append(State { .PrefixOpExpression = result_ptr }) %% unreachable; |
| 1084 | stack.append(State { .PrefixOpExpression = dest_ptr }) %% unreachable; |
| 1031 | 1085 | continue; |
| 1032 | 1086 | }, |
| 1033 | 1087 | |
| ... | ... | @@ -1051,7 +1105,9 @@ const Parser = struct { |
| 1051 | 1105 | @panic("TODO fn proto align"); |
| 1052 | 1106 | } |
| 1053 | 1107 | if (token.id == Token.Id.Arrow) { |
| 1054 | | stack.append(State { .TypeExpr = removeNullCast(&fn_proto.return_type) }) %% unreachable; |
| 1108 | stack.append(State { |
| 1109 | .TypeExpr = DestPtr {.NullableField = &fn_proto.return_type}, |
| 1110 | }) %% unreachable; |
| 1055 | 1111 | continue; |
| 1056 | 1112 | } else { |
| 1057 | 1113 | self.putBackToken(token); |
| ... | ... | @@ -1091,7 +1147,9 @@ const Parser = struct { |
| 1091 | 1147 | |
| 1092 | 1148 | stack.append(State { .ParamDecl = fn_proto }) %% unreachable; |
| 1093 | 1149 | %return stack.append(State.ParamDeclComma); |
| 1094 | | %return stack.append(State { .TypeExpr = &param_decl.type_node }); |
| 1150 | %return stack.append(State { |
| 1151 | .TypeExpr = DestPtr {.Field = &param_decl.type_node} |
| 1152 | }); |
| 1095 | 1153 | continue; |
| 1096 | 1154 | }, |
| 1097 | 1155 | |
| ... | ... | @@ -1107,6 +1165,70 @@ const Parser = struct { |
| 1107 | 1165 | } |
| 1108 | 1166 | }, |
| 1109 | 1167 | |
| 1168 | State.FnDef => |fn_proto| { |
| 1169 | const token = self.getNextToken(); |
| 1170 | switch(token.id) { |
| 1171 | Token.Id.LBrace => { |
| 1172 | const block = %return self.createBlock(token); |
| 1173 | fn_proto.body_node = &block.base; |
| 1174 | stack.append(State { .Block = block }) %% unreachable; |
| 1175 | continue; |
| 1176 | }, |
| 1177 | Token.Id.Semicolon => continue, |
| 1178 | else => return self.parseError(token, "expected ';' or '{{', found {}", @tagName(token.id)), |
| 1179 | } |
| 1180 | }, |
| 1181 | |
| 1182 | State.Block => |block| { |
| 1183 | const token = self.getNextToken(); |
| 1184 | switch (token.id) { |
| 1185 | Token.Id.RBrace => { |
| 1186 | block.end_token = token; |
| 1187 | continue; |
| 1188 | }, |
| 1189 | else => { |
| 1190 | self.putBackToken(token); |
| 1191 | stack.append(State { .Block = block }) %% unreachable; |
| 1192 | %return stack.append(State { .Statement = block }); |
| 1193 | continue; |
| 1194 | }, |
| 1195 | } |
| 1196 | }, |
| 1197 | |
| 1198 | State.Statement => |block| { |
| 1199 | { |
| 1200 | // Look for comptime var, comptime const |
| 1201 | const comptime_token = self.getNextToken(); |
| 1202 | if (comptime_token.id == Token.Id.Keyword_comptime) { |
| 1203 | const mut_token = self.getNextToken(); |
| 1204 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { |
| 1205 | // TODO shouldn't need these casts |
| 1206 | const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null), |
| 1207 | mut_token, (?Token)(comptime_token), (?Token)(null)); |
| 1208 | %return stack.append(State { .VarDecl = var_decl }); |
| 1209 | continue; |
| 1210 | } |
| 1211 | self.putBackToken(mut_token); |
| 1212 | } |
| 1213 | self.putBackToken(comptime_token); |
| 1214 | } |
| 1215 | { |
| 1216 | // Look for const, var |
| 1217 | const mut_token = self.getNextToken(); |
| 1218 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { |
| 1219 | // TODO shouldn't need these casts |
| 1220 | const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null), |
| 1221 | mut_token, (?Token)(null), (?Token)(null)); |
| 1222 | %return stack.append(State { .VarDecl = var_decl }); |
| 1223 | continue; |
| 1224 | } |
| 1225 | self.putBackToken(mut_token); |
| 1226 | } |
| 1227 | |
| 1228 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable; |
| 1229 | %return stack.append(State { .Expression = DestPtr{.List = &block.statements} }); |
| 1230 | continue; |
| 1231 | }, |
| 1110 | 1232 | |
| 1111 | 1233 | State.GroupedExpression => @panic("TODO"), |
| 1112 | 1234 | } |
| ... | ... | @@ -1176,7 +1298,7 @@ const Parser = struct { |
| 1176 | 1298 | .extern_token = *extern_token, |
| 1177 | 1299 | .inline_token = *inline_token, |
| 1178 | 1300 | .cc_token = *cc_token, |
| 1179 | | .fn_def_node = null, |
| 1301 | .body_node = null, |
| 1180 | 1302 | .lib_name = null, |
| 1181 | 1303 | .align_expr = null, |
| 1182 | 1304 | }; |
| ... | ... | @@ -1215,10 +1337,23 @@ const Parser = struct { |
| 1215 | 1337 | return node; |
| 1216 | 1338 | } |
| 1217 | 1339 | |
| 1218 | | fn createAttachAddrOfExpr(self: &Parser, result_ptr: &&AstNode, op_token: &const Token) -> %&AstNodeAddrOfExpr { |
| 1340 | fn createBlock(self: &Parser, begin_token: &const Token) -> %&AstNodeBlock { |
| 1341 | const node = %return self.allocator.create(AstNodeBlock); |
| 1342 | %defer self.allocator.destroy(node); |
| 1343 | |
| 1344 | *node = AstNodeBlock { |
| 1345 | .base = AstNode {.id = AstNode.Id.Block}, |
| 1346 | .begin_token = *begin_token, |
| 1347 | .end_token = undefined, |
| 1348 | .statements = ArrayList(&AstNode).init(self.allocator), |
| 1349 | }; |
| 1350 | return node; |
| 1351 | } |
| 1352 | |
| 1353 | fn createAttachAddrOfExpr(self: &Parser, dest_ptr: &const DestPtr, op_token: &const Token) -> %&AstNodeAddrOfExpr { |
| 1219 | 1354 | const node = %return self.createAddrOfExpr(op_token); |
| 1220 | 1355 | %defer self.allocator.destroy(node); |
| 1221 | | *result_ptr = &node.base; |
| 1356 | %return dest_ptr.store(&node.base); |
| 1222 | 1357 | return node; |
| 1223 | 1358 | } |
| 1224 | 1359 | |
| ... | ... | @@ -1337,7 +1472,11 @@ const Parser = struct { |
| 1337 | 1472 | Text: []const u8, |
| 1338 | 1473 | Expression: &AstNode, |
| 1339 | 1474 | AddrOfExprBit: &AstNodeAddrOfExpr, |
| 1475 | VarDecl: &AstNodeVarDecl, |
| 1340 | 1476 | VarDeclAlign: &AstNodeVarDecl, |
| 1477 | Statement: &AstNode, |
| 1478 | PrintIndent, |
| 1479 | Indent: usize, |
| 1341 | 1480 | }; |
| 1342 | 1481 | |
| 1343 | 1482 | pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &AstNodeRoot) -> %void { |
| ... | ... | @@ -1353,6 +1492,8 @@ const Parser = struct { |
| 1353 | 1492 | } |
| 1354 | 1493 | } |
| 1355 | 1494 | |
| 1495 | const indent_delta = 4; |
| 1496 | var indent: usize = 0; |
| 1356 | 1497 | while (stack.popOrNull()) |state| { |
| 1357 | 1498 | switch (state) { |
| 1358 | 1499 | RenderState.TopLevelDecl => |decl| { |
| ... | ... | @@ -1378,7 +1519,7 @@ const Parser = struct { |
| 1378 | 1519 | %return stream.print("("); |
| 1379 | 1520 | |
| 1380 | 1521 | %return stack.append(RenderState { .Text = "\n" }); |
| 1381 | | if (fn_proto.fn_def_node == null) { |
| 1522 | if (fn_proto.body_node == null) { |
| 1382 | 1523 | %return stack.append(RenderState { .Text = ";" }); |
| 1383 | 1524 | } |
| 1384 | 1525 | |
| ... | ... | @@ -1395,36 +1536,42 @@ const Parser = struct { |
| 1395 | 1536 | }, |
| 1396 | 1537 | AstNode.Id.VarDecl => { |
| 1397 | 1538 | const var_decl = @fieldParentPtr(AstNodeVarDecl, "base", decl); |
| 1398 | | if (var_decl.visib_token) |visib_token| { |
| 1399 | | %return stream.print("{} ", self.tokenizer.getTokenSlice(visib_token)); |
| 1400 | | } |
| 1401 | | if (var_decl.extern_token) |extern_token| { |
| 1402 | | %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); |
| 1403 | | if (var_decl.lib_name != null) { |
| 1404 | | @panic("TODO"); |
| 1405 | | } |
| 1406 | | } |
| 1407 | | if (var_decl.comptime_token) |comptime_token| { |
| 1408 | | %return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); |
| 1409 | | } |
| 1410 | | %return stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token)); |
| 1411 | | %return stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token)); |
| 1539 | %return stack.append(RenderState { .Text = "\n"}); |
| 1540 | %return stack.append(RenderState { .VarDecl = var_decl}); |
| 1412 | 1541 | |
| 1413 | | %return stack.append(RenderState { .VarDeclAlign = var_decl }); |
| 1414 | | if (var_decl.type_node) |type_node| { |
| 1415 | | %return stream.print(": "); |
| 1416 | | %return stack.append(RenderState { .Expression = type_node }); |
| 1417 | | } |
| 1418 | 1542 | }, |
| 1419 | 1543 | else => unreachable, |
| 1420 | 1544 | } |
| 1421 | 1545 | }, |
| 1422 | 1546 | |
| 1547 | RenderState.VarDecl => |var_decl| { |
| 1548 | if (var_decl.visib_token) |visib_token| { |
| 1549 | %return stream.print("{} ", self.tokenizer.getTokenSlice(visib_token)); |
| 1550 | } |
| 1551 | if (var_decl.extern_token) |extern_token| { |
| 1552 | %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); |
| 1553 | if (var_decl.lib_name != null) { |
| 1554 | @panic("TODO"); |
| 1555 | } |
| 1556 | } |
| 1557 | if (var_decl.comptime_token) |comptime_token| { |
| 1558 | %return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); |
| 1559 | } |
| 1560 | %return stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token)); |
| 1561 | %return stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token)); |
| 1562 | |
| 1563 | %return stack.append(RenderState { .VarDeclAlign = var_decl }); |
| 1564 | if (var_decl.type_node) |type_node| { |
| 1565 | %return stream.print(": "); |
| 1566 | %return stack.append(RenderState { .Expression = type_node }); |
| 1567 | } |
| 1568 | }, |
| 1569 | |
| 1423 | 1570 | RenderState.VarDeclAlign => |var_decl| { |
| 1424 | 1571 | if (var_decl.align_node != null) { |
| 1425 | 1572 | @panic("TODO"); |
| 1426 | 1573 | } |
| 1427 | | %return stack.append(RenderState { .Text = ";\n" }); |
| 1574 | %return stack.append(RenderState { .Text = ";" }); |
| 1428 | 1575 | if (var_decl.init_node) |init_node| { |
| 1429 | 1576 | %return stream.print(" = "); |
| 1430 | 1577 | %return stack.append(RenderState { .Expression = init_node }); |
| ... | ... | @@ -1467,6 +1614,23 @@ const Parser = struct { |
| 1467 | 1614 | %return stack.append(RenderState { .Expression = align_expr}); |
| 1468 | 1615 | } |
| 1469 | 1616 | }, |
| 1617 | AstNode.Id.Block => { |
| 1618 | const block = @fieldParentPtr(AstNodeBlock, "base", base); |
| 1619 | %return stream.write("{"); |
| 1620 | %return stack.append(RenderState { .Text = "}"}); |
| 1621 | %return stack.append(RenderState.PrintIndent); |
| 1622 | %return stack.append(RenderState { .Indent = indent}); |
| 1623 | %return stack.append(RenderState { .Text = "\n"}); |
| 1624 | var i = block.statements.len; |
| 1625 | while (i != 0) { |
| 1626 | i -= 1; |
| 1627 | const statement_node = block.statements.items[i]; |
| 1628 | %return stack.append(RenderState { .Statement = statement_node}); |
| 1629 | %return stack.append(RenderState.PrintIndent); |
| 1630 | %return stack.append(RenderState { .Indent = indent + indent_delta}); |
| 1631 | %return stack.append(RenderState { .Text = "\n" }); |
| 1632 | } |
| 1633 | }, |
| 1470 | 1634 | else => unreachable, |
| 1471 | 1635 | }, |
| 1472 | 1636 | RenderState.AddrOfExprBit => |addr_of_expr| { |
| ... | ... | @@ -1491,9 +1655,24 @@ const Parser = struct { |
| 1491 | 1655 | } |
| 1492 | 1656 | if (fn_proto.return_type) |return_type| { |
| 1493 | 1657 | %return stream.print(" -> "); |
| 1658 | if (fn_proto.body_node) |body_node| { |
| 1659 | %return stack.append(RenderState { .Expression = body_node}); |
| 1660 | %return stack.append(RenderState { .Text = " "}); |
| 1661 | } |
| 1494 | 1662 | %return stack.append(RenderState { .Expression = return_type}); |
| 1495 | 1663 | } |
| 1496 | 1664 | }, |
| 1665 | RenderState.Statement => |base| { |
| 1666 | switch (base.id) { |
| 1667 | AstNode.Id.VarDecl => { |
| 1668 | const var_decl = @fieldParentPtr(AstNodeVarDecl, "base", base); |
| 1669 | %return stack.append(RenderState { .VarDecl = var_decl}); |
| 1670 | }, |
| 1671 | else => unreachable, |
| 1672 | } |
| 1673 | }, |
| 1674 | RenderState.Indent => |new_indent| indent = new_indent, |
| 1675 | RenderState.PrintIndent => %return stream.writeByteNTimes(' ', indent), |
| 1497 | 1676 | } |
| 1498 | 1677 | } |
| 1499 | 1678 | } |
| ... | ... | @@ -1555,15 +1734,6 @@ pub fn main2() -> %void { |
| 1555 | 1734 | %return parser.renderSource(out_stream, root_node); |
| 1556 | 1735 | } |
| 1557 | 1736 | |
| 1558 | | fn removeNullCast(x: var) -> {const InnerPtr = @typeOf(x).Child.Child; &InnerPtr} { |
| 1559 | | comptime assert(@typeId(@typeOf(x)) == builtin.TypeId.Pointer); |
| 1560 | | comptime assert(@typeId(@typeOf(x).Child) == builtin.TypeId.Nullable); |
| 1561 | | comptime assert(@typeId(@typeOf(x).Child.Child) == builtin.TypeId.Pointer); |
| 1562 | | const InnerPtr = @typeOf(x).Child.Child; |
| 1563 | | return @ptrCast(&InnerPtr, x); |
| 1564 | | } |
| 1565 | | |
| 1566 | | |
| 1567 | 1737 | |
| 1568 | 1738 | fn testCanonical(source: []const u8) { |
| 1569 | 1739 | const allocator = std.debug.global_allocator; |
| ... | ... | @@ -1612,4 +1782,11 @@ test "zig fmt" { |
| 1612 | 1782 | \\extern var foo: c_int; |
| 1613 | 1783 | \\ |
| 1614 | 1784 | ); |
| 1785 | |
| 1786 | testCanonical( |
| 1787 | \\fn main(argc: c_int, argv: &&u8) -> c_int { |
| 1788 | \\ const a = b; |
| 1789 | \\} |
| 1790 | \\ |
| 1791 | ); |
| 1615 | 1792 | } |