Allow _ in floats

This commit is contained in:
Ginger Bill
2017-01-29 23:13:50 +00:00
parent 9e143a38ce
commit 0ca1b4612c
4 changed files with 101 additions and 27 deletions

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;