aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-21 03:02:25 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-21 03:02:25 -0700
commit32e2196257b2650e41b683d16bf00ba77ccfbb13 (patch)
tree1eb681e2443aa31c4d5fea8ab798f12faaf7b3d2 /src/codegen.cpp
parent5e212db29cf9e2c06aba363736ffb965e631aa2d (diff)
downloadzig-32e2196257b2650e41b683d16bf00ba77ccfbb13.tar.gz
zig-32e2196257b2650e41b683d16bf00ba77ccfbb13.zip
number literal rework
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp169
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) {