mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
make _V_mret_ unique by putting p.token_idx in it
This commit is contained in:
parent
729f9c3391
commit
e31d892598
@ -127,15 +127,15 @@ fn (v mut V) new_parser_from_file(path string) Parser {
|
||||
if path_ending == '_mac.v' {
|
||||
p := path_ending.replace('_mac.v', '_darwin.v')
|
||||
println('warning: use "$p" file name instead of "$path"')
|
||||
}
|
||||
}
|
||||
if path_ending == '_lin.v' {
|
||||
p := path_ending.replace('_lin.v', '_linux.v')
|
||||
println('warning: use "$p" file name instead of "$path"')
|
||||
}
|
||||
}
|
||||
if path_ending == '_win.v' {
|
||||
p := path_ending.replace('_win.v', '_windows.v')
|
||||
println('warning: use "$p" file name instead of "$path"')
|
||||
}
|
||||
}
|
||||
path_platform = path_ending
|
||||
path_pcguard = platform_postfix_to_ifdefguard( path_ending )
|
||||
break
|
||||
@ -160,7 +160,7 @@ fn (v mut V) new_parser_from_file(path string) Parser {
|
||||
//if p.pref.generating_vh {
|
||||
// Keep newlines
|
||||
//p.scanner.is_vh = true
|
||||
//}
|
||||
//}
|
||||
p.scan_tokens()
|
||||
//p.scanner.debug_tokens()
|
||||
return p
|
||||
@ -220,7 +220,7 @@ fn (p mut Parser) next() {
|
||||
// (only when vfmt compile time flag is enabled, otherwise this function
|
||||
// is not even generated)
|
||||
p.fnext()
|
||||
|
||||
|
||||
p.prev_tok2 = p.prev_tok
|
||||
p.prev_tok = p.tok
|
||||
p.scanner.prev_tok = p.tok
|
||||
@ -248,7 +248,7 @@ fn (p &Parser) peek() TokenKind {
|
||||
tok := p.tokens[i]
|
||||
if tok.tok != .mline_comment && tok.tok != .line_comment {
|
||||
return tok.tok
|
||||
}
|
||||
}
|
||||
i++
|
||||
}
|
||||
return .eof
|
||||
@ -464,7 +464,7 @@ fn (p mut Parser) parse(pass Pass) {
|
||||
!p.pref.enable_globals
|
||||
{
|
||||
p.error('use `v --enable-globals ...` to enable globals')
|
||||
|
||||
|
||||
//p.error('__global is only allowed in translated code')
|
||||
}
|
||||
p.next()
|
||||
@ -489,7 +489,7 @@ fn (p mut Parser) parse(pass Pass) {
|
||||
if p.tok != .key_global {
|
||||
// An extra empty line to separate a block of globals
|
||||
p.fgen_nl()
|
||||
}
|
||||
}
|
||||
}
|
||||
.eof {
|
||||
//p.log('end of parse()')
|
||||
@ -612,7 +612,7 @@ fn (p mut Parser) const_decl() {
|
||||
is_pub := p.tok == .key_pub
|
||||
if is_pub {
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
p.inside_const = true
|
||||
p.check(.key_const)
|
||||
p.fspace()
|
||||
@ -797,10 +797,10 @@ fn (p &Parser) strtok() string {
|
||||
}
|
||||
if p.tok == .number {
|
||||
return p.lit
|
||||
}
|
||||
}
|
||||
if p.tok == .chartoken {
|
||||
return '`$p.lit`'
|
||||
}
|
||||
}
|
||||
if p.tok == .str {
|
||||
if p.lit.contains("'") {
|
||||
return '"$p.lit"'
|
||||
@ -945,7 +945,7 @@ fn (p mut Parser) get_type() string {
|
||||
p.register_map(typ)
|
||||
return typ
|
||||
}
|
||||
|
||||
|
||||
// ptr/ref
|
||||
mut warn := false
|
||||
for p.tok == .mul {
|
||||
@ -1009,7 +1009,7 @@ fn (p mut Parser) get_type() string {
|
||||
}
|
||||
else if !t.is_public && t.mod != p.mod && !p.is_vgen && t.name != '' && !p.first_pass() {
|
||||
p.error('type `$t.name` is private')
|
||||
}
|
||||
}
|
||||
}
|
||||
if typ == 'void' {
|
||||
p.error('unknown type `$typ`')
|
||||
@ -1262,7 +1262,7 @@ fn (p mut Parser) statement(add_semi bool) string {
|
||||
p.check(.lcbr)
|
||||
if p.tok == .rcbr {
|
||||
p.error('empty statements block')
|
||||
}
|
||||
}
|
||||
p.genln('{')
|
||||
p.statements()
|
||||
return ''
|
||||
@ -1289,7 +1289,7 @@ fn (p mut Parser) statement(add_semi bool) string {
|
||||
}
|
||||
.key_asm {
|
||||
p.inline_asm()
|
||||
}
|
||||
}
|
||||
else {
|
||||
// An expression as a statement
|
||||
typ := p.expression()
|
||||
@ -1387,7 +1387,7 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) {
|
||||
p.gen_handle_option_or_else(expr_type, vname, ph)
|
||||
}
|
||||
else if expr_type[0]==`[` {
|
||||
// assignment to a fixed_array `mut a:=[3]int a=[1,2,3]!!`
|
||||
// assignment to a fixed_array `mut a:=[3]int a=[1,2,3]!!`
|
||||
expr := p.cgen.cur_line[pos..].all_after('{').all_before('}') // TODO cgen line hack
|
||||
left := p.cgen.cur_line[..pos].all_before('=')
|
||||
cline_pos := p.cgen.cur_line[pos..]
|
||||
@ -1471,7 +1471,7 @@ fn (p mut Parser) var_decl() {
|
||||
if is_decl_assign && var_names.len == 1 && var_names[0] == '_' {
|
||||
p.error_with_token_index('use `=` instead of `:=`', var_token_idxs.last())
|
||||
}
|
||||
p.var_decl_name = if var_names.len > 1 { '_V_mret_'+var_names.join('_') } else { var_names[0] }
|
||||
p.var_decl_name = if var_names.len > 1 { '_V_mret_${p.token_idx}_'+var_names.join('_') } else { var_names[0] }
|
||||
t := p.gen_var_decl(p.var_decl_name, is_static)
|
||||
if t == 'void' {
|
||||
_, fn_name := p.is_expr_fn_call(p.token_idx-3)
|
||||
@ -1597,7 +1597,7 @@ fn (p mut Parser) get_var_type(name string, is_ptr bool, deref_nr int) string {
|
||||
/*
|
||||
if !p.inside_unsafe && !p.pref.building_v && p.mod != 'os' {
|
||||
p.error('dereferencing can only be done inside an `unsafe` block')
|
||||
}
|
||||
}
|
||||
*/
|
||||
if !typ.contains('*') && !typ.ends_with('ptr') {
|
||||
println('name="$name", t=$v.typ')
|
||||
@ -1633,7 +1633,7 @@ fn (p mut Parser) get_const_type(name string, is_ptr bool) string {
|
||||
}
|
||||
if !c.is_public && c.mod != p.mod {
|
||||
p.warn('constant `$c.name` is private')
|
||||
}
|
||||
}
|
||||
mut typ := p.var_expr(c)
|
||||
if is_ptr {
|
||||
typ += '*'
|
||||
@ -1784,11 +1784,11 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string {
|
||||
if field_name == 'filter' && str_typ.starts_with('array_') {
|
||||
p.gen_array_filter(str_typ, method_ph)
|
||||
return str_typ
|
||||
}
|
||||
}
|
||||
else if field_name == 'map' && str_typ.starts_with('array_') {
|
||||
return p.gen_array_map(str_typ, method_ph)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fname_tidx := p.cur_tok_index()
|
||||
//p.log('dot() field_name=$field_name typ=$str_typ')
|
||||
//if p.fileis('main.v') {
|
||||
@ -1959,7 +1959,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
||||
if p.builtin_mod || p.pref.is_bare {
|
||||
p.gen('.str[')
|
||||
close_bracket = true
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Bounds check everywhere else
|
||||
p.gen(', ')
|
||||
@ -2029,7 +2029,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
||||
typ = 'string'
|
||||
} else {
|
||||
p.error('slicing is supported by arrays and strings only')
|
||||
}
|
||||
}
|
||||
is_slice = true
|
||||
p.next()
|
||||
p.gen(',')
|
||||
@ -2042,7 +2042,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
||||
else {
|
||||
p.gen('-1, true')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
T := p.table.find_type(p.expression())
|
||||
@ -2444,7 +2444,7 @@ fn (p mut Parser) array_init() string {
|
||||
expected_array_type := p.expected_type
|
||||
//if p.fileis('interface_') {
|
||||
//println('a exp='+p.expected_type)
|
||||
//}
|
||||
//}
|
||||
p.is_alloc = true
|
||||
p.check(.lsbr)
|
||||
mut is_integer := p.tok == .number // for `[10]int`
|
||||
@ -2508,8 +2508,8 @@ fn (p mut Parser) array_init() string {
|
||||
if expected_array_type.ends_with('er') {
|
||||
if p.satisfies_interface(expected_array_type, typ, false) {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
p.error('bad array element type `$val_typ` instead of `$typ`')
|
||||
}
|
||||
@ -2537,12 +2537,12 @@ fn (p mut Parser) array_init() string {
|
||||
// vals.len == 0 {
|
||||
if exp_array {
|
||||
p.error('no need to specify the full array type here, use `[]` instead of `[]${p.expected_type[6..]}`')
|
||||
}
|
||||
}
|
||||
typ = p.get_type()
|
||||
} else if exp_array && i == 0 {
|
||||
// allow `known_array = []`
|
||||
typ = p.expected_type[6..]
|
||||
}
|
||||
}
|
||||
// ! after array => no malloc and no copy
|
||||
no_alloc := p.tok == .not
|
||||
if no_alloc {
|
||||
@ -2734,7 +2734,7 @@ if (!$tmp) {
|
||||
')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
p.genln(';\n
|
||||
if (!$tmp) {
|
||||
g_test_fails++;
|
||||
@ -3069,4 +3069,4 @@ fn (p mut Parser) is_expr_fn_call(start_tok_idx int) (bool, string) {
|
||||
|
||||
fn todo_remove() {
|
||||
x64.new_gen('f')
|
||||
}
|
||||
}
|
||||
|
15
vlib/compiler/tests/repeated_multiret_values_test.v
Normal file
15
vlib/compiler/tests/repeated_multiret_values_test.v
Normal file
@ -0,0 +1,15 @@
|
||||
// verify fix for #2913
|
||||
|
||||
fn some_multiret_fn(a int, b int) (int, int) {
|
||||
return a+1, b+1
|
||||
}
|
||||
|
||||
fn test_repeated_multiple_multiret() {
|
||||
a, b := some_multiret_fn(1,2)
|
||||
assert a == 2
|
||||
assert b == 3
|
||||
|
||||
c, d := some_multiret_fn(3,4)
|
||||
assert c == 4
|
||||
assert d == 5
|
||||
}
|
27
vlib/compiler/tests/reusable_mut_multiret_values_test.v
Normal file
27
vlib/compiler/tests/reusable_mut_multiret_values_test.v
Normal file
@ -0,0 +1,27 @@
|
||||
// verify fix for #2913
|
||||
|
||||
fn some_multiret_fn(a int, b int) (int, int) {
|
||||
return a+1, b+1
|
||||
}
|
||||
|
||||
fn test_reuse_multiple_multiret() {
|
||||
mut c, mut d := some_multiret_fn(4,10)
|
||||
|
||||
mut a, mut b := some_multiret_fn(c,d)
|
||||
assert a == c+1
|
||||
assert b == d+1
|
||||
|
||||
for i in 1..10 {
|
||||
c += i
|
||||
d += i
|
||||
a, b = some_multiret_fn(c,d)
|
||||
assert a == c+1
|
||||
assert b == d+1
|
||||
|
||||
c += i+1
|
||||
d += i+1
|
||||
a, b = some_multiret_fn(c,d)
|
||||
assert a == c+1
|
||||
assert b == d+1
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user