Browse Source

Improve #assert to show the procedure and signature it was called with; Allow the ability to print ExactValue correct now.

gingerBill 6 years ago
parent
commit
cf23954297
4 changed files with 179 additions and 25 deletions
  1. 8 1
      src/check_expr.cpp
  2. 46 0
      src/exact_value.cpp
  3. 83 1
      src/string.cpp
  4. 42 23
      src/types.cpp

+ 8 - 1
src/check_expr.cpp

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

+ 46 - 0
src/exact_value.cpp

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

+ 83 - 1
src/string.cpp

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

+ 42 - 23
src/types.cpp

@@ -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 (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 {
+						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 (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->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 {
-						GB_ASSERT(var->kind == Entity_TypeName);
-						if (var->type->kind == Type_Generic) {
-							str = gb_string_appendc(str, "type/");
+						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");
 						}
 					}
 				}