simplify & optimize cgen sort_structs
parent
a206667b4d
commit
8e25019634
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue