authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-10 11:48:54-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-10 11:48:54-07:00
logd4b8852d784b6f180e5329efa8d418397ee7f1ef
treed281a93575cd30dcf4c30339a8c5cfa312fa3828
parent75d57866035a5e27a7e62f7cfabbc899affd3e8b

parsing enum declarations


7 files changed, 190 insertions(+), 16 deletions(-)

doc/langref.md+13-3
......@@ -32,16 +32,24 @@ zig | C equivalent | Description
3232```
3333Root : many(TopLevelDecl) token(EOF)
3434
35TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | VariableDeclaration
35TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | VariableDeclaration | EnumDecl
3636
3737VariableDeclaration : option(FnVisibleMod) (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
3838
39StructDecl : many(Directive) option(FnVisibleMod) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)
39StructDecl : many(Directive) option(FnVisibleMod) token(Struct) StructPayload
40
41StructPayload: token(Symbol) token(LBrace) many(StructMember) token(RBrace)
42
43EnumDecl : many(Directive) option(FnVisibleMod) token(Enum) token(Symbol) token(LBrace) many(EnumField) token(RBrace)
4044
4145StructMember: StructField | FnDecl
4246
4347StructField : token(Symbol) token(Colon) Type token(Comma)
4448
49EnumField : (EnumDiscriminant | StructPayload) token(Comma)
50
51EnumDiscriminant : token(Symbol) option(token(Eq) Expression)
52
4553Use : many(Directive) token(Use) token(String) token(Semicolon)
4654
4755RootExportDecl : many(Directive) token(Export) token(Symbol) token(String) token(Semicolon)
......@@ -160,7 +168,9 @@ SliceExpression : token(LBracket) Expression token(Ellipsis) option(Expression)
160168
161169PrefixOp : token(Not) | token(Dash) | token(Tilde) | token(Star) | (token(Ampersand) option(token(Const)))
162170
163PrimaryExpression : token(Number) | token(String) | token(CharLiteral) | KeywordLiteral | GroupedExpression | Goto | token(Break) | token(Continue) | BlockExpression | token(Symbol) | StructValueExpression | CompilerFnType | (token(AtSign) token(Symbol) FnCallExpression)
171PrimaryExpression : token(Number) | token(String) | token(CharLiteral) | KeywordLiteral | GroupedExpression | Goto | token(Break) | token(Continue) | BlockExpression | token(Symbol) | StructValueExpression | CompilerFnType | (token(AtSign) token(Symbol) FnCallExpression) | NamespaceSymbol
172
173NamespaceSymbol : token(Symbol) token(ColonColon) token(Symbol)
164174
165175StructValueExpression : token(Type) token(LBrace) list(StructValueExpressionField, token(Comma)) token(RBrace)
166176
src/analyze.cpp+24-8
......@@ -63,6 +63,8 @@ static AstNode *first_executing_node(AstNode *node) {
6363 case NodeTypeAsmExpr:
6464 case NodeTypeStructDecl:
6565 case NodeTypeStructField:
66 case NodeTypeEnumDecl:
67 case NodeTypeEnumField:
6668 case NodeTypeStructValueExpr:
6769 case NodeTypeStructValueField:
6870 case NodeTypeWhileExpr:
......@@ -894,6 +896,11 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
894896 // struct member fns will get resolved independently
895897 break;
896898 }
899 case NodeTypeEnumDecl:
900 {
901 zig_panic("TODO resolve enum decl");
902 break;
903 }
897904 case NodeTypeVariableDeclaration:
898905 {
899906 VariableTableEntry *var = analyze_variable_declaration(g, import, import->block_context,
......@@ -936,6 +943,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
936943 case NodeTypeAsmExpr:
937944 case NodeTypeFieldAccessExpr:
938945 case NodeTypeStructField:
946 case NodeTypeEnumField:
939947 case NodeTypeStructValueExpr:
940948 case NodeTypeStructValueField:
941949 case NodeTypeCompilerFnExpr:
......@@ -2490,6 +2498,8 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
24902498 case NodeTypeLabel:
24912499 case NodeTypeStructDecl:
24922500 case NodeTypeStructField:
2501 case NodeTypeEnumDecl:
2502 case NodeTypeEnumField:
24932503 case NodeTypeStructValueField:
24942504 case NodeTypeCompilerFnExpr:
24952505 zig_unreachable();
......@@ -2589,13 +2599,6 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
25892599 case NodeTypeFnDef:
25902600 analyze_top_level_fn_def(g, import, node);
25912601 break;
2592 case NodeTypeRootExportDecl:
2593 case NodeTypeExternBlock:
2594 // already looked at these in the preview pass
2595 break;
2596 case NodeTypeUse:
2597 // already took care of this
2598 break;
25992602 case NodeTypeStructDecl:
26002603 {
26012604 for (int i = 0; i < node->data.struct_decl.fns.length; i += 1) {
......@@ -2604,8 +2607,12 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
26042607 }
26052608 break;
26062609 }
2610 case NodeTypeRootExportDecl:
2611 case NodeTypeExternBlock:
2612 case NodeTypeUse:
2613 case NodeTypeEnumDecl:
26072614 case NodeTypeVariableDeclaration:
2608 // handled in resolve phase
2615 // already took care of these
26092616 break;
26102617 case NodeTypeDirective:
26112618 case NodeTypeParamDecl:
......@@ -2639,6 +2646,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
26392646 case NodeTypeAsmExpr:
26402647 case NodeTypeFieldAccessExpr:
26412648 case NodeTypeStructField:
2649 case NodeTypeEnumField:
26422650 case NodeTypeStructValueExpr:
26432651 case NodeTypeStructValueField:
26442652 case NodeTypeCompilerFnExpr:
......@@ -2772,6 +2780,8 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
27722780 case NodeTypeLabel:
27732781 case NodeTypeStructDecl:
27742782 case NodeTypeStructField:
2783 case NodeTypeEnumDecl:
2784 case NodeTypeEnumField:
27752785 case NodeTypeStructValueField:
27762786 zig_unreachable();
27772787 }
......@@ -2879,6 +2889,11 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
28792889 detect_top_level_decl_deps(g, import, fn_def_node);
28802890 }
28812891
2892 break;
2893 }
2894 case NodeTypeEnumDecl:
2895 {
2896 zig_panic("TODO detect enum top level decl deps");
28822897 break;
28832898 }
28842899 case NodeTypeExternBlock:
......@@ -2974,6 +2989,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
29742989 case NodeTypeAsmExpr:
29752990 case NodeTypeFieldAccessExpr:
29762991 case NodeTypeStructField:
2992 case NodeTypeEnumField:
29772993 case NodeTypeStructValueExpr:
29782994 case NodeTypeStructValueField:
29792995 case NodeTypeCompilerFnExpr:
src/codegen.cpp+2
......@@ -1754,6 +1754,8 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {
17541754 case NodeTypeUse:
17551755 case NodeTypeStructDecl:
17561756 case NodeTypeStructField:
1757 case NodeTypeEnumDecl:
1758 case NodeTypeEnumField:
17571759 case NodeTypeStructValueField:
17581760 case NodeTypeCompilerFnExpr:
17591761 zig_unreachable();
src/parser.cpp+130-5
......@@ -144,6 +144,10 @@ const char *node_type_str(NodeType node_type) {
144144 return "StructDecl";
145145 case NodeTypeStructField:
146146 return "StructField";
147 case NodeTypeEnumDecl:
148 return "EnumDecl";
149 case NodeTypeEnumField:
150 return "EnumField";
147151 case NodeTypeStructValueExpr:
148152 return "StructValueExpr";
149153 case NodeTypeStructValueField:
......@@ -429,6 +433,24 @@ void ast_print(AstNode *node, int indent) {
429433 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.struct_field.name));
430434 ast_print(node->data.struct_field.type, indent + 2);
431435 break;
436 case NodeTypeEnumDecl:
437 fprintf(stderr, "%s '%s'\n",
438 node_type_str(node->type), buf_ptr(&node->data.enum_decl.name));
439 for (int i = 0; i < node->data.enum_decl.fields.length; i += 1) {
440 AstNode *child = node->data.enum_decl.fields.at(i);
441 ast_print(child, indent + 2);
442 }
443 break;
444 case NodeTypeEnumField:
445 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.enum_field.name));
446 if (node->data.enum_field.val_expr) {
447 ast_print(node->data.enum_field.val_expr, indent + 2);
448 }
449 for (int i = 0; i < node->data.enum_field.fields.length; i += 1) {
450 AstNode *child = node->data.enum_field.fields.at(i);
451 ast_print(child, indent + 2);
452 }
453 break;
432454 case NodeTypeStructValueExpr:
433455 fprintf(stderr, "%s\n", node_type_str(node->type));
434456 ast_print(node->data.struct_val_expr.type, indent + 2);
......@@ -2705,7 +2727,106 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index) {
27052727}
27062728
27072729/*
2708StructDecl : many(Directive) option(FnVisibleMod) token(Struct) token(Symbol) token(LBrace) many(StructMember) token(RBrace)
2730EnumDecl : many(Directive) option(FnVisibleMod) token(Enum) token(Symbol) token(LBrace) many(EnumField) token(RBrace)
2731EnumField : (EnumDiscriminant | StructPayload) token(Comma)
2732EnumDiscriminant : token(Symbol) option(token(Eq) Expression)
2733*/
2734static 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/*
2828StructDecl : many(Directive) option(FnVisibleMod) token(Struct) StructPayload
2829StructPayload: token(Symbol) token(LBrace) many(StructMember) token(RBrace)
27092830StructMember: StructField | FnDecl
27102831StructField : token(Symbol) token(Colon) Type token(Comma)
27112832*/
......@@ -2737,9 +2858,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {
27372858 return nullptr;
27382859 }
27392860
2740 Token *struct_name = &pc->tokens->at(*token_index);
2741 *token_index += 1;
2742 ast_expect_token(pc, struct_name, TokenIdSymbol);
2861 Token *struct_name = ast_eat_token(pc, token_index, TokenIdSymbol);
27432862
27442863 AstNode *node = ast_create_node(pc, NodeTypeStructDecl, first_token);
27452864 ast_buf_from_token(pc, struct_name, &node->data.struct_decl.name);
......@@ -2798,7 +2917,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {
27982917}
27992918
28002919/*
2801TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | VariableDeclaration
2920TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | VariableDeclaration | EnumDecl
28022921*/
28032922static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigList<AstNode *> *top_level_decls) {
28042923 for (;;) {
......@@ -2837,6 +2956,12 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis
28372956 continue;
28382957 }
28392958
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
28402965 if (pc->directive_list->length > 0) {
28412966 ast_error(pc, directive_token, "invalid directive");
28422967 }
src/parser.hpp+17
......@@ -59,6 +59,8 @@ enum NodeType {
5959 NodeTypeStructField,
6060 NodeTypeStructValueExpr,
6161 NodeTypeStructValueField,
62 NodeTypeEnumDecl,
63 NodeTypeEnumField,
6264 NodeTypeCompilerFnExpr,
6365 NodeTypeCompilerFnType,
6466};
......@@ -316,6 +318,19 @@ struct AstNodeStructField {
316318 ZigList<AstNode *> *directives;
317319};
318320
321struct AstNodeEnumDecl {
322 Buf name;
323 ZigList<AstNode *> fields;
324 ZigList<AstNode *> *directives;
325 VisibMod visib_mod;
326};
327
328struct AstNodeEnumField {
329 Buf name;
330 ZigList<AstNode *> fields; // length 0 means simple enum
331 AstNode *val_expr;
332};
333
319334struct AstNodeStringLiteral {
320335 Buf buf;
321336 bool c;
......@@ -411,6 +426,8 @@ struct AstNode {
411426 AstNodeFieldAccessExpr field_access_expr;
412427 AstNodeStructDecl struct_decl;
413428 AstNodeStructField struct_field;
429 AstNodeEnumDecl enum_decl;
430 AstNodeEnumField enum_field;
414431 AstNodeStringLiteral string_literal;
415432 AstNodeCharLiteral char_literal;
416433 AstNodeNumberLiteral number_literal;
src/tokenizer.cpp+3
......@@ -235,6 +235,8 @@ static void end_token(Tokenize *t) {
235235 t->cur_tok->id = TokenIdKeywordAsm;
236236 } else if (mem_eql_str(token_mem, token_len, "struct")) {
237237 t->cur_tok->id = TokenIdKeywordStruct;
238 } else if (mem_eql_str(token_mem, token_len, "enum")) {
239 t->cur_tok->id = TokenIdKeywordEnum;
238240 } else if (mem_eql_str(token_mem, token_len, "while")) {
239241 t->cur_tok->id = TokenIdKeywordWhile;
240242 } else if (mem_eql_str(token_mem, token_len, "continue")) {
......@@ -1021,6 +1023,7 @@ static const char * token_name(Token *token) {
10211023 case TokenIdKeywordVolatile: return "Volatile";
10221024 case TokenIdKeywordAsm: return "Asm";
10231025 case TokenIdKeywordStruct: return "Struct";
1026 case TokenIdKeywordEnum: return "Enum";
10241027 case TokenIdKeywordWhile: return "While";
10251028 case TokenIdKeywordContinue: return "Continue";
10261029 case TokenIdKeywordBreak: return "Break";
src/tokenizer.hpp+1
......@@ -32,6 +32,7 @@ enum TokenId {
3232 TokenIdKeywordAsm,
3333 TokenIdKeywordVolatile,
3434 TokenIdKeywordStruct,
35 TokenIdKeywordEnum,
3536 TokenIdKeywordWhile,
3637 TokenIdKeywordContinue,
3738 TokenIdKeywordBreak,