mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-19 21:10:30 +00:00
Allow _ in floats
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
15
src/ir.c
15
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;
|
||||
|
||||
Reference in New Issue
Block a user