From 576618d8cc502ff89e66b41b97d7dddd97aae259 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 12 Dec 2019 04:09:31 +0300 Subject: [PATCH] string cloning; fix `foo.str += 's'` --- vlib/builtin/builtin.v | 12 ------------ vlib/builtin/builtin_nix.v | 4 ++++ vlib/builtin/builtin_windows.v | 7 ++++++- vlib/compiler/cc.v | 2 +- vlib/compiler/parser.v | 29 +++++++++++++++++++++-------- vlib/strings/similarity.v | 3 ++- 6 files changed, 34 insertions(+), 23 deletions(-) diff --git a/vlib/builtin/builtin.v b/vlib/builtin/builtin.v index 1c2ede6a72..55e967a865 100644 --- a/vlib/builtin/builtin.v +++ b/vlib/builtin/builtin.v @@ -76,18 +76,6 @@ pub fn panic(s string) { C.exit(1) } -pub fn println(s string) { - // Should never happen - if isnil(s.str) { - panic('println(NIL)') - } - $if windows { - C._putws(s.to_wide()) - } $else { - C.printf('%.*s\n', s.len, s.str) - } -} - pub fn eprintln(s string) { if isnil(s.str) { panic('eprintln(NIL)') diff --git a/vlib/builtin/builtin_nix.v b/vlib/builtin/builtin_nix.v index 9bbd164748..eb98ceb6b0 100644 --- a/vlib/builtin/builtin_nix.v +++ b/vlib/builtin/builtin_nix.v @@ -4,6 +4,10 @@ module builtin +pub fn println(s string) { + C.printf('%.*s\n', s.len, s.str) +} + fn print_backtrace_skipping_top_frames_msvc(skipframes int) bool { println('not implemented, see builtin_windows.v') return false diff --git a/vlib/builtin/builtin_windows.v b/vlib/builtin/builtin_windows.v index ea04878492..8d3cea3266 100644 --- a/vlib/builtin/builtin_windows.v +++ b/vlib/builtin/builtin_windows.v @@ -73,7 +73,7 @@ $if msvc { handle := C.GetCurrentProcess() defer { C.SymCleanup(handle) } - + options := C.SymSetOptions(SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME) syminitok := C.SymInitialize( handle, 0, 1) if syminitok != 1 { @@ -133,3 +133,8 @@ fn print_backtrace_skipping_top_frames_nix(skipframes int) bool { println('not implemented, see builtin_nix.v') return false } + +pub fn println(s string) { + C._putws(s.to_wide()) +} + diff --git a/vlib/compiler/cc.v b/vlib/compiler/cc.v index 69e470576f..9056351cb0 100644 --- a/vlib/compiler/cc.v +++ b/vlib/compiler/cc.v @@ -87,7 +87,7 @@ fn (v mut V) cc() { //'-Wno-unused-but-set-variable', '-Wno-unused-parameter', '-Wno-unused-result', - '-Wunused-function', + '-Wno-unused-function', '-Wno-missing-braces', '-Wno-unused-label'] // TCC on Linux by default, unless -cc was provided diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index d84d3ba952..8b51196c83 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -1163,6 +1163,10 @@ fn (p mut Parser) close_scope() { fn (p mut Parser) free_var(v Var) { // Clean up memory, only do this if -autofree was passed for now //if p.fileis('mem.v') {println('free_var() $v.name')} + //println(p.cur_fn.name) + if p.cur_fn.name in ['add', 'clone', 'free'] { + return + } mut free_fn := 'free' if v.typ.starts_with('array_') { free_fn = 'v_array_free' @@ -1181,11 +1185,19 @@ fn (p mut Parser) free_var(v Var) { if p.returns { // Don't free a variable that's being returned if !v.is_returned && v.typ != 'FILE*' { //!v.is_c { - prev_line := p.cgen.lines[p.cgen.lines.len-2] - p.cgen.lines[p.cgen.lines.len-2] = - '$free_fn ($v.name); /* :) close_scope free $v.typ */' + prev_line + //p.cgen.cur_line = '/* free */' + p.cgen.cur_line + //p.cgen.set_placeholder(0, '/*free2*/') + prev_line := p.cgen.lines[p.cgen.lines.len-1] + free := '$free_fn ($v.name); /* :) close_scope free $v.typ */' + p.cgen.lines[p.cgen.lines.len-1] = free + '\n' + prev_line + //'$free_fn ($v.name); /* :) close_scope free $v.typ */\n' + prev_line } - } else { + } else if p.mod != 'strings' { //&& p.mod != 'builtin' { + /* + prev_line := p.cgen.lines[p.cgen.lines.len-1] + free := '$free_fn ($v.name); /* :) close_scope free $v.typ */' + p.cgen.lines[p.cgen.lines.len-1] = free + '\n' + prev_line + */ //if p.fileis('mem.v') {println(v.name)} p.genln('$free_fn ($v.name); // close_scope free') } @@ -1359,7 +1371,7 @@ fn (p mut Parser) assign_statement(v Var, ph int, is_map bool) { if v.is_arg { if p.cur_fn.args.len > 0 && p.cur_fn.args[0].name == v.name { println('make the receiver `$v.name` mutable: -fn ($v.name mut $v.typ) $p.cur_fn.name (...) { +fn ($v.name mut $v.typ) ${p.cur_fn.name}(...) { ') } } @@ -1368,8 +1380,8 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) { if !v.is_changed { p.mark_var_changed(v) } - is_str := v.typ == 'string' - is_ustr := v.typ == 'ustring' + is_str := p.expected_type == 'string' + is_ustr := p.expected_type == 'ustring' match tok { .assign { if !is_map && !p.is_empty_c_struct_init { @@ -1378,7 +1390,8 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) { } .plus_assign { if is_str && !p.is_js { - p.gen('= string_add($v.name, ')// TODO can't do `foo.bar += '!'` + expr := p.cgen.cur_line + p.gen('= string_add($expr, ') } else if is_ustr { p.gen('= ustring_add($v.name, ') diff --git a/vlib/strings/similarity.v b/vlib/strings/similarity.v index 0f21d39721..4b4a337ea0 100644 --- a/vlib/strings/similarity.v +++ b/vlib/strings/similarity.v @@ -45,7 +45,8 @@ pub fn dice_coefficient(s1, s2 string) f32 { mut first_bigrams := map[string]int for i := 0; i < a.len-1; i++ { bigram := a[i..i+2] - q := if bigram in first_bigrams { first_bigrams[bigram]+1 } else { 1 } + q := if bigram in first_bigrams { + first_bigrams[bigram]+1 } else { 1 } first_bigrams[bigram] = q } mut intersection_size := 0