merge constant expression evaluator with analyzer
parent
0c9afede9e
commit
b0f608a6a7
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
1190
src/analyze.cpp
1190
src/analyze.cpp
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue