| ... | ... | @@ -105,8 +105,6 @@ const char *node_type_str(NodeType node_type) { |
| 105 | 105 | return "ArrayAccessExpr"; |
| 106 | 106 | case NodeTypeSliceExpr: |
| 107 | 107 | return "SliceExpr"; |
| 108 | | case NodeTypeExternBlock: |
| 109 | | return "ExternBlock"; |
| 110 | 108 | case NodeTypeDirective: |
| 111 | 109 | return "Directive"; |
| 112 | 110 | case NodeTypeReturnExpr: |
| ... | ... | @@ -258,15 +256,6 @@ void ast_print(AstNode *node, int indent) { |
| 258 | 256 | fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(name_buf)); |
| 259 | 257 | break; |
| 260 | 258 | } |
| 261 | | case NodeTypeExternBlock: |
| 262 | | { |
| 263 | | fprintf(stderr, "%s\n", node_type_str(node->type)); |
| 264 | | for (int i = 0; i < node->data.extern_block.fn_decls.length; i += 1) { |
| 265 | | AstNode *child = node->data.extern_block.fn_decls.at(i); |
| 266 | | ast_print(child, indent + 2); |
| 267 | | } |
| 268 | | break; |
| 269 | | } |
| 270 | 259 | case NodeTypeFnDecl: |
| 271 | 260 | fprintf(stderr, "%s\n", node_type_str(node->type)); |
| 272 | 261 | ast_print(node->data.fn_decl.fn_proto, indent + 2); |
| ... | ... | @@ -482,9 +471,9 @@ struct ParseContext { |
| 482 | 471 | Buf *buf; |
| 483 | 472 | AstNode *root; |
| 484 | 473 | ZigList<Token> *tokens; |
| 485 | | ZigList<AstNode *> *directive_list; |
| 486 | 474 | ImportTableEntry *owner; |
| 487 | 475 | ErrColor err_color; |
| 476 | bool parsed_root_export; |
| 488 | 477 | uint32_t *next_node_index; |
| 489 | 478 | }; |
| 490 | 479 | |
| ... | ... | @@ -2146,56 +2135,32 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m |
| 2146 | 2135 | } |
| 2147 | 2136 | |
| 2148 | 2137 | /* |
| 2149 | | VariableDeclaration : option(FnVisibleMod) ("var" | "const") "Symbol" ("=" Expression | ":" PrefixOpExpression option("=" Expression)) |
| 2138 | VariableDeclaration : ("var" | "const") "Symbol" ("=" Expression | ":" PrefixOpExpression option("=" Expression)) |
| 2150 | 2139 | */ |
| 2151 | | static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 2140 | static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token_index, bool mandatory, |
| 2141 | ZigList<AstNode*> *directives, VisibMod visib_mod) |
| 2142 | { |
| 2152 | 2143 | Token *first_token = &pc->tokens->at(*token_index); |
| 2153 | 2144 | |
| 2154 | | VisibMod visib_mod; |
| 2155 | 2145 | bool is_const; |
| 2156 | 2146 | |
| 2157 | | if (first_token->id == TokenIdKeywordPub) { |
| 2158 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2159 | | if (next_token->id == TokenIdKeywordVar || |
| 2160 | | next_token->id == TokenIdKeywordConst) |
| 2161 | | { |
| 2162 | | visib_mod = VisibModPub; |
| 2163 | | is_const = (next_token->id == TokenIdKeywordConst); |
| 2164 | | *token_index += 2; |
| 2165 | | } else if (mandatory) { |
| 2166 | | ast_invalid_token_error(pc, next_token); |
| 2167 | | } else { |
| 2168 | | return nullptr; |
| 2169 | | } |
| 2170 | | } else if (first_token->id == TokenIdKeywordExport) { |
| 2171 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2172 | | if (next_token->id == TokenIdKeywordVar || |
| 2173 | | next_token->id == TokenIdKeywordConst) |
| 2174 | | { |
| 2175 | | visib_mod = VisibModExport; |
| 2176 | | is_const = (next_token->id == TokenIdKeywordConst); |
| 2177 | | *token_index += 2; |
| 2178 | | } else if (mandatory) { |
| 2179 | | ast_invalid_token_error(pc, next_token); |
| 2180 | | } else { |
| 2181 | | return nullptr; |
| 2182 | | } |
| 2183 | | } else if (first_token->id == TokenIdKeywordVar || |
| 2184 | | first_token->id == TokenIdKeywordConst) |
| 2185 | | { |
| 2186 | | visib_mod = VisibModPrivate; |
| 2187 | | is_const = (first_token->id == TokenIdKeywordConst); |
| 2188 | | *token_index += 1; |
| 2147 | if (first_token->id == TokenIdKeywordVar) { |
| 2148 | is_const = false; |
| 2149 | } else if (first_token->id == TokenIdKeywordConst) { |
| 2150 | is_const = true; |
| 2189 | 2151 | } else if (mandatory) { |
| 2190 | 2152 | ast_invalid_token_error(pc, first_token); |
| 2191 | 2153 | } else { |
| 2192 | 2154 | return nullptr; |
| 2193 | 2155 | } |
| 2194 | 2156 | |
| 2157 | *token_index += 1; |
| 2158 | |
| 2195 | 2159 | AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, first_token); |
| 2196 | 2160 | |
| 2197 | 2161 | node->data.variable_declaration.is_const = is_const; |
| 2198 | 2162 | node->data.variable_declaration.visib_mod = visib_mod; |
| 2163 | node->data.variable_declaration.directives = directives; |
| 2199 | 2164 | |
| 2200 | 2165 | Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol); |
| 2201 | 2166 | ast_buf_from_token(pc, name_token, &node->data.variable_declaration.symbol); |
| ... | ... | @@ -2643,7 +2608,8 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato |
| 2643 | 2608 | if (statement_node) { |
| 2644 | 2609 | semicolon_expected = false; |
| 2645 | 2610 | } else { |
| 2646 | | statement_node = ast_parse_variable_declaration_expr(pc, token_index, false); |
| 2611 | statement_node = ast_parse_variable_declaration_expr(pc, token_index, false, |
| 2612 | nullptr, VisibModPrivate); |
| 2647 | 2613 | if (statement_node) { |
| 2648 | 2614 | semicolon_expected = true; |
| 2649 | 2615 | } else { |
| ... | ... | @@ -2677,47 +2643,25 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato |
| 2677 | 2643 | } |
| 2678 | 2644 | |
| 2679 | 2645 | /* |
| 2680 | | FnProto : many(Directive) option(FnVisibleMod) "fn" "Symbol" ParamDeclList option("->" PrefixOpExpression) |
| 2646 | FnProto : "fn" "Symbol" ParamDeclList option("->" PrefixOpExpression) |
| 2681 | 2647 | */ |
| 2682 | | static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory) { |
| 2648 | static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mandatory, |
| 2649 | ZigList<AstNode*> *directives, VisibMod visib_mod) |
| 2650 | { |
| 2683 | 2651 | Token *first_token = &pc->tokens->at(*token_index); |
| 2684 | 2652 | |
| 2685 | | VisibMod visib_mod; |
| 2686 | | |
| 2687 | | if (first_token->id == TokenIdKeywordPub) { |
| 2688 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2689 | | if (next_token->id == TokenIdKeywordFn) { |
| 2690 | | visib_mod = VisibModPub; |
| 2691 | | *token_index += 2; |
| 2692 | | } else if (mandatory) { |
| 2693 | | ast_invalid_token_error(pc, first_token); |
| 2694 | | } else { |
| 2695 | | return nullptr; |
| 2696 | | } |
| 2697 | | } else if (first_token->id == TokenIdKeywordExport) { |
| 2698 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2699 | | if (next_token->id == TokenIdKeywordFn) { |
| 2700 | | visib_mod = VisibModExport; |
| 2701 | | *token_index += 2; |
| 2702 | | } else if (mandatory) { |
| 2703 | | ast_invalid_token_error(pc, first_token); |
| 2653 | if (first_token->id != TokenIdKeywordFn) { |
| 2654 | if (mandatory) { |
| 2655 | ast_expect_token(pc, first_token, TokenIdKeywordFn); |
| 2704 | 2656 | } else { |
| 2705 | 2657 | return nullptr; |
| 2706 | 2658 | } |
| 2707 | | } else if (first_token->id == TokenIdKeywordFn) { |
| 2708 | | visib_mod = VisibModPrivate; |
| 2709 | | *token_index += 1; |
| 2710 | | } else if (mandatory) { |
| 2711 | | ast_invalid_token_error(pc, first_token); |
| 2712 | | } else { |
| 2713 | | return nullptr; |
| 2714 | 2659 | } |
| 2660 | *token_index += 1; |
| 2715 | 2661 | |
| 2716 | 2662 | AstNode *node = ast_create_node(pc, NodeTypeFnProto, first_token); |
| 2717 | 2663 | node->data.fn_proto.visib_mod = visib_mod; |
| 2718 | | node->data.fn_proto.directives = pc->directive_list; |
| 2719 | | pc->directive_list = nullptr; |
| 2720 | | |
| 2664 | node->data.fn_proto.directives = directives; |
| 2721 | 2665 | |
| 2722 | 2666 | Token *fn_name = &pc->tokens->at(*token_index); |
| 2723 | 2667 | *token_index += 1; |
| ... | ... | @@ -2743,107 +2687,59 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mand |
| 2743 | 2687 | /* |
| 2744 | 2688 | FnDef : FnProto Block |
| 2745 | 2689 | */ |
| 2746 | | static AstNode *ast_parse_fn_def(ParseContext *pc, int *token_index, bool mandatory) { |
| 2747 | | AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, mandatory); |
| 2690 | static AstNode *ast_parse_fn_def(ParseContext *pc, int *token_index, bool mandatory, |
| 2691 | ZigList<AstNode*> *directives, VisibMod visib_mod) |
| 2692 | { |
| 2693 | AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, mandatory, directives, visib_mod); |
| 2748 | 2694 | if (!fn_proto) |
| 2749 | 2695 | return nullptr; |
| 2750 | 2696 | AstNode *node = ast_create_node_with_node(pc, NodeTypeFnDef, fn_proto); |
| 2751 | 2697 | |
| 2752 | 2698 | node->data.fn_def.fn_proto = fn_proto; |
| 2753 | 2699 | node->data.fn_def.body = ast_parse_block(pc, token_index, true); |
| 2754 | | |
| 2755 | | normalize_parent_ptrs(node); |
| 2756 | | return node; |
| 2757 | | } |
| 2758 | | |
| 2759 | | /* |
| 2760 | | FnDecl : FnProto token(Semicolon) |
| 2761 | | */ |
| 2762 | | static AstNode *ast_parse_fn_decl(ParseContext *pc, int *token_index) { |
| 2763 | | AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, true); |
| 2764 | | AstNode *node = ast_create_node_with_node(pc, NodeTypeFnDecl, fn_proto); |
| 2765 | | |
| 2766 | | node->data.fn_decl.fn_proto = fn_proto; |
| 2767 | | |
| 2768 | | Token *semicolon = &pc->tokens->at(*token_index); |
| 2769 | | *token_index += 1; |
| 2770 | | ast_expect_token(pc, semicolon, TokenIdSemicolon); |
| 2771 | | |
| 2772 | 2700 | normalize_parent_ptrs(node); |
| 2773 | 2701 | return node; |
| 2774 | 2702 | } |
| 2775 | 2703 | |
| 2776 | 2704 | /* |
| 2777 | | Directive : token(NumberSign) token(Symbol) token(LParen) token(String) token(RParen) |
| 2778 | | */ |
| 2779 | | /* |
| 2780 | | ExternBlock : many(Directive) token(Extern) token(LBrace) many(FnProtoDecl) token(RBrace) |
| 2705 | ExternDecl : "extern" FnProto ";" |
| 2781 | 2706 | */ |
| 2782 | | static AstNode *ast_parse_extern_block(ParseContext *pc, int *token_index, bool mandatory) { |
| 2707 | static AstNode *ast_parse_extern_decl(ParseContext *pc, int *token_index, bool mandatory, |
| 2708 | ZigList<AstNode *> *directives, VisibMod visib_mod) |
| 2709 | { |
| 2783 | 2710 | Token *extern_kw = &pc->tokens->at(*token_index); |
| 2784 | 2711 | if (extern_kw->id != TokenIdKeywordExtern) { |
| 2785 | | if (mandatory) |
| 2712 | if (mandatory) { |
| 2786 | 2713 | ast_invalid_token_error(pc, extern_kw); |
| 2787 | | else |
| 2714 | } else { |
| 2788 | 2715 | return nullptr; |
| 2716 | } |
| 2789 | 2717 | } |
| 2790 | 2718 | *token_index += 1; |
| 2791 | 2719 | |
| 2792 | | AstNode *node = ast_create_node(pc, NodeTypeExternBlock, extern_kw); |
| 2793 | | |
| 2794 | | node->data.extern_block.directives = pc->directive_list; |
| 2795 | | pc->directive_list = nullptr; |
| 2796 | | |
| 2797 | | Token *l_brace = &pc->tokens->at(*token_index); |
| 2798 | | *token_index += 1; |
| 2799 | | ast_expect_token(pc, l_brace, TokenIdLBrace); |
| 2800 | | |
| 2801 | | for (;;) { |
| 2802 | | Token *directive_token = &pc->tokens->at(*token_index); |
| 2803 | | assert(!pc->directive_list); |
| 2804 | | pc->directive_list = allocate<ZigList<AstNode*>>(1); |
| 2805 | | ast_parse_directives(pc, token_index, pc->directive_list); |
| 2806 | | |
| 2807 | | Token *token = &pc->tokens->at(*token_index); |
| 2808 | | if (token->id == TokenIdRBrace) { |
| 2809 | | if (pc->directive_list->length > 0) { |
| 2810 | | ast_error(pc, directive_token, "invalid directive"); |
| 2811 | | } |
| 2812 | | pc->directive_list = nullptr; |
| 2813 | | |
| 2814 | | *token_index += 1; |
| 2815 | | |
| 2816 | | normalize_parent_ptrs(node); |
| 2817 | | return node; |
| 2818 | | } else { |
| 2819 | | AstNode *child = ast_parse_fn_decl(pc, token_index); |
| 2820 | | node->data.extern_block.fn_decls.append(child); |
| 2821 | | } |
| 2822 | | } |
| 2720 | AstNode *node = ast_parse_fn_proto(pc, token_index, true, directives, visib_mod); |
| 2823 | 2721 | |
| 2722 | ast_eat_token(pc, token_index, TokenIdSemicolon); |
| 2824 | 2723 | |
| 2825 | | zig_unreachable(); |
| 2724 | node->data.fn_proto.is_extern = true; |
| 2725 | normalize_parent_ptrs(node); |
| 2726 | return node; |
| 2826 | 2727 | } |
| 2827 | 2728 | |
| 2828 | 2729 | /* |
| 2829 | | RootExportDecl : many(Directive) token(Export) token(Symbol) token(String) token(Semicolon) |
| 2730 | RootExportDecl : "export" "Symbol" "String" ";" |
| 2830 | 2731 | */ |
| 2831 | | static AstNode *ast_parse_root_export_decl(ParseContext *pc, int *token_index, bool mandatory) { |
| 2832 | | assert(mandatory == false); |
| 2833 | | |
| 2834 | | Token *export_kw = &pc->tokens->at(*token_index); |
| 2835 | | if (export_kw->id != TokenIdKeywordExport) |
| 2836 | | return nullptr; |
| 2837 | | |
| 2838 | | Token *export_type = &pc->tokens->at(*token_index + 1); |
| 2732 | static AstNode *ast_parse_root_export_decl(ParseContext *pc, int *token_index, |
| 2733 | ZigList<AstNode*> *directives) |
| 2734 | { |
| 2735 | Token *export_type = &pc->tokens->at(*token_index); |
| 2839 | 2736 | if (export_type->id != TokenIdSymbol) |
| 2840 | 2737 | return nullptr; |
| 2841 | 2738 | |
| 2842 | | *token_index += 2; |
| 2739 | *token_index += 1; |
| 2843 | 2740 | |
| 2844 | | AstNode *node = ast_create_node(pc, NodeTypeRootExportDecl, export_kw); |
| 2845 | | node->data.root_export_decl.directives = pc->directive_list; |
| 2846 | | pc->directive_list = nullptr; |
| 2741 | AstNode *node = ast_create_node(pc, NodeTypeRootExportDecl, export_type); |
| 2742 | node->data.root_export_decl.directives = directives; |
| 2847 | 2743 | |
| 2848 | 2744 | ast_buf_from_token(pc, export_type, &node->data.root_export_decl.type); |
| 2849 | 2745 | |
| ... | ... | @@ -2862,11 +2758,13 @@ static AstNode *ast_parse_root_export_decl(ParseContext *pc, int *token_index, b |
| 2862 | 2758 | } |
| 2863 | 2759 | |
| 2864 | 2760 | /* |
| 2865 | | Use : many(Directive) token(Use) token(String) token(Semicolon) |
| 2761 | Import : "import" "String" ";" |
| 2866 | 2762 | */ |
| 2867 | | static AstNode *ast_parse_use(ParseContext *pc, int *token_index) { |
| 2868 | | Token *use_kw = &pc->tokens->at(*token_index); |
| 2869 | | if (use_kw->id != TokenIdKeywordImport) |
| 2763 | static AstNode *ast_parse_import(ParseContext *pc, int *token_index, |
| 2764 | ZigList<AstNode*> *directives, VisibMod visib_mod) |
| 2765 | { |
| 2766 | Token *import_kw = &pc->tokens->at(*token_index); |
| 2767 | if (import_kw->id != TokenIdKeywordImport) |
| 2870 | 2768 | return nullptr; |
| 2871 | 2769 | *token_index += 1; |
| 2872 | 2770 | |
| ... | ... | @@ -2878,59 +2776,35 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index) { |
| 2878 | 2776 | *token_index += 1; |
| 2879 | 2777 | ast_expect_token(pc, semicolon, TokenIdSemicolon); |
| 2880 | 2778 | |
| 2881 | | AstNode *node = ast_create_node(pc, NodeTypeUse, use_kw); |
| 2779 | AstNode *node = ast_create_node(pc, NodeTypeUse, import_kw); |
| 2780 | node->data.use.visib_mod = visib_mod; |
| 2781 | node->data.use.directives = directives; |
| 2882 | 2782 | |
| 2883 | 2783 | parse_string_literal(pc, use_name, &node->data.use.path, nullptr, nullptr); |
| 2884 | | |
| 2885 | | node->data.use.directives = pc->directive_list; |
| 2886 | | pc->directive_list = nullptr; |
| 2887 | | |
| 2888 | 2784 | normalize_parent_ptrs(node); |
| 2889 | 2785 | return node; |
| 2890 | 2786 | } |
| 2891 | 2787 | |
| 2892 | 2788 | /* |
| 2893 | | ContainerDecl : many(Directive) option(FnVisibleMod) (token(Struct) | token(Enum)) token(Symbol) token(LBrace) many(StructMember) token(RBrace) |
| 2894 | | StructMember: StructField | FnDecl |
| 2895 | | StructField : token(Symbol) option(token(Colon) Expression) token(Comma)) |
| 2789 | ContainerDecl : ("struct" | "enum") "Symbol" "{" many(StructMember) "}" |
| 2790 | StructMember: many(Directive) option(VisibleMod) (StructField | FnDef) |
| 2791 | StructField : "Symbol" option(":" Expression) ",") |
| 2896 | 2792 | */ |
| 2897 | | static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2793 | static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index, |
| 2794 | ZigList<AstNode*> *directives, VisibMod visib_mod) |
| 2795 | { |
| 2898 | 2796 | Token *first_token = &pc->tokens->at(*token_index); |
| 2899 | 2797 | |
| 2900 | | VisibMod visib_mod; |
| 2901 | 2798 | ContainerKind kind; |
| 2902 | 2799 | |
| 2903 | | if (first_token->id == TokenIdKeywordPub) { |
| 2904 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2905 | | if (next_token->id == TokenIdKeywordStruct || |
| 2906 | | next_token->id == TokenIdKeywordEnum) |
| 2907 | | { |
| 2908 | | visib_mod = VisibModPub; |
| 2909 | | kind = (next_token->id == TokenIdKeywordStruct) ? ContainerKindStruct : ContainerKindEnum; |
| 2910 | | *token_index += 2; |
| 2911 | | } else { |
| 2912 | | return nullptr; |
| 2913 | | } |
| 2914 | | } else if (first_token->id == TokenIdKeywordExport) { |
| 2915 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2916 | | if (next_token->id == TokenIdKeywordStruct || |
| 2917 | | next_token->id == TokenIdKeywordEnum) |
| 2918 | | { |
| 2919 | | visib_mod = VisibModExport; |
| 2920 | | kind = (next_token->id == TokenIdKeywordStruct) ? ContainerKindStruct : ContainerKindEnum; |
| 2921 | | *token_index += 2; |
| 2922 | | } else { |
| 2923 | | return nullptr; |
| 2924 | | } |
| 2925 | | } else if (first_token->id == TokenIdKeywordStruct || |
| 2926 | | first_token->id == TokenIdKeywordEnum) |
| 2927 | | { |
| 2928 | | visib_mod = VisibModPrivate; |
| 2929 | | kind = (first_token->id == TokenIdKeywordStruct) ? ContainerKindStruct : ContainerKindEnum; |
| 2930 | | *token_index += 1; |
| 2800 | if (first_token->id == TokenIdKeywordStruct) { |
| 2801 | kind = ContainerKindStruct; |
| 2802 | } else if (first_token->id == TokenIdKeywordEnum) { |
| 2803 | kind = ContainerKindEnum; |
| 2931 | 2804 | } else { |
| 2932 | 2805 | return nullptr; |
| 2933 | 2806 | } |
| 2807 | *token_index += 1; |
| 2934 | 2808 | |
| 2935 | 2809 | Token *struct_name = ast_eat_token(pc, token_index, TokenIdSymbol); |
| 2936 | 2810 | |
| ... | ... | @@ -2938,19 +2812,28 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2938 | 2812 | node->data.struct_decl.kind = kind; |
| 2939 | 2813 | ast_buf_from_token(pc, struct_name, &node->data.struct_decl.name); |
| 2940 | 2814 | node->data.struct_decl.visib_mod = visib_mod; |
| 2815 | node->data.struct_decl.directives = directives; |
| 2941 | 2816 | |
| 2942 | 2817 | ast_eat_token(pc, token_index, TokenIdLBrace); |
| 2943 | 2818 | |
| 2944 | | node->data.struct_decl.directives = pc->directive_list; |
| 2945 | | pc->directive_list = nullptr; |
| 2946 | | |
| 2947 | 2819 | for (;;) { |
| 2948 | | assert(!pc->directive_list); |
| 2949 | | pc->directive_list = allocate<ZigList<AstNode*>>(1); |
| 2950 | 2820 | Token *directive_token = &pc->tokens->at(*token_index); |
| 2951 | | ast_parse_directives(pc, token_index, pc->directive_list); |
| 2821 | ZigList<AstNode *> *directive_list = allocate<ZigList<AstNode*>>(1); |
| 2822 | ast_parse_directives(pc, token_index, directive_list); |
| 2823 | |
| 2824 | Token *visib_tok = &pc->tokens->at(*token_index); |
| 2825 | VisibMod visib_mod; |
| 2826 | if (visib_tok->id == TokenIdKeywordPub) { |
| 2827 | *token_index += 1; |
| 2828 | visib_mod = VisibModPub; |
| 2829 | } else if (visib_tok->id == TokenIdKeywordExport) { |
| 2830 | *token_index += 1; |
| 2831 | visib_mod = VisibModExport; |
| 2832 | } else { |
| 2833 | visib_mod = VisibModPrivate; |
| 2834 | } |
| 2952 | 2835 | |
| 2953 | | AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false); |
| 2836 | AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, directive_list, visib_mod); |
| 2954 | 2837 | if (fn_def_node) { |
| 2955 | 2838 | node->data.struct_decl.fns.append(fn_def_node); |
| 2956 | 2839 | continue; |
| ... | ... | @@ -2959,10 +2842,9 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2959 | 2842 | Token *token = &pc->tokens->at(*token_index); |
| 2960 | 2843 | |
| 2961 | 2844 | if (token->id == TokenIdRBrace) { |
| 2962 | | if (pc->directive_list->length > 0) { |
| 2845 | if (directive_list->length > 0) { |
| 2963 | 2846 | ast_error(pc, directive_token, "invalid directive"); |
| 2964 | 2847 | } |
| 2965 | | pc->directive_list = nullptr; |
| 2966 | 2848 | |
| 2967 | 2849 | *token_index += 1; |
| 2968 | 2850 | break; |
| ... | ... | @@ -2970,8 +2852,8 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2970 | 2852 | AstNode *field_node = ast_create_node(pc, NodeTypeStructField, token); |
| 2971 | 2853 | *token_index += 1; |
| 2972 | 2854 | |
| 2973 | | field_node->data.struct_field.directives = pc->directive_list; |
| 2974 | | pc->directive_list = nullptr; |
| 2855 | field_node->data.struct_field.visib_mod = visib_mod; |
| 2856 | field_node->data.struct_field.directives = directive_list; |
| 2975 | 2857 | |
| 2976 | 2858 | ast_buf_from_token(pc, token, &field_node->data.struct_field.name); |
| 2977 | 2859 | |
| ... | ... | @@ -2997,47 +2879,24 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2997 | 2879 | } |
| 2998 | 2880 | |
| 2999 | 2881 | /* |
| 3000 | | ErrorValueDecl : option(FnVisibleMod) "error" "Symbol" |
| 2882 | ErrorValueDecl : "error" "Symbol" ";" |
| 3001 | 2883 | */ |
| 3002 | | static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, bool mandatory) { |
| 2884 | static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, |
| 2885 | ZigList<AstNode*> *directives, VisibMod visib_mod) |
| 2886 | { |
| 3003 | 2887 | Token *first_token = &pc->tokens->at(*token_index); |
| 3004 | 2888 | |
| 3005 | | VisibMod visib_mod; |
| 3006 | | |
| 3007 | | if (first_token->id == TokenIdKeywordPub) { |
| 3008 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 3009 | | if (next_token->id == TokenIdKeywordError) { |
| 3010 | | visib_mod = VisibModPub; |
| 3011 | | *token_index += 2; |
| 3012 | | } else if (mandatory) { |
| 3013 | | ast_invalid_token_error(pc, next_token); |
| 3014 | | } else { |
| 3015 | | return nullptr; |
| 3016 | | } |
| 3017 | | } else if (first_token->id == TokenIdKeywordExport) { |
| 3018 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 3019 | | if (next_token->id == TokenIdKeywordError) { |
| 3020 | | visib_mod = VisibModExport; |
| 3021 | | *token_index += 2; |
| 3022 | | } else if (mandatory) { |
| 3023 | | ast_invalid_token_error(pc, next_token); |
| 3024 | | } else { |
| 3025 | | return nullptr; |
| 3026 | | } |
| 3027 | | } else if (first_token->id == TokenIdKeywordError) { |
| 3028 | | visib_mod = VisibModPrivate; |
| 3029 | | *token_index += 1; |
| 3030 | | } else if (mandatory) { |
| 3031 | | ast_invalid_token_error(pc, first_token); |
| 3032 | | } else { |
| 2889 | if (first_token->id != TokenIdKeywordError) { |
| 3033 | 2890 | return nullptr; |
| 3034 | 2891 | } |
| 2892 | *token_index += 1; |
| 3035 | 2893 | |
| 3036 | 2894 | Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); |
| 3037 | 2895 | ast_eat_token(pc, token_index, TokenIdSemicolon); |
| 3038 | 2896 | |
| 3039 | 2897 | AstNode *node = ast_create_node(pc, NodeTypeErrorValueDecl, first_token); |
| 3040 | 2898 | node->data.error_value_decl.visib_mod = visib_mod; |
| 2899 | node->data.error_value_decl.directives = directives; |
| 3041 | 2900 | ast_buf_from_token(pc, name_tok, &node->data.error_value_decl.name); |
| 3042 | 2901 | |
| 3043 | 2902 | normalize_parent_ptrs(node); |
| ... | ... | @@ -3045,63 +2904,79 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b |
| 3045 | 2904 | } |
| 3046 | 2905 | |
| 3047 | 2906 | /* |
| 3048 | | TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Import | ContainerDecl | VariableDeclaration | ErrorValueDecl |
| 2907 | TopLevelDecl : many(Directive) option(FnVisibleMod) (FnDef | ExternFnProto | RootExportDecl | Import | ContainerDecl | VariableDeclaration | ErrorValueDecl | CImportDecl) |
| 3049 | 2908 | */ |
| 3050 | 2909 | static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigList<AstNode *> *top_level_decls) { |
| 3051 | 2910 | for (;;) { |
| 3052 | 2911 | Token *directive_token = &pc->tokens->at(*token_index); |
| 3053 | | assert(!pc->directive_list); |
| 3054 | | pc->directive_list = allocate<ZigList<AstNode*>>(1); |
| 3055 | | ast_parse_directives(pc, token_index, pc->directive_list); |
| 2912 | ZigList<AstNode *> *directives = allocate<ZigList<AstNode*>>(1); |
| 2913 | ast_parse_directives(pc, token_index, directives); |
| 3056 | 2914 | |
| 3057 | | AstNode *root_export_decl_node = ast_parse_root_export_decl(pc, token_index, false); |
| 3058 | | if (root_export_decl_node) { |
| 3059 | | top_level_decls->append(root_export_decl_node); |
| 3060 | | continue; |
| 2915 | Token *visib_tok = &pc->tokens->at(*token_index); |
| 2916 | VisibMod visib_mod; |
| 2917 | if (visib_tok->id == TokenIdKeywordPub) { |
| 2918 | *token_index += 1; |
| 2919 | visib_mod = VisibModPub; |
| 2920 | } else if (visib_tok->id == TokenIdKeywordExport) { |
| 2921 | *token_index += 1; |
| 2922 | visib_mod = VisibModExport; |
| 2923 | } else { |
| 2924 | visib_mod = VisibModPrivate; |
| 3061 | 2925 | } |
| 3062 | 2926 | |
| 3063 | | AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false); |
| 2927 | bool try_to_parse_root_export = (visib_mod == VisibModExport && !pc->parsed_root_export); |
| 2928 | pc->parsed_root_export = true; |
| 2929 | |
| 2930 | if (try_to_parse_root_export) { |
| 2931 | AstNode *root_export_decl_node = ast_parse_root_export_decl(pc, token_index, directives); |
| 2932 | if (root_export_decl_node) { |
| 2933 | top_level_decls->append(root_export_decl_node); |
| 2934 | continue; |
| 2935 | } |
| 2936 | } |
| 2937 | |
| 2938 | AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, directives, visib_mod); |
| 3064 | 2939 | if (fn_def_node) { |
| 3065 | 2940 | top_level_decls->append(fn_def_node); |
| 3066 | 2941 | continue; |
| 3067 | 2942 | } |
| 3068 | 2943 | |
| 3069 | | AstNode *extern_node = ast_parse_extern_block(pc, token_index, false); |
| 3070 | | if (extern_node) { |
| 3071 | | top_level_decls->append(extern_node); |
| 2944 | AstNode *fn_proto_node = ast_parse_extern_decl(pc, token_index, false, directives, visib_mod); |
| 2945 | if (fn_proto_node) { |
| 2946 | top_level_decls->append(fn_proto_node); |
| 3072 | 2947 | continue; |
| 3073 | 2948 | } |
| 3074 | 2949 | |
| 3075 | | AstNode *use_node = ast_parse_use(pc, token_index); |
| 3076 | | if (use_node) { |
| 3077 | | top_level_decls->append(use_node); |
| 2950 | AstNode *import_node = ast_parse_import(pc, token_index, directives, visib_mod); |
| 2951 | if (import_node) { |
| 2952 | top_level_decls->append(import_node); |
| 3078 | 2953 | continue; |
| 3079 | 2954 | } |
| 3080 | 2955 | |
| 3081 | | AstNode *struct_node = ast_parse_struct_decl(pc, token_index); |
| 2956 | AstNode *struct_node = ast_parse_struct_decl(pc, token_index, directives, visib_mod); |
| 3082 | 2957 | if (struct_node) { |
| 3083 | 2958 | top_level_decls->append(struct_node); |
| 3084 | 2959 | continue; |
| 3085 | 2960 | } |
| 3086 | 2961 | |
| 3087 | | if (pc->directive_list->length > 0) { |
| 3088 | | ast_error(pc, directive_token, "invalid directive"); |
| 3089 | | } |
| 3090 | | pc->directive_list = nullptr; |
| 3091 | | |
| 3092 | | AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false); |
| 2962 | AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, |
| 2963 | directives, visib_mod); |
| 3093 | 2964 | if (var_decl_node) { |
| 3094 | 2965 | ast_eat_token(pc, token_index, TokenIdSemicolon); |
| 3095 | 2966 | top_level_decls->append(var_decl_node); |
| 3096 | 2967 | continue; |
| 3097 | 2968 | } |
| 3098 | 2969 | |
| 3099 | | AstNode *error_value_node = ast_parse_error_value_decl(pc, token_index, false); |
| 2970 | AstNode *error_value_node = ast_parse_error_value_decl(pc, token_index, directives, visib_mod); |
| 3100 | 2971 | if (error_value_node) { |
| 3101 | 2972 | top_level_decls->append(error_value_node); |
| 3102 | 2973 | continue; |
| 3103 | 2974 | } |
| 3104 | 2975 | |
| 2976 | if (directives->length > 0) { |
| 2977 | ast_error(pc, directive_token, "invalid directive"); |
| 2978 | } |
| 2979 | |
| 3105 | 2980 | return; |
| 3106 | 2981 | } |
| 3107 | 2982 | zig_unreachable(); |
| ... | ... | @@ -3175,10 +3050,6 @@ void normalize_parent_ptrs(AstNode *node) { |
| 3175 | 3050 | case NodeTypeBlock: |
| 3176 | 3051 | set_list_fields(&node->data.block.statements); |
| 3177 | 3052 | break; |
| 3178 | | case NodeTypeExternBlock: |
| 3179 | | set_list_fields(node->data.extern_block.directives); |
| 3180 | | set_list_fields(&node->data.extern_block.fn_decls); |
| 3181 | | break; |
| 3182 | 3053 | case NodeTypeDirective: |
| 3183 | 3054 | // none |
| 3184 | 3055 | break; |