add skeleton for union support
parent
4961910e7f
commit
46ab981787
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -30,6 +30,7 @@ enum TokenId {
|
||||||
TokenIdKeywordVolatile,
|
TokenIdKeywordVolatile,
|
||||||
TokenIdKeywordStruct,
|
TokenIdKeywordStruct,
|
||||||
TokenIdKeywordEnum,
|
TokenIdKeywordEnum,
|
||||||
|
TokenIdKeywordUnion,
|
||||||
TokenIdKeywordWhile,
|
TokenIdKeywordWhile,
|
||||||
TokenIdKeywordFor,
|
TokenIdKeywordFor,
|
||||||
TokenIdKeywordContinue,
|
TokenIdKeywordContinue,
|
||||||
|
|
Loading…
Reference in New Issue