add skeleton for union support

master
Andrew Kelley 2016-04-24 11:24:04 -07:00
parent 4961910e7f
commit 46ab981787
10 changed files with 64 additions and 7 deletions

View File

@ -15,7 +15,7 @@ GlobalVarDecl = VariableDeclaration ";"
VariableDeclaration = ("var" | "const") "Symbol" option(":" TypeExpr) "=" Expression VariableDeclaration = ("var" | "const") "Symbol" option(":" TypeExpr) "=" Expression
ContainerDecl = ("struct" | "enum") "Symbol" "{" many(StructMember) "}" ContainerDecl = ("struct" | "enum" | "union") "Symbol" "{" many(StructMember) "}"
StructMember = many(Directive) option(VisibleMod) (StructField | FnDef) StructMember = many(Directive) option(VisibleMod) (StructField | FnDef)

View File

@ -8,7 +8,7 @@ if exists("b:current_syntax")
endif endif
syn keyword zigStorage const var extern volatile export pub noalias inline syn keyword zigStorage const var extern volatile export pub noalias inline
syn keyword zigStructure struct enum syn keyword zigStructure struct enum union
syn keyword zigStatement goto break return continue asm defer syn keyword zigStatement goto break return continue asm defer
syn keyword zigConditional if else switch syn keyword zigConditional if else switch
syn keyword zigRepeat while for syn keyword zigRepeat while for

View File

@ -135,7 +135,7 @@ struct TopLevelDecl {
struct TypeEnumField { struct TypeEnumField {
Buf *name; Buf *name;
TypeTableEntry *type_entry; TypeTableEntry *type_entry;
uint32_t value; uint32_t value; // TODO is this used?
}; };
enum NodeType { enum NodeType {
@ -590,6 +590,7 @@ struct AstNodeAsmExpr {
enum ContainerKind { enum ContainerKind {
ContainerKindStruct, ContainerKindStruct,
ContainerKindEnum, ContainerKindEnum,
ContainerKindUnion,
}; };
struct AstNodeStructDecl { struct AstNodeStructDecl {
@ -905,6 +906,22 @@ struct TypeTableEntryEnum {
bool complete; bool complete;
}; };
struct TypeTableEntryUnion {
AstNode *decl_node;
uint32_t src_field_count;
uint32_t gen_field_count;
TypeStructField *fields;
uint64_t size_bytes;
bool is_invalid; // true if any fields are invalid
BlockContext *block_context;
// set this flag temporarily to detect infinite loops
bool embedded_in_current;
bool reported_infinite_err;
// whether we've finished resolving it
bool complete;
};
struct FnGenParamInfo { struct FnGenParamInfo {
int src_index; int src_index;
int gen_index; int gen_index;
@ -949,6 +966,7 @@ enum TypeTableEntryId {
TypeTableEntryIdErrorUnion, TypeTableEntryIdErrorUnion,
TypeTableEntryIdPureError, TypeTableEntryIdPureError,
TypeTableEntryIdEnum, TypeTableEntryIdEnum,
TypeTableEntryIdUnion,
TypeTableEntryIdFn, TypeTableEntryIdFn,
TypeTableEntryIdTypeDecl, TypeTableEntryIdTypeDecl,
TypeTableEntryIdNamespace, TypeTableEntryIdNamespace,
@ -974,6 +992,7 @@ struct TypeTableEntry {
TypeTableEntryMaybe maybe; TypeTableEntryMaybe maybe;
TypeTableEntryError error; TypeTableEntryError error;
TypeTableEntryEnum enumeration; TypeTableEntryEnum enumeration;
TypeTableEntryUnion unionation;
TypeTableEntryFn fn; TypeTableEntryFn fn;
TypeTableEntryTypeDecl type_decl; TypeTableEntryTypeDecl type_decl;
TypeTableEntryGenericFn generic_fn; TypeTableEntryGenericFn generic_fn;

View File

@ -141,6 +141,8 @@ static BlockContext **get_container_block_context_ptr(TypeTableEntry *type_entry
return &type_entry->data.structure.block_context; return &type_entry->data.structure.block_context;
} else if (type_entry->id == TypeTableEntryIdEnum) { } else if (type_entry->id == TypeTableEntryIdEnum) {
return &type_entry->data.enumeration.block_context; return &type_entry->data.enumeration.block_context;
} else if (type_entry->id == TypeTableEntryIdUnion) {
return &type_entry->data.unionation.block_context;
} }
zig_unreachable(); zig_unreachable();
} }
@ -178,6 +180,8 @@ static bool type_is_complete(TypeTableEntry *type_entry) {
return type_entry->data.structure.complete; return type_entry->data.structure.complete;
case TypeTableEntryIdEnum: case TypeTableEntryIdEnum:
return type_entry->data.enumeration.complete; return type_entry->data.enumeration.complete;
case TypeTableEntryIdUnion:
return type_entry->data.unionation.complete;
case TypeTableEntryIdMetaType: case TypeTableEntryIdMetaType:
case TypeTableEntryIdVoid: case TypeTableEntryIdVoid:
case TypeTableEntryIdBool: case TypeTableEntryIdBool:
@ -732,6 +736,8 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {
return TypeTableEntryIdStruct; return TypeTableEntryIdStruct;
case ContainerKindEnum: case ContainerKindEnum:
return TypeTableEntryIdEnum; return TypeTableEntryIdEnum;
case ContainerKindUnion:
return TypeTableEntryIdUnion;
} }
zig_unreachable(); zig_unreachable();
} }
@ -749,6 +755,9 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,
case ContainerKindEnum: case ContainerKindEnum:
entry->data.enumeration.decl_node = decl_node; entry->data.enumeration.decl_node = decl_node;
break; break;
case ContainerKindUnion:
entry->data.unionation.decl_node = decl_node;
break;
} }
unsigned line = decl_node ? decl_node->line : 0; unsigned line = decl_node ? decl_node->line : 0;
@ -874,6 +883,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
case TypeTableEntryIdErrorUnion: case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError: case TypeTableEntryIdPureError:
case TypeTableEntryIdEnum: case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn: case TypeTableEntryIdFn:
case TypeTableEntryIdTypeDecl: case TypeTableEntryIdTypeDecl:
break; break;
@ -1397,6 +1407,10 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
struct_type->zero_bits = (debug_size_in_bits == 0); struct_type->zero_bits = (debug_size_in_bits == 0);
} }
static void resolve_union_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type) {
zig_panic("TODO");
}
static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t sep) { static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t sep) {
TopLevelDecl *tld = get_as_top_level_decl(decl_node); TopLevelDecl *tld = get_as_top_level_decl(decl_node);
AstNode *parent_decl = tld->parent_decl; AstNode *parent_decl = tld->parent_decl;
@ -1541,6 +1555,9 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)
case ContainerKindEnum: case ContainerKindEnum:
resolve_enum_type(g, import, type_entry); resolve_enum_type(g, import, type_entry);
break; break;
case ContainerKindUnion:
resolve_union_type(g, import, type_entry);
break;
} }
break; break;
@ -1672,6 +1689,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
case TypeTableEntryIdErrorUnion: case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError: case TypeTableEntryIdPureError:
case TypeTableEntryIdEnum: case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn: case TypeTableEntryIdFn:
return true; return true;
@ -4450,6 +4468,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
case TypeTableEntryIdErrorUnion: case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdPureError: case TypeTableEntryIdPureError:
case TypeTableEntryIdEnum: case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn: case TypeTableEntryIdFn:
case TypeTableEntryIdTypeDecl: case TypeTableEntryIdTypeDecl:
return resolve_expr_const_val_as_type(g, node, type_entry); return resolve_expr_const_val_as_type(g, node, type_entry);
@ -6179,6 +6198,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
return false; return false;
case TypeTableEntryIdArray: case TypeTableEntryIdArray:
case TypeTableEntryIdStruct: case TypeTableEntryIdStruct:
case TypeTableEntryIdUnion:
return true; return true;
case TypeTableEntryIdErrorUnion: case TypeTableEntryIdErrorUnion:
return type_has_bits(type_entry->data.error.child_type); 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)
case TypeTableEntryIdStruct: case TypeTableEntryIdStruct:
// TODO better hashing algorithm // TODO better hashing algorithm
return 1532530855; return 1532530855;
case TypeTableEntryIdUnion:
// TODO better hashing algorithm
return 2709806591;
case TypeTableEntryIdMaybe: case TypeTableEntryIdMaybe:
if (const_val->data.x_maybe) { if (const_val->data.x_maybe) {
TypeTableEntry *child_type = type->data.maybe.child_type; TypeTableEntry *child_type = type->data.maybe.child_type;
@ -6374,6 +6397,8 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
return type_of_first_thing_in_memory(type_entry->data.array.child_type); return type_of_first_thing_in_memory(type_entry->data.array.child_type);
case TypeTableEntryIdStruct: case TypeTableEntryIdStruct:
return type_of_first_thing_in_memory(first_struct_field_type(type_entry)); return type_of_first_thing_in_memory(first_struct_field_type(type_entry));
case TypeTableEntryIdUnion:
zig_panic("TODO");
case TypeTableEntryIdMaybe: case TypeTableEntryIdMaybe:
return type_of_first_thing_in_memory(type_entry->data.maybe.child_type); return type_of_first_thing_in_memory(type_entry->data.maybe.child_type);
case TypeTableEntryIdErrorUnion: case TypeTableEntryIdErrorUnion:

View File

@ -84,6 +84,7 @@ static const char *container_string(ContainerKind kind) {
switch (kind) { switch (kind) {
case ContainerKindEnum: return "enum"; case ContainerKindEnum: return "enum";
case ContainerKindStruct: return "struct"; case ContainerKindStruct: return "struct";
case ContainerKindUnion: return "union";
} }
zig_unreachable(); zig_unreachable();
} }

View File

@ -2972,6 +2972,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
return LLVMConstNamedStruct(type_entry->type_ref, fields, return LLVMConstNamedStruct(type_entry->type_ref, fields,
type_entry->data.structure.gen_field_count); type_entry->data.structure.gen_field_count);
} }
case TypeTableEntryIdUnion:
{
zig_panic("TODO");
}
case TypeTableEntryIdArray: case TypeTableEntryIdArray:
{ {
TypeTableEntry *child_type = type_entry->data.array.child_type; TypeTableEntry *child_type = type_entry->data.array.child_type;

View File

@ -41,6 +41,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
zig_panic("TODO"); zig_panic("TODO");
case TypeTableEntryIdStruct: case TypeTableEntryIdStruct:
zig_panic("TODO"); zig_panic("TODO");
case TypeTableEntryIdUnion:
zig_panic("TODO");
case TypeTableEntryIdUndefLit: case TypeTableEntryIdUndefLit:
zig_panic("TODO"); zig_panic("TODO");
case TypeTableEntryIdMaybe: case TypeTableEntryIdMaybe:

View File

@ -2504,11 +2504,11 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index,
} }
/* /*
ContainerDecl : ("struct" | "enum") "Symbol" "{" many(StructMember) "}" ContainerDecl = ("struct" | "enum" | "union") "Symbol" "{" many(StructMember) "}"
StructMember: many(Directive) option(VisibleMod) (StructField | FnDef) StructMember: many(Directive) option(VisibleMod) (StructField | FnDef)
StructField : "Symbol" option(":" Expression) ",") StructField : "Symbol" option(":" Expression) ",")
*/ */
static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index, static AstNode *ast_parse_container_decl(ParseContext *pc, int *token_index,
ZigList<AstNode*> *directives, VisibMod visib_mod) ZigList<AstNode*> *directives, VisibMod visib_mod)
{ {
Token *first_token = &pc->tokens->at(*token_index); Token *first_token = &pc->tokens->at(*token_index);
@ -2519,6 +2519,8 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index,
kind = ContainerKindStruct; kind = ContainerKindStruct;
} else if (first_token->id == TokenIdKeywordEnum) { } else if (first_token->id == TokenIdKeywordEnum) {
kind = ContainerKindEnum; kind = ContainerKindEnum;
} else if (first_token->id == TokenIdKeywordUnion) {
kind = ContainerKindUnion;
} else { } else {
return nullptr; return nullptr;
} }
@ -2689,7 +2691,7 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis
continue; continue;
} }
AstNode *struct_node = ast_parse_struct_decl(pc, token_index, directives, visib_mod); AstNode *struct_node = ast_parse_container_decl(pc, token_index, directives, visib_mod);
if (struct_node) { if (struct_node) {
top_level_decls->append(struct_node); top_level_decls->append(struct_node);
continue; continue;

View File

@ -108,7 +108,7 @@ const char * zig_keywords[] = {
"pub", "export", "use", "if", "else", "goto", "asm", "pub", "export", "use", "if", "else", "goto", "asm",
"volatile", "struct", "enum", "while", "for", "continue", "break", "volatile", "struct", "enum", "while", "for", "continue", "break",
"null", "noalias", "switch", "undefined", "error", "type", "inline", "null", "noalias", "switch", "undefined", "error", "type", "inline",
"defer", "defer", "union",
}; };
bool is_zig_keyword(Buf *buf) { bool is_zig_keyword(Buf *buf) {
@ -269,6 +269,8 @@ static void end_token(Tokenize *t) {
t->cur_tok->id = TokenIdKeywordStruct; t->cur_tok->id = TokenIdKeywordStruct;
} else if (mem_eql_str(token_mem, token_len, "enum")) { } else if (mem_eql_str(token_mem, token_len, "enum")) {
t->cur_tok->id = TokenIdKeywordEnum; t->cur_tok->id = TokenIdKeywordEnum;
} else if (mem_eql_str(token_mem, token_len, "union")) {
t->cur_tok->id = TokenIdKeywordUnion;
} else if (mem_eql_str(token_mem, token_len, "for")) { } else if (mem_eql_str(token_mem, token_len, "for")) {
t->cur_tok->id = TokenIdKeywordFor; t->cur_tok->id = TokenIdKeywordFor;
} else if (mem_eql_str(token_mem, token_len, "while")) { } else if (mem_eql_str(token_mem, token_len, "while")) {
@ -1195,6 +1197,7 @@ const char * token_name(TokenId id) {
case TokenIdKeywordAsm: return "asm"; case TokenIdKeywordAsm: return "asm";
case TokenIdKeywordStruct: return "struct"; case TokenIdKeywordStruct: return "struct";
case TokenIdKeywordEnum: return "enum"; case TokenIdKeywordEnum: return "enum";
case TokenIdKeywordUnion: return "union";
case TokenIdKeywordWhile: return "while"; case TokenIdKeywordWhile: return "while";
case TokenIdKeywordFor: return "for"; case TokenIdKeywordFor: return "for";
case TokenIdKeywordContinue: return "continue"; case TokenIdKeywordContinue: return "continue";

View File

@ -30,6 +30,7 @@ enum TokenId {
TokenIdKeywordVolatile, TokenIdKeywordVolatile,
TokenIdKeywordStruct, TokenIdKeywordStruct,
TokenIdKeywordEnum, TokenIdKeywordEnum,
TokenIdKeywordUnion,
TokenIdKeywordWhile, TokenIdKeywordWhile,
TokenIdKeywordFor, TokenIdKeywordFor,
TokenIdKeywordContinue, TokenIdKeywordContinue,