mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-31 18:32:12 +00:00
Improve #assert to show the procedure and signature it was called with; Allow the ability to print ExactValue correct now.
This commit is contained in:
@@ -3360,6 +3360,11 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
|
||||
if (!operand->value.value_bool) {
|
||||
gbString arg = expr_to_string(ce->args[0]);
|
||||
error(call, "Compile time assertion: %s", arg);
|
||||
if (c->proc_name != "") {
|
||||
gbString str = type_to_string(c->curr_proc_sig);
|
||||
error_line("\tCalled within '%.*s' :: %s\n", LIT(c->proc_name), str);
|
||||
gb_string_free(str);
|
||||
}
|
||||
gb_string_free(arg);
|
||||
}
|
||||
|
||||
@@ -3744,7 +3749,9 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
|
||||
}
|
||||
|
||||
if (x.mode == Addressing_Constant && y.mode == Addressing_Constant) {
|
||||
operand->value = exact_binary_operator_value(Token_Add, x.value, y.value);
|
||||
f64 r = exact_value_to_float(x.value).value_float;
|
||||
f64 i = exact_value_to_float(y.value).value_float;
|
||||
operand->value = exact_value_complex(r, i);
|
||||
operand->mode = Addressing_Constant;
|
||||
} else {
|
||||
operand->mode = Addressing_Value;
|
||||
|
||||
@@ -718,3 +718,49 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
||||
GB_PANIC("Invalid comparison");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Invalid:
|
||||
return str;
|
||||
case ExactValue_Bool:
|
||||
return gb_string_appendc(str, v.value_bool ? "true" : "false");
|
||||
case ExactValue_String: {
|
||||
String s = quote_to_ascii(heap_allocator(), v.value_string);
|
||||
string_limit = gb_max(string_limit, 36);
|
||||
if (s.len <= string_limit) {
|
||||
str = gb_string_append_length(str, s.text, s.len);
|
||||
} else {
|
||||
isize n = string_limit/5;
|
||||
str = gb_string_append_length(str, s.text, n);
|
||||
str = gb_string_append_fmt(str, "\"..%lld chars..\"", s.len-(2*n));
|
||||
str = gb_string_append_length(str, s.text+s.len-n, n);
|
||||
}
|
||||
gb_free(heap_allocator(), s.text);
|
||||
return str;
|
||||
}
|
||||
case ExactValue_Integer: {
|
||||
String s = big_int_to_string(heap_allocator(), &v.value_integer);
|
||||
str = gb_string_append_length(str, s.text, s.len);
|
||||
gb_free(heap_allocator(), s.text);
|
||||
return str;
|
||||
}
|
||||
case ExactValue_Float:
|
||||
return gb_string_append_fmt(str, "%f", v.value_float);
|
||||
case ExactValue_Complex:
|
||||
return gb_string_append_fmt(str, "%f+%fi", v.value_complex.real, v.value_complex.imag);
|
||||
|
||||
case ExactValue_Pointer:
|
||||
return str;
|
||||
case ExactValue_Compound:
|
||||
return str;
|
||||
case ExactValue_Procedure:
|
||||
return str;
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
gbString exact_value_to_string(ExactValue const &v, isize string_limit=35) {
|
||||
return write_exact_value_to_string(gb_string_make(heap_allocator(), ""), v, string_limit);
|
||||
}
|
||||
|
||||
@@ -440,12 +440,94 @@ String string16_to_string(gbAllocator a, String16 s) {
|
||||
|
||||
|
||||
|
||||
bool is_printable(Rune r) {
|
||||
if (r <= 0xff) {
|
||||
if (0x20 <= r && r <= 0x7e) {
|
||||
return true;
|
||||
}
|
||||
if (0xa1 <= r && r <= 0xff) {
|
||||
return r != 0xad;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gb_global char const lower_hex[] = "0123456789abcdef";
|
||||
|
||||
String quote_to_ascii(gbAllocator a, String str, u8 quote='"') {
|
||||
u8 *s = str.text;
|
||||
isize n = str.len;
|
||||
auto buf = array_make<u8>(a, 0, n);
|
||||
array_add(&buf, quote);
|
||||
for (isize width = 0; n > 0; s += width, n -= width) {
|
||||
Rune r = cast(Rune)s[0];
|
||||
width = 1;
|
||||
if (r >= 0x80) {
|
||||
width = gb_utf8_decode(s, n, &r);
|
||||
}
|
||||
if (width == 1 && r == GB_RUNE_INVALID) {
|
||||
array_add(&buf, cast(u8)'\\');
|
||||
array_add(&buf, cast(u8)'x');
|
||||
array_add(&buf, cast(u8)lower_hex[s[0]>>4]);
|
||||
array_add(&buf, cast(u8)lower_hex[s[0]&0xf]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (r == quote || r == '\\') {
|
||||
array_add(&buf, cast(u8)'\\');
|
||||
array_add(&buf, u8(r));
|
||||
continue;
|
||||
}
|
||||
if (r < 0x80 && is_printable(r)) {
|
||||
array_add(&buf, u8(r));
|
||||
continue;
|
||||
}
|
||||
switch (r) {
|
||||
case '\a':
|
||||
case '\b':
|
||||
case '\f':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case '\v':
|
||||
default:
|
||||
if (r < ' ') {
|
||||
u8 b = cast(u8)r;
|
||||
array_add(&buf, cast(u8)'\\');
|
||||
array_add(&buf, cast(u8)'x');
|
||||
array_add(&buf, cast(u8)lower_hex[b>>4]);
|
||||
array_add(&buf, cast(u8)lower_hex[b&0xf]);
|
||||
}
|
||||
if (r > GB_RUNE_MAX) {
|
||||
r = 0XFFFD;
|
||||
}
|
||||
if (r < 0x10000) {
|
||||
u8 b = cast(u8)r;
|
||||
array_add(&buf, cast(u8)'\\');
|
||||
array_add(&buf, cast(u8)'u');
|
||||
for (isize i = 12; i >= 0; i -= 4) {
|
||||
array_add(&buf, cast(u8)lower_hex[(r>>i)&0xf]);
|
||||
}
|
||||
} else {
|
||||
u8 b = cast(u8)r;
|
||||
array_add(&buf, cast(u8)'\\');
|
||||
array_add(&buf, cast(u8)'U');
|
||||
for (isize i = 28; i >= 0; i -= 4) {
|
||||
array_add(&buf, cast(u8)lower_hex[(r>>i)&0xf]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
array_add(&buf, quote);
|
||||
String res = {};
|
||||
res.text = buf.data;
|
||||
res.len = buf.count;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2968,35 +2968,54 @@ gbString write_type_to_string(gbString str, Type *type) {
|
||||
isize comma_index = 0;
|
||||
for_array(i, type->Tuple.variables) {
|
||||
Entity *var = type->Tuple.variables[i];
|
||||
if (var != nullptr) {
|
||||
if (var->kind == Entity_Constant) {
|
||||
// Ignore
|
||||
continue;
|
||||
}
|
||||
|
||||
if (comma_index++ > 0) {
|
||||
str = gb_string_appendc(str, ", ");
|
||||
}
|
||||
|
||||
if (var->kind == Entity_Variable) {
|
||||
if (var->flags&EntityFlag_CVarArg) {
|
||||
str = gb_string_appendc(str, "#c_vararg ");
|
||||
}
|
||||
if (var->flags&EntityFlag_Ellipsis) {
|
||||
Type *slice = base_type(var->type);
|
||||
str = gb_string_appendc(str, "..");
|
||||
GB_ASSERT(var->type->kind == Type_Slice);
|
||||
str = write_type_to_string(str, slice->Slice.elem);
|
||||
} else {
|
||||
str = write_type_to_string(str, var->type);
|
||||
}
|
||||
if (var == nullptr) {
|
||||
continue;
|
||||
}
|
||||
String name = var->token.string;
|
||||
if (var->kind == Entity_Constant) {
|
||||
str = gb_string_appendc(str, "$");
|
||||
str = gb_string_append_length(str, name.text, name.len);
|
||||
if (!is_type_untyped(var->type)) {
|
||||
str = gb_string_appendc(str, ": ");
|
||||
str = write_type_to_string(str, var->type);
|
||||
str = gb_string_appendc(str, " = ");
|
||||
str = write_exact_value_to_string(str, var->Constant.value);
|
||||
} else {
|
||||
GB_ASSERT(var->kind == Entity_TypeName);
|
||||
if (var->type->kind == Type_Generic) {
|
||||
str = gb_string_appendc(str, "type/");
|
||||
str = gb_string_appendc(str, "=");
|
||||
str = write_exact_value_to_string(str, var->Constant.value);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (comma_index++ > 0) {
|
||||
str = gb_string_appendc(str, ", ");
|
||||
}
|
||||
|
||||
if (var->kind == Entity_Variable) {
|
||||
if (var->flags&EntityFlag_CVarArg) {
|
||||
str = gb_string_appendc(str, "#c_vararg ");
|
||||
}
|
||||
if (var->flags&EntityFlag_Ellipsis) {
|
||||
Type *slice = base_type(var->type);
|
||||
str = gb_string_appendc(str, "..");
|
||||
GB_ASSERT(var->type->kind == Type_Slice);
|
||||
str = write_type_to_string(str, slice->Slice.elem);
|
||||
} else {
|
||||
str = write_type_to_string(str, var->type);
|
||||
}
|
||||
} else {
|
||||
GB_ASSERT(var->kind == Entity_TypeName);
|
||||
if (var->type->kind == Type_Generic) {
|
||||
str = gb_string_appendc(str, "typeid/");
|
||||
str = write_type_to_string(str, var->type);
|
||||
} else {
|
||||
if (var->kind == Entity_TypeName) {
|
||||
str = gb_string_appendc(str, "$");
|
||||
str = gb_string_append_length(str, name.text, name.len);
|
||||
str = gb_string_appendc(str, "=");
|
||||
str = write_type_to_string(str, var->type);
|
||||
} else {
|
||||
str = gb_string_appendc(str, "type");
|
||||
str = gb_string_appendc(str, "typeid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user