mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
use custom type for TopologicalSort result
This commit is contained in:
parent
48ce1c14bf
commit
28cb9bf36e
2 changed files with 32 additions and 8 deletions
|
@ -8,6 +8,7 @@ use crate::expr::{canonicalize_expr, Output, Recursive};
|
|||
use crate::pattern::{bindings_from_patterns, canonicalize_def_header_pattern, Pattern};
|
||||
use crate::procedure::References;
|
||||
use crate::reference_matrix::ReferenceMatrix;
|
||||
use crate::reference_matrix::TopologicalSort;
|
||||
use crate::scope::create_alias;
|
||||
use crate::scope::Scope;
|
||||
use roc_collections::{default_hasher, ImEntry, ImMap, ImSet, MutMap, MutSet, SendMap};
|
||||
|
@ -812,7 +813,7 @@ pub fn sort_can_defs(
|
|||
// TODO also do the same `addDirects` check elm/compiler does, so we can
|
||||
// report an error if a recursive definition can't possibly terminate!
|
||||
match def_ids.references.topological_sort_into_groups() {
|
||||
Ok(groups) => {
|
||||
TopologicalSort::Groups { groups } => {
|
||||
let mut declarations = Vec::new();
|
||||
|
||||
// groups are in reversed order
|
||||
|
@ -828,7 +829,10 @@ pub fn sort_can_defs(
|
|||
|
||||
(Ok(declarations), output)
|
||||
}
|
||||
Err((mut groups, nodes_in_cycle)) => {
|
||||
TopologicalSort::HasCycles {
|
||||
mut groups,
|
||||
nodes_in_cycle,
|
||||
} => {
|
||||
let mut declarations = Vec::new();
|
||||
let mut problems = Vec::new();
|
||||
|
||||
|
|
|
@ -50,13 +50,12 @@ impl ReferenceMatrix {
|
|||
//
|
||||
// Thank you, Samuel!
|
||||
impl ReferenceMatrix {
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn topological_sort_into_groups(&self) -> Result<Vec<Vec<u32>>, (Vec<Vec<u32>>, Vec<u32>)> {
|
||||
pub fn topological_sort_into_groups(&self) -> TopologicalSort {
|
||||
let length = self.length;
|
||||
let bitvec = &self.bitvec;
|
||||
|
||||
if length == 0 {
|
||||
return Ok(Vec::new());
|
||||
return TopologicalSort::Groups { groups: Vec::new() };
|
||||
}
|
||||
|
||||
let mut preds_map: Vec<i64> = vec![0; length];
|
||||
|
@ -85,7 +84,11 @@ impl ReferenceMatrix {
|
|||
|
||||
if prev_group.is_empty() {
|
||||
let remaining: Vec<u32> = (0u32..length as u32).collect();
|
||||
return Err((Vec::new(), remaining));
|
||||
|
||||
return TopologicalSort::HasCycles {
|
||||
groups: Vec::new(),
|
||||
nodes_in_cycle: remaining,
|
||||
};
|
||||
}
|
||||
|
||||
while preds_map.iter().any(|x| *x > 0) {
|
||||
|
@ -114,12 +117,16 @@ impl ReferenceMatrix {
|
|||
let remaining: Vec<u32> = (0u32..length as u32)
|
||||
.filter(|i| preds_map[*i as usize] > 0)
|
||||
.collect();
|
||||
return Err((groups, remaining));
|
||||
|
||||
return TopologicalSort::HasCycles {
|
||||
groups,
|
||||
nodes_in_cycle: remaining,
|
||||
};
|
||||
}
|
||||
}
|
||||
groups.push(prev_group);
|
||||
|
||||
Ok(groups)
|
||||
TopologicalSort::Groups { groups }
|
||||
}
|
||||
|
||||
pub fn strongly_connected_components(&self, group: &[u32]) -> Vec<Vec<u32>> {
|
||||
|
@ -141,6 +148,19 @@ impl ReferenceMatrix {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) enum TopologicalSort {
|
||||
/// There were no cycles, all nodes have been partitioned into groups
|
||||
Groups { groups: Vec<Vec<u32>> },
|
||||
/// Cycles were found. All nodes that are not part of a cycle have been partitioned
|
||||
/// into groups. The other elements are in the `cyclic` vector. However, there may be
|
||||
/// many cycles, or just one big one. Use strongly-connected components to find out
|
||||
/// exactly what the cycles are and how they fit into the groups.
|
||||
HasCycles {
|
||||
groups: Vec<Vec<u32>>,
|
||||
nodes_in_cycle: Vec<u32>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Preorder {
|
||||
Empty,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue