1
0
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:
bogen85 2019-11-29 02:11:53 -06:00 committed by Alexander Medvednikov
parent 729f9c3391
commit e31d892598
3 changed files with 74 additions and 32 deletions

View File

@ -127,15 +127,15 @@ fn (v mut V) new_parser_from_file(path string) Parser {
if path_ending == '_mac.v' { if path_ending == '_mac.v' {
p := path_ending.replace('_mac.v', '_darwin.v') p := path_ending.replace('_mac.v', '_darwin.v')
println('warning: use "$p" file name instead of "$path"') println('warning: use "$p" file name instead of "$path"')
} }
if path_ending == '_lin.v' { if path_ending == '_lin.v' {
p := path_ending.replace('_lin.v', '_linux.v') p := path_ending.replace('_lin.v', '_linux.v')
println('warning: use "$p" file name instead of "$path"') println('warning: use "$p" file name instead of "$path"')
} }
if path_ending == '_win.v' { if path_ending == '_win.v' {
p := path_ending.replace('_win.v', '_windows.v') p := path_ending.replace('_win.v', '_windows.v')
println('warning: use "$p" file name instead of "$path"') println('warning: use "$p" file name instead of "$path"')
} }
path_platform = path_ending path_platform = path_ending
path_pcguard = platform_postfix_to_ifdefguard( path_ending ) path_pcguard = platform_postfix_to_ifdefguard( path_ending )
break break
@ -160,7 +160,7 @@ fn (v mut V) new_parser_from_file(path string) Parser {
//if p.pref.generating_vh { //if p.pref.generating_vh {
// Keep newlines // Keep newlines
//p.scanner.is_vh = true //p.scanner.is_vh = true
//} //}
p.scan_tokens() p.scan_tokens()
//p.scanner.debug_tokens() //p.scanner.debug_tokens()
return p return p
@ -220,7 +220,7 @@ fn (p mut Parser) next() {
// (only when vfmt compile time flag is enabled, otherwise this function // (only when vfmt compile time flag is enabled, otherwise this function
// is not even generated) // is not even generated)
p.fnext() p.fnext()
p.prev_tok2 = p.prev_tok p.prev_tok2 = p.prev_tok
p.prev_tok = p.tok p.prev_tok = p.tok
p.scanner.prev_tok = p.tok p.scanner.prev_tok = p.tok
@ -248,7 +248,7 @@ fn (p &Parser) peek() TokenKind {
tok := p.tokens[i] tok := p.tokens[i]
if tok.tok != .mline_comment && tok.tok != .line_comment { if tok.tok != .mline_comment && tok.tok != .line_comment {
return tok.tok return tok.tok
} }
i++ i++
} }
return .eof return .eof
@ -464,7 +464,7 @@ fn (p mut Parser) parse(pass Pass) {
!p.pref.enable_globals !p.pref.enable_globals
{ {
p.error('use `v --enable-globals ...` to enable globals') p.error('use `v --enable-globals ...` to enable globals')
//p.error('__global is only allowed in translated code') //p.error('__global is only allowed in translated code')
} }
p.next() p.next()
@ -489,7 +489,7 @@ fn (p mut Parser) parse(pass Pass) {
if p.tok != .key_global { if p.tok != .key_global {
// An extra empty line to separate a block of globals // An extra empty line to separate a block of globals
p.fgen_nl() p.fgen_nl()
} }
} }
.eof { .eof {
//p.log('end of parse()') //p.log('end of parse()')
@ -612,7 +612,7 @@ fn (p mut Parser) const_decl() {
is_pub := p.tok == .key_pub is_pub := p.tok == .key_pub
if is_pub { if is_pub {
p.next() p.next()
} }
p.inside_const = true p.inside_const = true
p.check(.key_const) p.check(.key_const)
p.fspace() p.fspace()
@ -797,10 +797,10 @@ fn (p &Parser) strtok() string {
} }
if p.tok == .number { if p.tok == .number {
return p.lit return p.lit
} }
if p.tok == .chartoken { if p.tok == .chartoken {
return '`$p.lit`' return '`$p.lit`'
} }
if p.tok == .str { if p.tok == .str {
if p.lit.contains("'") { if p.lit.contains("'") {
return '"$p.lit"' return '"$p.lit"'
@ -945,7 +945,7 @@ fn (p mut Parser) get_type() string {
p.register_map(typ) p.register_map(typ)
return typ return typ
} }
// ptr/ref // ptr/ref
mut warn := false mut warn := false
for p.tok == .mul { 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() { else if !t.is_public && t.mod != p.mod && !p.is_vgen && t.name != '' && !p.first_pass() {
p.error('type `$t.name` is private') p.error('type `$t.name` is private')
} }
} }
if typ == 'void' { if typ == 'void' {
p.error('unknown type `$typ`') p.error('unknown type `$typ`')
@ -1262,7 +1262,7 @@ fn (p mut Parser) statement(add_semi bool) string {
p.check(.lcbr) p.check(.lcbr)
if p.tok == .rcbr { if p.tok == .rcbr {
p.error('empty statements block') p.error('empty statements block')
} }
p.genln('{') p.genln('{')
p.statements() p.statements()
return '' return ''
@ -1289,7 +1289,7 @@ fn (p mut Parser) statement(add_semi bool) string {
} }
.key_asm { .key_asm {
p.inline_asm() p.inline_asm()
} }
else { else {
// An expression as a statement // An expression as a statement
typ := p.expression() 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) p.gen_handle_option_or_else(expr_type, vname, ph)
} }
else if expr_type[0]==`[` { 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 expr := p.cgen.cur_line[pos..].all_after('{').all_before('}') // TODO cgen line hack
left := p.cgen.cur_line[..pos].all_before('=') left := p.cgen.cur_line[..pos].all_before('=')
cline_pos := p.cgen.cur_line[pos..] 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] == '_' { if is_decl_assign && var_names.len == 1 && var_names[0] == '_' {
p.error_with_token_index('use `=` instead of `:=`', var_token_idxs.last()) 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) t := p.gen_var_decl(p.var_decl_name, is_static)
if t == 'void' { if t == 'void' {
_, fn_name := p.is_expr_fn_call(p.token_idx-3) _, 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' { if !p.inside_unsafe && !p.pref.building_v && p.mod != 'os' {
p.error('dereferencing can only be done inside an `unsafe` block') p.error('dereferencing can only be done inside an `unsafe` block')
} }
*/ */
if !typ.contains('*') && !typ.ends_with('ptr') { if !typ.contains('*') && !typ.ends_with('ptr') {
println('name="$name", t=$v.typ') 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 { if !c.is_public && c.mod != p.mod {
p.warn('constant `$c.name` is private') p.warn('constant `$c.name` is private')
} }
mut typ := p.var_expr(c) mut typ := p.var_expr(c)
if is_ptr { if is_ptr {
typ += '*' 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_') { if field_name == 'filter' && str_typ.starts_with('array_') {
p.gen_array_filter(str_typ, method_ph) p.gen_array_filter(str_typ, method_ph)
return str_typ return str_typ
} }
else if field_name == 'map' && str_typ.starts_with('array_') { else if field_name == 'map' && str_typ.starts_with('array_') {
return p.gen_array_map(str_typ, method_ph) return p.gen_array_map(str_typ, method_ph)
} }
fname_tidx := p.cur_tok_index() fname_tidx := p.cur_tok_index()
//p.log('dot() field_name=$field_name typ=$str_typ') //p.log('dot() field_name=$field_name typ=$str_typ')
//if p.fileis('main.v') { //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 { if p.builtin_mod || p.pref.is_bare {
p.gen('.str[') p.gen('.str[')
close_bracket = true close_bracket = true
} }
else { else {
// Bounds check everywhere else // Bounds check everywhere else
p.gen(', ') p.gen(', ')
@ -2029,7 +2029,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
typ = 'string' typ = 'string'
} else { } else {
p.error('slicing is supported by arrays and strings only') p.error('slicing is supported by arrays and strings only')
} }
is_slice = true is_slice = true
p.next() p.next()
p.gen(',') p.gen(',')
@ -2042,7 +2042,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
else { else {
p.gen('-1, true') p.gen('-1, true')
} }
} }
} }
else { else {
T := p.table.find_type(p.expression()) T := p.table.find_type(p.expression())
@ -2444,7 +2444,7 @@ fn (p mut Parser) array_init() string {
expected_array_type := p.expected_type expected_array_type := p.expected_type
//if p.fileis('interface_') { //if p.fileis('interface_') {
//println('a exp='+p.expected_type) //println('a exp='+p.expected_type)
//} //}
p.is_alloc = true p.is_alloc = true
p.check(.lsbr) p.check(.lsbr)
mut is_integer := p.tok == .number // for `[10]int` 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 expected_array_type.ends_with('er') {
if p.satisfies_interface(expected_array_type, typ, false) { if p.satisfies_interface(expected_array_type, typ, false) {
ok = true ok = true
} }
} }
if !ok { if !ok {
p.error('bad array element type `$val_typ` instead of `$typ`') 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 { // vals.len == 0 {
if exp_array { if exp_array {
p.error('no need to specify the full array type here, use `[]` instead of `[]${p.expected_type[6..]}`') p.error('no need to specify the full array type here, use `[]` instead of `[]${p.expected_type[6..]}`')
} }
typ = p.get_type() typ = p.get_type()
} else if exp_array && i == 0 { } else if exp_array && i == 0 {
// allow `known_array = []` // allow `known_array = []`
typ = p.expected_type[6..] typ = p.expected_type[6..]
} }
// ! after array => no malloc and no copy // ! after array => no malloc and no copy
no_alloc := p.tok == .not no_alloc := p.tok == .not
if no_alloc { if no_alloc {
@ -2734,7 +2734,7 @@ if (!$tmp) {
') ')
return return
} }
p.genln(';\n p.genln(';\n
if (!$tmp) { if (!$tmp) {
g_test_fails++; g_test_fails++;
@ -3069,4 +3069,4 @@ fn (p mut Parser) is_expr_fn_call(start_tok_idx int) (bool, string) {
fn todo_remove() { fn todo_remove() {
x64.new_gen('f') x64.new_gen('f')
} }

View 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
}

View 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
}
}