cgen: hex representation of signed and pointers
parent
081338b8bf
commit
a4b6c3fa5d
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue