diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2015-12-14 02:46:37 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2015-12-14 02:46:37 -0700 |
| commit | e411467e1dd4557bb11698f2a5d979dfcbaea444 (patch) | |
| tree | 8b9bf14a1dee5310a8e18099fc354e1b9b1d2152 /src/codegen.cpp | |
| parent | 3d8eb10897a86b2616c6a1aa843b7ebe4134ac51 (diff) | |
| download | zig-e411467e1dd4557bb11698f2a5d979dfcbaea444.tar.gz zig-e411467e1dd4557bb11698f2a5d979dfcbaea444.zip | |
add number literal type
it gets implicitly casted to whatever is needed.
closes #24
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 95 |
1 files changed, 90 insertions, 5 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index fcd0214b07..47f64541a5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -279,6 +279,8 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { CastNode *cast_node = &node->codegen_node->data.cast_node; switch (cast_node->op) { + case CastOpNothing: + return expr_val; case CastOpPtrToInt: return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); case CastOpIntWidenOrShorten: @@ -901,11 +903,29 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { return gen_asm_expr(g, node); case NodeTypeNumberLiteral: { - Buf *number_str = &node->data.number; - LLVMTypeRef number_type = LLVMInt32Type(); - LLVMValueRef number_val = LLVMConstIntOfStringAndSize(number_type, - buf_ptr(number_str), buf_len(number_str), 10); - return number_val; + NumberLiteralNode *codegen_num_lit = &node->codegen_node->data.num_lit_node; + assert(codegen_num_lit); + TypeTableEntry *type_entry = codegen_num_lit->resolved_type; + assert(type_entry); + + // TODO this is kinda iffy. make sure josh is on board with this + node->codegen_node->expr_node.type_entry = type_entry; + + 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 + + return LLVMConstInt(type_entry->type_ref, + node->data.number_literal.data.x_uint, + type_entry->data.integral.is_signed); + } else if (type_entry->id == TypeTableEntryIdFloat) { + + return LLVMConstReal(type_entry->type_ref, + node->data.number_literal.data.x_float); + } else { + zig_panic("bad number literal type"); + } } case NodeTypeStringLiteral: { @@ -1186,6 +1206,20 @@ static void do_code_gen(CodeGen *g) { #endif } +static const NumLit num_lit_kinds[] = { + NumLitF32, + NumLitF64, + NumLitF128, + NumLitI8, + NumLitU8, + NumLitI16, + NumLitU16, + NumLitI32, + NumLitU32, + NumLitI64, + NumLitU64, +}; + static void define_builtin_types(CodeGen *g) { { // if this type is anywhere in the AST, we should never hit codegen. @@ -1193,6 +1227,19 @@ 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; + g->num_lit_types[i] = entry; + } + { TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool); entry->type_ref = LLVMInt1Type(); @@ -1217,6 +1264,19 @@ static void define_builtin_types(CodeGen *g) { g->type_table.put(&entry->name, entry); g->builtin_types.entry_u8 = entry; } + { + TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); + entry->type_ref = LLVMInt64Type(); + buf_init_from_str(&entry->name, "u64"); + entry->size_in_bits = 64; + entry->align_in_bits = 64; + entry->data.integral.is_signed = false; + entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), + entry->size_in_bits, entry->align_in_bits, + LLVMZigEncoding_DW_ATE_unsigned()); + g->type_table.put(&entry->name, entry); + g->builtin_types.entry_u64 = entry; + } g->builtin_types.entry_c_string_literal = get_pointer_to_type(g, g->builtin_types.entry_u8, true); { TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); @@ -1233,6 +1293,19 @@ static void define_builtin_types(CodeGen *g) { } { TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); + entry->type_ref = LLVMInt64Type(); + buf_init_from_str(&entry->name, "i64"); + entry->size_in_bits = 64; + entry->align_in_bits = 64; + entry->data.integral.is_signed = true; + entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), + entry->size_in_bits, entry->align_in_bits, + LLVMZigEncoding_DW_ATE_signed()); + g->type_table.put(&entry->name, entry); + g->builtin_types.entry_i64 = entry; + } + { + TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8); buf_init_from_str(&entry->name, "isize"); entry->size_in_bits = g->pointer_size_bytes * 8; @@ -1270,6 +1343,18 @@ static void define_builtin_types(CodeGen *g) { g->builtin_types.entry_f32 = entry; } { + TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat); + entry->type_ref = LLVMFloatType(); + buf_init_from_str(&entry->name, "f64"); + entry->size_in_bits = 64; + entry->align_in_bits = 64; + entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), + entry->size_in_bits, entry->align_in_bits, + LLVMZigEncoding_DW_ATE_float()); + g->type_table.put(&entry->name, entry); + g->builtin_types.entry_f64 = entry; + } + { TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid); entry->type_ref = LLVMVoidType(); buf_init_from_str(&entry->name, "void"); |
