From b4d033ff54bde811fa569c2a86db7ea3729ce16f Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Wed, 4 Sep 2019 02:11:21 +1000 Subject: [PATCH] compiler: generalize mod dag & use for sorting structs also --- compiler/cgen.v | 47 ++++++++----- compiler/depgraph.v | 130 +++++++++++++++++++++++++++++++++++ compiler/main.v | 2 +- compiler/modules.v | 127 ++-------------------------------- vlib/encoding/csv/csv_test.v | 69 +++++++++---------- 5 files changed, 200 insertions(+), 175 deletions(-) create mode 100644 compiler/depgraph.v diff --git a/compiler/cgen.v b/compiler/cgen.v index bd86ecb064..23b9eb9e4f 100644 --- a/compiler/cgen.v +++ b/compiler/cgen.v @@ -360,24 +360,39 @@ fn types_to_c(types []Type, table &Table) string { return sb.str() } -// pretty inefficient algo, works fine with N < 1000 (TODO optimize) +// sort structs by dependant fields fn sort_structs(types mut []Type) { - mut cnt := 0 + mut graph := new_dep_graph() + // types list + mut type_names := []string for i := 0; i < types.len; i++ { - for j in 0 .. i { - t := types[i] - //t2 := types[j] - // check if any of the types before `t` reference `t` - if types[j].contains_field_type(t.name) { - //println('moving up: $t.name len=$types.len') - types.insert(j, t) - types.delete(i+1) - i = 0 // Start from scratch - cnt++ - if cnt > 500 { - println('infinite type loop (perhaps you have a recursive struct `$t.name`?)') - exit(1) - } + type_names << types[i].name + } + // loop over types + for i := 0; i < types.len; i++ { + t := types[i] + // create list of deps + mut field_types := []string + for field in t.fields { + // skip if not in types list + if !(field.typ in type_names) { + continue + } + field_types << field.typ + } + // add type and dependant types to graph + graph.add(t.name, field_types) + } + // sort + sorted := graph.resolve() + // reorder types + old_types := types.clone() + for i:=0; i 'VROOT/vlib/strings' // 'installed_mod' => '~/.vmodules/installed_mod' // 'local_mod' => '/path/to/current/dir/local_mod' diff --git a/vlib/encoding/csv/csv_test.v b/vlib/encoding/csv/csv_test.v index 74bf980391..08e7c80539 100644 --- a/vlib/encoding/csv/csv_test.v +++ b/vlib/encoding/csv/csv_test.v @@ -1,41 +1,40 @@ -// Skip this test until struct field order bug is fixed -// import encoding.csv +import encoding.csv -// fn test_encoding_csv_reader() { -// data := 'name,email,phone,other\njoe,joe@blow.com,0400000000,test\nsam,sam@likesham.com,0433000000,"test quoted field"\n#chris,chris@nomail.com,94444444,"commented row"\nmike,mike@mikesbikes.com,98888888,"bike store"\n' -// mut csv_reader := csv.new_reader(data) +fn test_encoding_csv_reader() { + data := 'name,email,phone,other\njoe,joe@blow.com,0400000000,test\nsam,sam@likesham.com,0433000000,"test quoted field"\n#chris,chris@nomail.com,94444444,"commented row"\nmike,mike@mikesbikes.com,98888888,"bike store"\n' + mut csv_reader := csv.new_reader(data) -// mut row_count := 0 -// for { -// row := csv_reader.read() or { -// break -// } -// row_count++ -// if row_count== 1 { -// assert row[0] == 'name' -// } -// if row_count == 2 { -// assert row[0] == 'joe' -// } -// if row_count == 3 { -// assert row[0] == 'sam' -// // quoted field -// assert row[3] == 'test quoted field' -// } -// if row_count == 4 { -// assert row[0] == 'mike' -// } -// } + mut row_count := 0 + for { + row := csv_reader.read() or { + break + } + row_count++ + if row_count== 1 { + assert row[0] == 'name' + } + if row_count == 2 { + assert row[0] == 'joe' + } + if row_count == 3 { + assert row[0] == 'sam' + // quoted field + assert row[3] == 'test quoted field' + } + if row_count == 4 { + assert row[0] == 'mike' + } + } -// assert row_count == 4 -// } + assert row_count == 4 +} -// fn test_encoding_csv_writer() { -// mut csv_writer := csv.new_writer() +fn test_encoding_csv_writer() { + mut csv_writer := csv.new_writer() -// csv_writer.write(['name', 'email', 'phone', 'other']) -// csv_writer.write(['joe', 'joe@blow.com', '0400000000', 'test']) -// csv_writer.write(['sam', 'sam@likesham.com', '0433000000', 'needs, quoting']) + csv_writer.write(['name', 'email', 'phone', 'other']) + csv_writer.write(['joe', 'joe@blow.com', '0400000000', 'test']) + csv_writer.write(['sam', 'sam@likesham.com', '0433000000', 'needs, quoting']) -// assert csv_writer.str() == 'name,email,phone,other\njoe,joe@blow.com,0400000000,test\nsam,sam@likesham.com,0433000000,"needs, quoting"\n' -// } + assert csv_writer.str() == 'name,email,phone,other\njoe,joe@blow.com,0400000000,test\nsam,sam@likesham.com,0433000000,"needs, quoting"\n' +}