From 23e30962b9f373c25605ef34fae7fc15a21cfda5 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Mon, 23 Sep 2019 20:39:35 +1000 Subject: [PATCH] compiler: multiple returns - add test & fix use with array/map --- compiler/fn.v | 2 +- compiler/parser.v | 12 +++++------- compiler/tests/fn_multiple_returns_test.v | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 compiler/tests/fn_multiple_returns_test.v diff --git a/compiler/fn.v b/compiler/fn.v index f2b01bec97..957c232add 100644 --- a/compiler/fn.v +++ b/compiler/fn.v @@ -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;' diff --git a/compiler/parser.v b/compiler/parser.v index e78e7f2505..7bd49ff8d2 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -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(' ') { diff --git a/compiler/tests/fn_multiple_returns_test.v b/compiler/tests/fn_multiple_returns_test.v new file mode 100644 index 0000000000..063c7dd882 --- /dev/null +++ b/compiler/tests/fn_multiple_returns_test.v @@ -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 +}