From a4b6c3fa5daf84134451eff7f33e75f30d607869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kr=C3=BCger?= <45282134+UweKrueger@users.noreply.github.com> Date: Tue, 5 May 2020 00:24:33 +0200 Subject: [PATCH] cgen: hex representation of signed and pointers --- vlib/v/gen/cgen.v | 36 +++++++++++++++++++----- vlib/v/gen/str.v | 2 ++ vlib/v/table/atypes.v | 6 ++++ vlib/v/tests/string_interpolation_test.v | 9 ++++++ 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 64099f5cf0..1c4b449239 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2368,8 +2368,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { mut fmt := '' // field width and precision if sfmt.len > 0 { // analyze and validate format specifier - if sfmt[sfmt.len - 1] in [`E`, `F`, `G`, `e`, `f`, `g`, `e`, - `d`, `u`, `x`, `X`, `o`, `c`, `s`] { + if sfmt[sfmt.len - 1] in [`E`, `F`, `G`, `e`, `f`, `g`, + `d`, `u`, `x`, `X`, `o`, `c`, `s`, `p`] { fspec = sfmt[sfmt.len - 1] } fmt = if fspec == `_` { @@ -2385,6 +2385,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { fspec = `d` } else if node.expr_types[i].is_unsigned() { fspec = `u` + } else if node.expr_types[i].is_pointer() { + fspec = `p` } else if node.expr_types[i] in [table.string_type, table.bool_type] || sym.kind in [.enum_, .array, .array_fixed, .struct_, .map] || g.typ(node.expr_types[i]).starts_with('Option') || sym.has_method('str') { @@ -2400,8 +2402,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { if fields.len > 2 || fields.len == 2 && !(node.expr_types[i].is_float()) || node.expr_types[i].is_signed() && !(fspec in [`d`, `c`, `x`, `X`, `o`]) || node.expr_types[i].is_unsigned() && !(fspec in [`u`, `x`, `X`, `o`, `c`]) || node.expr_types[i].is_float() && !(fspec in [`E`, `F`, `G`, - `e`, `f`, - `g`, `e`]) { + `e`, `f`, `g`]) || node.expr_types[i].is_pointer() && !(fspec in [`p`, `x`, `X`]) { verror('illegal format specifier ${fspec:c} for type ${g.table.get_type_name(node.expr_types[i])}') } // make sure that format paramters are valid numbers @@ -2427,8 +2428,14 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { } else { g.write('*.*s') } - } else if node.expr_types[i].is_float() { + } else if node.expr_types[i].is_float() || node.expr_types[i].is_pointer() { g.write('$fmt${fspec:c}') + } else if node.expr_types[i].is_pointer() { + if fspec == `p` { + g.write('${fmt}p') + } else { + g.write('${fmt}l${fspec:c}') + } } else if node.expr_types[i].is_int() { if fspec == `c` { if node.expr_types[i].idx() in [table.i64_type_idx, table.f64_type_idx] { @@ -2463,8 +2470,23 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { } else if node.expr_types[i] == table.bool_type { g.expr(expr) g.write(' ? _SLIT("true") : _SLIT("false")') - } else if node.expr_types[i].is_number() || specs[i] == `d` { - g.expr(expr) + } else if node.expr_types[i].is_number() || node.expr_types[i].is_pointer() || specs[i] == `d` { + if node.expr_types[i].is_signed() && specs[i] in [`x`, `X`, `o`] { + // convert to unsigned first befors C's integer propagation strikes + if node.expr_types[i] == table.i8_type { + g.write('(byte)(') + } else if node.expr_types[i] == table.i16_type { + g.write('(u16)(') + } else if node.expr_types[i] == table.int_type { + g.write('(u32)(') + } else { + g.write('(u64)(') + } + g.expr(expr) + g.write(')') + } else { + g.expr(expr) + } } else if specs[i] == `s` { sym := g.table.get_type_symbol(node.expr_types[i]) if node.expr_types[i].flag_is(.variadic) { diff --git a/vlib/v/gen/str.v b/vlib/v/gen/str.v index 820e4377d7..4bf44d11df 100644 --- a/vlib/v/gen/str.v +++ b/vlib/v/gen/str.v @@ -52,6 +52,8 @@ string _STR(const char *fmt, int nfmts, ...) { else _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+8, va_arg(argptr, int)); } else if (fup >= 'E' && fup <= 'G') { // floating point _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+10, va_arg(argptr, double)); + } else if (f == 'p') { + _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+14, va_arg(argptr, void*)); } else if (f == 's') { // v string string s = va_arg(argptr, string); if (fmt[k-4] == '*') { // %*.*s diff --git a/vlib/v/table/atypes.v b/vlib/v/table/atypes.v index 90c135a009..f1507f927d 100644 --- a/vlib/v/table/atypes.v +++ b/vlib/v/table/atypes.v @@ -130,6 +130,12 @@ pub fn new_type_ptr(idx, nr_muls int) Type { return (nr_muls << 16) | u16(idx) } +// built in pointers (voidptr, byteptr, charptr) +[inline] +pub fn (typ Type) is_pointer() bool { + return typ.idx() in pointer_type_idxs +} + [inline] pub fn (typ Type) is_float() bool { return typ.idx() in float_type_idxs diff --git a/vlib/v/tests/string_interpolation_test.v b/vlib/v/tests/string_interpolation_test.v index e62fcefb77..bc076c2501 100644 --- a/vlib/v/tests/string_interpolation_test.v +++ b/vlib/v/tests/string_interpolation_test.v @@ -79,10 +79,13 @@ fn test_string_interpolation_string_prefix() { fn test_inttypes_string_interpolation() { c := i8(-103) uc := byte(217) + uc2 := byte(13) s := i16(-23456) us := u16(54321) i := -1622999040 ui := u32(3421958087) + vp := voidptr(ui) + bp := byteptr(15541149836) l := i64(-7694555558525237396) ul := u64(17234006112912956370) assert '$s $us' == '-23456 54321' @@ -91,6 +94,12 @@ fn test_inttypes_string_interpolation() { assert '>${s:11}:${us:-13}<' == '> -23456:54321 <' assert '0x${ul:-19x}:${l:22d}' == '0xef2b7d4001165bd2 : -7694555558525237396' assert '${c:5}${uc:-7}x' == ' -103217 x' + assert '${c:x}:${uc:x}:${uc2:02X}' == '99:d9:0D' + assert '${s:X}:${us:x}:${u16(uc):04x}' == 'A460:d431:00d9' + assert '${i:x}:${ui:X}:${int(s):x}' == '9f430000:CBF6EFC7:ffffa460' + assert '${l:x}:${ul:X}' == '9537727cad98876c:EF2B7D4001165BD2' + // TODO this does not work on Windows + // assert '${vp:p}:$bp' == '0xcbf6efc7:0x39e53208c' } fn test_utf8_string_interpolation() {