cgen: hex representation of signed and pointers

pull/4720/head
Uwe Krüger 2020-05-05 00:24:33 +02:00 committed by GitHub
parent 081338b8bf
commit a4b6c3fa5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 7 deletions

View File

@ -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) {

View File

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

View File

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

View File

@ -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() {