compiler: multiple returns - add test & fix use with array/map

pull/2083/head
joe-conigliaro 2019-09-23 20:39:35 +10:00 committed by Alexander Medvednikov
parent 60d932e57d
commit 23e30962b9
3 changed files with 25 additions and 8 deletions

View File

@ -293,7 +293,7 @@ fn (p mut Parser) fn_decl() {
name: typ,
mod: p.mod
})
for i, t in typ.replace('MultiReturn_', '').replace('0ptr0', '*').split('_') {
for i, t in typ.replace('MultiReturn_', '').replace('_ZptrZ_', '*').split('_Z_') {
p.table.add_field(typ, 'var_$i', t, false, '', .public)
}
p.cgen.typedefs << 'typedef struct $typ $typ;'

View File

@ -835,14 +835,12 @@ fn (p mut Parser) get_type() string {
mut typ := ''
// multiple returns
if p.tok == .lpar {
// if p.inside_tuple {
// p.error('unexpected (')
// }
// if p.inside_tuple {p.error('unexpected (')}
// p.inside_tuple = true
p.check(.lpar)
mut types := []string
for {
types << p.get_type()
types << p.get_type()
if p.tok != .comma {
break
}
@ -850,7 +848,7 @@ fn (p mut Parser) get_type() string {
}
p.check(.rpar)
// p.inside_tuple = false
return 'MultiReturn_' + types.join('_').replace('*', '0ptr0')
return 'MultiReturn_' + types.join('_Z_').replace('*', '_ZptrZ_')
}
// fn type
if p.tok == .func {
@ -1361,7 +1359,7 @@ fn (p mut Parser) var_decl() {
// multiple returns
if names.len > 1 {
// should we register __ret var?
types = t.replace('MultiReturn_', '').replace('0ptr0', '*').split('_')
types = t.replace('MultiReturn_', '').replace('_ZptrZ_', '*').split('_Z_')
}
for i, name in names {
typ := types[i]
@ -3588,7 +3586,7 @@ fn (p mut Parser) return_st() {
}
// multiple returns
if types.len > 1 {
expr_type = 'MultiReturn_' + types.join('_').replace('*', '0ptr0')
expr_type = 'MultiReturn_' + types.join('_Z_').replace('*', '_ZptrZ_')
ret_vals := p.cgen.cur_line.right(ph)
mut ret_fields := ''
for ret_val_idx, ret_val in ret_vals.split(' ') {

View File

@ -0,0 +1,19 @@
struct UserData {
test string
}
fn test_fn_multiple_returns() {
name, age, groups, data := fn_mr_get_user()
assert name == 'joe'
assert age == 34
assert groups[0] == 'admins'
assert groups[1] == 'users'
assert data.test == 'Test Data'
println('name: $name | age: $age | groups: ' + groups.join(',') + ' | data: $data.test')
}
fn fn_mr_get_user() (string, int, []string, UserData) {
groups := ['admins', 'users']
data := UserData{test: 'Test Data'}
return 'joe',34,groups,data
}