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

parser: fix a bug with complex ref fn args

This commit is contained in:
Alexander Medvednikov 2019-11-10 21:54:28 +03:00
parent 76c27c0b03
commit f30d0ce667
4 changed files with 72 additions and 12 deletions

View File

@ -270,6 +270,18 @@ fn (s mut Scanner) eat_single_newline(){
/////////////////////////////// ///////////////////////////////
fn (p mut Parser) mutable_arg_error(i int, arg Var, f Fn) {
mut dots_example := 'mut $p.lit'
if i > 0 {
dots_example = '.., ' + dots_example
}
if i < f.args.len - 1 {
dots_example = dots_example + ',..'
}
p.error('`$arg.name` is a mutable argument, you need to provide `mut`: ' +
'`$f.name($dots_example)`')
}
const ( const (
warn_match_arrow = '=> is no longer needed in match statements, use\n' + warn_match_arrow = '=> is no longer needed in match statements, use\n' +
'match foo { 'match foo {

View File

@ -933,6 +933,21 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
if f.args.len > 1 { // && !p.is_js { if f.args.len > 1 { // && !p.is_js {
p.gen(', ') p.gen(', ')
} }
//if f.args[0].typ.ends_with('*') {
//p.gen('&/*119*/')
//}
/*
pos := p.cgen.cur_line.index('/* ? */')
if pos > -1 {
expr := p.cgen.cur_line[pos..]
// TODO hack
// If current expression is a func call, generate the array hack
if expr.contains('(') {
p.cgen.set_placeholder(pos, '(${arg.typ[..arg.typ.len-1]}[]){')
p.gen('}[0] ')
}
}
*/
continue continue
} }
// Reached the final vararg? Quit // Reached the final vararg? Quit
@ -948,14 +963,7 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
// `mut numbers := [1,2,3]; reverse(mut numbers);` // `mut numbers := [1,2,3]; reverse(mut numbers);`
if arg.is_mut { if arg.is_mut {
if p.tok != .key_mut && p.tok == .name { if p.tok != .key_mut && p.tok == .name {
mut dots_example := 'mut $p.lit' p.mutable_arg_error(i, arg, f)
if i > 0 {
dots_example = '.., ' + dots_example
}
if i < f.args.len - 1 {
dots_example = dots_example + ',..'
}
p.error('`$arg.name` is a mutable argument, you need to provide `mut`: `$f.name($dots_example)`')
} }
if p.peek() != .name { if p.peek() != .name {
p.error('`$arg.name` is a mutable argument, you need to provide a variable to modify: `$f.name(... mut a...)`') p.error('`$arg.name` is a mutable argument, you need to provide a variable to modify: `$f.name(... mut a...)`')
@ -1105,13 +1113,26 @@ fn (p mut Parser) fn_call_args(f mut Fn) {
p.cgen.set_placeholder(ph, '& /*111*/ (array[]){') p.cgen.set_placeholder(ph, '& /*111*/ (array[]){')
p.gen('}[0] ') p.gen('}[0] ')
} }
else if exp_ptr && expected == got + '*' {
expr := p.cgen.cur_line[ph..]
// TODO hack
// If current expression is a func call, generate the array hack
if expr.contains('(') {
//println('fn hack expr=$expr')
p.cgen.set_placeholder(ph, '& /*113 e="$expected" g="$got"*/ ($got[]){')
p.gen('}[0] ')
} else {
p.cgen.set_placeholder(ph, '& /*114*/')
}
}
// println('\ne:"$expected" got:"$got"') // println('\ne:"$expected" got:"$got"')
else if ! (expected == 'void*' && got == 'int') && else if ! (expected == 'void*' && got == 'int') &&
! (expected == 'byte*' && got.contains(']byte')) && ! (expected == 'byte*' && got.contains(']byte')) &&
! (expected == 'byte*' && got == 'string') && ! (expected == 'byte*' && got == 'string') &&
//! (expected == 'void*' && got == 'array_int') { //! (expected == 'void*' && got == 'array_int') {
! (expected == 'byte*' && got == 'byteptr') { ! (expected == 'byte*' && got == 'byteptr') {
p.cgen.set_placeholder(ph, '& /*112 EXP:"$expected" GOT:"$got" */') p.cgen.set_placeholder(ph, '& /*112 e="$expected" g="$got" */')
} }
} }
} }

View File

@ -21,6 +21,8 @@ multi line comment (3)
multi line comment (2) multi line comment (2)
*/ */
import time
type myfn fn (int) string type myfn fn (int) string
type myfn2 fn (a int, b int) int type myfn2 fn (a int, b int) int
@ -119,3 +121,29 @@ fn test_fns() {
// no asserts for now, just test function declarations above // no asserts for now, just test function declarations above
} }
struct Foo {
}
fn process_foo(foo &Foo) {
}
fn get_foo() Foo {
return Foo{}
}
// This used to be broken.
fn test_ref_fn_arg() {
process_foo(get_foo())
println(3434)
assert true
/*
res := (time.random().calc_unix())
println(res)
assert true
*/
}

View File

@ -110,7 +110,6 @@ pub fn now() Time {
pub fn random() Time { pub fn random() Time {
now_unix := now().uni now_unix := now().uni
rand_unix := rand.next(now_unix) rand_unix := rand.next(now_unix)
return time.unix(rand_unix) return time.unix(rand_unix)
} }