mirror of
https://github.com/ziglang/zig.git
synced 2025-02-04 20:02:47 +00:00
add skeleton for union support
This commit is contained in:
parent
4961910e7f
commit
46ab981787
@ -15,7 +15,7 @@ GlobalVarDecl = VariableDeclaration ";"
|
||||
|
||||
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)
|
||||
|
||||
|
@ -8,7 +8,7 @@ if exists("b:current_syntax")
|
||||
endif
|
||||
|
||||
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 zigConditional if else switch
|
||||
syn keyword zigRepeat while for
|
||||
|
@ -135,7 +135,7 @@ struct TopLevelDecl {
|
||||
struct TypeEnumField {
|
||||
Buf *name;
|
||||
TypeTableEntry *type_entry;
|
||||
uint32_t value;
|
||||
uint32_t value; // TODO is this used?
|
||||
};
|
||||
|
||||
enum NodeType {
|
||||
@ -590,6 +590,7 @@ struct AstNodeAsmExpr {
|
||||
enum ContainerKind {
|
||||
ContainerKindStruct,
|
||||
ContainerKindEnum,
|
||||
ContainerKindUnion,
|
||||
};
|
||||
|
||||
struct AstNodeStructDecl {
|
||||
@ -905,6 +906,22 @@ struct TypeTableEntryEnum {
|
||||
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 {
|
||||
int src_index;
|
||||
int gen_index;
|
||||
@ -949,6 +966,7 @@ enum TypeTableEntryId {
|
||||
TypeTableEntryIdErrorUnion,
|
||||
TypeTableEntryIdPureError,
|
||||
TypeTableEntryIdEnum,
|
||||
TypeTableEntryIdUnion,
|
||||
TypeTableEntryIdFn,
|
||||
TypeTableEntryIdTypeDecl,
|
||||
TypeTableEntryIdNamespace,
|
||||
@ -974,6 +992,7 @@ struct TypeTableEntry {
|
||||
TypeTableEntryMaybe maybe;
|
||||
TypeTableEntryError error;
|
||||
TypeTableEntryEnum enumeration;
|
||||
TypeTableEntryUnion unionation;
|
||||
TypeTableEntryFn fn;
|
||||
TypeTableEntryTypeDecl type_decl;
|
||||
TypeTableEntryGenericFn generic_fn;
|
||||
|
@ -141,6 +141,8 @@ static BlockContext **get_container_block_context_ptr(TypeTableEntry *type_entry
|
||||
return &type_entry->data.structure.block_context;
|
||||
} else if (type_entry->id == TypeTableEntryIdEnum) {
|
||||
return &type_entry->data.enumeration.block_context;
|
||||
} else if (type_entry->id == TypeTableEntryIdUnion) {
|
||||
return &type_entry->data.unionation.block_context;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -178,6 +180,8 @@ static bool type_is_complete(TypeTableEntry *type_entry) {
|
||||
return type_entry->data.structure.complete;
|
||||
case TypeTableEntryIdEnum:
|
||||
return type_entry->data.enumeration.complete;
|
||||
case TypeTableEntryIdUnion:
|
||||
return type_entry->data.unionation.complete;
|
||||
case TypeTableEntryIdMetaType:
|
||||
case TypeTableEntryIdVoid:
|
||||
case TypeTableEntryIdBool:
|
||||
@ -732,6 +736,8 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {
|
||||
return TypeTableEntryIdStruct;
|
||||
case ContainerKindEnum:
|
||||
return TypeTableEntryIdEnum;
|
||||
case ContainerKindUnion:
|
||||
return TypeTableEntryIdUnion;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -749,6 +755,9 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,
|
||||
case ContainerKindEnum:
|
||||
entry->data.enumeration.decl_node = decl_node;
|
||||
break;
|
||||
case ContainerKindUnion:
|
||||
entry->data.unionation.decl_node = decl_node;
|
||||
break;
|
||||
}
|
||||
|
||||
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 TypeTableEntryIdPureError:
|
||||
case TypeTableEntryIdEnum:
|
||||
case TypeTableEntryIdUnion:
|
||||
case TypeTableEntryIdFn:
|
||||
case TypeTableEntryIdTypeDecl:
|
||||
break;
|
||||
@ -1397,6 +1407,10 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
|
||||
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) {
|
||||
TopLevelDecl *tld = get_as_top_level_decl(decl_node);
|
||||
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:
|
||||
resolve_enum_type(g, import, type_entry);
|
||||
break;
|
||||
case ContainerKindUnion:
|
||||
resolve_union_type(g, import, type_entry);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1672,6 +1689,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
|
||||
case TypeTableEntryIdErrorUnion:
|
||||
case TypeTableEntryIdPureError:
|
||||
case TypeTableEntryIdEnum:
|
||||
case TypeTableEntryIdUnion:
|
||||
case TypeTableEntryIdFn:
|
||||
return true;
|
||||
|
||||
@ -4450,6 +4468,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
|
||||
case TypeTableEntryIdErrorUnion:
|
||||
case TypeTableEntryIdPureError:
|
||||
case TypeTableEntryIdEnum:
|
||||
case TypeTableEntryIdUnion:
|
||||
case TypeTableEntryIdFn:
|
||||
case TypeTableEntryIdTypeDecl:
|
||||
return resolve_expr_const_val_as_type(g, node, type_entry);
|
||||
@ -6179,6 +6198,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
|
||||
return false;
|
||||
case TypeTableEntryIdArray:
|
||||
case TypeTableEntryIdStruct:
|
||||
case TypeTableEntryIdUnion:
|
||||
return true;
|
||||
case TypeTableEntryIdErrorUnion:
|
||||
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:
|
||||
// TODO better hashing algorithm
|
||||
return 1532530855;
|
||||
case TypeTableEntryIdUnion:
|
||||
// TODO better hashing algorithm
|
||||
return 2709806591;
|
||||
case TypeTableEntryIdMaybe:
|
||||
if (const_val->data.x_maybe) {
|
||||
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);
|
||||
case TypeTableEntryIdStruct:
|
||||
return type_of_first_thing_in_memory(first_struct_field_type(type_entry));
|
||||
case TypeTableEntryIdUnion:
|
||||
zig_panic("TODO");
|
||||
case TypeTableEntryIdMaybe:
|
||||
return type_of_first_thing_in_memory(type_entry->data.maybe.child_type);
|
||||
case TypeTableEntryIdErrorUnion:
|
||||
|
@ -84,6 +84,7 @@ static const char *container_string(ContainerKind kind) {
|
||||
switch (kind) {
|
||||
case ContainerKindEnum: return "enum";
|
||||
case ContainerKindStruct: return "struct";
|
||||
case ContainerKindUnion: return "union";
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
@ -2972,6 +2972,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
|
||||
return LLVMConstNamedStruct(type_entry->type_ref, fields,
|
||||
type_entry->data.structure.gen_field_count);
|
||||
}
|
||||
case TypeTableEntryIdUnion:
|
||||
{
|
||||
zig_panic("TODO");
|
||||
}
|
||||
case TypeTableEntryIdArray:
|
||||
{
|
||||
TypeTableEntry *child_type = type_entry->data.array.child_type;
|
||||
|
@ -41,6 +41,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
|
||||
zig_panic("TODO");
|
||||
case TypeTableEntryIdStruct:
|
||||
zig_panic("TODO");
|
||||
case TypeTableEntryIdUnion:
|
||||
zig_panic("TODO");
|
||||
case TypeTableEntryIdUndefLit:
|
||||
zig_panic("TODO");
|
||||
case TypeTableEntryIdMaybe:
|
||||
|
@ -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)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
} else if (first_token->id == TokenIdKeywordEnum) {
|
||||
kind = ContainerKindEnum;
|
||||
} else if (first_token->id == TokenIdKeywordUnion) {
|
||||
kind = ContainerKindUnion;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
@ -2689,7 +2691,7 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis
|
||||
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) {
|
||||
top_level_decls->append(struct_node);
|
||||
continue;
|
||||
|
@ -108,7 +108,7 @@ const char * zig_keywords[] = {
|
||||
"pub", "export", "use", "if", "else", "goto", "asm",
|
||||
"volatile", "struct", "enum", "while", "for", "continue", "break",
|
||||
"null", "noalias", "switch", "undefined", "error", "type", "inline",
|
||||
"defer",
|
||||
"defer", "union",
|
||||
};
|
||||
|
||||
bool is_zig_keyword(Buf *buf) {
|
||||
@ -269,6 +269,8 @@ static void end_token(Tokenize *t) {
|
||||
t->cur_tok->id = TokenIdKeywordStruct;
|
||||
} else if (mem_eql_str(token_mem, token_len, "enum")) {
|
||||
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")) {
|
||||
t->cur_tok->id = TokenIdKeywordFor;
|
||||
} 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 TokenIdKeywordStruct: return "struct";
|
||||
case TokenIdKeywordEnum: return "enum";
|
||||
case TokenIdKeywordUnion: return "union";
|
||||
case TokenIdKeywordWhile: return "while";
|
||||
case TokenIdKeywordFor: return "for";
|
||||
case TokenIdKeywordContinue: return "continue";
|
||||
|
@ -30,6 +30,7 @@ enum TokenId {
|
||||
TokenIdKeywordVolatile,
|
||||
TokenIdKeywordStruct,
|
||||
TokenIdKeywordEnum,
|
||||
TokenIdKeywordUnion,
|
||||
TokenIdKeywordWhile,
|
||||
TokenIdKeywordFor,
|
||||
TokenIdKeywordContinue,
|
||||
|
Loading…
Reference in New Issue
Block a user