mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 16:18:52 +00:00
Hexadecimal floats for "perfect values" 0h42f60000 == 123; use bit_cast in compiler
This commit is contained in:
@@ -346,7 +346,7 @@ void init_build_context(void) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
u16 x = 1;
|
u16 x = 1;
|
||||||
bool big = !(*cast(u8 *)&x);
|
bool big = !bit_cast<u8>(x);
|
||||||
bc->ODIN_ENDIAN = big ? str_lit("big") : str_lit("little");
|
bc->ODIN_ENDIAN = big ? str_lit("big") : str_lit("little");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1227,7 +1227,7 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
|
|||||||
}
|
}
|
||||||
|
|
||||||
i64 i = v.value_integer;
|
i64 i = v.value_integer;
|
||||||
u64 u = *cast(u64 *)&i;
|
u64 u = bit_cast<u64>(i);
|
||||||
i64 s = 8*type_size_of(c->allocator, type);
|
i64 s = 8*type_size_of(c->allocator, type);
|
||||||
u64 umax = ~cast(u64)0ull;
|
u64 umax = ~cast(u64)0ull;
|
||||||
if (s < 64) {
|
if (s < 64) {
|
||||||
@@ -1336,7 +1336,7 @@ void check_is_expressible(Checker *c, Operand *o, Type *type) {
|
|||||||
String str = {};
|
String str = {};
|
||||||
i64 i = o->value.value_integer;
|
i64 i = o->value.value_integer;
|
||||||
if (is_type_unsigned(o->type)) {
|
if (is_type_unsigned(o->type)) {
|
||||||
str = u64_to_string(*cast(u64 *)&i, buf, gb_size_of(buf));
|
str = u64_to_string(bit_cast<u64>(i), buf, gb_size_of(buf));
|
||||||
} else {
|
} else {
|
||||||
str = i64_to_string(i, buf, gb_size_of(buf));
|
str = i64_to_string(i, buf, gb_size_of(buf));
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -262,7 +262,7 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
|
|||||||
ExactValue v = exact_value_to_integer(rhs->value);
|
ExactValue v = exact_value_to_integer(rhs->value);
|
||||||
if (v.kind == ExactValue_Integer) {
|
if (v.kind == ExactValue_Integer) {
|
||||||
i64 i = v.value_integer;
|
i64 i = v.value_integer;
|
||||||
u64 u = *cast(u64 *)&i;
|
u64 u = bit_cast<u64>(i);
|
||||||
u64 umax = ~cast(u64)0ull;
|
u64 umax = ~cast(u64)0ull;
|
||||||
if (lhs_bits < 64) {
|
if (lhs_bits < 64) {
|
||||||
umax = (1ull << cast(u64)lhs_bits) - 1ull;
|
umax = (1ull << cast(u64)lhs_bits) - 1ull;
|
||||||
|
|||||||
@@ -12,6 +12,14 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
template <typename U, typename V>
|
||||||
|
gb_inline U bit_cast(V &v) { return reinterpret_cast<U &>(v); }
|
||||||
|
|
||||||
|
template <typename U, typename V>
|
||||||
|
gb_inline U const &bit_cast(V const &v) { return reinterpret_cast<U const &>(v); }
|
||||||
|
|
||||||
|
|
||||||
gb_inline i64 align_formula(i64 size, i64 align) {
|
gb_inline i64 align_formula(i64 size, i64 align) {
|
||||||
if (align > 0) {
|
if (align > 0) {
|
||||||
i64 result = size + align-1;
|
i64 result = size + align-1;
|
||||||
@@ -164,6 +172,7 @@ u64 u64_from_string(String string) {
|
|||||||
case 'd': base = 10; has_prefix = true; break;
|
case 'd': base = 10; has_prefix = true; break;
|
||||||
case 'z': base = 12; has_prefix = true; break;
|
case 'z': base = 12; has_prefix = true; break;
|
||||||
case 'x': base = 16; has_prefix = true; break;
|
case 'x': base = 16; has_prefix = true; break;
|
||||||
|
case 'h': base = 16; has_prefix = true; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-34
@@ -156,39 +156,6 @@ f64 float_from_string(String string) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (len-i > 2 &&
|
|
||||||
str[i] == '0' &&
|
|
||||||
str[i+1] == 'h') {
|
|
||||||
i += 2;
|
|
||||||
u8 *text = string.text;
|
|
||||||
isize len = string.len;
|
|
||||||
if (has_prefix) {
|
|
||||||
text += 2;
|
|
||||||
len -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 base = 16;
|
|
||||||
|
|
||||||
u64 result = {0};
|
|
||||||
for (isize i = 0; i < len; i++) {
|
|
||||||
Rune r = cast(Rune)text[i];
|
|
||||||
if (r == '_') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
u64 v = bit128__digit_value(r);
|
|
||||||
if (v >= base) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result *= base;
|
|
||||||
result += v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return *cast(f64 *)&result;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
f64 value = 0.0;
|
f64 value = 0.0;
|
||||||
for (; i < len; i++) {
|
for (; i < len; i++) {
|
||||||
Rune r = cast(Rune)str[i];
|
Rune r = cast(Rune)str[i];
|
||||||
@@ -255,7 +222,29 @@ f64 float_from_string(String string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExactValue exact_value_float_from_string(String string) {
|
ExactValue exact_value_float_from_string(String string) {
|
||||||
return exact_value_float(float_from_string(string));
|
if (string.len > 2 && string[0] == '0' && string[1] == 'h') {
|
||||||
|
|
||||||
|
isize digit_count = 0;
|
||||||
|
for (isize i = 2; i < string.len; i++) {
|
||||||
|
if (string[i] != '_') {
|
||||||
|
digit_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u64 u = u64_from_string(string);
|
||||||
|
if (digit_count == 8) {
|
||||||
|
u32 x = cast(u32)u;
|
||||||
|
f32 f = bit_cast<f32>(x);
|
||||||
|
return exact_value_float(cast(f64)f);
|
||||||
|
} else if (digit_count == 16) {
|
||||||
|
f64 f = bit_cast<f64>(u);
|
||||||
|
return exact_value_float(f);
|
||||||
|
} else {
|
||||||
|
GB_PANIC("Invalid hexadecimal float, expected 8 or 16 digits, got %td", digit_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f64 f = float_from_string(string);
|
||||||
|
return exact_value_float(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -278,7 +278,7 @@ f64 u128_to_f64(u128 a) {
|
|||||||
return -((cast(f64)h * 18446744073709551616.0) + cast(f64)l);
|
return -((cast(f64)h * 18446744073709551616.0) + cast(f64)l);
|
||||||
}
|
}
|
||||||
i128 u128_to_i128(u128 a) {
|
i128 u128_to_i128(u128 a) {
|
||||||
return *cast(i128 *)&a;
|
return bit_cast<i128>(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ f64 i128_to_f64(i128 a) {
|
|||||||
return -((cast(f64)h * 18446744073709551616.0) + cast(f64)l);
|
return -((cast(f64)h * 18446744073709551616.0) + cast(f64)l);
|
||||||
}
|
}
|
||||||
u128 i128_to_u128(i128 a) {
|
u128 i128_to_u128(i128 a) {
|
||||||
return *cast(u128 *)&a;
|
return bit_cast<u128>(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -335,7 +335,7 @@ String i128_to_string(i128 a, char *out_buf, isize out_buf_len) {
|
|||||||
a = i128_neg(a);
|
a = i128_neg(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
u128 v = *cast(u128 *)&a;
|
u128 v = bit_cast<u128>(a);
|
||||||
u128 b = u128_from_u64(10);;
|
u128 b = u128_from_u64(10);;
|
||||||
while (u128_ge(v, b)) {
|
while (u128_ge(v, b)) {
|
||||||
buf[--i] = gb__num_to_char_table[u128_to_i64(u128_mod(v, b))];
|
buf[--i] = gb__num_to_char_table[u128_to_i64(u128_mod(v, b))];
|
||||||
@@ -692,9 +692,9 @@ void i128_divide(i128 a, i128 b, i128 *quo_, i128 *rem_) {
|
|||||||
irem = i128_from_i64(r);
|
irem = i128_from_i64(r);
|
||||||
} else if (a.hi > 0 || b.hi > 0) {
|
} else if (a.hi > 0 || b.hi > 0) {
|
||||||
u128 q, r = {0};
|
u128 q, r = {0};
|
||||||
u128_divide(*cast(u128 *)&a, *cast(u128 *)&b, &q, &r);
|
u128_divide(bit_cast<u128>(a), bit_cast<u128>(b), &q, &r);
|
||||||
iquo = *cast(i128 *)&q;
|
iquo = bit_cast<i128>(q);
|
||||||
irem = *cast(i128 *)&r;
|
irem = bit_cast<i128>(r);
|
||||||
} else if (i128_eq(b, I128_ZERO)) {
|
} else if (i128_eq(b, I128_ZERO)) {
|
||||||
iquo = i128_from_u64(a.lo/b.lo);
|
iquo = i128_from_u64(a.lo/b.lo);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -595,7 +595,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
case ExactValue_Float: {
|
case ExactValue_Float: {
|
||||||
GB_ASSERT_MSG(is_type_float(type), "%s", type_to_string(type));
|
GB_ASSERT_MSG(is_type_float(type), "%s", type_to_string(type));
|
||||||
type = core_type(type);
|
type = core_type(type);
|
||||||
u64 u = *cast(u64*)&value.value_float;
|
u64 u = bit_cast<u64>(value.value_float);
|
||||||
switch (type->Basic.kind) {
|
switch (type->Basic.kind) {
|
||||||
case Basic_f32:
|
case Basic_f32:
|
||||||
// IMPORTANT NOTE(bill): LLVM requires all floating point constants to be
|
// IMPORTANT NOTE(bill): LLVM requires all floating point constants to be
|
||||||
|
|||||||
+1
-1
@@ -72,7 +72,7 @@ gb_inline HashKey hash_integer(u64 u) {
|
|||||||
}
|
}
|
||||||
gb_inline HashKey hash_f64(f64 f) {
|
gb_inline HashKey hash_f64(f64 f) {
|
||||||
HashKey h = {HashKey_Default};
|
HashKey h = {HashKey_Default};
|
||||||
h.key = *cast(u64 *)&f;
|
h.key = bit_cast<u64>(f);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+26
-8
@@ -254,7 +254,7 @@ void syntax_error_va(Token token, char *fmt, va_list va) {
|
|||||||
LIT(token.pos.file), token.pos.line, token.pos.column,
|
LIT(token.pos.file), token.pos.line, token.pos.column,
|
||||||
gb_bprintf_va(fmt, va));
|
gb_bprintf_va(fmt, va));
|
||||||
} else if (token.pos.line == 0) {
|
} else if (token.pos.line == 0) {
|
||||||
gb_printf_err("Error: %s\n", gb_bprintf_va(fmt, va));
|
gb_printf_err("Syntax Error: %s\n", gb_bprintf_va(fmt, va));
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_mutex_unlock(&global_error_collector.mutex);
|
gb_mutex_unlock(&global_error_collector.mutex);
|
||||||
@@ -401,15 +401,15 @@ void tokenizer_err(Tokenizer *t, char *msg, ...) {
|
|||||||
if (column < 1) {
|
if (column < 1) {
|
||||||
column = 1;
|
column = 1;
|
||||||
}
|
}
|
||||||
|
Token token = {};
|
||||||
gb_printf_err("%.*s(%td:%td) Syntax error: ", LIT(t->fullpath), t->line_count, column);
|
token.pos.file = t->fullpath;
|
||||||
|
token.pos.line = t->line_count;
|
||||||
|
token.pos.column = column;
|
||||||
|
|
||||||
va_start(va, msg);
|
va_start(va, msg);
|
||||||
gb_printf_err_va(msg, va);
|
syntax_error_va(token, msg, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
gb_printf_err("\n");
|
|
||||||
|
|
||||||
t->error_count++;
|
t->error_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,14 +577,32 @@ Token scan_number_to_token(Tokenizer *t, bool seen_decimal_point) {
|
|||||||
if (t->curr - prev <= 2) {
|
if (t->curr - prev <= 2) {
|
||||||
token.kind = Token_Invalid;
|
token.kind = Token_Invalid;
|
||||||
}
|
}
|
||||||
} /* else if (t->curr_rune == 'h') { // Hexadecimal Float
|
} else if (t->curr_rune == 'h') { // Hexadecimal Float
|
||||||
token.kind = Token_Float;
|
token.kind = Token_Float;
|
||||||
advance_to_next_rune(t);
|
advance_to_next_rune(t);
|
||||||
scan_mantissa(t, 16);
|
scan_mantissa(t, 16);
|
||||||
if (t->curr - prev <= 2) {
|
if (t->curr - prev <= 2) {
|
||||||
token.kind = Token_Invalid;
|
token.kind = Token_Invalid;
|
||||||
|
} else {
|
||||||
|
u8 *start = prev+2;
|
||||||
|
isize n = t->curr - start;
|
||||||
|
isize digit_count = 0;
|
||||||
|
for (isize i = 0; i < n; i++) {
|
||||||
|
if (start[i] != '_') {
|
||||||
|
digit_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (digit_count) {
|
||||||
|
case 8:
|
||||||
|
case 16:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tokenizer_err(t, "Invalid hexadecimal float, expected 8 or 16 digits, got %td", digit_count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} */ else {
|
|
||||||
|
} else {
|
||||||
seen_decimal_point = false;
|
seen_decimal_point = false;
|
||||||
scan_mantissa(t, 10);
|
scan_mantissa(t, 10);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user