mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
compiler: small fixes + some logic for freeing strings
This commit is contained in:
@@ -89,6 +89,17 @@ fn (p mut Parser) mark_var_changed(v Var) {
|
||||
p.local_vars[v.idx].is_changed = true
|
||||
}
|
||||
|
||||
fn (p mut Parser) mark_arg_moved(v Var) {
|
||||
for i, arg in p.cur_fn.args {
|
||||
if arg.name == v.name {
|
||||
//println('setting f $p.cur_fn.name arg $arg.name to is_mut')
|
||||
p.cur_fn.args[i].is_moved = true
|
||||
break
|
||||
}
|
||||
}
|
||||
p.table.fns[p.cur_fn.name] = p.cur_fn
|
||||
}
|
||||
|
||||
fn (p mut Parser) known_var(name string) bool {
|
||||
_ = p.find_var(name) or {
|
||||
return false
|
||||
@@ -759,7 +770,7 @@ fn (p mut Parser) fn_args(f mut Fn) {
|
||||
if is_mut {
|
||||
typ += '*'
|
||||
}
|
||||
v := Var {
|
||||
v := Var{
|
||||
name: name
|
||||
typ: typ
|
||||
is_arg: true
|
||||
@@ -775,7 +786,7 @@ fn (p mut Parser) fn_args(f mut Fn) {
|
||||
p.next()
|
||||
}
|
||||
if p.tok == .dotdot {
|
||||
f.args << Var {
|
||||
f.args << Var{
|
||||
name: '..'
|
||||
}
|
||||
p.next()
|
||||
@@ -818,10 +829,9 @@ fn (p mut Parser) fn_call_args(f mut Fn) &Fn {
|
||||
'_panic_debug ($p.scanner.line_nr, tos2((byte *)"$file_path"), tos2((byte *)"$mod_name"), tos2((byte *)"$fn_name"), '
|
||||
))
|
||||
}
|
||||
// Receiver - first arg
|
||||
for i, arg in f.args {
|
||||
// println('$i) arg=$arg.name')
|
||||
// Skip receiver, because it was already generated in the expression
|
||||
// Receiver is the first arg
|
||||
// Skip the receiver, because it was already generated in the expression
|
||||
if i == 0 && f.is_method {
|
||||
if f.args.len > 1 && !p.is_js {
|
||||
p.gen(',')
|
||||
@@ -865,7 +875,14 @@ fn (p mut Parser) fn_call_args(f mut Fn) &Fn {
|
||||
}
|
||||
}
|
||||
p.expected_type = arg.typ
|
||||
clone := p.pref.autofree && arg.typ == 'string' && arg.is_moved && p.mod != 'builtin'
|
||||
if clone {
|
||||
p.gen('/*YY f=$f.name arg=$arg.name is_moved=$arg.is_moved*/string_clone(')
|
||||
}
|
||||
mut typ := p.bool_expression()
|
||||
if clone {
|
||||
p.gen(')')
|
||||
}
|
||||
// Optimize `println`: replace it with `printf` to avoid extra allocations and
|
||||
// function calls.
|
||||
// `println(777)` => `printf("%d\n", 777)`
|
||||
@@ -927,9 +944,20 @@ fn (p mut Parser) fn_call_args(f mut Fn) &Fn {
|
||||
expected := arg.typ
|
||||
// println('fn arg got="$got" exp="$expected"')
|
||||
if !p.check_types_no_throw(got, expected) {
|
||||
mut err := 'Fn "$f.name" wrong arg #${i+1}. '
|
||||
err += 'Expected "$arg.typ" ($arg.name) but got "$typ"'
|
||||
p.error(err)
|
||||
mut j := i
|
||||
if f.is_method {
|
||||
j--
|
||||
}
|
||||
mut nr := '${i+1}th'
|
||||
if j == 0 {
|
||||
nr = 'first'
|
||||
} else if j == 1 {
|
||||
nr = 'second'
|
||||
} else if j == 2 {
|
||||
nr = 'third'
|
||||
}
|
||||
p.error('cannot use type `$typ` as type `$arg.typ` in $nr ' +
|
||||
'argument to `$f.name()`')
|
||||
}
|
||||
is_interface := p.table.is_interface(arg.typ)
|
||||
// Add `&` or `*` before an argument?
|
||||
|
||||
Reference in New Issue
Block a user