From 0ca1b4612c35c649d16476aa67462835249145e8 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Sun, 29 Jan 2017 23:13:50 +0000 Subject: [PATCH] Allow _ in floats --- code/demo.odin | 14 +++---- core/_preload.odin | 4 +- src/exact_value.c | 95 ++++++++++++++++++++++++++++++++++++++-------- src/ir.c | 15 ++++++-- 4 files changed, 101 insertions(+), 27 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index ec5ccfb40..21cfb6f63 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -1,13 +1,13 @@ #import "fmt.odin"; main :: proc() { - foo :: proc() -> [dynamic]int { - x: [dynamic]int; - append(^x, 2, 3, 5, 7); - return x; - } + x: [dynamic]f64; + defer free(x); + append(^x, 2_000_000.500_000, 3, 5, 7); - for p in foo() { - fmt.println(p); + for p, i in x { + if i > 0 { fmt.print(", "); } + fmt.print(p); } + fmt.println(); } diff --git a/core/_preload.odin b/core/_preload.odin index 0c10f9cc2..76bea89ff 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -357,9 +357,9 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int, array := cast(^Raw_Dynamic_Array)array_; ok := true; - if array.data == nil || array.capacity <= array.count+item_count { + if array.capacity <= array.count+item_count { capacity := 2 * array.capacity + max(8, item_count); - ok := __dynamic_array_reserve(array, elem_size, elem_align, capacity); + ok = __dynamic_array_reserve(array, elem_size, elem_align, capacity); } if !ok { // TODO(bill): Better error handling for failed reservation diff --git a/src/exact_value.c b/src/exact_value.c index 2a8b4eb20..83add68f4 100644 --- a/src/exact_value.c +++ b/src/exact_value.c @@ -60,6 +60,19 @@ ExactValue make_exact_value_integer(i64 i) { return result; } +ExactValue make_exact_value_float(f64 f) { + ExactValue result = {ExactValue_Float}; + result.value_float = f; + return result; +} + +ExactValue make_exact_value_pointer(i64 ptr) { + ExactValue result = {ExactValue_Pointer}; + result.value_pointer = ptr; + return result; +} + + ExactValue make_exact_value_integer_from_string(String string) { // TODO(bill): Allow for numbers with underscores in them i32 base = 10; @@ -106,23 +119,75 @@ ExactValue make_exact_value_integer_from_string(String string) { ExactValue make_exact_value_float_from_string(String string) { - // TODO(bill): Allow for numbers with underscores in them - ExactValue result = {ExactValue_Float}; - result.value_float = gb_str_to_f64(cast(char *)string.text, NULL); - return result; + isize i = 0; + u8 *str = string.text; + isize len = string.len; + + f64 sign = 1.0; + if (str[i] == '-') { + sign = -1.0; + i++; + } else if (*str == '+') { + i++; + } + + f64 value = 0.0; + for (; i < len; i++) { + Rune r = cast(Rune)str[i]; + if (r == '_') { + continue; + } + if (!gb_char_is_digit(r)) { + break; + } + i64 v = r - '0'; + value *= 10.0; + value += v; + } + + if (str[i] == '.') { + f64 pow10 = 10.0; + i++; + for (; i < string.len; i++) { + Rune r = cast(Rune)str[i]; + if (r == '_') { + continue; + } + if (!gb_char_is_digit(r)) { + break; + } + value += (r-'0')/pow10; + pow10 *= 10.0; + } + } + + f64 frac = 0; + f64 scale = 1.0; + if ((str[i] == 'e') || (str[i] == 'E')) { + i++; + + if (str[i] == '-') { + frac = 1; + i++; + } else if (str[i] == '+') { + i++; + } + + u32 exp; + for (exp = 0; gb_char_is_digit(str[i]); i++) { + exp = exp * 10 + (str[i]-'0'); + } + if (exp > 308) exp = 308; + + while (exp >= 50) { scale *= 1e50; exp -= 50; } + while (exp >= 8) { scale *= 1e8; exp -= 8; } + while (exp > 0) { scale *= 10.0; exp -= 1; } + } + + f64 result = sign * (frac ? (value / scale) : (value * scale)); + return make_exact_value_float(result); } -ExactValue make_exact_value_float(f64 f) { - ExactValue result = {ExactValue_Float}; - result.value_float = f; - return result; -} - -ExactValue make_exact_value_pointer(i64 ptr) { - ExactValue result = {ExactValue_Pointer}; - result.value_pointer = ptr; - return result; -} ExactValue make_exact_value_from_basic_literal(Token token) { switch (token.kind) { diff --git a/src/ir.c b/src/ir.c index ccd72e5d3..c715f5db0 100644 --- a/src/ir.c +++ b/src/ir.c @@ -1734,6 +1734,8 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, Type *type, irValue *e, Selec } } else if (type->kind == Type_Slice) { e = ir_emit_struct_ep(proc, e, index); + } else if (type->kind == Type_DynamicArray) { + e = ir_emit_struct_ep(proc, e, index); } else if (type->kind == Type_Vector) { e = ir_emit_array_epi(proc, e, index); } else if (type->kind == Type_Array) { @@ -3551,6 +3553,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { } } else { Type *type = base_type(type_of_expr(proc->module->info, se->expr)); + GB_ASSERT(is_type_integer(type)); ExactValue val = type_and_value_of_expression(proc->module->info, sel)->value; i64 index = val.value_integer; @@ -3581,6 +3584,14 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { ir_emit_store(proc, v, ir_emit_transmute(proc, ir_build_expr(proc, ce->expr), type)); return ir_make_addr(v, expr); } + case Token_down_cast: { + ir_emit_comment(proc, str_lit("Cast - down_cast")); + // NOTE(bill): Needed for dereference of pointer conversion + Type *type = type_of_expr(proc->module->info, expr); + irValue *v = ir_add_local_generated(proc, type); + ir_emit_store(proc, v, ir_emit_down_cast(proc, ir_build_expr(proc, ce->expr), type)); + return ir_make_addr(v, expr); + } default: GB_PANIC("Unknown cast expression"); } @@ -3860,13 +3871,13 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { case_end; case_ast_node(ce, CallExpr, expr); + // NOTE(bill): This is make sure you never need to have an `array_ev` irValue *e = ir_build_expr(proc, expr); irValue *v = ir_add_local_generated(proc, ir_type(e)); ir_emit_store(proc, v, e); return ir_make_addr(v, expr); case_end; - case_ast_node(cl, CompoundLit, expr); ir_emit_comment(proc, str_lit("CompoundLit")); Type *type = type_of_expr(proc->module->info, expr); @@ -4046,8 +4057,6 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { return ir_make_addr(v, expr); case_end; - - } TokenPos token_pos = ast_node_token(expr).pos;