| ... | ... | @@ -431,7 +431,9 @@ void ast_print(AstNode *node, int indent) { |
| 431 | 431 | break; |
| 432 | 432 | case NodeTypeStructField: |
| 433 | 433 | fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_field.name)); |
| 434 | | ast_print(node->data.struct_field.type, indent + 2); |
| 434 | if (node->data.struct_field.type) { |
| 435 | ast_print(node->data.struct_field.type, indent + 2); |
| 436 | } |
| 435 | 437 | break; |
| 436 | 438 | case NodeTypeEnumDecl: |
| 437 | 439 | fprintf(stderr, "%s '%s'\n", |
| ... | ... | @@ -2727,106 +2729,7 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index) { |
| 2727 | 2729 | } |
| 2728 | 2730 | |
| 2729 | 2731 | /* |
| 2730 | | EnumDecl : many(Directive) option(FnVisibleMod) token(Enum) token(Symbol) token(LBrace) many(EnumField) token(RBrace) |
| 2731 | | EnumField : (EnumDiscriminant | StructPayload) token(Comma) |
| 2732 | | EnumDiscriminant : token(Symbol) option(token(Eq) Expression) |
| 2733 | | */ |
| 2734 | | static AstNode *ast_parse_enum_decl(ParseContext *pc, int *token_index) { |
| 2735 | | Token *first_token = &pc->tokens->at(*token_index); |
| 2736 | | |
| 2737 | | VisibMod visib_mod; |
| 2738 | | if (first_token->id == TokenIdKeywordPub) { |
| 2739 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2740 | | if (next_token->id == TokenIdKeywordEnum) { |
| 2741 | | visib_mod = VisibModPub; |
| 2742 | | *token_index += 2; |
| 2743 | | } else { |
| 2744 | | return nullptr; |
| 2745 | | } |
| 2746 | | } else if (first_token->id == TokenIdKeywordExport) { |
| 2747 | | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2748 | | if (next_token->id == TokenIdKeywordEnum) { |
| 2749 | | visib_mod = VisibModExport; |
| 2750 | | *token_index += 2; |
| 2751 | | } else { |
| 2752 | | return nullptr; |
| 2753 | | } |
| 2754 | | } else if (first_token->id == TokenIdKeywordEnum) { |
| 2755 | | visib_mod = VisibModPrivate; |
| 2756 | | *token_index += 1; |
| 2757 | | } else { |
| 2758 | | return nullptr; |
| 2759 | | } |
| 2760 | | |
| 2761 | | Token *enum_name = ast_eat_token(pc, token_index, TokenIdSymbol); |
| 2762 | | AstNode *node = ast_create_node(pc, NodeTypeEnumDecl, first_token); |
| 2763 | | ast_buf_from_token(pc, enum_name, &node->data.enum_decl.name); |
| 2764 | | node->data.enum_decl.visib_mod = visib_mod; |
| 2765 | | |
| 2766 | | node->data.enum_decl.directives = pc->directive_list; |
| 2767 | | pc->directive_list = nullptr; |
| 2768 | | |
| 2769 | | ast_eat_token(pc, token_index, TokenIdLBrace); |
| 2770 | | |
| 2771 | | for (;;) { |
| 2772 | | Token *token = &pc->tokens->at(*token_index); |
| 2773 | | |
| 2774 | | if (token->id == TokenIdRBrace) { |
| 2775 | | *token_index += 1; |
| 2776 | | break; |
| 2777 | | } else if (token->id == TokenIdSymbol) { |
| 2778 | | AstNode *field_node = ast_create_node(pc, NodeTypeEnumField, token); |
| 2779 | | *token_index += 1; |
| 2780 | | |
| 2781 | | ast_buf_from_token(pc, token, &field_node->data.enum_field.name); |
| 2782 | | |
| 2783 | | Token *eq_tok = &pc->tokens->at(*token_index); |
| 2784 | | if (eq_tok->id == TokenIdEq) { |
| 2785 | | *token_index += 1; |
| 2786 | | |
| 2787 | | field_node->data.enum_field.val_expr = ast_parse_expression(pc, token_index, true); |
| 2788 | | } else if (eq_tok->id == TokenIdLBrace) { |
| 2789 | | *token_index += 1; |
| 2790 | | |
| 2791 | | for (;;) { |
| 2792 | | Token *token = &pc->tokens->at(*token_index); |
| 2793 | | |
| 2794 | | if (token->id == TokenIdRBrace) { |
| 2795 | | *token_index += 1; |
| 2796 | | break; |
| 2797 | | } else if (token->id == TokenIdSymbol) { |
| 2798 | | AstNode *sub_field_node = ast_create_node(pc, NodeTypeStructField, token); |
| 2799 | | *token_index += 1; |
| 2800 | | |
| 2801 | | ast_buf_from_token(pc, token, &sub_field_node->data.struct_field.name); |
| 2802 | | |
| 2803 | | ast_eat_token(pc, token_index, TokenIdColon); |
| 2804 | | |
| 2805 | | sub_field_node->data.struct_field.type = ast_parse_type(pc, token_index); |
| 2806 | | |
| 2807 | | ast_eat_token(pc, token_index, TokenIdComma); |
| 2808 | | |
| 2809 | | field_node->data.enum_decl.fields.append(sub_field_node); |
| 2810 | | } else { |
| 2811 | | ast_invalid_token_error(pc, token); |
| 2812 | | } |
| 2813 | | } |
| 2814 | | } |
| 2815 | | |
| 2816 | | ast_eat_token(pc, token_index, TokenIdComma); |
| 2817 | | |
| 2818 | | node->data.enum_decl.fields.append(field_node); |
| 2819 | | } else { |
| 2820 | | ast_invalid_token_error(pc, token); |
| 2821 | | } |
| 2822 | | } |
| 2823 | | |
| 2824 | | return node; |
| 2825 | | } |
| 2826 | | |
| 2827 | | /* |
| 2828 | | StructDecl : many(Directive) option(FnVisibleMod) token(Struct) StructPayload |
| 2829 | | StructPayload: token(Symbol) token(LBrace) many(StructMember) token(RBrace) |
| 2732 | ContainerDecl : many(Directive) option(FnVisibleMod) (token(Struct) | token(Enum)) token(Symbol) token(LBrace) many(StructMember) token(RBrace) |
| 2830 | 2733 | StructMember: StructField | FnDecl |
| 2831 | 2734 | StructField : token(Symbol) token(Colon) Type token(Comma) |
| 2832 | 2735 | */ |
| ... | ... | @@ -2834,25 +2737,35 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2834 | 2737 | Token *first_token = &pc->tokens->at(*token_index); |
| 2835 | 2738 | |
| 2836 | 2739 | VisibMod visib_mod; |
| 2740 | ContainerKind kind; |
| 2837 | 2741 | |
| 2838 | 2742 | if (first_token->id == TokenIdKeywordPub) { |
| 2839 | 2743 | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2840 | | if (next_token->id == TokenIdKeywordStruct) { |
| 2744 | if (next_token->id == TokenIdKeywordStruct || |
| 2745 | next_token->id == TokenIdKeywordEnum) |
| 2746 | { |
| 2841 | 2747 | visib_mod = VisibModPub; |
| 2748 | kind = (next_token->id == TokenIdKeywordStruct) ? ContainerKindStruct : ContainerKindEnum; |
| 2842 | 2749 | *token_index += 2; |
| 2843 | 2750 | } else { |
| 2844 | 2751 | return nullptr; |
| 2845 | 2752 | } |
| 2846 | 2753 | } else if (first_token->id == TokenIdKeywordExport) { |
| 2847 | 2754 | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2848 | | if (next_token->id == TokenIdKeywordStruct) { |
| 2755 | if (next_token->id == TokenIdKeywordStruct || |
| 2756 | next_token->id == TokenIdKeywordEnum) |
| 2757 | { |
| 2849 | 2758 | visib_mod = VisibModExport; |
| 2759 | kind = (next_token->id == TokenIdKeywordStruct) ? ContainerKindStruct : ContainerKindEnum; |
| 2850 | 2760 | *token_index += 2; |
| 2851 | 2761 | } else { |
| 2852 | 2762 | return nullptr; |
| 2853 | 2763 | } |
| 2854 | | } else if (first_token->id == TokenIdKeywordStruct) { |
| 2764 | } else if (first_token->id == TokenIdKeywordStruct || |
| 2765 | first_token->id == TokenIdKeywordEnum) |
| 2766 | { |
| 2855 | 2767 | visib_mod = VisibModPrivate; |
| 2768 | kind = (first_token->id == TokenIdKeywordStruct) ? ContainerKindStruct : ContainerKindEnum; |
| 2856 | 2769 | *token_index += 1; |
| 2857 | 2770 | } else { |
| 2858 | 2771 | return nullptr; |
| ... | ... | @@ -2861,6 +2774,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2861 | 2774 | Token *struct_name = ast_eat_token(pc, token_index, TokenIdSymbol); |
| 2862 | 2775 | |
| 2863 | 2776 | AstNode *node = ast_create_node(pc, NodeTypeStructDecl, first_token); |
| 2777 | node->data.struct_decl.kind = kind; |
| 2864 | 2778 | ast_buf_from_token(pc, struct_name, &node->data.struct_decl.name); |
| 2865 | 2779 | node->data.struct_decl.visib_mod = visib_mod; |
| 2866 | 2780 | |
| ... | ... | @@ -2900,9 +2814,13 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2900 | 2814 | |
| 2901 | 2815 | ast_buf_from_token(pc, token, &field_node->data.struct_field.name); |
| 2902 | 2816 | |
| 2903 | | ast_eat_token(pc, token_index, TokenIdColon); |
| 2904 | | |
| 2905 | | field_node->data.struct_field.type = ast_parse_type(pc, token_index); |
| 2817 | Token *colon_tok = &pc->tokens->at(*token_index); |
| 2818 | if (colon_tok->id == TokenIdColon) { |
| 2819 | *token_index += 1; |
| 2820 | field_node->data.struct_field.type = ast_parse_type(pc, token_index); |
| 2821 | } else { |
| 2822 | field_node->data.struct_field.type = ast_create_void_type_node(pc, colon_tok); |
| 2823 | } |
| 2906 | 2824 | |
| 2907 | 2825 | ast_eat_token(pc, token_index, TokenIdComma); |
| 2908 | 2826 | |
| ... | ... | @@ -2956,12 +2874,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis |
| 2956 | 2874 | continue; |
| 2957 | 2875 | } |
| 2958 | 2876 | |
| 2959 | | AstNode *enum_node = ast_parse_enum_decl(pc, token_index); |
| 2960 | | if (enum_node) { |
| 2961 | | top_level_decls->append(enum_node); |
| 2962 | | continue; |
| 2963 | | } |
| 2964 | | |
| 2965 | 2877 | if (pc->directive_list->length > 0) { |
| 2966 | 2878 | ast_error(pc, directive_token, "invalid directive"); |
| 2967 | 2879 | } |