| ... | @@ -431,7 +431,9 @@ void ast_print(AstNode *node, int indent) { | ... | @@ -431,7 +431,9 @@ void ast_print(AstNode *node, int indent) { |
| 431 | break; | 431 | break; |
| 432 | case NodeTypeStructField: | 432 | case NodeTypeStructField: |
| 433 | fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_field.name)); | 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 | break; | 437 | break; |
| 436 | case NodeTypeEnumDecl: | 438 | case NodeTypeEnumDecl: |
| 437 | fprintf(stderr, "%s '%s'\n", | 439 | fprintf(stderr, "%s '%s'\n", |
| ... | @@ -2727,106 +2729,7 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index) { | ... | @@ -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) | 2732 | ContainerDecl : many(Directive) option(FnVisibleMod) (token(Struct) | token(Enum)) token(Symbol) token(LBrace) many(StructMember) 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) | | |
| 2830 | StructMember: StructField | FnDecl | 2733 | StructMember: StructField | FnDecl |
| 2831 | StructField : token(Symbol) token(Colon) Type token(Comma) | 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,25 +2737,35 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2834 | Token *first_token = &pc->tokens->at(*token_index); | 2737 | Token *first_token = &pc->tokens->at(*token_index); |
| 2835 | | 2738 | |
| 2836 | VisibMod visib_mod; | 2739 | VisibMod visib_mod; |
| | 2740 | ContainerKind kind; |
| 2837 | | 2741 | |
| 2838 | if (first_token->id == TokenIdKeywordPub) { | 2742 | if (first_token->id == TokenIdKeywordPub) { |
| 2839 | Token *next_token = &pc->tokens->at(*token_index + 1); | 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 | visib_mod = VisibModPub; | 2747 | visib_mod = VisibModPub; |
| | 2748 | kind = (next_token->id == TokenIdKeywordStruct) ? ContainerKindStruct : ContainerKindEnum; |
| 2842 | *token_index += 2; | 2749 | *token_index += 2; |
| 2843 | } else { | 2750 | } else { |
| 2844 | return nullptr; | 2751 | return nullptr; |
| 2845 | } | 2752 | } |
| 2846 | } else if (first_token->id == TokenIdKeywordExport) { | 2753 | } else if (first_token->id == TokenIdKeywordExport) { |
| 2847 | Token *next_token = &pc->tokens->at(*token_index + 1); | 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 | visib_mod = VisibModExport; | 2758 | visib_mod = VisibModExport; |
| | 2759 | kind = (next_token->id == TokenIdKeywordStruct) ? ContainerKindStruct : ContainerKindEnum; |
| 2850 | *token_index += 2; | 2760 | *token_index += 2; |
| 2851 | } else { | 2761 | } else { |
| 2852 | return nullptr; | 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 | visib_mod = VisibModPrivate; | 2767 | visib_mod = VisibModPrivate; |
| | 2768 | kind = (first_token->id == TokenIdKeywordStruct) ? ContainerKindStruct : ContainerKindEnum; |
| 2856 | *token_index += 1; | 2769 | *token_index += 1; |
| 2857 | } else { | 2770 | } else { |
| 2858 | return nullptr; | 2771 | return nullptr; |
| ... | @@ -2861,6 +2774,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { | ... | @@ -2861,6 +2774,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2861 | Token *struct_name = ast_eat_token(pc, token_index, TokenIdSymbol); | 2774 | Token *struct_name = ast_eat_token(pc, token_index, TokenIdSymbol); |
| 2862 | | 2775 | |
| 2863 | AstNode *node = ast_create_node(pc, NodeTypeStructDecl, first_token); | 2776 | AstNode *node = ast_create_node(pc, NodeTypeStructDecl, first_token); |
| | 2777 | node->data.struct_decl.kind = kind; |
| 2864 | ast_buf_from_token(pc, struct_name, &node->data.struct_decl.name); | 2778 | ast_buf_from_token(pc, struct_name, &node->data.struct_decl.name); |
| 2865 | node->data.struct_decl.visib_mod = visib_mod; | 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,9 +2814,13 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2900 | | 2814 | |
| 2901 | ast_buf_from_token(pc, token, &field_node->data.struct_field.name); | 2815 | ast_buf_from_token(pc, token, &field_node->data.struct_field.name); |
| 2902 | | 2816 | |
| 2903 | ast_eat_token(pc, token_index, TokenIdColon); | 2817 | Token *colon_tok = &pc->tokens->at(*token_index); |
| 2904 | | 2818 | if (colon_tok->id == TokenIdColon) { |
| 2905 | field_node->data.struct_field.type = ast_parse_type(pc, token_index); | 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 | ast_eat_token(pc, token_index, TokenIdComma); | 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,12 +2874,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis |
| 2956 | continue; | 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 | if (pc->directive_list->length > 0) { | 2877 | if (pc->directive_list->length > 0) { |
| 2966 | ast_error(pc, directive_token, "invalid directive"); | 2878 | ast_error(pc, directive_token, "invalid directive"); |
| 2967 | } | 2879 | } |