authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-24 11:24:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-24 11:24:04-07:00
log46ab981787a108ad4326c86aa2a6af4247e7191b
tree6ae8c6ca2774ea4dba4f5db784efb8233c623421
parent4961910e7faf4df0a88d9571e894563f80613f7f

add skeleton for union support


10 files changed, 64 insertions(+), 7 deletions(-)

doc/langref.md+1-1
...@@ -15,7 +15,7 @@ GlobalVarDecl = VariableDeclaration ";"...@@ -15,7 +15,7 @@ GlobalVarDecl = VariableDeclaration ";"
1515
16VariableDeclaration = ("var" | "const") "Symbol" option(":" TypeExpr) "=" Expression16VariableDeclaration = ("var" | "const") "Symbol" option(":" TypeExpr) "=" Expression
1717
18ContainerDecl = ("struct" | "enum") "Symbol" "{" many(StructMember) "}"18ContainerDecl = ("struct" | "enum" | "union") "Symbol" "{" many(StructMember) "}"
1919
20StructMember = many(Directive) option(VisibleMod) (StructField | FnDef)20StructMember = many(Directive) option(VisibleMod) (StructField | FnDef)
2121
doc/vim/syntax/zig.vim+1-1
...@@ -8,7 +8,7 @@ if exists("b:current_syntax")...@@ -8,7 +8,7 @@ if exists("b:current_syntax")
8endif8endif
99
10syn keyword zigStorage const var extern volatile export pub noalias inline10syn keyword zigStorage const var extern volatile export pub noalias inline
11syn keyword zigStructure struct enum11syn keyword zigStructure struct enum union
12syn keyword zigStatement goto break return continue asm defer12syn keyword zigStatement goto break return continue asm defer
13syn keyword zigConditional if else switch13syn keyword zigConditional if else switch
14syn keyword zigRepeat while for14syn keyword zigRepeat while for
src/all_types.hpp+20-1
...@@ -135,7 +135,7 @@ struct TopLevelDecl {...@@ -135,7 +135,7 @@ struct TopLevelDecl {
135struct TypeEnumField {135struct TypeEnumField {
136 Buf *name;136 Buf *name;
137 TypeTableEntry *type_entry;137 TypeTableEntry *type_entry;
138 uint32_t value;138 uint32_t value; // TODO is this used?
139};139};
140140
141enum NodeType {141enum NodeType {
...@@ -590,6 +590,7 @@ struct AstNodeAsmExpr {...@@ -590,6 +590,7 @@ struct AstNodeAsmExpr {
590enum ContainerKind {590enum ContainerKind {
591 ContainerKindStruct,591 ContainerKindStruct,
592 ContainerKindEnum,592 ContainerKindEnum,
593 ContainerKindUnion,
593};594};
594595
595struct AstNodeStructDecl {596struct AstNodeStructDecl {
...@@ -905,6 +906,22 @@ struct TypeTableEntryEnum {...@@ -905,6 +906,22 @@ struct TypeTableEntryEnum {
905 bool complete;906 bool complete;
906};907};
907908
909struct TypeTableEntryUnion {
910 AstNode *decl_node;
911 uint32_t src_field_count;
912 uint32_t gen_field_count;
913 TypeStructField *fields;
914 uint64_t size_bytes;
915 bool is_invalid; // true if any fields are invalid
916 BlockContext *block_context;
917
918 // set this flag temporarily to detect infinite loops
919 bool embedded_in_current;
920 bool reported_infinite_err;
921 // whether we've finished resolving it
922 bool complete;
923};
924
908struct FnGenParamInfo {925struct FnGenParamInfo {
909 int src_index;926 int src_index;
910 int gen_index;927 int gen_index;
...@@ -949,6 +966,7 @@ enum TypeTableEntryId {...@@ -949,6 +966,7 @@ enum TypeTableEntryId {
949 TypeTableEntryIdErrorUnion,966 TypeTableEntryIdErrorUnion,
950 TypeTableEntryIdPureError,967 TypeTableEntryIdPureError,
951 TypeTableEntryIdEnum,968 TypeTableEntryIdEnum,
969 TypeTableEntryIdUnion,
952 TypeTableEntryIdFn,970 TypeTableEntryIdFn,
953 TypeTableEntryIdTypeDecl,971 TypeTableEntryIdTypeDecl,
954 TypeTableEntryIdNamespace,972 TypeTableEntryIdNamespace,
...@@ -974,6 +992,7 @@ struct TypeTableEntry {...@@ -974,6 +992,7 @@ struct TypeTableEntry {
974 TypeTableEntryMaybe maybe;992 TypeTableEntryMaybe maybe;
975 TypeTableEntryError error;993 TypeTableEntryError error;
976 TypeTableEntryEnum enumeration;994 TypeTableEntryEnum enumeration;
995 TypeTableEntryUnion unionation;
977 TypeTableEntryFn fn;996 TypeTableEntryFn fn;
978 TypeTableEntryTypeDecl type_decl;997 TypeTableEntryTypeDecl type_decl;
979 TypeTableEntryGenericFn generic_fn;998 TypeTableEntryGenericFn generic_fn;
src/analyze.cpp+25
...@@ -141,6 +141,8 @@ static BlockContext **get_container_block_context_ptr(TypeTableEntry *type_entry...@@ -141,6 +141,8 @@ static BlockContext **get_container_block_context_ptr(TypeTableEntry *type_entry
141 return &type_entry->data.structure.block_context;141 return &type_entry->data.structure.block_context;
142 } else if (type_entry->id == TypeTableEntryIdEnum) {142 } else if (type_entry->id == TypeTableEntryIdEnum) {
143 return &type_entry->data.enumeration.block_context;143 return &type_entry->data.enumeration.block_context;
144 } else if (type_entry->id == TypeTableEntryIdUnion) {
145 return &type_entry->data.unionation.block_context;
144 }146 }
145 zig_unreachable();147 zig_unreachable();
146}148}
...@@ -178,6 +180,8 @@ static bool type_is_complete(TypeTableEntry *type_entry) {...@@ -178,6 +180,8 @@ static bool type_is_complete(TypeTableEntry *type_entry) {
178 return type_entry->data.structure.complete;180 return type_entry->data.structure.complete;
179 case TypeTableEntryIdEnum:181 case TypeTableEntryIdEnum:
180 return type_entry->data.enumeration.complete;182 return type_entry->data.enumeration.complete;
183 case TypeTableEntryIdUnion:
184 return type_entry->data.unionation.complete;
181 case TypeTableEntryIdMetaType:185 case TypeTableEntryIdMetaType:
182 case TypeTableEntryIdVoid:186 case TypeTableEntryIdVoid:
183 case TypeTableEntryIdBool:187 case TypeTableEntryIdBool:
...@@ -732,6 +736,8 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {...@@ -732,6 +736,8 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {
732 return TypeTableEntryIdStruct;736 return TypeTableEntryIdStruct;
733 case ContainerKindEnum:737 case ContainerKindEnum:
734 return TypeTableEntryIdEnum;738 return TypeTableEntryIdEnum;
739 case ContainerKindUnion:
740 return TypeTableEntryIdUnion;
735 }741 }
736 zig_unreachable();742 zig_unreachable();
737}743}
...@@ -749,6 +755,9 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,...@@ -749,6 +755,9 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,
749 case ContainerKindEnum:755 case ContainerKindEnum:
750 entry->data.enumeration.decl_node = decl_node;756 entry->data.enumeration.decl_node = decl_node;
751 break;757 break;
758 case ContainerKindUnion:
759 entry->data.unionation.decl_node = decl_node;
760 break;
752 }761 }
753762
754 unsigned line = decl_node ? decl_node->line : 0;763 unsigned line = decl_node ? decl_node->line : 0;
...@@ -874,6 +883,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -874,6 +883,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
874 case TypeTableEntryIdErrorUnion:883 case TypeTableEntryIdErrorUnion:
875 case TypeTableEntryIdPureError:884 case TypeTableEntryIdPureError:
876 case TypeTableEntryIdEnum:885 case TypeTableEntryIdEnum:
886 case TypeTableEntryIdUnion:
877 case TypeTableEntryIdFn:887 case TypeTableEntryIdFn:
878 case TypeTableEntryIdTypeDecl:888 case TypeTableEntryIdTypeDecl:
879 break;889 break;
...@@ -1397,6 +1407,10 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1397,6 +1407,10 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1397 struct_type->zero_bits = (debug_size_in_bits == 0);1407 struct_type->zero_bits = (debug_size_in_bits == 0);
1398}1408}
13991409
1410static void resolve_union_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type) {
1411 zig_panic("TODO");
1412}
1413
1400static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t sep) {1414static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t sep) {
1401 TopLevelDecl *tld = get_as_top_level_decl(decl_node);1415 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
1402 AstNode *parent_decl = tld->parent_decl;1416 AstNode *parent_decl = tld->parent_decl;
...@@ -1541,6 +1555,9 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)...@@ -1541,6 +1555,9 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)
1541 case ContainerKindEnum:1555 case ContainerKindEnum:
1542 resolve_enum_type(g, import, type_entry);1556 resolve_enum_type(g, import, type_entry);
1543 break;1557 break;
1558 case ContainerKindUnion:
1559 resolve_union_type(g, import, type_entry);
1560 break;
1544 }1561 }
15451562
1546 break;1563 break;
...@@ -1672,6 +1689,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {...@@ -1672,6 +1689,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
1672 case TypeTableEntryIdErrorUnion:1689 case TypeTableEntryIdErrorUnion:
1673 case TypeTableEntryIdPureError:1690 case TypeTableEntryIdPureError:
1674 case TypeTableEntryIdEnum:1691 case TypeTableEntryIdEnum:
1692 case TypeTableEntryIdUnion:
1675 case TypeTableEntryIdFn:1693 case TypeTableEntryIdFn:
1676 return true;1694 return true;
16771695
...@@ -4450,6 +4468,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -4450,6 +4468,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
4450 case TypeTableEntryIdErrorUnion:4468 case TypeTableEntryIdErrorUnion:
4451 case TypeTableEntryIdPureError:4469 case TypeTableEntryIdPureError:
4452 case TypeTableEntryIdEnum:4470 case TypeTableEntryIdEnum:
4471 case TypeTableEntryIdUnion:
4453 case TypeTableEntryIdFn:4472 case TypeTableEntryIdFn:
4454 case TypeTableEntryIdTypeDecl:4473 case TypeTableEntryIdTypeDecl:
4455 return resolve_expr_const_val_as_type(g, node, type_entry);4474 return resolve_expr_const_val_as_type(g, node, type_entry);
...@@ -6179,6 +6198,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -6179,6 +6198,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
6179 return false;6198 return false;
6180 case TypeTableEntryIdArray:6199 case TypeTableEntryIdArray:
6181 case TypeTableEntryIdStruct:6200 case TypeTableEntryIdStruct:
6201 case TypeTableEntryIdUnion:
6182 return true;6202 return true;
6183 case TypeTableEntryIdErrorUnion:6203 case TypeTableEntryIdErrorUnion:
6184 return type_has_bits(type_entry->data.error.child_type);6204 return type_has_bits(type_entry->data.error.child_type);
...@@ -6280,6 +6300,9 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)...@@ -6280,6 +6300,9 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
6280 case TypeTableEntryIdStruct:6300 case TypeTableEntryIdStruct:
6281 // TODO better hashing algorithm6301 // TODO better hashing algorithm
6282 return 1532530855;6302 return 1532530855;
6303 case TypeTableEntryIdUnion:
6304 // TODO better hashing algorithm
6305 return 2709806591;
6283 case TypeTableEntryIdMaybe:6306 case TypeTableEntryIdMaybe:
6284 if (const_val->data.x_maybe) {6307 if (const_val->data.x_maybe) {
6285 TypeTableEntry *child_type = type->data.maybe.child_type;6308 TypeTableEntry *child_type = type->data.maybe.child_type;
...@@ -6374,6 +6397,8 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)...@@ -6374,6 +6397,8 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
6374 return type_of_first_thing_in_memory(type_entry->data.array.child_type);6397 return type_of_first_thing_in_memory(type_entry->data.array.child_type);
6375 case TypeTableEntryIdStruct:6398 case TypeTableEntryIdStruct:
6376 return type_of_first_thing_in_memory(first_struct_field_type(type_entry));6399 return type_of_first_thing_in_memory(first_struct_field_type(type_entry));
6400 case TypeTableEntryIdUnion:
6401 zig_panic("TODO");
6377 case TypeTableEntryIdMaybe:6402 case TypeTableEntryIdMaybe:
6378 return type_of_first_thing_in_memory(type_entry->data.maybe.child_type);6403 return type_of_first_thing_in_memory(type_entry->data.maybe.child_type);
6379 case TypeTableEntryIdErrorUnion:6404 case TypeTableEntryIdErrorUnion:
src/ast_render.cpp+1
...@@ -84,6 +84,7 @@ static const char *container_string(ContainerKind kind) {...@@ -84,6 +84,7 @@ static const char *container_string(ContainerKind kind) {
84 switch (kind) {84 switch (kind) {
85 case ContainerKindEnum: return "enum";85 case ContainerKindEnum: return "enum";
86 case ContainerKindStruct: return "struct";86 case ContainerKindStruct: return "struct";
87 case ContainerKindUnion: return "union";
87 }88 }
88 zig_unreachable();89 zig_unreachable();
89}90}
src/codegen.cpp+4
...@@ -2972,6 +2972,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -2972,6 +2972,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
2972 return LLVMConstNamedStruct(type_entry->type_ref, fields,2972 return LLVMConstNamedStruct(type_entry->type_ref, fields,
2973 type_entry->data.structure.gen_field_count);2973 type_entry->data.structure.gen_field_count);
2974 }2974 }
2975 case TypeTableEntryIdUnion:
2976 {
2977 zig_panic("TODO");
2978 }
2975 case TypeTableEntryIdArray:2979 case TypeTableEntryIdArray:
2976 {2980 {
2977 TypeTableEntry *child_type = type_entry->data.array.child_type;2981 TypeTableEntry *child_type = type_entry->data.array.child_type;
src/eval.cpp+2
...@@ -41,6 +41,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty...@@ -41,6 +41,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
41 zig_panic("TODO");41 zig_panic("TODO");
42 case TypeTableEntryIdStruct:42 case TypeTableEntryIdStruct:
43 zig_panic("TODO");43 zig_panic("TODO");
44 case TypeTableEntryIdUnion:
45 zig_panic("TODO");
44 case TypeTableEntryIdUndefLit:46 case TypeTableEntryIdUndefLit:
45 zig_panic("TODO");47 zig_panic("TODO");
46 case TypeTableEntryIdMaybe:48 case TypeTableEntryIdMaybe:
src/parser.cpp+5-3
...@@ -2504,11 +2504,11 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index,...@@ -2504,11 +2504,11 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index,
2504}2504}
25052505
2506/*2506/*
2507ContainerDecl : ("struct" | "enum") "Symbol" "{" many(StructMember) "}"2507ContainerDecl = ("struct" | "enum" | "union") "Symbol" "{" many(StructMember) "}"
2508StructMember: many(Directive) option(VisibleMod) (StructField | FnDef)2508StructMember: many(Directive) option(VisibleMod) (StructField | FnDef)
2509StructField : "Symbol" option(":" Expression) ",")2509StructField : "Symbol" option(":" Expression) ",")
2510*/2510*/
2511static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index,2511static AstNode *ast_parse_container_decl(ParseContext *pc, int *token_index,
2512 ZigList<AstNode*> *directives, VisibMod visib_mod)2512 ZigList<AstNode*> *directives, VisibMod visib_mod)
2513{2513{
2514 Token *first_token = &pc->tokens->at(*token_index);2514 Token *first_token = &pc->tokens->at(*token_index);
...@@ -2519,6 +2519,8 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index,...@@ -2519,6 +2519,8 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index,
2519 kind = ContainerKindStruct;2519 kind = ContainerKindStruct;
2520 } else if (first_token->id == TokenIdKeywordEnum) {2520 } else if (first_token->id == TokenIdKeywordEnum) {
2521 kind = ContainerKindEnum;2521 kind = ContainerKindEnum;
2522 } else if (first_token->id == TokenIdKeywordUnion) {
2523 kind = ContainerKindUnion;
2522 } else {2524 } else {
2523 return nullptr;2525 return nullptr;
2524 }2526 }
...@@ -2689,7 +2691,7 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis...@@ -2689,7 +2691,7 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis
2689 continue;2691 continue;
2690 }2692 }
26912693
2692 AstNode *struct_node = ast_parse_struct_decl(pc, token_index, directives, visib_mod);2694 AstNode *struct_node = ast_parse_container_decl(pc, token_index, directives, visib_mod);
2693 if (struct_node) {2695 if (struct_node) {
2694 top_level_decls->append(struct_node);2696 top_level_decls->append(struct_node);
2695 continue;2697 continue;
src/tokenizer.cpp+4-1
...@@ -108,7 +108,7 @@ const char * zig_keywords[] = {...@@ -108,7 +108,7 @@ const char * zig_keywords[] = {
108 "pub", "export", "use", "if", "else", "goto", "asm",108 "pub", "export", "use", "if", "else", "goto", "asm",
109 "volatile", "struct", "enum", "while", "for", "continue", "break",109 "volatile", "struct", "enum", "while", "for", "continue", "break",
110 "null", "noalias", "switch", "undefined", "error", "type", "inline",110 "null", "noalias", "switch", "undefined", "error", "type", "inline",
111 "defer",111 "defer", "union",
112};112};
113113
114bool is_zig_keyword(Buf *buf) {114bool is_zig_keyword(Buf *buf) {
...@@ -269,6 +269,8 @@ static void end_token(Tokenize *t) {...@@ -269,6 +269,8 @@ static void end_token(Tokenize *t) {
269 t->cur_tok->id = TokenIdKeywordStruct;269 t->cur_tok->id = TokenIdKeywordStruct;
270 } else if (mem_eql_str(token_mem, token_len, "enum")) {270 } else if (mem_eql_str(token_mem, token_len, "enum")) {
271 t->cur_tok->id = TokenIdKeywordEnum;271 t->cur_tok->id = TokenIdKeywordEnum;
272 } else if (mem_eql_str(token_mem, token_len, "union")) {
273 t->cur_tok->id = TokenIdKeywordUnion;
272 } else if (mem_eql_str(token_mem, token_len, "for")) {274 } else if (mem_eql_str(token_mem, token_len, "for")) {
273 t->cur_tok->id = TokenIdKeywordFor;275 t->cur_tok->id = TokenIdKeywordFor;
274 } else if (mem_eql_str(token_mem, token_len, "while")) {276 } else if (mem_eql_str(token_mem, token_len, "while")) {
...@@ -1195,6 +1197,7 @@ const char * token_name(TokenId id) {...@@ -1195,6 +1197,7 @@ const char * token_name(TokenId id) {
1195 case TokenIdKeywordAsm: return "asm";1197 case TokenIdKeywordAsm: return "asm";
1196 case TokenIdKeywordStruct: return "struct";1198 case TokenIdKeywordStruct: return "struct";
1197 case TokenIdKeywordEnum: return "enum";1199 case TokenIdKeywordEnum: return "enum";
1200 case TokenIdKeywordUnion: return "union";
1198 case TokenIdKeywordWhile: return "while";1201 case TokenIdKeywordWhile: return "while";
1199 case TokenIdKeywordFor: return "for";1202 case TokenIdKeywordFor: return "for";
1200 case TokenIdKeywordContinue: return "continue";1203 case TokenIdKeywordContinue: return "continue";
src/tokenizer.hpp+1
...@@ -30,6 +30,7 @@ enum TokenId {...@@ -30,6 +30,7 @@ enum TokenId {
30 TokenIdKeywordVolatile,30 TokenIdKeywordVolatile,
31 TokenIdKeywordStruct,31 TokenIdKeywordStruct,
32 TokenIdKeywordEnum,32 TokenIdKeywordEnum,
33 TokenIdKeywordUnion,
33 TokenIdKeywordWhile,34 TokenIdKeywordWhile,
34 TokenIdKeywordFor,35 TokenIdKeywordFor,
35 TokenIdKeywordContinue,36 TokenIdKeywordContinue,