all: string interpolation code cleaning (#10204)
parent
5e26273529
commit
2dd1d3fcbb
|
@ -637,13 +637,11 @@ pub const (
|
|||
si_g64_code = '0xfe0f'
|
||||
)
|
||||
|
||||
// replace _STR("\'%.*s\\000\'", 2, in_str)
|
||||
[inline]
|
||||
pub fn str_intp_sq(in_str string) string {
|
||||
return 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("\'"), $si_s_code, {.d_s = $in_str}},{_SLIT("\'"), 0, {.d_c = 0 }}}))'
|
||||
}
|
||||
|
||||
// replace _STR("\`%.*s\\000\`", 2, in_str)
|
||||
[inline]
|
||||
pub fn str_intp_rune(in_str string) string {
|
||||
return 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("\`"), $si_s_code, {.d_s = $in_str}},{_SLIT("\`"), 0, {.d_c = 0 }}}))'
|
||||
|
@ -660,15 +658,25 @@ pub fn str_intp_g64(in_str string) string {
|
|||
}
|
||||
|
||||
// replace %% with the in_str
|
||||
[manualfree]
|
||||
pub fn str_intp_sub(base_str string, in_str string) string {
|
||||
index := base_str.index('%%') or {
|
||||
eprintln('No strin interpolation %% parameteres')
|
||||
exit(1)
|
||||
}
|
||||
// return base_str[..index] + in_str + base_str[index+2..]
|
||||
if index + 2 < base_str.len {
|
||||
return 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("${base_str[..index]}"), $si_s_code, {.d_s = $in_str }},{_SLIT("${base_str[
|
||||
index + 2..]}"), 0, {.d_c = 0}}}))'
|
||||
|
||||
unsafe {
|
||||
st_str := base_str[..index]
|
||||
if index + 2 < base_str.len {
|
||||
en_str := base_str[index + 2..]
|
||||
res_str := 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("$st_str"), $si_s_code, {.d_s = $in_str }},{_SLIT("$en_str"), 0, {.d_c = 0}}}))'
|
||||
st_str.free()
|
||||
en_str.free()
|
||||
return res_str
|
||||
}
|
||||
res2_str := 'str_intp(1, _MOV((StrIntpData[]){{_SLIT("$st_str"), $si_s_code, {.d_s = $in_str }}}))'
|
||||
st_str.free()
|
||||
return res2_str
|
||||
}
|
||||
return 'str_intp(1, _MOV((StrIntpData[]){{_SLIT("${base_str[..index]}"), $si_s_code, {.d_s = $in_str }}}))'
|
||||
}
|
||||
|
|
|
@ -59,17 +59,11 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string
|
|||
} else {
|
||||
g.auto_str_funcs.writeln('\t\tstring x = ${str_intp_g64('it')};')
|
||||
}
|
||||
|
||||
// g.auto_str_funcs.writeln('\t\tstring x = _STR("%g", 1, it);')
|
||||
} else if sym.kind == .rune {
|
||||
// Rune are managed at this level as strings
|
||||
g.auto_str_funcs.writeln('\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_SLIT("\`"), $si_s_code, {.d_s = ${elem_str_fn_name}(it) }}, {_SLIT("\`"), 0, {.d_c = 0 }}}));\n')
|
||||
|
||||
// g.auto_str_funcs.writeln('\t\tstring x = _STR("`%.*s\\000`", 2, ${elem_str_fn_name}(it));')
|
||||
} else if sym.kind == .string {
|
||||
g.auto_str_funcs.writeln('\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_SLIT("\'"), $si_s_code, {.d_s = it }}, {_SLIT("\'"), 0, {.d_c = 0 }}}));\n')
|
||||
|
||||
// g.auto_str_funcs.writeln('\t\tstring x = _STR("\'%.*s\\000\'", 2, it);')
|
||||
} else {
|
||||
// There is a custom .str() method, so use it.
|
||||
// NB: we need to take account of whether the user has defined
|
||||
|
@ -146,14 +140,11 @@ fn (mut g Gen) gen_str_for_array_fixed(info ast.ArrayFixed, styp string, str_fn_
|
|||
} else {
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${str_intp_g64('a[i]')} );')
|
||||
}
|
||||
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("%g", 1, a[i]));')
|
||||
} else if sym.kind == .string {
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${str_intp_sq('a[i]')});')
|
||||
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("\'%.*s\\000\'", 2, a[i]));')
|
||||
} else if sym.kind == .rune {
|
||||
tmp_str := str_intp_rune('${elem_str_fn_name}( $deref a[i])')
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, $tmp_str);')
|
||||
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("`%.*s\\000`", 2, ${elem_str_fn_name}(a[i])));')
|
||||
} else {
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${elem_str_fn_name}( $deref a[i]));')
|
||||
}
|
||||
|
|
|
@ -46,11 +46,9 @@ fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) {
|
|||
}
|
||||
if key_sym.kind == .string {
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${str_intp_sq('key')});')
|
||||
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("\'%.*s\\000\'", 2, key));')
|
||||
} else if key_sym.kind == .rune {
|
||||
tmp_str := str_intp_rune('${key_str_fn_name}(key)')
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, $tmp_str);')
|
||||
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("`%.*s\\000`", 2, ${key_str_fn_name}(key)));')
|
||||
} else {
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${key_str_fn_name}(key));')
|
||||
}
|
||||
|
@ -60,7 +58,6 @@ fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) {
|
|||
} else if val_sym.kind == .string {
|
||||
tmp_str := str_intp_sq('*($val_styp*)DenseArray_value(&m.key_values, i)')
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, $tmp_str);')
|
||||
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("\'%.*s\\000\'", 2, *($val_styp*)DenseArray_value(&m.key_values, i)));')
|
||||
} else if should_use_indent_func(val_sym.kind) && !val_sym.has_method('str') {
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, indent_${elem_str_fn_name}(*($val_styp*)DenseArray_value(&m.key_values, i), indent_count));')
|
||||
} else if val_sym.kind in [.f32, .f64] {
|
||||
|
@ -70,11 +67,9 @@ fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) {
|
|||
} else {
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${str_intp_g64(tmp_val)});')
|
||||
}
|
||||
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("%g", 1, *($val_styp*)DenseArray_value(&m.key_values, i)));')
|
||||
} else if val_sym.kind == .rune {
|
||||
tmp_str := str_intp_rune('${elem_str_fn_name}(*($val_styp*)DenseArray_value(&m.key_values, i))')
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, $tmp_str);')
|
||||
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("`%.*s\\000`", 2, ${elem_str_fn_name}(*($val_styp*)DenseArray_value(&m.key_values, i))));')
|
||||
} else {
|
||||
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${elem_str_fn_name}(*($val_styp*)DenseArray_value(&m.key_values, i)));')
|
||||
}
|
||||
|
|
|
@ -201,7 +201,6 @@ fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string)
|
|||
if sym.kind == .string {
|
||||
tmp_res := '${parent_str_fn_name}(*($sym.cname*)it.data)'
|
||||
g.auto_str_funcs.writeln('\t\tres = ${str_intp_sq(tmp_res)};')
|
||||
// g.auto_str_funcs.writeln('\t\tres = _STR("\'%.*s\\000\'", 2, ${parent_str_fn_name}(*($sym.cname*)it.data));')
|
||||
} else if should_use_indent_func(sym.kind) && !sym_has_str_method {
|
||||
g.auto_str_funcs.writeln('\t\tres = indent_${parent_str_fn_name}(*($sym.cname*)it.data, indent_count);')
|
||||
} else {
|
||||
|
@ -211,12 +210,9 @@ fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string)
|
|||
|
||||
tmp_str := str_intp_sub('error: %%', 'IError_str(it.err)')
|
||||
g.auto_str_funcs.writeln('\t\tres = $tmp_str;')
|
||||
// g.auto_str_funcs.writeln('\t\tres = _STR("error: %.*s\\000", 2, IError_str(it.err));')
|
||||
|
||||
g.auto_str_funcs.writeln('\t}')
|
||||
|
||||
g.auto_str_funcs.writeln('\treturn ${str_intp_sub('Option(%%)', 'res')};')
|
||||
// g.auto_str_funcs.writeln('\treturn _STR("Option(%.*s\\000)", 2, res);')
|
||||
g.auto_str_funcs.writeln('}')
|
||||
}
|
||||
|
||||
|
@ -243,8 +239,6 @@ fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string
|
|||
{_SLIT(")"), 0, {.d_c = 0 }}
|
||||
}));\n')
|
||||
|
||||
// g.auto_str_funcs.writeln('\treturn _STR("%.*s\\000${clean_type_v_type_name}(%.*s\\000)", 3, indents, ${parent_str_fn_name}(it));')
|
||||
|
||||
g.auto_str_funcs.writeln('}')
|
||||
}
|
||||
|
||||
|
@ -284,11 +278,9 @@ fn (mut g Gen) gen_str_for_multi_return(info ast.MultiReturn, styp string, str_f
|
|||
tmp_val := str_intp_g64('a.arg$i')
|
||||
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, $tmp_val);')
|
||||
}
|
||||
// g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _STR("%g", 1, a.arg$i));')
|
||||
} else if sym.kind == .string {
|
||||
tmp_str := str_intp_sq('a.arg$i')
|
||||
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, $tmp_str);')
|
||||
// g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _STR("\'%.*s\\000\'", 2, a.arg$i));')
|
||||
} else if sym.kind == .function {
|
||||
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, ${arg_str_fn_name}());')
|
||||
} else {
|
||||
|
@ -402,21 +394,6 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_nam
|
|||
g.auto_str_funcs.write_string('\tif (x._typ == _${styp}_${subtype.cname}_index)')
|
||||
g.auto_str_funcs.write_string(' return $res;\n')
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
/*
|
||||
deref := if sym_has_str_method && str_method_expects_ptr { ' ' } else { '*' }
|
||||
value_fmt := if typ == ast.string_type { "'%.*s\\000'" } else { '%.*s\\000' }
|
||||
|
||||
g.auto_str_funcs.write_string('\tif (x._typ == _${styp}_${subtype.cname}_index)')
|
||||
g.auto_str_funcs.write_string(' return _STR("${clean_interface_v_type_name}($value_fmt)", 2, ')
|
||||
g.auto_str_funcs.write_string('${func_name}(${deref}($subtype.cname*)x._$subtype.cname')
|
||||
if should_use_indent_func(subtype.kind) && !sym_has_str_method {
|
||||
g.auto_str_funcs.write_string(', indent_count')
|
||||
}
|
||||
g.auto_str_funcs.writeln('));\n')
|
||||
*/
|
||||
//------------------------------------------
|
||||
}
|
||||
g.auto_str_funcs.writeln('\treturn _SLIT("unknown interface value");')
|
||||
g.auto_str_funcs.writeln('}')
|
||||
|
@ -482,20 +459,6 @@ fn (mut g Gen) gen_str_for_union_sum_type(info ast.SumType, styp string, str_fn_
|
|||
}))'
|
||||
g.auto_str_funcs.write_string('\t\tcase $typ: return $res;')
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
/*
|
||||
mut value_fmt := '%.*s\\000'
|
||||
if typ == ast.string_type {
|
||||
value_fmt = "'$value_fmt'"
|
||||
}
|
||||
g.auto_str_funcs.write_string('\t\tcase $typ: return _STR("${clean_sum_type_v_type_name}($value_fmt)", 2, ${func_name}(${deref}($typ_str*)x._$sym.cname')
|
||||
if should_use_indent_func(sym.kind) && !sym_has_str_method {
|
||||
g.auto_str_funcs.write_string(', indent_count')
|
||||
}
|
||||
g.auto_str_funcs.writeln('));')
|
||||
*/
|
||||
//------------------------------------------
|
||||
}
|
||||
g.auto_str_funcs.writeln('\t\tdefault: return _SLIT("unknown sum type value");')
|
||||
g.auto_str_funcs.writeln('\t}')
|
||||
|
|
|
@ -212,176 +212,3 @@ fn struct_auto_str_func1(sym &ast.TypeSymbol, field_type ast.Type, fn_name strin
|
|||
return method_str
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// OLD CODE
|
||||
//=============================================================================
|
||||
/*
|
||||
fn (g &Gen) type_to_fmt(typ ast.Type) string {
|
||||
if typ == ast.byte_type_idx {
|
||||
return '%hhx\\000'
|
||||
}
|
||||
if typ == ast.char_type_idx {
|
||||
return '%c\\000'
|
||||
}
|
||||
if typ == ast.voidptr_type_idx || typ in ast.byteptr_types {
|
||||
return '%p\\000'
|
||||
}
|
||||
if typ in ast.charptr_types {
|
||||
return '%C\\000' // a C string
|
||||
}
|
||||
sym := g.table.get_type_symbol(typ)
|
||||
if typ.is_ptr() && (typ.is_int_valptr() || typ.is_float_valptr()) {
|
||||
return '%.*s\\000'
|
||||
} else if sym.kind in [.struct_, .array, .array_fixed, .map, .bool, .enum_, .interface_,
|
||||
.sum_type, .function, .alias] {
|
||||
return '%.*s\\000'
|
||||
} else if sym.kind == .string {
|
||||
return "'%.*s\\000'"
|
||||
} else if sym.kind in [.f32, .f64] {
|
||||
return '%g\\000' // g removes trailing zeros unlike %f
|
||||
} else if sym.kind == .int {
|
||||
return '%d\\000'
|
||||
} else if sym.kind == .u32 {
|
||||
return '%u\\000'
|
||||
} else if sym.kind == .u64 {
|
||||
return '%llu\\000'
|
||||
} else if sym.kind == .i64 {
|
||||
return '%lld\\000'
|
||||
}
|
||||
return '%d\\000'
|
||||
}
|
||||
|
||||
fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name string) {
|
||||
|
||||
//g.gen_str_for_struct1(info, styp, str_fn_name)
|
||||
|
||||
// TODO: short it if possible
|
||||
// generates all definitions of substructs
|
||||
mut fnames2strfunc := map{
|
||||
'': ''
|
||||
}
|
||||
for field in info.fields {
|
||||
sym := g.table.get_type_symbol(field.typ)
|
||||
if !sym.has_method('str') {
|
||||
mut typ := field.typ
|
||||
if typ.is_ptr() {
|
||||
typ = typ.deref()
|
||||
}
|
||||
field_styp := g.typ(typ)
|
||||
field_fn_name := g.gen_str_for_type(field.typ)
|
||||
fnames2strfunc[field_styp] = field_fn_name
|
||||
}
|
||||
}
|
||||
// _str() functions should have a single argument, the indenting ones take 2:
|
||||
g.type_definitions.writeln('static string ${str_fn_name}($styp it); // auto')
|
||||
g.auto_str_funcs.writeln('static string ${str_fn_name}($styp it) { return indent_${str_fn_name}(it, 0);}')
|
||||
g.type_definitions.writeln('static string indent_${str_fn_name}($styp it, int indent_count); // auto')
|
||||
g.auto_str_funcs.writeln('static string indent_${str_fn_name}($styp it, int indent_count) {')
|
||||
mut clean_struct_v_type_name := styp.replace('__', '.')
|
||||
if clean_struct_v_type_name.contains('_T_') {
|
||||
// TODO: this is a bit hacky. styp shouldn't be even parsed with _T_
|
||||
// use something different than g.typ for styp
|
||||
clean_struct_v_type_name =
|
||||
clean_struct_v_type_name.replace('Array_', '[]').replace('_T_', '<').replace('_', ', ') +
|
||||
'>'
|
||||
}
|
||||
clean_struct_v_type_name = util.strip_main_name(clean_struct_v_type_name)
|
||||
// generate ident / indent length = 4 spaces
|
||||
g.auto_str_funcs.writeln('\tstring indents = _SLIT("");')
|
||||
g.auto_str_funcs.writeln('\tfor (int i = 0; i < indent_count; ++i) {')
|
||||
g.auto_str_funcs.writeln('\t\tindents = string__plus(indents, _SLIT(" "));')
|
||||
g.auto_str_funcs.writeln('\t}')
|
||||
if info.fields.len == 0 {
|
||||
g.auto_str_funcs.write_string('\treturn _SLIT("$clean_struct_v_type_name{}");')
|
||||
} else {
|
||||
g.auto_str_funcs.write_string('\treturn _STR("$clean_struct_v_type_name{\\n"')
|
||||
for field in info.fields {
|
||||
mut fmt := if field.typ.is_ptr() { '&' } else { '' }
|
||||
fmt += g.type_to_fmt(field.typ)
|
||||
g.auto_str_funcs.writeln('\t\t"%.*s\\000 $field.name: $fmt\\n"')
|
||||
}
|
||||
g.auto_str_funcs.write_string('\t\t"%.*s\\000}", ${2 * (info.fields.len + 1)}')
|
||||
if info.fields.len > 0 {
|
||||
g.auto_str_funcs.write_string(',\n\t\t')
|
||||
for i, field in info.fields {
|
||||
sym := g.table.get_type_symbol(field.typ)
|
||||
has_custom_str := sym.has_method('str')
|
||||
mut field_styp := g.typ(field.typ).replace('*', '')
|
||||
field_styp_fn_name := if has_custom_str {
|
||||
'${field_styp}_str'
|
||||
} else {
|
||||
fnames2strfunc[field_styp]
|
||||
}
|
||||
g.auto_str_funcs.write_string('indents, ')
|
||||
mut func := struct_auto_str_func(sym, field.typ, field_styp_fn_name, field.name)
|
||||
// reference types can be "nil"
|
||||
if field.typ.is_ptr() && !(field.typ in ast.charptr_types
|
||||
|| field.typ in ast.byteptr_types
|
||||
|| field.typ == ast.voidptr_type_idx) {
|
||||
g.auto_str_funcs.write_string('isnil(it.${c_name(field.name)})')
|
||||
g.auto_str_funcs.write_string(' ? _SLIT("nil") : ')
|
||||
// struct, floats and ints have a special case through the _str function
|
||||
if sym.kind != .struct_ && !field.typ.is_int_valptr()
|
||||
&& !field.typ.is_float_valptr() {
|
||||
g.auto_str_funcs.write_string('*')
|
||||
}
|
||||
}
|
||||
// handle circular ref type of struct to the struct itself
|
||||
if styp == field_styp {
|
||||
g.auto_str_funcs.write_string('_SLIT("<circular>")')
|
||||
} else {
|
||||
g.auto_str_funcs.write_string(func)
|
||||
}
|
||||
|
||||
if i < info.fields.len - 1 {
|
||||
g.auto_str_funcs.write_string(',\n\t\t')
|
||||
}
|
||||
}
|
||||
}
|
||||
g.auto_str_funcs.writeln(',')
|
||||
g.auto_str_funcs.writeln('\t\tindents);')
|
||||
}
|
||||
g.auto_str_funcs.writeln('}')
|
||||
}
|
||||
|
||||
fn struct_auto_str_func(sym &ast.TypeSymbol, field_type ast.Type, fn_name string, field_name string) string {
|
||||
has_custom_str, expects_ptr, _ := sym.str_method_info()
|
||||
if sym.kind == .enum_ {
|
||||
return '${fn_name}(it.${c_name(field_name)})'
|
||||
} else if should_use_indent_func(sym.kind) {
|
||||
mut obj := 'it.${c_name(field_name)}'
|
||||
if field_type.is_ptr() && !expects_ptr {
|
||||
obj = '*$obj'
|
||||
}
|
||||
if has_custom_str {
|
||||
return '${fn_name}($obj)'
|
||||
}
|
||||
return 'indent_${fn_name}($obj, indent_count + 1)'
|
||||
} else if sym.kind in [.array, .array_fixed, .map, .sum_type] {
|
||||
if has_custom_str {
|
||||
return '${fn_name}(it.${c_name(field_name)})'
|
||||
}
|
||||
return 'indent_${fn_name}(it.${c_name(field_name)}, indent_count + 1)'
|
||||
} else if sym.kind == .function {
|
||||
return '${fn_name}()'
|
||||
} else {
|
||||
mut method_str := 'it.${c_name(field_name)}'
|
||||
if sym.kind == .bool {
|
||||
method_str += ' ? _SLIT("true") : _SLIT("false")'
|
||||
} else if (field_type.is_int_valptr() || field_type.is_float_valptr())
|
||||
&& field_type.is_ptr() && !expects_ptr {
|
||||
// ptr int can be "nil", so this needs to be castet to a string
|
||||
fmt := if sym.kind in [.f32, .f64] {
|
||||
'%g\\000'
|
||||
} else if sym.kind == .u64 {
|
||||
'%lld\\000'
|
||||
} else {
|
||||
'%d\\000'
|
||||
}
|
||||
method_str = '_STR("$fmt", 2, *$method_str)'
|
||||
}
|
||||
return method_str
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -408,8 +408,6 @@ pub fn (mut g Gen) init() {
|
|||
} else {
|
||||
g.cheaders.writeln(c_headers)
|
||||
}
|
||||
// g.definitions.writeln('string _STR(const char*, int, ...);')
|
||||
// g.definitions.writeln('string _STR_TMP(const char*, ...);')
|
||||
}
|
||||
if g.pref.os == .ios {
|
||||
g.cheaders.writeln('#define __TARGET_IOS__ 1')
|
||||
|
@ -2196,7 +2194,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
// here, not in call_expr().
|
||||
// `pos := s.index('x') or { return }`
|
||||
// ==========>
|
||||
// Option_int _t190 = string_index(s, _STR("x"));
|
||||
// Option_int _t190 = string_index(s, _STR("x")); // _STR() no more used!!
|
||||
// if (_t190.state != 2) {
|
||||
// Error err = _t190.err;
|
||||
// return;
|
||||
|
|
|
@ -47,130 +47,9 @@ static inline void __sort_ptr(uintptr_t a[], bool b[], int l)
|
|||
}
|
||||
}
|
||||
'
|
||||
c_str_fn_defs = '' // NO _STR() test
|
||||
/*
|
||||
c_str_fn_defs = '
|
||||
void _STR_PRINT_ARG(const char *fmt, char** refbufp, int *nbytes, int *memsize, int guess, ...) {
|
||||
va_list args;
|
||||
va_start(args, guess);
|
||||
// NB: (*memsize - *nbytes) === how much free space is left at the end of the current buffer refbufp
|
||||
// *memsize === total length of the buffer refbufp
|
||||
// *nbytes === already occupied bytes of buffer refbufp
|
||||
// guess === how many bytes were taken during the current vsnprintf run
|
||||
for(;;) {
|
||||
int remaining_space = *memsize - *nbytes;
|
||||
if (guess < remaining_space) {
|
||||
guess = vsnprintf(*refbufp + *nbytes, *memsize - *nbytes, fmt, args);
|
||||
if (guess < remaining_space) { // result did fit into buffer
|
||||
*nbytes += guess;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// increase buffer (somewhat exponentially)
|
||||
*memsize += guess + 3 * (*memsize) / 2;
|
||||
*refbufp = (char*)v_realloc((void*)*refbufp, *memsize);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
// TODO: must be romved in future, no more mof use for it.
|
||||
c_str_fn_defs = ''
|
||||
|
||||
string _STR(const char *fmt, int nfmts, ...) {
|
||||
va_list argptr;
|
||||
int memsize = 128;
|
||||
int nbytes = 0;
|
||||
char* buf = (char*)v_malloc(memsize);
|
||||
va_start(argptr, nfmts);
|
||||
for (int i=0; i<nfmts; ++i) {
|
||||
int k = strlen(fmt);
|
||||
bool is_fspec = false;
|
||||
for (int j=0; j<k; ++j) {
|
||||
if (fmt[j] == \'%\') {
|
||||
j++;
|
||||
if (fmt[j] != \'%\') {
|
||||
is_fspec = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_fspec) {
|
||||
char f = fmt[k-1];
|
||||
char fup = f & 0xdf; // toupper
|
||||
bool l = fmt[k-2] == \'l\';
|
||||
bool ll = l && fmt[k-3] == \'l\';
|
||||
if (f == \'u\' || fup == \'X\' || f == \'o\' || f == \'d\' || f == \'c\') { // int...
|
||||
if (ll) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+16, va_arg(argptr, long long));
|
||||
else if (l) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+10, va_arg(argptr, long));
|
||||
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 == \'C\') { // a C string
|
||||
char* sptr = va_arg(argptr, char*);
|
||||
char* fmt_no_c = (char*)v_malloc(k+4);
|
||||
memcpy(fmt_no_c, fmt, k);
|
||||
fmt_no_c[k-2]=\'C\';
|
||||
fmt_no_c[k-1]=\'"\';
|
||||
fmt_no_c[k]=\'%\';
|
||||
fmt_no_c[k+1]=\'s\';
|
||||
fmt_no_c[k+2]=\'"\';
|
||||
fmt_no_c[k+3]=0;
|
||||
_STR_PRINT_ARG(fmt_no_c, &buf, &nbytes, &memsize, k + 4 + 100, sptr);
|
||||
v_free(fmt_no_c);
|
||||
} else if (f == \'s\') { // v string
|
||||
string s = va_arg(argptr, string);
|
||||
if (fmt[k-4] == \'*\') { // %*.*s
|
||||
int fwidth = va_arg(argptr, int);
|
||||
if (fwidth < 0)
|
||||
fwidth -= (s.len - utf8_str_visible_length(s));
|
||||
else
|
||||
fwidth += (s.len - utf8_str_visible_length(s));
|
||||
_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+s.len-4, fwidth, s.len, s.str);
|
||||
} else { // %.*s
|
||||
_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+s.len-4, s.len, s.str);
|
||||
}
|
||||
} else {
|
||||
//v_panic(tos3(\'Invaid format specifier\'));
|
||||
}
|
||||
} else {
|
||||
_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k);
|
||||
}
|
||||
fmt += k+1;
|
||||
}
|
||||
va_end(argptr);
|
||||
buf[nbytes] = 0;
|
||||
|
||||
#ifdef DEBUG_ALLOC
|
||||
//puts(\'_STR:\');
|
||||
puts(buf);
|
||||
#endif
|
||||
|
||||
#if _VAUTOFREE
|
||||
//g_cur_str = (byteptr)buf;
|
||||
#endif
|
||||
return tos2((byteptr)buf);
|
||||
}
|
||||
|
||||
string _STR_TMP(const char *fmt, ...) {
|
||||
va_list argptr;
|
||||
va_start(argptr, fmt);
|
||||
size_t len = vsnprintf(0, 0, fmt, argptr) + 1;
|
||||
va_end(argptr);
|
||||
va_start(argptr, fmt);
|
||||
vsprintf((char *)g_str_buf, fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
#ifdef DEBUG_ALLOC
|
||||
//puts(\'_STR_TMP:\');
|
||||
//puts(g_str_buf);
|
||||
#endif
|
||||
string res = tos(g_str_buf, len);
|
||||
res.is_lit = 1;
|
||||
return res;
|
||||
|
||||
} // endof _STR_TMP
|
||||
|
||||
'
|
||||
*/
|
||||
c_common_macros = '
|
||||
#define EMPTY_VARG_INITIALIZATION 0
|
||||
#define EMPTY_STRUCT_DECLARATION
|
||||
|
|
|
@ -74,140 +74,6 @@ fn (mut g Gen) string_inter_literal_sb_optimized(call_expr ast.CallExpr) {
|
|||
return
|
||||
}
|
||||
|
||||
/*
|
||||
fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||
g.write('_STR("')
|
||||
// Build the string with %
|
||||
mut end_string := false
|
||||
for i, val in node.vals {
|
||||
mut escaped_val := val.replace_each(['%', '%%'])
|
||||
escaped_val = util.smart_quote(escaped_val, false)
|
||||
if i >= node.exprs.len {
|
||||
if escaped_val.len > 0 {
|
||||
end_string = true
|
||||
g.write('\\000')
|
||||
g.write(escaped_val)
|
||||
}
|
||||
break
|
||||
}
|
||||
g.write(escaped_val)
|
||||
mut typ := g.unwrap_generic(node.expr_types[i])
|
||||
sym := g.table.get_type_symbol(typ)
|
||||
if sym.kind == .alias {
|
||||
typ = (sym.info as ast.Alias).parent_type
|
||||
}
|
||||
// write correct format specifier to intermediate string
|
||||
g.write('%')
|
||||
fspec := node.fmts[i]
|
||||
mut fmt := if node.pluss[i] { '+' } else { '' }
|
||||
if node.fills[i] && node.fwidths[i] >= 0 {
|
||||
fmt = '${fmt}0'
|
||||
}
|
||||
if node.fwidths[i] != 0 {
|
||||
fmt = '$fmt${node.fwidths[i]}'
|
||||
}
|
||||
if node.precisions[i] != 987698 {
|
||||
fmt = '${fmt}.${node.precisions[i]}'
|
||||
}
|
||||
if fspec == `s` {
|
||||
if node.fwidths[i] == 0 {
|
||||
g.write('.*s')
|
||||
} else {
|
||||
g.write('*.*s')
|
||||
}
|
||||
} else if typ.is_float() {
|
||||
g.write('$fmt${fspec:c}')
|
||||
} else if typ.is_pointer() {
|
||||
if fspec == `p` {
|
||||
g.write('${fmt}p')
|
||||
} else {
|
||||
g.write('$fmt"PRI${fspec:c}PTR"')
|
||||
}
|
||||
} else if typ.is_int() {
|
||||
if fspec == `c` {
|
||||
g.write('${fmt}c')
|
||||
} else {
|
||||
g.write('$fmt"PRI${fspec:c}')
|
||||
if typ in [ast.i8_type, ast.byte_type] {
|
||||
g.write('8')
|
||||
} else if typ in [ast.i16_type, ast.u16_type] {
|
||||
g.write('16')
|
||||
} else if typ in [ast.i64_type, ast.u64_type] {
|
||||
g.write('64')
|
||||
} else {
|
||||
g.write('32')
|
||||
}
|
||||
g.write('"')
|
||||
}
|
||||
} else {
|
||||
// TODO: better check this case
|
||||
g.write('$fmt"PRId32"')
|
||||
}
|
||||
if i < node.exprs.len - 1 {
|
||||
g.write('\\000')
|
||||
}
|
||||
}
|
||||
num_string_parts := if end_string { node.exprs.len + 1 } else { node.exprs.len }
|
||||
g.write('", $num_string_parts, ')
|
||||
// Build args
|
||||
for i, expr in node.exprs {
|
||||
typ := g.unwrap_generic(node.expr_types[i])
|
||||
if typ == ast.string_type {
|
||||
if g.inside_vweb_tmpl {
|
||||
g.write('vweb__filter(')
|
||||
if expr.is_auto_deref_var() {
|
||||
g.write('*')
|
||||
}
|
||||
g.expr(expr)
|
||||
g.write(')')
|
||||
} else {
|
||||
if expr.is_auto_deref_var() {
|
||||
g.write('*')
|
||||
}
|
||||
g.expr(expr)
|
||||
}
|
||||
} else if node.fmts[i] == `s` || typ.has_flag(.variadic) {
|
||||
g.gen_expr_to_string(expr, typ)
|
||||
} else if typ.is_number() || typ.is_pointer() || node.fmts[i] == `d` {
|
||||
if typ.is_signed() && node.fmts[i] in [`x`, `X`, `o`] {
|
||||
// convert to unsigned first befors C's integer propagation strikes
|
||||
if typ == ast.i8_type {
|
||||
g.write('(byte)(')
|
||||
} else if typ == ast.i16_type {
|
||||
g.write('(u16)(')
|
||||
} else if typ == ast.int_type {
|
||||
g.write('(u32)(')
|
||||
} else {
|
||||
g.write('(u64)(')
|
||||
}
|
||||
if expr.is_auto_deref_var() {
|
||||
g.write('*')
|
||||
}
|
||||
g.expr(expr)
|
||||
g.write(')')
|
||||
} else {
|
||||
if expr.is_auto_deref_var() {
|
||||
g.write('*')
|
||||
}
|
||||
g.expr(expr)
|
||||
}
|
||||
} else {
|
||||
if expr.is_auto_deref_var() {
|
||||
g.write('*')
|
||||
}
|
||||
g.expr(expr)
|
||||
}
|
||||
if node.fmts[i] == `s` && node.fwidths[i] != 0 {
|
||||
g.write(', ${node.fwidths[i]}')
|
||||
}
|
||||
if i < node.exprs.len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
}
|
||||
g.write(')')
|
||||
}
|
||||
*/
|
||||
|
||||
fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
||||
is_shared := etype.has_flag(.shared_f)
|
||||
mut typ := etype
|
||||
|
@ -258,7 +124,6 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
|
|||
str_fn_name := g.gen_str_for_type(typ)
|
||||
if is_ptr && !is_var_mut {
|
||||
g.write('str_intp(1, _MOV((StrIntpData[]){_SLIT("&"), $si_s_code ,{.d_s=')
|
||||
// g.write('_STR("&%.*s\\000", 2, ')
|
||||
}
|
||||
g.write('${str_fn_name}(')
|
||||
if str_method_expects_ptr && !is_ptr {
|
||||
|
|
Loading…
Reference in New Issue