strings,cgen: add .write2/2 and .writeln2/2 methods to reduce consecutive write calls (#22610)

This commit is contained in:
Felipe Pena 2024-10-22 10:30:58 -03:00 committed by GitHub
parent 7a0febb12d
commit b2ac2ed627
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 286 additions and 393 deletions

View File

@ -143,6 +143,17 @@ pub fn (mut b Builder) write_string(s string) {
// b.buf << []u8(s) // TODO
}
// write_string2 appends the strings `s1` and `s2` to the buffer
@[inline]
pub fn (mut b Builder) write_string2(s1 string, s2 string) {
if s1.len != 0 {
unsafe { b.push_many(s1.str, s1.len) }
}
if s2.len != 0 {
unsafe { b.push_many(s2.str, s2.len) }
}
}
// writeln_string appends the string `s`+`\n` to the buffer
@[deprecated: 'use writeln() instead']
@[deprecated_after: '2024-03-21']
@ -204,6 +215,19 @@ pub fn (mut b Builder) writeln(s string) {
b << u8(`\n`)
}
// writeln2 appends two strings: `s1` + `\n`, and `s2` + `\n`, to the buffer.
@[inline]
pub fn (mut b Builder) writeln2(s1 string, s2 string) {
if s1 != '' {
unsafe { b.push_many(s1.str, s1.len) }
}
b << u8(`\n`)
if s2 != '' {
unsafe { b.push_many(s2.str, s2.len) }
}
b << u8(`\n`)
}
// last_n(5) returns 'world'
// buf == 'hello world'
pub fn (b &Builder) last_n(n int) string {

View File

@ -117,8 +117,7 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st
g.write('0')
}
g.write('}')
g.writeln(';')
g.writeln('{')
g.writeln2(';', '{')
g.indent++
g.writeln('${elem_typ_str}* pelem = (${elem_typ_str}*)${past.tmp_var};')
g.writeln('int _len = (int)sizeof(${past.tmp_var}) / sizeof(${elem_typ_str});')
@ -311,16 +310,13 @@ fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp
} else {
0
}
g.write('(${elem_styp}[]){')
g.write(g.type_default(node.elem_type))
g.write2('(${elem_styp}[]){', g.type_default(node.elem_type))
g.write('}[0], ${depth})')
} else if node.has_len && node.elem_type == ast.string_type {
g.write('&(${elem_styp}[]){')
g.write('_SLIT("")')
g.write2('&(${elem_styp}[]){', '_SLIT("")')
g.write('})')
} else if node.has_len && elem_type.unaliased_sym.kind in [.array, .map] {
g.write('(voidptr)&(${elem_styp}[]){')
g.write(g.type_default(node.elem_type))
g.write2('(voidptr)&(${elem_styp}[]){', g.type_default(node.elem_type))
g.write('}[0])')
} else {
g.write('0)')
@ -330,8 +326,7 @@ fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp
} else if is_amp {
g.write(')')
}
g.writeln(';')
g.writeln('{')
g.writeln2(';', '{')
g.indent++
g.writeln('${elem_typ}* pelem = (${elem_typ}*)${past.tmp_var}.data;')
g.writeln('for (int index=0; index<${past.tmp_var}.len; index++, pelem++) {')
@ -410,10 +405,8 @@ fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp
g.write(g.type_default(node.elem_type))
}
}
g.writeln(';')
g.writeln('}')
g.write(line)
g.write(' (voidptr)${tmp})')
g.writeln2(';', '}')
g.write2(line, ' (voidptr)${tmp})')
} else if node.has_init {
g.write('&(${elem_styp}[]){')
g.expr_with_init(node)
@ -423,12 +416,10 @@ fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp
g.expr_with_opt(ast.None{}, ast.none_type, node.elem_type)
g.write(')')
} else if node.has_len && node.elem_type == ast.string_type {
g.write('&(${elem_styp}[]){')
g.write('_SLIT("")')
g.write2('&(${elem_styp}[]){', '_SLIT("")')
g.write('})')
} else if node.has_len && elem_type.unaliased_sym.kind in [.struct, .array, .map] {
g.write('(voidptr)&(${elem_styp}[]){')
g.write(g.type_default(node.elem_type))
g.write2('(voidptr)&(${elem_styp}[]){', g.type_default(node.elem_type))
g.write('}[0])')
} else {
g.write('0)')
@ -582,8 +573,7 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
g.expr(expr)
}
}
g.writeln(';')
g.writeln('array_push${noscan}((array*)&${past.tmp_var}, &${tmp_map_expr_result_name});')
g.writeln2(';', 'array_push${noscan}((array*)&${past.tmp_var}, &${tmp_map_expr_result_name});')
g.indent--
g.writeln('}')
if !is_embed_map_filter {
@ -746,15 +736,14 @@ fn (mut g Gen) gen_array_sort_call(node ast.CallExpr, compare_fn string) {
g.empty_line = true
g.write('if (')
g.expr(node.left)
g.write('${deref_field}len > 0) { ')
g.write('qsort(')
g.write2('${deref_field}len > 0) { ', 'qsort(')
g.expr(node.left)
g.write('${deref_field}data, ')
g.expr(node.left)
g.write('${deref_field}len, ')
g.expr(node.left)
g.write('${deref_field}element_size, (int (*)(const void *, const void *))&${compare_fn});')
g.write(' }')
g.write2('${deref_field}element_size, (int (*)(const void *, const void *))&${compare_fn});',
' }')
}
// `nums.filter(it % 2 == 0)`
@ -835,8 +824,7 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
g.expr(expr)
}
}
g.writeln(') {')
g.writeln('\tarray_push${noscan}((array*)&${past.tmp_var}, &${var_name});')
g.writeln2(') {', '\tarray_push${noscan}((array*)&${past.tmp_var}, &${var_name});')
g.writeln('}')
g.indent--
g.writeln('}')
@ -1040,8 +1028,7 @@ fn (mut g Gen) gen_array_contains_methods() {
// `nums.contains(2)`
fn (mut g Gen) gen_array_contains(left_type ast.Type, left ast.Expr, right_type ast.Type, right ast.Expr) {
fn_name := g.get_array_contains_method(left_type)
g.write('${fn_name}(')
g.write(strings.repeat(`*`, left_type.nr_muls()))
g.write2('${fn_name}(', strings.repeat(`*`, left_type.nr_muls()))
if left_type.share() == .shared_t {
g.go_back(1)
}
@ -1068,8 +1055,7 @@ fn (mut g Gen) gen_array_contains(left_type ast.Type, left ast.Expr, right_type
if g.is_cc_msvc {
stmts := g.go_before_last_stmt().trim_space()
tmp_var := g.new_tmp_var()
g.write('${g.styp(right_type)} ${tmp_var} = ${g.expr_string(right)};')
g.write(stmts)
g.write2('${g.styp(right_type)} ${tmp_var} = ${g.expr_string(right)};', stmts)
g.write(tmp_var)
} else {
g.write('(${g.styp(right.typ)})')
@ -1224,8 +1210,8 @@ fn (mut g Gen) gen_array_index(node ast.CallExpr) {
if g.is_cc_msvc {
stmts := g.go_before_last_stmt().trim_space()
tmp_var := g.new_tmp_var()
g.write('${g.styp(node.args[0].typ)} ${tmp_var} = ${g.expr_string(node.args[0].expr)};')
g.write(stmts)
g.write2('${g.styp(node.args[0].typ)} ${tmp_var} = ${g.expr_string(node.args[0].expr)};',
stmts)
g.write(tmp_var)
} else {
g.write('(${g.styp(node.args[0].typ)})')
@ -1338,10 +1324,8 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) {
g.expr(expr)
}
}
g.writeln(') {')
g.writeln('\t${past.tmp_var} = true;')
g.writeln('\tbreak;')
g.writeln('}')
g.writeln2(') {', '\t${past.tmp_var} = true;')
g.writeln2('\tbreak;', '}')
g.indent--
g.writeln('}')
if !is_embed_map_filter {
@ -1433,10 +1417,8 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) {
g.expr(expr)
}
}
g.writeln(')) {')
g.writeln('\t${past.tmp_var} = false;')
g.writeln('\tbreak;')
g.writeln('}')
g.writeln2(')) {', '\t${past.tmp_var} = false;')
g.writeln2('\tbreak;', '}')
g.indent--
g.writeln('}')
if !is_embed_map_filter {

View File

@ -121,8 +121,7 @@ fn (mut g Gen) gen_assert_postfailure_mode(node ast.AssertStmt) {
if g.pref.is_test {
g.writeln('\tlongjmp(g_jump_buffer, 1);')
}
g.writeln('\t// TODO')
g.writeln('\t// Maybe print all vars in a test function if it fails?')
g.writeln2('\t// TODO', '\t// Maybe print all vars in a test function if it fails?')
if g.pref.assert_failure_mode != .continues {
g.writeln('\t_v_panic(_SLIT("Assertion failed..."));')
}

View File

@ -915,8 +915,7 @@ fn (mut g Gen) gen_multi_return_assign(node &ast.AssignStmt, return_type ast.Typ
g.expr(lx)
sym := g.table.final_sym(node.left_types[i])
if sym.kind == .array_fixed {
g.writeln(';')
g.writeln('memcpy(&${g.expr_string(lx)}, &${mr_var_name}.arg${i}, sizeof(${styp}));')
g.writeln2(';', 'memcpy(&${g.expr_string(lx)}, &${mr_var_name}.arg${i}, sizeof(${styp}));')
} else {
if cur_indexexpr != -1 {
if is_auto_heap {
@ -1123,8 +1122,7 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
for lx in left {
if lx is ast.Ident {
if val.name == lx.name {
g.write('_var_')
g.write(lx.pos.pos.str())
g.write2('_var_', lx.pos.pos.str())
has_var = true
break
}
@ -1138,8 +1136,7 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
mut has_var := false
for lx in left {
if val_.str() == lx.str() {
g.write('_var_')
g.write(lx.pos().pos.str())
g.write2('_var_', lx.pos().pos.str())
has_var = true
break
}
@ -1152,10 +1149,8 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
sym := g.table.sym(val.left_type)
if _ := g.table.find_method(sym, val.op.str()) {
left_styp := g.styp(val.left_type.set_nr_muls(0))
g.write(left_styp)
g.write('_')
g.write(util.replace_op(val.op.str()))
g.write('(')
g.write2(left_styp, '_')
g.write2(util.replace_op(val.op.str()), '(')
g.gen_cross_tmp_variable(left, val.left)
g.write(', ')
g.gen_cross_tmp_variable(left, val.right)
@ -1216,8 +1211,7 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
mut has_var := false
for lx in left {
if val_.str() == lx.str() {
g.write('_var_')
g.write(lx.pos().pos.str())
g.write2('_var_', lx.pos().pos.str())
has_var = true
break
}

View File

@ -417,8 +417,8 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, typ_str st
{_SLIT("${clean_interface_v_type_name}(\'"), ${si_s_code}, {.d_s = ${val}}},
{_SLIT("\')"), 0, {.d_c = 0 }}
}))'
fn_builder.write_string('\tif (x._typ == _${styp}_${sub_sym.cname}_index)')
fn_builder.write_string(' return ${res};')
fn_builder.write_string2('\tif (x._typ == _${styp}_${sub_sym.cname}_index)',
' return ${res};')
} else {
mut val := '${func_name}(${deref}(${sub_sym.cname}*)x._${sub_sym.cname}'
if should_use_indent_func(sub_sym.kind) && !sym_has_str_method {
@ -429,8 +429,8 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, typ_str st
{_SLIT("${clean_interface_v_type_name}("), ${si_s_code}, {.d_s = ${val}}},
{_SLIT(")"), 0, {.d_c = 0 }}
}))'
fn_builder.write_string('\tif (x._typ == _${styp}_${sub_sym.cname}_index)')
fn_builder.write_string(' return ${res};\n')
fn_builder.write_string2('\tif (x._typ == _${styp}_${sub_sym.cname}_index)',
' return ${res};\n')
}
}
fn_builder.writeln('\treturn _SLIT("unknown interface value");')
@ -1116,8 +1116,7 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, lang ast.Language, styp strin
'\tstring_free(&${tmpvar});')
fn_body.write_string(tmpvar)
} else {
fn_body.write_string(funcprefix)
fn_body.write_string(func)
fn_body.write_string2(funcprefix, func)
}
}
}

View File

@ -556,20 +556,14 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (str
if g.use_segfault_handler || g.pref.is_prof {
b.writeln('\n#define V_USE_SIGNAL_H')
}
b.writeln('\n// V comptime_definitions:')
b.write_string(g.comptime_definitions.str())
b.writeln('\n// V typedefs:')
b.write_string(g.typedefs.str())
b.writeln('\n // V preincludes:')
b.write_string(g.preincludes.str())
b.writeln('\n// V cheaders:')
b.write_string(g.cheaders.str())
b.write_string2('\n// V comptime_definitions:\n', g.comptime_definitions.str())
b.write_string2('\n// V typedefs:\n', g.typedefs.str())
b.write_string2('\n // V preincludes:\n', g.preincludes.str())
b.write_string2('\n// V cheaders:', g.cheaders.str())
if g.pcs_declarations.len > 0 {
b.writeln('\n// V profile counters:')
b.write_string(g.pcs_declarations.str())
b.write_string2('\n// V profile counters:\n', g.pcs_declarations.str())
}
b.writeln('\n// V includes:')
b.write_string(g.includes.str())
b.write_string2('\n// V includes:\n', g.includes.str())
b.writeln('\n// V global/const #define ... :')
for var_name in g.sorted_global_const_names {
if var := g.global_const_defs[var_name] {
@ -578,24 +572,15 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (str
}
}
}
b.writeln('\n// Enum definitions:')
b.write_string(g.enum_typedefs.str())
b.writeln('\n// Thread definitions:')
b.write_string(g.thread_definitions.str())
b.writeln('\n// V type definitions:')
b.write_string(g.type_definitions.str())
b.writeln('\n// V alias definitions:')
b.write_string(g.alias_definitions.str())
b.writeln('\n// V shared types:')
b.write_string(g.shared_types.str())
b.writeln('\n// V Option_xxx definitions:')
b.write_string(g.out_options.str())
b.writeln('\n// V result_xxx definitions:')
b.write_string(g.out_results.str())
b.writeln('\n// V json forward decls:')
b.write_string(g.json_forward_decls.str())
b.writeln('\n// V definitions:')
b.write_string(g.definitions.str())
b.write_string2('\n// Enum definitions:\n', g.enum_typedefs.str())
b.write_string2('\n// Thread definitions:\n', g.thread_definitions.str())
b.write_string2('\n// V type definitions:\n', g.type_definitions.str())
b.write_string2('\n// V alias definitions:\n', g.alias_definitions.str())
b.write_string2('\n// V shared types:\n', g.shared_types.str())
b.write_string2('\n// V Option_xxx definitions:\n', g.out_options.str())
b.write_string2('\n// V result_xxx definitions:\n', g.out_results.str())
b.write_string2('\n// V json forward decls:\n', g.json_forward_decls.str())
b.write_string2('\n// V definitions:\n', g.definitions.str())
b.writeln('\n// V global/const non-precomputed definitions:')
for var_name in g.sorted_global_const_names {
if var := g.global_const_defs[var_name] {
@ -606,37 +591,29 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (str
}
interface_table := g.interface_table()
if interface_table.len > 0 {
b.writeln('\n// V interface table:')
b.write_string(interface_table)
b.write_string2('\n// V interface table:\n', interface_table)
}
if g.gowrappers.len > 0 {
b.writeln('\n// V gowrappers:')
b.write_string(g.gowrappers.str())
b.write_string2('\n// V gowrappers:\n', g.gowrappers.str())
}
if g.hotcode_definitions.len > 0 {
b.writeln('\n// V hotcode definitions:')
b.write_string(g.hotcode_definitions.str())
b.write_string2('\n// V hotcode definitions:\n', g.hotcode_definitions.str())
}
if g.embedded_data.len > 0 {
b.writeln('\n// V embedded data:')
b.write_string(g.embedded_data.str())
b.write_string2('\n// V embedded data:\n', g.embedded_data.str())
}
if g.shared_functions.len > 0 {
b.writeln('\n// V shared type functions:')
b.write_string(g.shared_functions.str())
b.write_string(c_concurrency_helpers)
b.writeln('\n// V shared type functions:\n')
b.write_string2(g.shared_functions.str(), c_concurrency_helpers)
}
if g.channel_definitions.len > 0 {
b.writeln('\n// V channel code:')
b.write_string(g.channel_definitions.str())
b.write_string2('\n// V channel code:\n', g.channel_definitions.str())
}
if g.auto_str_funcs.len > 0 {
b.writeln('\n// V auto str functions:')
b.write_string(g.auto_str_funcs.str())
b.write_string2('\n// V auto str functions:\n', g.auto_str_funcs.str())
}
if g.dump_funcs.len > 0 {
b.writeln('\n// V dump functions:')
b.write_string(g.dump_funcs.str())
b.write_string2('\n// V dump functions:\n', g.dump_funcs.str())
}
if g.auto_fn_definitions.len > 0 {
b.writeln('\n// V auto functions:')
@ -646,8 +623,7 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (str
}
if g.anon_fn_definitions.len > 0 {
if g.nr_closures > 0 {
b.writeln('\n// V closure helpers')
b.writeln(c_closure_helpers(g.pref))
b.writeln2('\n// V closure helpers', c_closure_helpers(g.pref))
}
b.writeln('\n// V anon functions:')
for fn_def in g.anon_fn_definitions {
@ -655,8 +631,7 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (str
}
}
if g.pref.is_coverage {
b.writeln('\n// V coverage:')
b.write_string(g.cov_declarations.str())
b.write_string2('\n// V coverage:\n', g.cov_declarations.str())
}
b.writeln('\n// end of V out')
mut header := b.last_n(b.len)
@ -988,8 +963,7 @@ pub fn (mut g Gen) get_sumtype_variant_name(typ ast.Type, sym ast.TypeSymbol) st
}
pub fn (mut g Gen) write_typeof_functions() {
g.writeln('')
g.writeln('// >> typeof() support for sum types / interfaces')
g.writeln2('', '// >> typeof() support for sum types / interfaces')
for ityp, sym in g.table.type_symbols {
if sym.kind == .sum_type {
static_prefix := if g.pref.build_mode == .build_module { 'static ' } else { '' }
@ -1022,8 +996,7 @@ pub fn (mut g Gen) write_typeof_functions() {
g.writeln('\t\tdefault: return "unknown ${util.strip_main_name(sym.name)}";')
g.writeln('\t}')
}
g.writeln('}')
g.writeln('')
g.writeln2('}', '')
g.writeln('${static_prefix}int v_typeof_sumtype_idx_${sym.cname}(int sidx) { /* ${sym.name} */ ')
if g.pref.build_mode == .build_module {
g.writeln('\t\tif( sidx == _v_type_idx_${sym.cname}() ) return ${int(ityp)};')
@ -1034,8 +1007,7 @@ pub fn (mut g Gen) write_typeof_functions() {
g.writeln('\treturn ${int(ityp)};')
} else {
tidx := g.table.find_type_idx(sym.name)
g.writeln('\tswitch(sidx) {')
g.writeln('\t\tcase ${tidx}: return ${int(ityp)};')
g.writeln2('\tswitch(sidx) {', '\t\tcase ${tidx}: return ${int(ityp)};')
mut idxs := []int{}
for v in sum_info.variants {
if v in idxs {
@ -1044,8 +1016,7 @@ pub fn (mut g Gen) write_typeof_functions() {
g.writeln('\t\tcase ${int(v)}: return ${int(v)};')
idxs << v
}
g.writeln('\t\tdefault: return ${int(ityp)};')
g.writeln('\t}')
g.writeln2('\t\tdefault: return ${int(ityp)};', '\t}')
}
g.writeln('}')
} else if sym.kind == .interface {
@ -1065,10 +1036,8 @@ pub fn (mut g Gen) write_typeof_functions() {
}
g.writeln('\tif (sidx == _${sym.cname}_${sub_sym.cname}_index) return "${util.strip_main_name(sub_sym.name)}";')
}
g.writeln('\treturn "unknown ${util.strip_main_name(sym.name)}";')
g.writeln('}')
g.writeln('')
g.writeln('static int v_typeof_interface_idx_${sym.cname}(int sidx) { /* ${sym.name} */ ')
g.writeln2('\treturn "unknown ${util.strip_main_name(sym.name)}";', '}')
g.writeln2('', 'static int v_typeof_interface_idx_${sym.cname}(int sidx) { /* ${sym.name} */ ')
for t in inter_info.types {
sub_sym := g.table.sym(ast.mktyp(t))
if sub_sym.info is ast.Struct && sub_sym.info.is_unresolved_generic() {
@ -1076,12 +1045,10 @@ pub fn (mut g Gen) write_typeof_functions() {
}
g.writeln('\tif (sidx == _${sym.cname}_${sub_sym.cname}_index) return ${int(t.set_nr_muls(0))};')
}
g.writeln('\treturn ${int(ityp)};')
g.writeln('}')
g.writeln2('\treturn ${int(ityp)};', '}')
}
}
g.writeln('// << typeof() support for sum types')
g.writeln('')
g.writeln2('// << typeof() support for sum types', '')
}
// V type to C typecc
@ -2004,8 +1971,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
}
g.indent--
if g.inside_ternary > 0 {
g.write('')
g.write(')')
g.write2('', ')')
}
if g.is_autofree && !g.inside_vweb_tmpl && stmts.len > 0 {
// use the first stmt to get the scope
@ -2124,8 +2090,7 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
g.set_current_pos_as_last_stmt_pos()
}
g.write(stmt_str)
g.write(' ')
g.write2(stmt_str, ' ')
g.write(tmp_var)
}
@ -2402,20 +2367,17 @@ fn (mut g Gen) stmt(node ast.Stmt) {
fn (mut g Gen) write_defer_stmts() {
for i := g.defer_stmts.len - 1; i >= 0; i-- {
defer_stmt := g.defer_stmts[i]
g.writeln('// Defer begin')
g.writeln('if (${g.defer_flag_var(defer_stmt)}) {')
g.writeln2('// Defer begin', 'if (${g.defer_flag_var(defer_stmt)}) {')
// g.indent++
if defer_stmt.ifdef.len > 0 {
g.writeln(defer_stmt.ifdef)
g.stmts(defer_stmt.stmts)
g.writeln('')
g.writeln('#endif')
g.writeln2('', '#endif')
} else {
g.stmts(defer_stmt.stmts)
}
// g.indent--
g.writeln('}')
g.writeln('// Defer end')
g.writeln2('}', '// Defer end')
}
}
@ -2629,8 +2591,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
// Do not allocate for `Interface(unsafe{nil})` casts
is_nil_cast := expr is ast.UnsafeExpr && expr.expr is ast.Nil
if is_nil_cast {
g.write('/*nili*/')
g.write('((void*)0)')
g.write2('/*nili*/', '((void*)0)')
return
}
}
@ -2696,8 +2657,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
g.write('${got_styp} ${tmp_var} = ')
g.expr(expr)
g.writeln(';')
g.write(stmt_str)
g.write(' ')
g.write2(stmt_str, ' ')
g.write('${fname}(&${tmp_var})')
return
} else {
@ -2866,8 +2826,7 @@ fn (mut g Gen) asm_stmt(stmt ast.AsmStmt) {
g.write(': ')
}
for i, clob in stmt.clobbered {
g.write('"')
g.write(clob.reg.name)
g.write2('"', clob.reg.name)
g.write('"')
if i + 1 < stmt.clobbered.len {
g.writeln(',')
@ -3512,10 +3471,8 @@ fn (mut g Gen) expr(node_ ast.Expr) {
} else {
g.write('0')
}
g.write(', sizeof(')
g.write(elem_typ_str)
g.write(')>0 ? sizeof(')
g.write(elem_typ_str)
g.write2(', sizeof(', elem_typ_str)
g.write2(')>0 ? sizeof(', elem_typ_str)
g.write(') : 1)')
}
ast.CharLiteral {
@ -3588,11 +3545,9 @@ fn (mut g Gen) expr(node_ ast.Expr) {
}
ast.IntegerLiteral {
if node.val.starts_with('0o') {
g.write('0')
g.write(node.val[2..])
g.write2('0', node.val[2..])
} else if node.val.starts_with('-0o') {
g.write('-0')
g.write(node.val[3..])
g.write2('-0', node.val[3..])
} else {
g.write(node.val)
}
@ -3678,8 +3633,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
expr_str = node.expr.name
}
g.writeln('if (${expr_str}.state != 0) {')
g.writeln('\tpanic_option_not_set(_SLIT("none"));')
g.writeln('}')
g.writeln2('\tpanic_option_not_set(_SLIT("none"));', '}')
g.write(cur_line)
typ := g.resolve_comptime_type(node.expr, node.typ)
g.write('*(${g.base_type(typ)}*)&')
@ -3962,8 +3916,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
g.write(')')
}
g.or_block(tmp_var, node.or_block, node.typ)
g.write(stmt_str)
g.write(' ')
g.write2(stmt_str, ' ')
unwrapped_typ := node.typ.clear_option_and_result()
unwrapped_styp := g.styp(unwrapped_typ)
g.write('(*(${unwrapped_styp}*)${tmp_var}.data)')
@ -3991,8 +3944,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
return
} else if g.enum_data_type == node.typ {
g.expr(node.expr)
g.write('.')
g.write(node.field_name)
g.write2('.', node.field_name)
return
}
mut sum_type_deref_field := ''
@ -4142,8 +4094,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
}
n_ptr := node.expr_type.nr_muls() - 1
if n_ptr > 0 {
g.write('(')
g.write('*'.repeat(n_ptr))
g.write2('(', '*'.repeat(n_ptr))
g.expr(node.expr)
g.write(')')
} else {
@ -4389,11 +4340,9 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
}
g.writeln('{')
g.writeln('\tMap_string_string _scope = new_map_init(&map_hash_string, &map_eq_string, &map_clone_string, &map_free_string, ${vars.len}, sizeof(string), sizeof(v__debug__DebugContextVar),')
g.write('\t\t_MOV((string[${vars.len}]){')
g.write(keys.str())
g.write2('\t\t_MOV((string[${vars.len}]){', keys.str())
g.writeln('}),')
g.write('\t\t_MOV((v__debug__DebugContextVar[${vars.len}]){')
g.write(values.str())
g.write2('\t\t_MOV((v__debug__DebugContextVar[${vars.len}]){', values.str())
g.writeln('}));')
g.writeln('\tv__debug__Debugger_interact(&g_debugger, (v__debug__DebugContextInfo){.is_anon=${is_anon},.is_generic=${is_generic},.is_method=${is_method},.receiver_typ_name=_SLIT("${receiver_type}"),.line=${paline},.file=_SLIT("${pafile}"),.mod=_SLIT("${pamod}"),.fn_name=_SLIT("${pafn}"),.scope=_scope});')
g.write('}')
@ -4408,11 +4357,9 @@ fn (mut g Gen) enum_decl(node ast.EnumDecl) {
g.enum_typedefs.writeln('')
g.enum_typedefs.writeln('typedef ${enum_typ_name} ${enum_name};')
for i, field in node.fields {
g.enum_typedefs.write_string('\t#define ${enum_name}__${field.name} ')
g.enum_typedefs.write_string('(')
g.enum_typedefs.write_string2('\t#define ${enum_name}__${field.name} ', '(')
if is_flag {
g.enum_typedefs.write_string((u64(1) << i).str())
g.enum_typedefs.write_string('ULL')
g.enum_typedefs.write_string2((u64(1) << i).str(), 'ULL')
} else if field.has_expr {
expr_str := g.expr_string(field.expr)
g.enum_typedefs.write_string(expr_str)
@ -4456,8 +4403,7 @@ fn (mut g Gen) enum_decl(node ast.EnumDecl) {
} else if is_flag {
g.enum_typedefs.write_string(' = ')
cur_enum_expr = 'u64(1) << ${i}'
g.enum_typedefs.write_string((u64(1) << i).str())
g.enum_typedefs.write_string('U')
g.enum_typedefs.write_string2((u64(1) << i).str(), 'U')
cur_enum_offset = 0
}
cur_value := if cur_enum_offset > 0 {
@ -4514,15 +4460,13 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
g.writeln('->mtx);')
} else {
mtxs = g.new_tmp_var()
g.writeln('uintptr_t _arr_${mtxs}[${node.lockeds.len}];')
g.writeln('bool _isrlck_${mtxs}[${node.lockeds.len}];')
g.writeln2('uintptr_t _arr_${mtxs}[${node.lockeds.len}];', 'bool _isrlck_${mtxs}[${node.lockeds.len}];')
mut j := 0
for i, is_rlock in node.is_rlock {
if !is_rlock {
g.write('_arr_${mtxs}[${j}] = (uintptr_t)&')
g.expr(node.lockeds[i])
g.writeln('->mtx;')
g.writeln('_isrlck_${mtxs}[${j}] = false;')
g.writeln2('->mtx;', '_isrlck_${mtxs}[${j}] = false;')
j++
}
}
@ -4530,8 +4474,7 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
if is_rlock {
g.write('_arr_${mtxs}[${j}] = (uintptr_t)&')
g.expr(node.lockeds[i])
g.writeln('->mtx;')
g.writeln('_isrlck_${mtxs}[${j}] = true;')
g.writeln2('->mtx;', '_isrlck_${mtxs}[${j}] = true;')
j++
}
}
@ -4547,12 +4490,9 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
} else {
g.writeln('__sort_ptr(_arr_${mtxs}, _isrlck_${mtxs}, ${node.lockeds.len});')
}
g.writeln('for (int ${mtxs}=0; ${mtxs}<${node.lockeds.len}; ${mtxs}++) {')
g.writeln('\tif (${mtxs} && _arr_${mtxs}[${mtxs}] == _arr_${mtxs}[${mtxs}-1]) continue;')
g.writeln('\tif (_isrlck_${mtxs}[${mtxs}])')
g.writeln('\t\tsync__RwMutex_rlock((sync__RwMutex*)_arr_${mtxs}[${mtxs}]);')
g.writeln('\telse')
g.writeln('\t\tsync__RwMutex_lock((sync__RwMutex*)_arr_${mtxs}[${mtxs}]);')
g.writeln2('for (int ${mtxs}=0; ${mtxs}<${node.lockeds.len}; ${mtxs}++) {', '\tif (${mtxs} && _arr_${mtxs}[${mtxs}] == _arr_${mtxs}[${mtxs}-1]) continue;')
g.writeln2('\tif (_isrlck_${mtxs}[${mtxs}])', '\t\tsync__RwMutex_rlock((sync__RwMutex*)_arr_${mtxs}[${mtxs}]);')
g.writeln2('\telse', '\t\tsync__RwMutex_lock((sync__RwMutex*)_arr_${mtxs}[${mtxs}]);')
g.writeln('}')
}
g.mtxs = mtxs
@ -4568,8 +4508,7 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) {
g.unlock_locks()
if node.is_expr {
g.writeln('')
g.write(cur_line)
g.write('${tmp_result}')
g.write2(cur_line, '${tmp_result}')
}
}
@ -4642,8 +4581,7 @@ fn (mut g Gen) map_init(node ast.MapInit) {
g.expr(expr)
g.writeln(',')
}
g.writeln('\t}),')
g.writeln('\t_MOV((${effective_typ_str}[${size}]){')
g.writeln2('\t}),', '\t_MOV((${effective_typ_str}[${size}]){')
for i, expr in node.vals {
g.write('\t\t')
if expr.is_auto_deref_var() {
@ -4658,8 +4596,7 @@ fn (mut g Gen) map_init(node ast.MapInit) {
}
g.writeln(', ')
}
g.writeln('\t})')
g.writeln(')')
g.writeln2('\t})', ')')
} else if node.has_update_expr {
g.write('map_clone(&(')
g.expr(node.update_expr)
@ -4809,8 +4746,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
}
g.writeln(');')
// free the temps that were created
g.writeln('array_free(&${objs_array});')
g.writeln('array_free(&${directions_array});')
g.writeln2('array_free(&${objs_array});', 'array_free(&${directions_array});')
g.writeln('array_free(&${chan_array});')
mut i := 0
for j in 0 .. node.branches.len {
@ -4834,8 +4770,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
g.writeln('}')
if is_expr {
g.empty_line = false
g.write(cur_line)
g.write('(${select_result} != -2)')
g.write2(cur_line, '(${select_result} != -2)')
}
}
@ -5050,10 +4985,8 @@ fn (mut g Gen) ident(node ast.Ident) {
g.write(closure_ctx + '->')
}
if node.obj.typ.nr_muls() > 1 {
g.write('(')
g.write('*'.repeat(node.obj.typ.nr_muls() - 1))
g.write(name)
g.write(')')
g.write2('(', '*'.repeat(node.obj.typ.nr_muls() - 1))
g.write2(name, ')')
} else {
g.write(name)
}
@ -5209,14 +5142,12 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
parent_type := (sym.info as ast.Alias).parent_type
tmp_var := g.new_tmp_var()
tmp_var2 := g.new_tmp_var()
g.writeln('${styp} ${tmp_var};')
g.writeln('${g.styp(parent_type)} ${tmp_var2};')
g.writeln2('${styp} ${tmp_var};', '${g.styp(parent_type)} ${tmp_var2};')
g.write('_option_ok(&(${g.base_type(parent_type)}[]) { ')
g.expr(node.expr)
g.writeln(' }, (${option_name}*)(&${tmp_var2}), sizeof(${g.base_type(parent_type)}));')
g.writeln('_option_ok(&(${g.styp(parent_type)}[]) { ${tmp_var2} }, (${option_name}*)&${tmp_var}, sizeof(${g.styp(parent_type)}));')
g.write(cur_stmt)
g.write(tmp_var)
g.write2(cur_stmt, tmp_var)
} else if node.expr_type.has_flag(.option) {
g.expr_opt_with_cast(node.expr, expr_type, node.typ)
} else {
@ -5684,8 +5615,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
g.expr(expr)
g.writeln(', sizeof(${expr_styp}));')
final_assignments += g.go_before_last_stmt() + '\t'
g.write(line)
g.write('{0}')
g.write2(line, '{0}')
} else {
if expr.is_auto_deref_var() {
g.write('*')
@ -6506,8 +6436,7 @@ fn (mut g Gen) write_debug_calls_typeof_functions() {
return
}
g.writeln('\t// we call these functions in debug mode so that the C compiler')
g.writeln('\t// does not optimize them and we can access them in the debugger.')
g.writeln2('\t// we call these functions in debug mode so that the C compiler', '\t// does not optimize them and we can access them in the debugger.')
for _, sym in g.table.type_symbols {
if sym.kind == .sum_type {
sum_info := sym.info as ast.SumType
@ -6649,8 +6578,7 @@ fn (mut g Gen) write_init_function() {
// g.writeln('puts("cleaning up...");')
reversed_table_modules := g.table.modules.reverse()
for mod_name in reversed_table_modules {
g.writeln('\t// Cleanups for module ${mod_name} :')
g.writeln(g.cleanups[mod_name].str())
g.writeln2('\t// Cleanups for module ${mod_name} :', g.cleanups[mod_name].str())
}
g.writeln('\tarray_free(&as_cast_type_indexes);')
}
@ -7259,8 +7187,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
} else {
styp := g.styp(g.fn_decl.return_type)
err_obj := g.new_tmp_var()
g.writeln('\t${styp} ${err_obj};')
g.writeln('\tmemcpy(&${err_obj}, &${cvar_name}, sizeof(${result_name}));')
g.writeln2('\t${styp} ${err_obj};', '\tmemcpy(&${err_obj}, &${cvar_name}, sizeof(${result_name}));')
g.writeln('\treturn ${err_obj};')
}
}
@ -7288,8 +7215,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
} else {
styp := g.styp(g.fn_decl.return_type).replace('*', '_ptr')
err_obj := g.new_tmp_var()
g.writeln('\t${styp} ${err_obj};')
g.writeln('\tmemcpy(&${err_obj}, &${cvar_name}, sizeof(_option));')
g.writeln2('\t${styp} ${err_obj};', '\tmemcpy(&${err_obj}, &${cvar_name}, sizeof(_option));')
g.writeln('\treturn ${err_obj};')
}
}
@ -7618,10 +7544,8 @@ fn (mut g Gen) as_cast(node ast.AsCast) {
} else {
g.write('/* as */ *(${styp}*)__as_cast(')
}
g.write(tmp_var)
g.write(dot)
g.write('_${sym.cname},')
g.write(tmp_var)
g.write2(tmp_var, dot)
g.write2('_${sym.cname},', tmp_var)
g.write(dot)
sidx := g.type_sidx(unwrapped_node_typ)
g.write('_typ, ${sidx}); })')
@ -7633,13 +7557,10 @@ fn (mut g Gen) as_cast(node ast.AsCast) {
}
g.write('(')
g.expr(node.expr)
g.write(')')
g.write(dot)
g.write('_${sym.cname},')
g.write('(')
g.write2(')', dot)
g.write2('_${sym.cname},', '(')
g.expr(node.expr)
g.write(')')
g.write(dot)
g.write2(')', dot)
sidx := g.type_sidx(unwrapped_node_typ)
g.write('_typ, ${sidx})')
}
@ -7681,11 +7602,9 @@ fn (mut g Gen) as_cast(node ast.AsCast) {
} else {
g.write('/* as */ *(${styp}*)__as_cast(')
}
g.write(tmp_var)
g.write(dot)
g.write2(tmp_var, dot)
g.write('_${sym.cname},v_typeof_interface_idx_${expr_type_sym.cname}(')
g.write(tmp_var)
g.write(dot)
g.write2(tmp_var, dot)
sidx := g.type_sidx(unwrapped_node_typ)
g.write('_typ), ${sidx}); })')
} else {
@ -7696,13 +7615,10 @@ fn (mut g Gen) as_cast(node ast.AsCast) {
}
g.write('(')
g.expr(node.expr)
g.write(')')
g.write(dot)
g.write('_${sym.cname},v_typeof_interface_idx_${expr_type_sym.cname}(')
g.write('(')
g.write2(')', dot)
g.write2('_${sym.cname},v_typeof_interface_idx_${expr_type_sym.cname}(', '(')
g.expr(node.expr)
g.write(')')
g.write(dot)
g.write2(')', dot)
sidx := g.type_sidx(unwrapped_node_typ)
g.write('_typ), ${sidx})')
}
@ -8046,16 +7962,14 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}*
pmessage := 'string__plus(string__plus(tos3("`as_cast`: cannot convert "), tos3(v_typeof_interface_${interface_name}(x._typ))), tos3(" to ${util.strip_main_name(vsym.name)}"))'
if g.pref.is_debug {
// TODO: actually return a valid position here
conversion_functions.write_string('\tpanic_debug(1, tos3("builtin.v"), tos3("builtin"), tos3("__as_cast"), ')
conversion_functions.write_string(pmessage)
conversion_functions.write_string2('\tpanic_debug(1, tos3("builtin.v"), tos3("builtin"), tos3("__as_cast"), ',
pmessage)
conversion_functions.writeln(');')
} else {
conversion_functions.write_string('\t_v_panic(')
conversion_functions.write_string(pmessage)
conversion_functions.write_string2('\t_v_panic(', pmessage)
conversion_functions.writeln(');')
}
conversion_functions.writeln('\treturn (${vsym.cname}){0};')
conversion_functions.writeln('}')
conversion_functions.writeln2('\treturn (${vsym.cname}){0};', '}')
}
sb.writeln('// ^^^ number of types for interface ${interface_name}: ${current_iinidx - iinidx_minimum_base}')
if iname_table_length == 0 {
@ -8068,8 +7982,7 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}*
// add line return after interface index declarations
sb.writeln('')
if inter_methods.len > 0 {
sb.writeln(methods_wrapper.str())
sb.writeln(methods_struct_def.str())
sb.writeln2(methods_wrapper.str(), methods_struct_def.str())
sb.writeln(methods_struct.str())
}
sb.writeln(cast_functions.str())

View File

@ -42,10 +42,8 @@ fn (mut g Gen) gen_vlines_reset() {
// The rest is auto generated code, which will not have
// different .v source file/line numbers.
g.vlines_path = util.vlines_escape_path(g.pref.out_name_c, g.pref.ccompiler)
g.writeln('')
g.writeln('// Reset the C file/line numbers')
g.writeln('${reset_dbg_line} "${g.vlines_path}"')
g.writeln('')
g.writeln2('', '// Reset the C file/line numbers')
g.writeln2('${reset_dbg_line} "${g.vlines_path}"', '')
}
}
@ -136,8 +134,7 @@ fn (mut g Gen) gen_c_main_function_only_header() {
fn (mut g Gen) gen_c_main_function_header() {
g.gen_c_main_function_only_header()
g.gen_c_main_trace_calls_hook()
g.writeln('\tg_main_argc = ___argc;')
g.writeln('\tg_main_argv = ___argv;')
g.writeln2('\tg_main_argc = ___argc;', '\tg_main_argv = ___argv;')
if g.nr_closures > 0 {
g.writeln('\t__closure_init(); // main()')
}
@ -170,8 +167,7 @@ fn (mut g Gen) gen_c_main_header() {
pub fn (mut g Gen) gen_c_main_footer() {
g.writeln('\t_vcleanup();')
g.writeln('\treturn 0;')
g.writeln('}')
g.writeln2('\treturn 0;', '}')
}
pub fn (mut g Gen) gen_c_android_sokol_main() {
@ -206,8 +202,7 @@ sapp_desc sokol_main(int argc, char* argv[]) {
if g.pref.gc_mode == .boehm_leak {
g.writeln('\tGC_set_find_leak(1);')
}
g.writeln('\tGC_set_pages_executable(0);')
g.writeln('\tGC_INIT();')
g.writeln2('\tGC_set_pages_executable(0);', '\tGC_INIT();')
if g.pref.gc_mode in [.boehm_incr, .boehm_incr_opt] {
g.writeln('\tGC_enable_incremental();')
}
@ -230,8 +225,7 @@ sapp_desc sokol_main(int argc, char* argv[]) {
}
')
}
g.writeln(' return g_desc;')
g.writeln('}')
g.writeln2(' return g_desc;', '}')
}
pub fn (mut g Gen) write_tests_definitions() {
@ -261,11 +255,9 @@ pub fn (mut g Gen) gen_failing_return_error_for_test_fn(return_stmt ast.Return,
pub fn (mut g Gen) gen_c_main_profile_hook() {
if g.pref.is_prof {
g.writeln('')
g.writeln('\tsignal(SIGINT, vprint_profile_stats_on_signal);')
g.writeln2('', '\tsignal(SIGINT, vprint_profile_stats_on_signal);')
g.writeln('\tsignal(SIGTERM, vprint_profile_stats_on_signal);')
g.writeln('\tatexit(vprint_profile_stats);')
g.writeln('')
g.writeln2('\tatexit(vprint_profile_stats);', '')
}
if g.pref.profile_file != '' {
if 'no_profile_startup' in g.pref.compile_defines {
@ -308,14 +300,11 @@ pub fn (mut g Gen) gen_c_main_for_tests() {
if g.pref.show_asserts {
g.writeln('\tmain__BenchedTests bt = main__start_testing(${all_tfuncs.len}, v_test_file);')
}
g.writeln('')
g.writeln('\tstruct _main__TestRunner_interface_methods _vtrunner = main__TestRunner_name_table[test_runner._typ];')
g.writeln('\tvoid * _vtobj = test_runner._object;')
g.writeln('')
g.writeln2('', '\tstruct _main__TestRunner_interface_methods _vtrunner = main__TestRunner_name_table[test_runner._typ];')
g.writeln2('\tvoid * _vtobj = test_runner._object;', '')
g.writeln('\tmain__VTestFileMetaInfo_free(test_runner.file_test_info);')
g.writeln('\t*(test_runner.file_test_info) = main__vtest_new_filemetainfo(v_test_file, ${all_tfuncs.len});')
g.writeln('\t_vtrunner._method_start(_vtobj, ${all_tfuncs.len});')
g.writeln('')
g.writeln2('\t_vtrunner._method_start(_vtobj, ${all_tfuncs.len});', '')
for tnumber, tname in all_tfuncs {
tcname := util.no_dots(tname)
testfn := unsafe { g.table.fns[tname] }
@ -347,16 +336,12 @@ pub fn (mut g Gen) gen_c_main_for_tests() {
if g.pref.show_asserts {
g.writeln('\tmain__BenchedTests_end_testing(&bt);')
}
g.writeln('')
g.writeln('\t_vtrunner._method_finish(_vtobj);')
g.writeln2('', '\t_vtrunner._method_finish(_vtobj);')
g.writeln('\tint test_exit_code = _vtrunner._method_exit_code(_vtobj);')
g.writeln('\t_vtrunner._method__v_free(_vtobj);')
g.writeln('')
g.writeln('\t_vcleanup();')
g.writeln('')
g.writeln('\treturn test_exit_code;')
g.writeln('}')
g.writeln2('\t_vtrunner._method__v_free(_vtobj);', '')
g.writeln2('\t_vcleanup();', '')
g.writeln2('\treturn test_exit_code;', '}')
if g.pref.printfn_list.len > 0 && 'main' in g.pref.printfn_list {
println(g.out.after(main_fn_start_pos))
}

View File

@ -265,8 +265,7 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
if !g.inside_assign {
cur_line := g.go_before_last_stmt()
tmp_var := g.new_tmp_var()
g.write('${g.styp(m.return_type)} ${tmp_var} = ')
g.write(cur_line)
g.write2('${g.styp(m.return_type)} ${tmp_var} = ', cur_line)
g.or_block(tmp_var, node.or_block, m.return_type)
}
}
@ -414,8 +413,7 @@ fn (mut g Gen) comptime_if(node ast.IfExpr) {
g.stmt(last)
}
g.skip_stmt_pos = prev_skip_stmt_pos
g.writeln(';')
g.writeln('}')
g.writeln2(';', '}')
g.indent--
} else {
g.indent++

View File

@ -341,8 +341,7 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
}
g.writeln('\treturn ret;')
}
g.writeln('}')
g.writeln('')
g.writeln2('}', '')
g.trace_fn_definitions << trace_fn
}
}
@ -525,10 +524,8 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
export_alias := '${weak}${type_name} ${fn_attrs}${attr.arg}(${arg_str})'
g.definitions.writeln('VV_EXPORTED_SYMBOL ${export_alias}; // exported fn ${node.name}')
g.writeln('${export_alias} {')
g.write('\treturn ${name}(')
g.write(fargs.join(', '))
g.writeln(');')
g.writeln('}')
g.write2('\treturn ${name}(', fargs.join(', '))
g.writeln2(');', '}')
}
}
}
@ -709,10 +706,8 @@ fn (mut g Gen) write_defer_stmts_when_needed() {
g.write_defer_stmts()
}
if g.defer_profile_code.len > 0 {
g.writeln('')
g.writeln('\t// defer_profile_code')
g.writeln(g.defer_profile_code)
g.writeln('')
g.writeln2('', '\t// defer_profile_code')
g.writeln2(g.defer_profile_code, '')
}
}
@ -887,8 +882,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
g.expr(node)
g.inside_curry_call = old_inside_curry_call
g.write(line)
g.write('*(${g.base_type(ret_typ)}*)${tmp_res}.data')
g.write2(line, '*(${g.base_type(ret_typ)}*)${tmp_res}.data')
return
}
}
@ -1131,8 +1125,7 @@ fn (mut g Gen) gen_array_method_call(node ast.CallExpr, left_type ast.Type, left
g.gen_arg_from_type(left_type, node.left)
} else {
if node.left_type.is_ptr() {
g.write('(')
g.write('*'.repeat(node.left_type.nr_muls()))
g.write2('(', '*'.repeat(node.left_type.nr_muls()))
g.expr(node.left)
g.write(')')
} else {
@ -1658,8 +1651,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
left_type_name := util.no_dots(left_cc_type)
g.write('${c_name(left_type_name)}_name_table[')
if node.left.is_auto_deref_var() && left_type.nr_muls() > 1 {
g.write('(')
g.write('*'.repeat(left_type.nr_muls() - 1))
g.write2('(', '*'.repeat(left_type.nr_muls() - 1))
g.expr(node.left)
g.write(')')
} else {
@ -1669,8 +1661,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
mname := c_fn_name(node.name)
g.write('${dot}_typ]._method_${mname}(')
if node.left.is_auto_deref_var() && left_type.nr_muls() > 1 {
g.write('(')
g.write('*'.repeat(left_type.nr_muls() - 1))
g.write2('(', '*'.repeat(left_type.nr_muls() - 1))
g.expr(node.left)
g.write(')')
} else {
@ -1865,8 +1856,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
} else if !is_interface && node.from_embed_types.len > 0 {
n_ptr := node.left_type.nr_muls() - 1
if n_ptr > 0 {
g.write('(')
g.write('*'.repeat(n_ptr))
g.write2('(', '*'.repeat(n_ptr))
g.expr(node.left)
g.write(')')
} else {
@ -1878,27 +1868,23 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
}
if node.receiver_type.is_ptr() && left_type.is_ptr() {
// (main__IFoo*)bar
g.write('(')
g.write(g.table.sym(node.from_embed_types.last()).cname)
g.write2('(', g.table.sym(node.from_embed_types.last()).cname)
g.write('*)')
g.expr(node.left)
} else if node.receiver_type.is_ptr() && !left_type.is_ptr() {
// (main__IFoo*)&bar
g.write('(')
g.write(g.table.sym(node.from_embed_types.last()).cname)
g.write2('(', g.table.sym(node.from_embed_types.last()).cname)
g.write('*)&')
g.expr(node.left)
} else if !node.receiver_type.is_ptr() && left_type.is_ptr() {
// *((main__IFoo*)bar)
g.write('*((')
g.write(g.table.sym(node.from_embed_types.last()).cname)
g.write2('*((', g.table.sym(node.from_embed_types.last()).cname)
g.write('*)')
g.expr(node.left)
g.write(')')
} else {
// *((main__IFoo*)&bar)
g.write('*((')
g.write(g.table.sym(node.from_embed_types.last()).cname)
g.write2('*((', g.table.sym(node.from_embed_types.last()).cname)
g.write('*)&')
g.expr(node.left)
g.write(')')

View File

@ -239,8 +239,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) {
cond_var = g.expr_string(node.cond)
} else {
cond_var = g.new_tmp_var()
g.write(g.styp(node.cond_type))
g.write(' ${cond_var} = ')
g.write2(g.styp(node.cond_type), ' ${cond_var} = ')
old_inside_opt_or_res := g.inside_opt_or_res
if node.cond_type.has_flag(.option) {
g.inside_opt_or_res = true
@ -289,8 +288,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) {
cond_is_literal := node.cond is ast.ArrayInit
if cond_is_literal {
cond_var = g.new_tmp_var()
g.write(g.styp(node.cond_type))
g.write(' ${cond_var} = ')
g.write2(g.styp(node.cond_type), ' ${cond_var} = ')
g.expr(node.cond)
g.writeln(';')
} else if cond_type_is_ptr {
@ -348,8 +346,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) {
cond_var = g.expr_string(node.cond)
} else {
cond_var = g.new_tmp_var()
g.write(g.styp(node.cond_type))
g.write(' ${cond_var} = ')
g.write2(g.styp(node.cond_type), ' ${cond_var} = ')
g.expr(node.cond)
g.writeln(';')
}

View File

@ -354,8 +354,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
g.writeln(';')
branch_cond_var_names << cond_var_name
g.set_current_pos_as_last_stmt_pos()
g.writeln(line)
g.writeln('if (${cond_var_name}) {')
g.writeln2(line, 'if (${cond_var_name}) {')
} else if i > 0 && branch_cond_var_names.len > 0 && !needs_tmp_var && needs_conds_order {
cond_var_name := g.new_tmp_var()
line := g.go_before_last_stmt()

View File

@ -117,8 +117,7 @@ fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
g.write('${styp} ${var} = ')
g.expr(node.left)
g.writeln(';')
g.write(line)
g.write(' ${var})')
g.write2(line, ' ${var})')
} else {
g.expr(node.left)
g.write(')')

View File

@ -145,14 +145,12 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
} else {
g.write(g.styp(left.unaliased.set_nr_muls(0)))
}
g.write('__eq(')
g.write('*'.repeat(left.typ.nr_muls()))
g.write2('__eq(', '*'.repeat(left.typ.nr_muls()))
if eq_operator_expects_ptr {
g.write('&')
}
g.expr(node.left)
g.write(', ')
g.write('*'.repeat(right.typ.nr_muls()))
g.write2(', ', '*'.repeat(right.typ.nr_muls()))
if eq_operator_expects_ptr {
g.write('&')
}
@ -362,28 +360,24 @@ fn (mut g Gen) infix_expr_cmp_op(node ast.InfixExpr) {
method_name = g.generic_fn_name(concrete_types, method_name)
g.write(method_name)
if node.op in [.lt, .ge] {
g.write('(')
g.write('*'.repeat(left.typ.nr_muls()))
g.write2('(', '*'.repeat(left.typ.nr_muls()))
if operator_expects_ptr {
g.write('&')
}
g.expr(node.left)
g.write(', ')
g.write('*'.repeat(right.typ.nr_muls()))
g.write2(', ', '*'.repeat(right.typ.nr_muls()))
if operator_expects_ptr {
g.write('&')
}
g.expr(node.right)
g.write(')')
} else {
g.write('(')
g.write('*'.repeat(right.typ.nr_muls()))
g.write2('(', '*'.repeat(right.typ.nr_muls()))
if operator_expects_ptr {
g.write('&')
}
g.expr(node.right)
g.write(', ')
g.write('*'.repeat(left.typ.nr_muls()))
g.write2(', ', '*'.repeat(left.typ.nr_muls()))
if operator_expects_ptr {
g.write('&')
}
@ -394,31 +388,26 @@ fn (mut g Gen) infix_expr_cmp_op(node ast.InfixExpr) {
if node.op in [.le, .ge] {
g.write('!')
}
g.write(g.styp(left.typ.set_nr_muls(0)))
g.write('__lt')
g.write2(g.styp(left.typ.set_nr_muls(0)), '__lt')
if node.op in [.lt, .ge] {
g.write('(')
g.write('*'.repeat(left.typ.nr_muls()))
g.write2('(', '*'.repeat(left.typ.nr_muls()))
if operator_expects_ptr {
g.write('&')
}
g.expr(node.left)
g.write(', ')
g.write('*'.repeat(right.typ.nr_muls()))
g.write2(', ', '*'.repeat(right.typ.nr_muls()))
if operator_expects_ptr {
g.write('&')
}
g.expr(node.right)
g.write(')')
} else {
g.write('(')
g.write('*'.repeat(right.typ.nr_muls()))
g.write2('(', '*'.repeat(right.typ.nr_muls()))
if operator_expects_ptr {
g.write('&')
}
g.expr(node.right)
g.write(', ')
g.write('*'.repeat(left.typ.nr_muls()))
g.write2(', ', '*'.repeat(left.typ.nr_muls()))
if operator_expects_ptr {
g.write('&')
}
@ -618,13 +607,11 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
g.gen_array_contains(node.right_type, node.right, node.left_type, node.left)
g.write(')')
} else if right.unaliased_sym.kind == .string {
g.write('(')
g.write('string_contains(')
g.write2('(', 'string_contains(')
g.expr(node.right)
g.write(', ')
g.expr(node.left)
g.write(')')
g.write(')')
g.write('))')
}
}
@ -775,8 +762,7 @@ fn (mut g Gen) infix_expr_arithmetic_op(node ast.InfixExpr) {
if left.sym.info is ast.Struct && left.sym.info.generic_types.len > 0 {
mut method_name := left.sym.cname + '_' + util.replace_op(node.op.str())
method_name = g.generic_fn_name(left.sym.info.concrete_types, method_name)
g.write(method_name)
g.write('(')
g.write2(method_name, '(')
g.expr(node.left)
g.write(', ')
g.expr(node.right)
@ -811,8 +797,7 @@ fn (mut g Gen) infix_expr_arithmetic_op(node ast.InfixExpr) {
g.writeln(';')
g.write(cur_line)
}
g.write(method_name)
g.write('(')
g.write2(method_name, '(')
g.op_arg(node.left, method.params[0].typ, left.typ)
if right_var != '' {
g.write(', ${right_var}')
@ -1011,12 +996,10 @@ fn (mut g Gen) gen_is_none_check(node ast.InfixExpr) {
g.empty_line = true
left_var := g.expr_with_opt(node.left, node.left_type, node.left_type)
g.writeln(';')
g.write(stmt_str)
g.write(' ')
g.write2(stmt_str, ' ')
g.write('${left_var}.state')
}
g.write(' ${node.op.str()} ')
g.write('2') // none state
g.write(' ${node.op.str()} 2') // none state
}
// gen_plain_infix_expr generates basic code for infix expressions,

View File

@ -72,8 +72,7 @@ fn (mut g Gen) generate_hotcode_reloading_main_caller() {
}
g.writeln('')
// We are in live code reload mode, so start the .so loader in the background
g.writeln('\t// live code initialization section:')
g.writeln('\t{')
g.writeln2('\t// live code initialization section:', '\t{')
g.writeln('\t\t// initialization of live function pointers')
for fname in g.hotcode_fn_names {
g.writeln('\t\timpl_live_${fname} = 0;')

View File

@ -543,8 +543,7 @@ fn (mut g Gen) match_expr_classic(node ast.MatchExpr, is_expr bool, cond_var str
if g.inside_ternary == 0 && node.branches.len >= 1 {
if reset_if {
has_goto = true
g.writeln('\tgoto end_block_${node.pos.line_nr};')
g.writeln('}')
g.writeln2('\tgoto end_block_${node.pos.line_nr};', '}')
g.set_current_pos_as_last_stmt_pos()
} else {
g.write('}')

View File

@ -60,8 +60,7 @@ fn (mut g Gen) sql_insert_expr(node ast.SqlExpr) {
g.write_orm_insert(hack_stmt_line, table_name, connection_var_name, result_var_name,
node.or_expr)
g.write(left)
g.write('orm__Connection_name_table[${connection_var_name}._typ]._method_last_id(${connection_var_name}._object)')
g.write2(left, 'orm__Connection_name_table[${connection_var_name}._typ]._method_last_id(${connection_var_name}._object)')
}
// sql_stmt writes C code that calls ORM functions for
@ -258,8 +257,7 @@ fn (mut g Gen) write_orm_update(node &ast.SqlStmtLine, table_name string, connec
g.writeln('.fields = __new_array_with_default_noscan(${node.updated_columns.len}, ${node.updated_columns.len}, sizeof(string), 0')
}
g.writeln('),')
g.writeln('.data = new_array_from_c_array(${node.update_exprs.len}, ${node.update_exprs.len}, sizeof(orm__Primitive),')
g.writeln2('),', '.data = new_array_from_c_array(${node.update_exprs.len}, ${node.update_exprs.len}, sizeof(orm__Primitive),')
if node.update_exprs.len > 0 {
g.indent++
@ -715,8 +713,7 @@ fn (mut g Gen) write_orm_where(where_expr ast.Expr) {
g.write('.is_and = __new_array_with_default_noscan(${is_ands.len}, ${is_ands.len}, sizeof(bool), 0')
}
g.indent--
g.writeln('),')
g.writeln('}')
g.writeln2('),', '}')
}
// write_orm_where_expr writes C code that generates expression which is used in the `QueryData`.
@ -913,8 +910,7 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
g.writeln('NULL')
}
g.indent--
g.writeln('),')
g.writeln('.types = new_array_from_c_array(${types.len}, ${types.len}, sizeof(${ast.int_type_name}),')
g.writeln2('),', '.types = new_array_from_c_array(${types.len}, ${types.len}, sizeof(${ast.int_type_name}),')
g.indent++
if types.len > 0 {

View File

@ -142,8 +142,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
if node.is_expr && node.call_expr.return_type != ast.void_type {
g.writeln('${gohandle_name} thread_${tmp} = {')
g.writeln('\t.ret_ptr = ${arg_tmp_var}->ret_ptr,')
g.writeln('\t.handle = thread_handle_${tmp}')
g.writeln('};')
g.writeln2('\t.handle = thread_handle_${tmp}', '};')
}
if !node.is_expr {
g.writeln('CloseHandle(thread_${tmp});')
@ -315,12 +314,11 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
&& (typ_sym.info as ast.Interface).defines_method(expr.name) {
rec_cc_type := g.cc_type(unwrapped_rec_type, false)
receiver_type_name := util.no_dots(rec_cc_type)
g.gowrappers.write_string('${c_name(receiver_type_name)}_name_table[')
g.gowrappers.write_string('arg->arg0')
g.gowrappers.write_string2('${c_name(receiver_type_name)}_name_table[',
'arg->arg0')
idot := if expr.left_type.is_ptr() { '->' } else { '.' }
mname := c_name(expr.name)
g.gowrappers.write_string('${idot}_typ]._method_${mname}(')
g.gowrappers.write_string('arg->arg0')
g.gowrappers.write_string2('${idot}_typ]._method_${mname}(', 'arg->arg0')
g.gowrappers.write_string('${idot}_object')
} else if typ_sym.kind == .struct && expr.is_field {
g.gowrappers.write_string('arg->arg0')
@ -328,8 +326,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
mname := c_name(expr.name)
g.gowrappers.write_string('${idot}${mname}(')
} else {
g.gowrappers.write_string('arg->fn(')
g.gowrappers.write_string('arg->arg0')
g.gowrappers.write_string2('arg->fn(', 'arg->arg0')
}
if expr.args.len > 0 && (typ_sym.kind != .struct || !expr.is_field) {
g.gowrappers.write_string(', ')
@ -400,8 +397,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
}
if node.is_expr {
g.empty_line = false
g.write(line)
g.write(handle)
g.write2(line, handle)
}
}

View File

@ -8,12 +8,10 @@ import v.util
fn (mut g Gen) string_literal(node ast.StringLiteral) {
escaped_val := cescape_nonascii(util.smart_quote(node.val, node.is_raw))
if node.language == .c {
g.write('"')
g.write(escaped_val)
g.write2('"', escaped_val)
g.write('"')
} else {
g.write('_SLIT("')
g.write(escaped_val)
g.write2('_SLIT("', escaped_val)
g.write('")')
}
}
@ -29,8 +27,7 @@ fn (mut g Gen) string_inter_literal_sb_optimized(call_expr ast.CallExpr) {
escaped_val := cescape_nonascii(util.smart_quote(val, false))
g.write('strings__Builder_write_string(&')
g.expr(call_expr.left)
g.write(', _SLIT("')
g.write(escaped_val)
g.write2(', _SLIT("', escaped_val)
g.writeln('"));')
if i >= node.exprs.len {
break
@ -43,8 +40,7 @@ fn (mut g Gen) string_inter_literal_sb_optimized(call_expr ast.CallExpr) {
g.expr(call_expr.left)
g.write(', ')
typ := node.expr_types[i]
g.write(g.styp(typ))
g.write('_str(')
g.write2(g.styp(typ), '_str(')
sym := g.table.sym(typ)
if sym.kind != .function {
g.expr(node.exprs[i])
@ -143,8 +139,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
} else {
g.expr(expr)
}
g.write('.data')
g.write(') ? _SLIT("Option(&nil)") : ')
g.write2('.data', ') ? _SLIT("Option(&nil)") : ')
} else {
inside_interface_deref_old := g.inside_interface_deref
g.inside_interface_deref = false
@ -159,8 +154,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
g.write(') ? _SLIT("nil") : ')
}
}
g.write(str_fn_name)
g.write('(')
g.write2(str_fn_name, '(')
if str_method_expects_ptr && !is_ptr {
if is_dump_expr || (g.pref.ccompiler_type != .tinyc && expr is ast.CallExpr) {
g.write('ADDR(${g.styp(typ)}, ')

View File

@ -186,8 +186,7 @@ fn (mut g Gen) str_val(node ast.StringInterLiteral, i int, fmts []u8) {
dot := if typ.is_ptr() { '->' } else { '.' }
g.write('${dot}_typ]._method_str(')
g.expr(expr)
g.write('${dot}_object')
g.write(')')
g.write2('${dot}_object', ')')
} else if fmt == `s` || typ.has_flag(.variadic) {
mut exp_typ := typ
if expr is ast.Ident {
@ -261,17 +260,14 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
}
}
}
g.write(' str_intp(')
g.write(node.vals.len.str())
g.write(', ')
g.write('_MOV((StrIntpData[]){')
g.write2(' str_intp(', node.vals.len.str())
g.write(', _MOV((StrIntpData[]){')
for i, val in node.vals {
mut escaped_val := cescape_nonascii(util.smart_quote(val, false))
escaped_val = escaped_val.replace('\0', '\\0')
if escaped_val.len > 0 {
g.write('{_SLIT("')
g.write(escaped_val)
g.write2('{_SLIT("', escaped_val)
g.write('"), ')
} else {
g.write('{_SLIT0, ')
@ -284,10 +280,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
}
ft_u64, ft_str := g.str_format(node, i, fmts)
g.write('0x')
g.write(ft_u64.hex())
g.write(', {.d_')
g.write(ft_str)
g.write2('0x', ft_u64.hex())
g.write2(', {.d_', ft_str)
g.write(' = ')
// for pointers we need a void* cast

View File

@ -108,8 +108,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
})
g.writeln('}, &${tmp_var}, sizeof(${base_styp}));')
g.empty_line = false
g.write(s)
g.write(tmp_var)
g.write2(s, tmp_var)
return
} else if g.inside_cinit {
if is_multiline {
@ -461,8 +460,7 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool {
g.expr(field.default_expr)
g.writeln(', sizeof(${styp}));')
g.empty_line = false
g.write(s)
g.write('{')
g.write2(s, '{')
for i in 0 .. final_sym.info.size {
g.write('${tmp_var}[${i}]')
if i != final_sym.info.size - 1 {

View File

@ -21,6 +21,35 @@ fn (mut g Gen) write(s string) {
g.empty_line = false
}
fn (mut g Gen) write2(s1 string, s2 string) {
$if trace_gen ? {
if g.file == unsafe { nil } {
eprintln('gen file: <nil> | last_fn_c_name: ${g.last_fn_c_name:-45} | write: ${s1}')
} else {
eprintln('gen file: ${g.file.path:-30} | last_fn_c_name: ${g.last_fn_c_name:-45} | write: ${s1}')
}
}
if g.indent > 0 && g.empty_line {
g.out.write_string(util.tabs(g.indent))
}
g.out.write_string(s1)
g.empty_line = false
$if trace_gen ? {
if g.file == unsafe { nil } {
eprintln('gen file: <nil> | last_fn_c_name: ${g.last_fn_c_name:-45} | write: ${s2}')
} else {
eprintln('gen file: ${g.file.path:-30} | last_fn_c_name: ${g.last_fn_c_name:-45} | write: ${s2}')
}
}
if g.indent > 0 && g.empty_line {
g.out.write_string(util.tabs(g.indent))
}
g.out.write_string(s2)
g.empty_line = false
}
fn (mut g Gen) write_decimal(x i64) {
$if trace_gen ? {
if g.file == unsafe { nil } {
@ -54,6 +83,36 @@ fn (mut g Gen) writeln(s string) {
g.empty_line = true
}
fn (mut g Gen) writeln2(s1 string, s2 string) {
// expansion for s1
$if trace_gen ? {
if g.file == unsafe { nil } {
eprintln('gen file: <nil> | last_fn_c_name: ${g.last_fn_c_name:-45} | writeln2: ${s1}')
} else {
eprintln('gen file: ${g.file.path:-30} | last_fn_c_name: ${g.last_fn_c_name:-45} | writeln2: ${s1}')
}
}
if g.indent > 0 && g.empty_line {
g.out.write_string(util.tabs(g.indent))
}
g.out.writeln(s1)
g.empty_line = true
// expansion for s2
$if trace_gen ? {
if g.file == unsafe { nil } {
eprintln('gen file: <nil> | last_fn_c_name: ${g.last_fn_c_name:-45} | writeln2: ${s2}')
} else {
eprintln('gen file: ${g.file.path:-30} | last_fn_c_name: ${g.last_fn_c_name:-45} | writeln2: ${s2}')
}
}
if g.indent > 0 && g.empty_line {
g.out.write_string(util.tabs(g.indent))
}
g.out.writeln(s2)
g.empty_line = true
}
// Below are hacks that should be removed at some point.
fn (mut g Gen) go_back(n int) {