diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-01-21 03:02:25 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-01-21 03:02:25 -0700 |
| commit | 32e2196257b2650e41b683d16bf00ba77ccfbb13 (patch) | |
| tree | 1eb681e2443aa31c4d5fea8ab798f12faaf7b3d2 /src/codegen.cpp | |
| parent | 5e212db29cf9e2c06aba363736ffb965e631aa2d (diff) | |
| download | zig-32e2196257b2650e41b683d16bf00ba77ccfbb13.tar.gz zig-32e2196257b2650e41b683d16bf00ba77ccfbb13.zip | |
number literal rework
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 169 |
1 files changed, 50 insertions, 119 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 25ca9bf54a..be4661c57f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -118,6 +118,9 @@ static TypeTableEntry *get_expr_type(AstNode *node) { if (expr->implicit_cast.after_type) { return expr->implicit_cast.after_type; } + if (expr->resolved_type) { + return expr->resolved_type; + } return expr->type_entry; } @@ -131,29 +134,35 @@ static TypeTableEntry *fn_proto_type_from_type_node(CodeGen *g, AstNode *type_no } } -static LLVMValueRef gen_number_literal_raw(CodeGen *g, AstNode *source_node, - NumLitCodeGen *codegen_num_lit, AstNodeNumberLiteral *num_lit_node) -{ - TypeTableEntry *type_entry = codegen_num_lit->resolved_type; +static LLVMValueRef gen_number_literal(CodeGen *g, AstNode *expr_node) { + Expr *expr = get_resolved_expr(expr_node); + TypeTableEntry *type_entry = expr->resolved_type; + if (!type_entry) { + type_entry = expr->type_entry; + } assert(type_entry); - // override the expression type for number literals - get_resolved_expr(source_node)->type_entry = type_entry; + ConstExprValue *const_val = &expr->const_val; - if (type_entry->id == TypeTableEntryIdInt) { - // here the union has int64_t and uint64_t and we purposefully read - // the uint64_t value in either case, because we want the twos - // complement representation + assert(const_val->ok); + if (type_entry->id == TypeTableEntryIdInt) { + assert(const_val->data.x_bignum.kind == BigNumKindInt); return LLVMConstInt(type_entry->type_ref, - num_lit_node->data.x_uint, - type_entry->data.integral.is_signed); + bignum_to_twos_complement(&const_val->data.x_bignum), + type_entry->data.integral.is_signed); } else if (type_entry->id == TypeTableEntryIdFloat) { - - return LLVMConstReal(type_entry->type_ref, - num_lit_node->data.x_float); + if (const_val->data.x_bignum.kind == BigNumKindFloat) { + return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float); + } else { + int64_t x = const_val->data.x_bignum.data.x_uint; + if (const_val->data.x_bignum.is_negative) { + x = -x; + } + return LLVMConstReal(type_entry->type_ref, x); + } } else { - zig_panic("bad number literal type"); + zig_unreachable(); } } @@ -265,73 +274,10 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { return nullptr; } case BuiltinFnIdSizeof: - { - assert(node->data.fn_call_expr.params.length == 1); - AstNode *type_node = node->data.fn_call_expr.params.at(0); - TypeTableEntry *type_entry = get_type_for_type_node(type_node); - - NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node); - AstNodeNumberLiteral num_lit_node; - num_lit_node.kind = NumLitU64; // this field isn't even read - num_lit_node.overflow = false; - num_lit_node.data.x_uint = type_entry->size_in_bits / 8; - return gen_number_literal_raw(g, node, codegen_num_lit, &num_lit_node); - } case BuiltinFnIdMinValue: - { - assert(node->data.fn_call_expr.params.length == 1); - AstNode *type_node = node->data.fn_call_expr.params.at(0); - TypeTableEntry *type_entry = get_type_for_type_node(type_node); - - - if (type_entry->id == TypeTableEntryIdInt) { - if (type_entry->data.integral.is_signed) { - return LLVMConstInt(type_entry->type_ref, 1ULL << (type_entry->size_in_bits - 1), false); - } else { - return LLVMConstNull(type_entry->type_ref); - } - } else if (type_entry->id == TypeTableEntryIdFloat) { - zig_panic("TODO codegen min_value float"); - } else { - zig_unreachable(); - } - } case BuiltinFnIdMaxValue: - { - assert(node->data.fn_call_expr.params.length == 1); - AstNode *type_node = node->data.fn_call_expr.params.at(0); - TypeTableEntry *type_entry = get_type_for_type_node(type_node); - - - if (type_entry->id == TypeTableEntryIdInt) { - if (type_entry->data.integral.is_signed) { - return LLVMConstInt(type_entry->type_ref, (1ULL << (type_entry->size_in_bits - 1)) - 1, false); - } else { - return LLVMConstAllOnes(type_entry->type_ref); - } - } else if (type_entry->id == TypeTableEntryIdFloat) { - zig_panic("TODO codegen max_value float"); - } else { - zig_unreachable(); - } - } case BuiltinFnIdMemberCount: - { - assert(node->data.fn_call_expr.params.length == 1); - AstNode *type_node = node->data.fn_call_expr.params.at(0); - TypeTableEntry *type_entry = get_type_for_type_node(type_node); - - if (type_entry->id == TypeTableEntryIdEnum) { - NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node); - AstNodeNumberLiteral num_lit_node; - num_lit_node.kind = NumLitU64; // field ignored - num_lit_node.overflow = false; - num_lit_node.data.x_uint = type_entry->data.enumeration.field_count; - return gen_number_literal_raw(g, node, codegen_num_lit, &num_lit_node); - } else { - zig_unreachable(); - } - } + return gen_number_literal(g, node); } zig_unreachable(); } @@ -1407,11 +1353,22 @@ static LLVMValueRef gen_if_bool_expr(CodeGen *g, AstNode *node) { assert(node->data.if_bool_expr.condition); assert(node->data.if_bool_expr.then_block); - LLVMValueRef cond_value = gen_expr(g, node->data.if_bool_expr.condition); + ConstExprValue *const_val = &get_resolved_expr(node->data.if_bool_expr.condition)->const_val; + if (const_val->ok) { + if (const_val->data.x_bool) { + return gen_expr(g, node->data.if_bool_expr.then_block); + } else if (node->data.if_bool_expr.else_node) { + return gen_expr(g, node->data.if_bool_expr.else_node); + } else { + return nullptr; + } + } else { + LLVMValueRef cond_value = gen_expr(g, node->data.if_bool_expr.condition); - return gen_if_bool_expr_raw(g, node, cond_value, - node->data.if_bool_expr.then_block, - node->data.if_bool_expr.else_node); + return gen_if_bool_expr_raw(g, node, cond_value, + node->data.if_bool_expr.then_block, + node->data.if_bool_expr.else_node); + } } static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) { @@ -1932,15 +1889,6 @@ static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) { get_resolved_expr(node)->block_context, false, &init_val); } -static LLVMValueRef gen_number_literal(CodeGen *g, AstNode *node) { - assert(node->type == NodeTypeNumberLiteral); - - NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node); - assert(codegen_num_lit); - - return gen_number_literal_raw(g, node, codegen_num_lit, &node->data.number_literal); -} - static LLVMValueRef gen_error_literal(CodeGen *g, AstNode *node) { assert(node->type == NodeTypeErrorLiteral); @@ -2383,20 +2331,6 @@ static void add_int_overflow_fns(CodeGen *g, TypeTableEntry *type_entry) { type_entry->data.integral.mul_with_overflow_fn = get_arithmetic_overflow_fn(g, type_entry, "smul", "umul"); } -static const NumLit num_lit_kinds[] = { - NumLitF32, - NumLitF64, - NumLitF128, - NumLitU8, - NumLitU16, - NumLitU32, - NumLitU64, - NumLitI8, - NumLitI16, - NumLitI32, - NumLitI64, -}; - static const int int_sizes_in_bits[] = { 8, 16, @@ -2411,18 +2345,15 @@ static void define_builtin_types(CodeGen *g) { buf_init_from_str(&entry->name, "(invalid)"); g->builtin_types.entry_invalid = entry; } - - assert(NumLitCount == array_length(num_lit_kinds)); - for (int i = 0; i < NumLitCount; i += 1) { - NumLit num_lit_kind = num_lit_kinds[i]; - // This type should just create a constant with whatever actual number - // type is expected at the time. - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumberLiteral); - buf_resize(&entry->name, 0); - buf_appendf(&entry->name, "(%s literal)", num_lit_str(num_lit_kind)); - entry->data.num_lit.kind = num_lit_kind; - entry->size_in_bits = num_lit_bit_count(num_lit_kind); - g->num_lit_types[i] = entry; + { + TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat); + buf_init_from_str(&entry->name, "(float literal)"); + g->builtin_types.entry_num_lit_float = entry; + } + { + TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt); + buf_init_from_str(&entry->name, "(integer literal)"); + g->builtin_types.entry_num_lit_int = entry; } for (int i = 0; i < array_length(int_sizes_in_bits); i += 1) { |
