1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: fix comptime interpolation (#18281)

This commit is contained in:
Felipe Pena 2023-05-27 15:41:40 -03:00 committed by GitHub
parent 43bc85d3bb
commit 6bfa6ec93c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 11 deletions

View File

@ -46,7 +46,7 @@ fn (mut g Gen) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 {
}
}
fn (mut g Gen) str_format(node ast.StringInterLiteral, i int) (u64, string) {
fn (mut g Gen) str_format(node ast.StringInterLiteral, i int, fmts []u8) (u64, string) {
mut base := 0 // numeric base
mut upper_case := false // set upercase for the result string
mut typ := g.unwrap_generic(node.expr_types[i])
@ -59,7 +59,7 @@ fn (mut g Gen) str_format(node ast.StringInterLiteral, i int) (u64, string) {
typ = (sym.info as ast.Alias).parent_type
}
mut remove_tail_zeros := false
fspec := node.fmts[i]
fspec := fmts[i]
mut fmt_type := StrIntpType.si_no_str
g.write('/*${fspec} ${sym}*/')
// upper cases
@ -159,9 +159,9 @@ fn (mut g Gen) str_format(node ast.StringInterLiteral, i int) (u64, string) {
return res, fmt_type.str()
}
fn (mut g Gen) str_val(node ast.StringInterLiteral, i int) {
fn (mut g Gen) str_val(node ast.StringInterLiteral, i int, fmts []u8) {
expr := node.exprs[i]
fmt := fmts[i]
typ := g.unwrap_generic(node.expr_types[i])
typ_sym := g.table.sym(typ)
if typ == ast.string_type && g.comptime_for_method.len == 0 {
@ -187,7 +187,7 @@ fn (mut g Gen) str_val(node ast.StringInterLiteral, i int) {
g.expr(expr)
g.write('${dot}_object')
g.write(')')
} else if node.fmts[i] == `s` || typ.has_flag(.variadic) {
} else if fmt == `s` || typ.has_flag(.variadic) {
mut exp_typ := typ
if expr is ast.Ident {
if expr.obj is ast.Var {
@ -203,8 +203,8 @@ fn (mut g Gen) str_val(node ast.StringInterLiteral, i int) {
}
}
g.gen_expr_to_string(expr, exp_typ)
} else if typ.is_number() || typ.is_pointer() || node.fmts[i] == `d` {
if typ.is_signed() && node.fmts[i] in [`x`, `X`, `o`] {
} else if typ.is_number() || typ.is_pointer() || fmt == `d` {
if typ.is_signed() && fmt in [`x`, `X`, `o`] {
// convert to unsigned first befors C's integer propagation strikes
if typ == ast.i8_type {
g.write('(byte)(')
@ -237,6 +237,7 @@ fn (mut g Gen) str_val(node ast.StringInterLiteral, i int) {
fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
// fn (mut g Gen) str_int2(node ast.StringInterLiteral) {
mut node_ := unsafe { node }
mut fmts := node_.fmts.clone()
for i, mut expr in node_.exprs {
if g.is_comptime_var(expr) {
ctyp := g.get_comptime_var_type(expr)
@ -249,7 +250,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
} else {
ctyp
}
node_.fmts[i] = g.get_default_fmt(ctyp, typ)
fmts[i] = g.get_default_fmt(ctyp, typ)
}
}
}
@ -271,16 +272,16 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
break
}
ft_u64, ft_str := g.str_format(node, i)
ft_u64, ft_str := g.str_format(node, i, fmts)
g.write('0x${ft_u64.hex()}, {.d_${ft_str} = ')
// for pointers we need a void* cast
if unsafe { ft_str.str[0] } == `p` {
g.write('(void*)(')
g.str_val(node, i)
g.str_val(node, i, fmts)
g.write(')')
} else {
g.str_val(node, i)
g.str_val(node, i, fmts)
}
g.write('}}')

View File

@ -0,0 +1,27 @@
struct Foo {
a int
b f32
c string
}
fn print_struct[T](x &T) []string {
mut a := []string{}
$for field in T.fields {
typ := typeof((*x).$(field.name)).name
val := (*x).$(field.name)
a << '${field.name} (${typ}) = ${val}'
}
return a
}
fn test_main() {
foo := Foo{
a: 123
b: 4.56
c: 'hello'
}
out := print_struct(&foo)
assert out[0] == 'a (int) = 123'
assert out[1] == 'b (f32) = 4.56'
assert out[2] == 'c (string) = hello'
}