merge constant expression evaluator with analyzer

master
Andrew Kelley 2016-01-15 04:45:25 -07:00
parent 0c9afede9e
commit b0f608a6a7
4 changed files with 628 additions and 646 deletions

View File

@ -8,14 +8,14 @@ if exists("b:current_syntax")
endif
syn keyword zigStorage const var extern volatile export pub noalias
syn keyword zigStructure struct enum type
syn keyword zigStructure struct enum
syn keyword zigStatement goto break return continue asm
syn keyword zigConditional if else switch
syn keyword zigRepeat while for
syn keyword zigConstant null
syn keyword zigKeyword fn use
syn keyword zigType bool i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 f128 string void unreachable
syn keyword zigKeyword fn import
syn keyword zigType bool i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 f128 string void unreachable type
syn keyword zigBoolean true false

View File

@ -57,6 +57,21 @@ struct Cast {
AstNode *source_node;
};
struct ConstExprValue {
bool ok; // true if constant expression evalution worked
bool depends_on_compile_var;
union {
uint64_t x_uint;
int64_t x_int;
double x_float;
bool x_bool;
FnTableEntry *x_fn;
TypeTableEntry *x_type;
ConstExprValue *x_maybe;
} data;
};
struct Expr {
TypeTableEntry *type_entry;
// the context in which this expression is evaluated.
@ -66,6 +81,8 @@ struct Expr {
// may be null for no cast
Cast implicit_cast; // happens first
Cast implicit_maybe_cast; // happens second
ConstExprValue const_val;
};
struct NumLitCodeGen {
@ -490,7 +507,6 @@ struct AstNodeNumberLiteral {
union {
uint64_t x_uint;
int64_t x_int;
double x_float;
} data;
@ -534,8 +550,6 @@ struct AstNodeSymbolExpr {
// populated by semantic analyzer
Expr resolved_expr;
VariableTableEntry *variable;
TypeTableEntry *meta_type;
FnTableEntry *fn_entry;
};
struct AstNodeBoolLiteral {
@ -670,10 +684,6 @@ struct TypeTableEntryMaybe {
TypeTableEntry *child_type;
};
struct TypeTableEntryMetaType {
TypeTableEntry *child_type;
};
struct TypeTableEntryEnum {
AstNode *decl_node;
uint32_t field_count;
@ -731,7 +741,6 @@ struct TypeTableEntry {
TypeTableEntryNumLit num_lit;
TypeTableEntryMaybe maybe;
TypeTableEntryEnum enumeration;
TypeTableEntryMetaType meta_type;
TypeTableEntryFn fn;
} data;
@ -740,7 +749,6 @@ struct TypeTableEntry {
TypeTableEntry *unknown_size_array_parent[2];
HashMap<uint64_t, TypeTableEntry *, uint64_hash, uint64_eq> arrays_by_size;
TypeTableEntry *maybe_parent;
TypeTableEntry *meta_parent;
};
struct ImporterInfo {
@ -852,6 +860,7 @@ struct CodeGen {
TypeTableEntry *entry_c_string_literal;
TypeTableEntry *entry_void;
TypeTableEntry *entry_unreachable;
TypeTableEntry *entry_type;
TypeTableEntry *entry_invalid;
} builtin_types;
@ -923,22 +932,4 @@ struct BlockContext {
LLVMZigDIScope *di_scope;
};
struct ConstExprValue {
bool ok; // true if constant expression evalution worked
bool depends_on_compile_var;
union {
uint64_t x_uint;
int64_t x_int;
double x_float;
bool x_bool;
FnTableEntry *x_fn;
TypeTableEntry *x_type;
struct {
bool is_null;
ConstExprValue *child_val;
} x_maybe;
} data;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -73,11 +73,13 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b
TypeTableEntry *op1_type, TypeTableEntry *op2_type);
static LLVMValueRef gen_bare_cast(CodeGen *g, AstNode *node, LLVMValueRef expr_val,
TypeTableEntry *actual_type, TypeTableEntry *wanted_type, Cast *cast_node);
static TypeTableEntry *get_type_for_type_node(AstNode *node) {
TypeTableEntry *meta_type_entry = get_resolved_expr(node)->type_entry;
assert(meta_type_entry->id == TypeTableEntryIdMetaType);
return meta_type_entry->data.meta_type.child_type;
Expr *expr = get_resolved_expr(node);
assert(expr->type_entry->id == TypeTableEntryIdMetaType);
ConstExprValue *const_val = &expr->const_val;
assert(const_val->ok);
return const_val->data.x_type;
}
static TypeTableEntry *fn_proto_type_from_type_node(CodeGen *g, AstNode *type_node) {
@ -434,10 +436,8 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
} else if (struct_type->id == TypeTableEntryIdPointer) {
assert(struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct);
fn_table_entry = node->data.fn_call_expr.fn_entry;
} else if (struct_type->id == TypeTableEntryIdMetaType &&
struct_type->data.meta_type.child_type->id == TypeTableEntryIdEnum)
{
TypeTableEntry *enum_type = struct_type->data.meta_type.child_type;
} else if (struct_type->id == TypeTableEntryIdMetaType) {
TypeTableEntry *enum_type = get_type_for_type_node(first_param_expr);
int param_count = node->data.fn_call_expr.params.length;
AstNode *arg1_node;
if (param_count == 1) {
@ -681,7 +681,8 @@ static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node, bool is_lva
static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lvalue) {
assert(node->type == NodeTypeFieldAccessExpr);
TypeTableEntry *struct_type = get_expr_type(node->data.field_access_expr.struct_expr);
AstNode *struct_expr = node->data.field_access_expr.struct_expr;
TypeTableEntry *struct_type = get_expr_type(struct_expr);
Buf *name = &node->data.field_access_expr.field_name;
if (struct_type->id == TypeTableEntryIdArray) {
@ -710,14 +711,12 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lva
add_debug_source_node(g, node);
return LLVMBuildLoad(g->builder, ptr, "");
}
} else if (struct_type->id == TypeTableEntryIdMetaType &&
struct_type->data.meta_type.child_type->id == TypeTableEntryIdEnum)
{
} else if (struct_type->id == TypeTableEntryIdMetaType) {
assert(!is_lvalue);
TypeTableEntry *enum_type = struct_type->data.meta_type.child_type;
TypeTableEntry *enum_type = get_type_for_type_node(struct_expr);
return gen_enum_value_expr(g, node, enum_type, nullptr);
} else {
zig_panic("gen_field_access_expr bad struct type");
zig_unreachable();
}
}
@ -2392,6 +2391,12 @@ static void define_builtin_types(CodeGen *g) {
g->builtin_types.entry_unreachable = entry;
g->primitive_type_table.put(&entry->name, entry);
}
{
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);
buf_init_from_str(&entry->name, "type");
g->builtin_types.entry_type = entry;
g->primitive_type_table.put(&entry->name, entry);
}
g->builtin_types.entry_c_string_literal = get_pointer_to_type(g, get_int_type(g, false, 8), true);