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 ";"
1515
1616VariableDeclaration = ("var" | "const") "Symbol" option(":" TypeExpr) "=" Expression
1717
18ContainerDecl = ("struct" | "enum") "Symbol" "{" many(StructMember) "}"
18ContainerDecl = ("struct" | "enum" | "union") "Symbol" "{" many(StructMember) "}"
1919
2020StructMember = many(Directive) option(VisibleMod) (StructField | FnDef)
2121
doc/vim/syntax/zig.vim+1-1
......@@ -8,7 +8,7 @@ if exists("b:current_syntax")
88endif
99
1010syn keyword zigStorage const var extern volatile export pub noalias inline
11syn keyword zigStructure struct enum
11syn keyword zigStructure struct enum union
1212syn keyword zigStatement goto break return continue asm defer
1313syn keyword zigConditional if else switch
1414syn keyword zigRepeat while for
src/all_types.hpp+20-1
......@@ -135,7 +135,7 @@ struct TopLevelDecl {
135135struct TypeEnumField {
136136 Buf *name;
137137 TypeTableEntry *type_entry;
138 uint32_t value;
138 uint32_t value; // TODO is this used?
139139};
140140
141141enum NodeType {
......@@ -590,6 +590,7 @@ struct AstNodeAsmExpr {
590590enum ContainerKind {
591591 ContainerKindStruct,
592592 ContainerKindEnum,
593 ContainerKindUnion,
593594};
594595
595596struct AstNodeStructDecl {
......@@ -905,6 +906,22 @@ struct TypeTableEntryEnum {
905906 bool complete;
906907};
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
908925struct FnGenParamInfo {
909926 int src_index;
910927 int gen_index;
......@@ -949,6 +966,7 @@ enum TypeTableEntryId {
949966 TypeTableEntryIdErrorUnion,
950967 TypeTableEntryIdPureError,
951968 TypeTableEntryIdEnum,
969 TypeTableEntryIdUnion,
952970 TypeTableEntryIdFn,
953971 TypeTableEntryIdTypeDecl,
954972 TypeTableEntryIdNamespace,
......@@ -974,6 +992,7 @@ struct TypeTableEntry {
974992 TypeTableEntryMaybe maybe;
975993 TypeTableEntryError error;
976994 TypeTableEntryEnum enumeration;
995 TypeTableEntryUnion unionation;
977996 TypeTableEntryFn fn;
978997 TypeTableEntryTypeDecl type_decl;
979998 TypeTableEntryGenericFn generic_fn;
src/analyze.cpp+25
......@@ -141,6 +141,8 @@ static BlockContext **get_container_block_context_ptr(TypeTableEntry *type_entry
141141 return &type_entry->data.structure.block_context;
142142 } else if (type_entry->id == TypeTableEntryIdEnum) {
143143 return &type_entry->data.enumeration.block_context;
144 } else if (type_entry->id == TypeTableEntryIdUnion) {
145 return &type_entry->data.unionation.block_context;
144146 }
145147 zig_unreachable();
146148}
......@@ -178,6 +180,8 @@ static bool type_is_complete(TypeTableEntry *type_entry) {
178180 return type_entry->data.structure.complete;
179181 case TypeTableEntryIdEnum:
180182 return type_entry->data.enumeration.complete;
183 case TypeTableEntryIdUnion:
184 return type_entry->data.unionation.complete;
181185 case TypeTableEntryIdMetaType:
182186 case TypeTableEntryIdVoid:
183187 case TypeTableEntryIdBool:
......@@ -732,6 +736,8 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {
732736 return TypeTableEntryIdStruct;
733737 case ContainerKindEnum:
734738 return TypeTableEntryIdEnum;
739 case ContainerKindUnion:
740 return TypeTableEntryIdUnion;
735741 }
736742 zig_unreachable();
737743}
......@@ -749,6 +755,9 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,
749755 case ContainerKindEnum:
750756 entry->data.enumeration.decl_node = decl_node;
751757 break;
758 case ContainerKindUnion:
759 entry->data.unionation.decl_node = decl_node;
760 break;
752761 }
753762
754763 unsigned line = decl_node ? decl_node->line : 0;
......@@ -874,6 +883,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
874883 case TypeTableEntryIdErrorUnion:
875884 case TypeTableEntryIdPureError:
876885 case TypeTableEntryIdEnum:
886 case TypeTableEntryIdUnion:
877887 case TypeTableEntryIdFn:
878888 case TypeTableEntryIdTypeDecl:
879889 break;
......@@ -1397,6 +1407,10 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
13971407 struct_type->zero_bits = (debug_size_in_bits == 0);
13981408}
13991409
1410static void resolve_union_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type) {
1411 zig_panic("TODO");
1412}
1413
14001414static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t sep) {
14011415 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
14021416 AstNode *parent_decl = tld->parent_decl;
......@@ -1541,6 +1555,9 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)
15411555 case ContainerKindEnum:
15421556 resolve_enum_type(g, import, type_entry);
15431557 break;
1558 case ContainerKindUnion:
1559 resolve_union_type(g, import, type_entry);
1560 break;
15441561 }
15451562
15461563 break;
......@@ -1672,6 +1689,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
16721689 case TypeTableEntryIdErrorUnion:
16731690 case TypeTableEntryIdPureError:
16741691 case TypeTableEntryIdEnum:
1692 case TypeTableEntryIdUnion:
16751693 case TypeTableEntryIdFn:
16761694 return true;
16771695
......@@ -4450,6 +4468,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
44504468 case TypeTableEntryIdErrorUnion:
44514469 case TypeTableEntryIdPureError:
44524470 case TypeTableEntryIdEnum:
4471 case TypeTableEntryIdUnion:
44534472 case TypeTableEntryIdFn:
44544473 case TypeTableEntryIdTypeDecl:
44554474 return resolve_expr_const_val_as_type(g, node, type_entry);
......@@ -6179,6 +6198,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
61796198 return false;
61806199 case TypeTableEntryIdArray:
61816200 case TypeTableEntryIdStruct:
6201 case TypeTableEntryIdUnion:
61826202 return true;
61836203 case TypeTableEntryIdErrorUnion:
61846204 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)
62806300 case TypeTableEntryIdStruct:
62816301 // TODO better hashing algorithm
62826302 return 1532530855;
6303 case TypeTableEntryIdUnion:
6304 // TODO better hashing algorithm
6305 return 2709806591;
62836306 case TypeTableEntryIdMaybe:
62846307 if (const_val->data.x_maybe) {
62856308 TypeTableEntry *child_type = type->data.maybe.child_type;
......@@ -6374,6 +6397,8 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
63746397 return type_of_first_thing_in_memory(type_entry->data.array.child_type);
63756398 case TypeTableEntryIdStruct:
63766399 return type_of_first_thing_in_memory(first_struct_field_type(type_entry));
6400 case TypeTableEntryIdUnion:
6401 zig_panic("TODO");
63776402 case TypeTableEntryIdMaybe:
63786403 return type_of_first_thing_in_memory(type_entry->data.maybe.child_type);
63796404 case TypeTableEntryIdErrorUnion:
src/ast_render.cpp+1
......@@ -84,6 +84,7 @@ static const char *container_string(ContainerKind kind) {
8484 switch (kind) {
8585 case ContainerKindEnum: return "enum";
8686 case ContainerKindStruct: return "struct";
87 case ContainerKindUnion: return "union";
8788 }
8889 zig_unreachable();
8990}
src/codegen.cpp+4
......@@ -2972,6 +2972,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
29722972 return LLVMConstNamedStruct(type_entry->type_ref, fields,
29732973 type_entry->data.structure.gen_field_count);
29742974 }
2975 case TypeTableEntryIdUnion:
2976 {
2977 zig_panic("TODO");
2978 }
29752979 case TypeTableEntryIdArray:
29762980 {
29772981 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
4141 zig_panic("TODO");
4242 case TypeTableEntryIdStruct:
4343 zig_panic("TODO");
44 case TypeTableEntryIdUnion:
45 zig_panic("TODO");
4446 case TypeTableEntryIdUndefLit:
4547 zig_panic("TODO");
4648 case TypeTableEntryIdMaybe:
src/parser.cpp+5-3
......@@ -2504,11 +2504,11 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index,
25042504}
25052505
25062506/*
2507ContainerDecl : ("struct" | "enum") "Symbol" "{" many(StructMember) "}"
2507ContainerDecl = ("struct" | "enum" | "union") "Symbol" "{" many(StructMember) "}"
25082508StructMember: many(Directive) option(VisibleMod) (StructField | FnDef)
25092509StructField : "Symbol" option(":" Expression) ",")
25102510*/
2511static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index,
2511static AstNode *ast_parse_container_decl(ParseContext *pc, int *token_index,
25122512 ZigList<AstNode*> *directives, VisibMod visib_mod)
25132513{
25142514 Token *first_token = &pc->tokens->at(*token_index);
......@@ -2519,6 +2519,8 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index,
25192519 kind = ContainerKindStruct;
25202520 } else if (first_token->id == TokenIdKeywordEnum) {
25212521 kind = ContainerKindEnum;
2522 } else if (first_token->id == TokenIdKeywordUnion) {
2523 kind = ContainerKindUnion;
25222524 } else {
25232525 return nullptr;
25242526 }
......@@ -2689,7 +2691,7 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis
26892691 continue;
26902692 }
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);
26932695 if (struct_node) {
26942696 top_level_decls->append(struct_node);
26952697 continue;
src/tokenizer.cpp+4-1
......@@ -108,7 +108,7 @@ const char * zig_keywords[] = {
108108 "pub", "export", "use", "if", "else", "goto", "asm",
109109 "volatile", "struct", "enum", "while", "for", "continue", "break",
110110 "null", "noalias", "switch", "undefined", "error", "type", "inline",
111 "defer",
111 "defer", "union",
112112};
113113
114114bool is_zig_keyword(Buf *buf) {
......@@ -269,6 +269,8 @@ static void end_token(Tokenize *t) {
269269 t->cur_tok->id = TokenIdKeywordStruct;
270270 } else if (mem_eql_str(token_mem, token_len, "enum")) {
271271 t->cur_tok->id = TokenIdKeywordEnum;
272 } else if (mem_eql_str(token_mem, token_len, "union")) {
273 t->cur_tok->id = TokenIdKeywordUnion;
272274 } else if (mem_eql_str(token_mem, token_len, "for")) {
273275 t->cur_tok->id = TokenIdKeywordFor;
274276 } else if (mem_eql_str(token_mem, token_len, "while")) {
......@@ -1195,6 +1197,7 @@ const char * token_name(TokenId id) {
11951197 case TokenIdKeywordAsm: return "asm";
11961198 case TokenIdKeywordStruct: return "struct";
11971199 case TokenIdKeywordEnum: return "enum";
1200 case TokenIdKeywordUnion: return "union";
11981201 case TokenIdKeywordWhile: return "while";
11991202 case TokenIdKeywordFor: return "for";
12001203 case TokenIdKeywordContinue: return "continue";
src/tokenizer.hpp+1
......@@ -30,6 +30,7 @@ enum TokenId {
3030 TokenIdKeywordVolatile,
3131 TokenIdKeywordStruct,
3232 TokenIdKeywordEnum,
33 TokenIdKeywordUnion,
3334 TokenIdKeywordWhile,
3435 TokenIdKeywordFor,
3536 TokenIdKeywordContinue,