From 6d6b2fdda8ad3596099dfb01fb431c45be674b26 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Fri, 24 Jan 2020 07:08:17 +1100 Subject: [PATCH] compiler: fix depgraph. will also make it work with new b-tree map --- vlib/compiler/depgraph.v | 102 +++++++++++++++++++------------ vlib/filepath/filepath.v | 15 ++--- vlib/filepath/filepath_nix.v | 6 ++ vlib/filepath/filepath_windows.v | 6 ++ 4 files changed, 78 insertions(+), 51 deletions(-) create mode 100644 vlib/filepath/filepath_nix.v create mode 100644 vlib/filepath/filepath_windows.v diff --git a/vlib/compiler/depgraph.v b/vlib/compiler/depgraph.v index 4e92ac64c2..20c9104f27 100644 --- a/vlib/compiler/depgraph.v +++ b/vlib/compiler/depgraph.v @@ -12,34 +12,63 @@ mut: } struct DepGraph { - // pub: -mut: +pub mut: acyclic bool nodes []DepGraphNode } -struct DepSet { +struct OrderedDepMap { mut: - items []string + keys []string + data map[string][]string } -pub fn (dset mut DepSet) add(item string) { - dset.items << item -} - -pub fn (dset &DepSet) diff(otherset DepSet) DepSet { - mut diff := DepSet{ +pub fn (o mut OrderedDepMap) set(name string, deps []string) { + if !(name in o.data) { + o.keys << name } - for item in dset.items { - if !item in otherset.items { - diff.items << item + o.data[name] = deps +} + +pub fn (o mut OrderedDepMap) add(name string, deps []string) { + mut d := o.data[name] + for dep in deps { + if !(dep in d) { + d << dep } } - return diff + o.set(name, d) } -pub fn (dset &DepSet) size() int { - return dset.items.len +pub fn (o &OrderedDepMap) get(name string) []string { + return o.data[name] +} + +pub fn (o mut OrderedDepMap) delete(name string) { + if !(name in o.data) { + panic('delete: no such key: $name') + } + for i, _ in o.keys { + if o.keys[i] == name { + o.keys.delete(i) + break + } + } + o.data.delete(name) +} + +pub fn (o mut OrderedDepMap) apply_diff(name string, deps []string) { + mut diff := []string + for dep in o.data[name] { + if !(dep in deps) { + diff << dep + } + } + o.set(name, diff) +} + +pub fn (o &OrderedDepMap) size() int { + return o.data.size } pub fn new_dep_graph() &DepGraph { @@ -56,40 +85,34 @@ pub fn (graph mut DepGraph) add(mod string, deps []string) { } pub fn (graph &DepGraph) resolve() &DepGraph { - mut node_names := map[string]DepGraphNode - mut node_deps := map[string]DepSet - for _, node in graph.nodes { - node_names[node.name] = node - mut dep_set := DepSet{ - } - for _, dep in node.deps { - dep_set.add(dep) - } - node_deps[node.name] = dep_set + mut node_names := OrderedDepMap{} + for node in graph.nodes { + node_names.add(node.name, node.deps) } + mut node_deps := node_names mut resolved := new_dep_graph() - for node_deps.size != 0 { - mut ready_set := DepSet{ - } - for name, deps in node_deps { - if deps.size() == 0 { - ready_set.add(name) + for node_deps.size() != 0 { + mut ready_set := []string + for name in node_deps.keys { + deps := node_deps.data[name] + if deps.len == 0 { + ready_set << name } } - if ready_set.size() == 0 { + if ready_set.len == 0 { mut g := new_dep_graph() g.acyclic = false - for name, _ in node_deps { - g.nodes << node_names[name] + for name in node_deps.keys { + g.add(name, node_names.data[name]) } return g } - for name in ready_set.items { + for name in ready_set { node_deps.delete(name) - resolved.nodes << node_names[name] + resolved.add(name, node_names.data[name]) } - for name, deps in node_deps { - node_deps[name] = deps.diff(ready_set) + for name in node_deps.keys { + node_deps.apply_diff(name, ready_set) } } return resolved @@ -128,4 +151,3 @@ pub fn (graph &DepGraph) display_cycles() string { } return out } - diff --git a/vlib/filepath/filepath.v b/vlib/filepath/filepath.v index 395a958c24..2f2774f396 100644 --- a/vlib/filepath/filepath.v +++ b/vlib/filepath/filepath.v @@ -1,9 +1,5 @@ module filepath -import ( - os -) - // ext returns the extension in the file `path`. pub fn ext(path string) string { pos := path.last_index('.') or { @@ -28,15 +24,12 @@ pub fn join(base string, dirs ...string) string { for d in dirs { result << d } - return result.join(os.path_separator) + return result.join(path_separator) } // dir returns all but the last element of path, typically the path's directory. pub fn dir(path string) string { - if path == '.' { - return os.getwd() - } - pos := path.last_index(os.path_separator) or { + pos := path.last_index(path_separator) or { return '.' } return path[..pos] @@ -44,7 +37,7 @@ pub fn dir(path string) string { // basedir returns a directory name from path pub fn basedir(path string) string { - pos := path.last_index(os.path_separator) or { + pos := path.last_index(path_separator) or { return path } // NB: *without* terminating / @@ -53,5 +46,5 @@ pub fn basedir(path string) string { // filename returns a file name from path pub fn filename(path string) string { - return path.all_after(os.path_separator) + return path.all_after(path_separator) } diff --git a/vlib/filepath/filepath_nix.v b/vlib/filepath/filepath_nix.v new file mode 100644 index 0000000000..d167b8278e --- /dev/null +++ b/vlib/filepath/filepath_nix.v @@ -0,0 +1,6 @@ +module filepath + +const ( + path_separator = '/' +) + diff --git a/vlib/filepath/filepath_windows.v b/vlib/filepath/filepath_windows.v new file mode 100644 index 0000000000..91ea107922 --- /dev/null +++ b/vlib/filepath/filepath_windows.v @@ -0,0 +1,6 @@ +module filepath + +const ( + path_separator = '\\' +) +