simplify & optimize cgen sort_structs

pull/1852/head
joe-conigliaro 2019-09-04 17:35:08 +10:00 committed by Alexander Medvednikov
parent a206667b4d
commit 8e25019634
1 changed files with 26 additions and 43 deletions

View File

@ -296,42 +296,24 @@ fn platform_postfix_to_ifdefguard(name string) string {
// Sort the types, make sure types that are referenced by other types // Sort the types, make sure types that are referenced by other types
// are added before them. // are added before them.
fn (v mut V) c_type_definitions() string { fn (v mut V) c_type_definitions() string {
mut types := []Type // structs that need to be sorted
mut top_types := []Type // builtin types and types that only have primitive fields
mut builtin_types := []Type mut builtin_types := []Type
// builtin types need to be on top // builtin types need to be on top
builtins := ['string', 'array', 'map', 'Option'] builtins := ['string', 'array', 'map', 'Option']
for builtin in builtins { for builtin in builtins {
typ := v.table.typesmap[builtin] typ := v.table.typesmap[builtin]
builtin_types << typ builtin_types << typ
v.table.typesmap.delete(builtin)
} }
// split all types // structs that need to be sorted
mut types := []Type
for _, t in v.table.typesmap { for _, t in v.table.typesmap {
if !t.name[0].is_capital() { if t.name in builtins {
top_types << t
continue
}
mut only_builtin_fields := true
for field in t.fields {
// user types start with a capital or contain __ (defined in another module)
if field.typ[0].is_capital() || field.typ.contains('__') {
only_builtin_fields = false
break
}
}
if only_builtin_fields {
top_types << t
continue continue
} }
types << t types << t
} }
sort_structs(mut top_types)
sort_structs(mut types)
// Generate C code // Generate C code
return types_to_c(builtin_types,v.table) + '\n//----\n' + return types_to_c(builtin_types,v.table) + '\n//----\n' +
types_to_c(top_types, v.table) + '\n/*----*/\n' + types_to_c(sort_structs(types), v.table)
types_to_c(types, v.table)
} }
fn types_to_c(types []Type, table &Table) string { fn types_to_c(types []Type, table &Table) string {
@ -361,41 +343,42 @@ fn types_to_c(types []Type, table &Table) string {
} }
// sort structs by dependant fields // sort structs by dependant fields
fn sort_structs(types mut []Type) { fn sort_structs(types []Type) []Type {
mut graph := new_dep_graph() mut dep_graph := new_dep_graph()
// types list // types name list
mut type_names := []string mut type_names := []string
for i := 0; i < types.len; i++ { for t in types {
type_names << types[i].name type_names << t.name
} }
// loop over types // loop over types
for i := 0; i < types.len; i++ { for t in types {
t := types[i]
// create list of deps // create list of deps
mut field_types := []string mut field_deps := []string
for field in t.fields { for field in t.fields {
// skip if not in types list // skip if not in types list or already in deps
if !(field.typ in type_names) { if !(field.typ in type_names) || field.typ in field_deps {
continue continue
} }
field_types << field.typ field_deps << field.typ
} }
// add type and dependant types to graph // add type and dependant types to graph
graph.add(t.name, field_types) dep_graph.add(t.name, field_deps)
} }
// sort // sort graph
sorted := graph.resolve() dep_graph_sorted := dep_graph.resolve()
// reorder types if !dep_graph_sorted.acyclic {
old_types := types.clone() cerror('error: cgen.sort_structs() DGNAC.\nplease create a new issue here: https://github.com/vlang/v/issues and tag @joe.conigliaro')
for i:=0; i<sorted.nodes.len; i++ { }
node := sorted.nodes[i] // sort types
for j := 0; j < old_types.len; j++ { mut types_sorted := []Type
t := old_types[j] for node in dep_graph_sorted.nodes {
for t in types {
if t.name == node.name { if t.name == node.name {
types[i] = t types_sorted << t
continue continue
} }
} }
} }
return types_sorted
} }