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

cgen: make multi return decl order consistant & use typedefs. closes #7728

This commit is contained in:
Joe Conigliaro 2020-12-31 21:55:21 +11:00
parent 20f507651e
commit b2bd2c9337
No known key found for this signature in database
GPG Key ID: C12F7136C08206F1
3 changed files with 34 additions and 30 deletions

View File

@ -362,6 +362,7 @@ pub fn (mut g Gen) init() {
g.cheaders.writeln('#include <spawn.h>')
}
g.write_builtin_types()
g.write_multi_return_typedefs()
g.write_typedef_types()
g.write_typeof_functions()
if g.pref.build_mode != .build_module {
@ -369,7 +370,7 @@ pub fn (mut g Gen) init() {
g.write_str_fn_definitions()
}
g.write_sorted_types()
g.write_multi_return_types()
g.write_multi_return_structs()
g.definitions.writeln('// end of definitions #endif')
//
g.stringliterals.writeln('')
@ -654,13 +655,8 @@ static inline void __${typ.cname}_pushval($typ.cname ch, $el_stype val) {
pub fn (mut g Gen) write_fn_typesymbol_declaration(sym table.TypeSymbol) {
info := sym.info as table.FnType
func := info.func
mut retsym := g.table.get_type_symbol(func.return_type)
is_multi := retsym.kind == .multi_return
is_fn_sig := func.name == ''
not_anon := !info.is_anon
if is_multi {
g.write_multi_return_type_declaration(mut retsym)
}
if !info.has_decl && (not_anon || is_fn_sig) {
fn_name := sym.cname
g.type_definitions.write('typedef ${g.typ(func.return_type)} (*$fn_name)(')
@ -674,30 +670,30 @@ pub fn (mut g Gen) write_fn_typesymbol_declaration(sym table.TypeSymbol) {
}
}
pub fn (mut g Gen) write_multi_return_type_declaration(mut sym table.TypeSymbol) {
if sym.is_written {
return
}
info := sym.info as table.MultiReturn
g.type_definitions.writeln('typedef struct {')
// TODO copy pasta StructDecl
// for field in struct_info.fields {
for i, mr_typ in info.types {
type_name := g.typ(mr_typ)
g.type_definitions.writeln('\t$type_name arg$i;')
}
g.type_definitions.writeln('} $sym.cname;\n')
// g.typedefs.writeln('typedef struct $name $name;')
sym.is_written = true
}
pub fn (mut g Gen) write_multi_return_types() {
g.type_definitions.writeln('\n// BEGIN_multi_return_structs')
for idx in 0 .. g.table.types.len {
if g.table.types[idx].kind != .multi_return {
pub fn (mut g Gen) write_multi_return_typedefs() {
g.type_definitions.writeln('\n// BEGIN_multi_return_typedefs')
for sym in g.table.types {
if sym.kind != .multi_return {
continue
}
g.write_multi_return_type_declaration(mut g.table.types[idx])
g.type_definitions.writeln('typedef struct $sym.cname $sym.cname;')
}
g.type_definitions.writeln('// END_multi_return_typedefs\n')
}
pub fn (mut g Gen) write_multi_return_structs() {
g.type_definitions.writeln('\n// BEGIN_multi_return_structs')
for sym in g.table.types {
if sym.kind != .multi_return {
continue
}
info := sym.info as table.MultiReturn
g.type_definitions.writeln('struct $sym.cname {')
for i, mr_typ in info.types {
type_name := g.typ(mr_typ)
g.type_definitions.writeln('\t$type_name arg$i;')
}
g.type_definitions.writeln('};\n')
}
g.type_definitions.writeln('// END_multi_return_structs\n')
}

View File

@ -42,7 +42,6 @@ pub mut:
methods []Fn
mod string
is_public bool
is_written bool // set to true, when the backend definition for a symbol had been written, to avoid duplicates
language Language
}
@ -183,7 +182,6 @@ pub fn (ts TypeSymbol) debug() []string {
res << 'info: $ts.info'
res << 'kind: $ts.kind'
res << 'is_public: $ts.is_public'
res << 'is_written: $ts.is_written'
res << 'language: $ts.language'
res << 'methods ($ts.methods.len): ' + ts.methods.map(it.str()).join(', ')
return res

View File

@ -390,5 +390,15 @@ fn test_multi_return() {
value: 'one'
}, Two{
value: 'two'
})"
anon_a := fn() (One, Two) {
one := One{}
two := Two{}
return one, two
}
assert '$anon_a()' == "(One{
value: 'one'
}, Two{
value: 'two'
})"
}