aboutsummaryrefslogtreecommitdiff
path: root/frontend/utilities.icl
diff options
context:
space:
mode:
authormartinw2001-01-12 16:25:02 +0000
committermartinw2001-01-12 16:25:02 +0000
commit18b01b5e638151124207d602d7a751f1f87b50d3 (patch)
tree09717828c1d0bf51b2cef779f9e12923bee20ab6 /frontend/utilities.icl
parentmore node_number=0 statements (diff)
New algorithm for explicit imports that also works with cyclic module dependencies
git-svn-id: https://svn.cs.ru.nl/repos/clean-compiler/trunk@286 1f8540f1-abd5-4d5b-9d24-4c5ce8603e2d
Diffstat (limited to 'frontend/utilities.icl')
-rw-r--r--frontend/utilities.icl133
1 files changed, 132 insertions, 1 deletions
diff --git a/frontend/utilities.icl b/frontend/utilities.icl
index 60a49d9..055f387 100644
--- a/frontend/utilities.icl
+++ b/frontend/utilities.icl
@@ -179,10 +179,18 @@ unsafeFold2St op l1 l2 st
:== ufold_st2 l1 l2 st
where
ufold_st2 [x : xs] [y : ys] st
- = op x y (ufold_st2 xs ys st)
+ = ufold_st2 xs ys (op x y st)
ufold_st2 _ _ st
= st
+unsafeFold3St op l1 l2 l3 st
+ :== ufold_st3 l1 l2 l3 st
+where
+ ufold_st3 [x : xs] [y : ys] [z : zs] st
+ = ufold_st3 xs ys zs (op x y z st)
+ ufold_st3 _ _ _ st
+ = st
+
// foldSt :: !(.a -> .(.st -> .st)) ![.a] !.st -> .st
foldSt op r l :== fold_st r l
where
@@ -232,6 +240,31 @@ iMapFilterYesSt f fr to st
st = st
= (f_fr_t2, st)
+foldlArrayStWithIndex f a st :== fold_a_st_i 0 a st
+ where
+ fold_a_st_i i a st
+ | i==size a
+ = st
+ # (ai, a) = a![i]
+ = fold_a_st_i (i+1) a (f i ai st)
+
+foldlArraySt f a st :== fold_a_st 0 a st
+ where
+ fold_a_st i a st
+ | i==size a
+ = st
+ # (ai, a) = a![i]
+ = fold_a_st (i+1) a (f ai st)
+
+foldrArraySt f a st
+ :== foldr_a_st (size a-1) a st
+ where
+ foldr_a_st i a st
+ | i==(-1)
+ = st
+ # (ai, a) = a![i]
+ = foldr_a_st (i-1) a (f ai st)
+
optCons :: !(Optional .a) !u:[.a] -> (!v:[.a], !Int) ,[u <= v]
optCons No l
= (l, 0)
@@ -294,3 +327,101 @@ bagToList bag
isEmptyBag :: !(Bag x) -> Bool
isEmptyBag Empty = True
isEmptyBag _ = False
+
+:: DAG =
+ { dag_nr_of_nodes :: !Int
+ , dag_get_children :: !Int -> [Int]
+ }
+
+:: PartitioningState =
+ { ps_marks :: !.{# Int}
+ , ps_next_num :: !Int
+ , ps_groups :: ![[Int]]
+ , ps_deps :: ![Int]
+ }
+
+NotChecked :== -1
+
+partitionateDAG :: !DAG ![Int] -> [[Int]]
+partitionateDAG pi=:{dag_nr_of_nodes} roots
+ # partitioning_info
+ = { ps_marks = createArray dag_nr_of_nodes NotChecked, ps_deps = [],
+ ps_next_num = 0, ps_groups = [] }
+ {ps_groups}
+ = foldSt (partitionate_node pi) roots partitioning_info
+ = ps_groups
+where
+ partitionate_node :: !DAG !Int !*PartitioningState -> *PartitioningState
+ partitionate_node pi node_index ps=:{ps_marks}
+ | ps_marks.[node_index] == NotChecked
+ = snd (partitionate_unvisited_node node_index pi ps)
+ = ps
+
+ partitionate_unvisited_node :: !Int !DAG !*PartitioningState
+ -> (!Int, !*PartitioningState)
+ partitionate_unvisited_node node_index pi ps=:{ps_next_num}
+ # children
+ = pi.dag_get_children node_index
+ (min_dep, ps)
+ = visit_children children pi.dag_nr_of_nodes pi (push_on_dep_stack node_index ps)
+ = try_to_close_group node_index ps_next_num min_dep pi ps
+
+ push_on_dep_stack :: !Int !*PartitioningState -> *PartitioningState
+ push_on_dep_stack node_index ps=:{ps_deps,ps_marks,ps_next_num}
+ = { ps & ps_deps = [node_index : ps_deps], ps_marks = { ps_marks & [node_index] = ps_next_num},
+ ps_next_num = inc ps_next_num}
+
+ visit_children :: ![Int] !Int !DAG !*PartitioningState -> (!Int, !*PartitioningState)
+ visit_children [child:children] min_dep pi ps=:{ps_marks}
+ #! mark = ps_marks.[child]
+ | mark == NotChecked
+ # (mark, ps) = partitionate_unvisited_node child pi ps
+ = visit_children children (min min_dep mark) pi ps
+ = visit_children children (min min_dep mark) pi ps
+ visit_children [] min_dep nr_of_nodes ps
+ = (min_dep, ps)
+
+
+ try_to_close_group :: !Int !Int !Int !DAG !*PartitioningState -> (!Int, !*PartitioningState)
+ try_to_close_group node_index next_num min_dep pi ps=:{ps_marks, ps_deps, ps_groups}
+ | next_num <= min_dep
+ # (ps_deps, ps_marks, group)
+ = close_group node_index ps_deps ps_marks [] pi
+ ps = { ps & ps_deps = ps_deps, ps_marks = ps_marks, ps_groups = [group : ps_groups] }
+ = (pi.dag_nr_of_nodes, ps)
+ = (min_dep, ps)
+
+ close_group :: !Int ![Int] !*{# Int} ![Int] !DAG -> (![Int], !*{# Int}, ![Int])
+ close_group node_index [d:ds] marks group pi
+ # marks = { marks & [d] = pi.dag_nr_of_nodes }
+ | d == node_index
+ = (ds, marks, [d : group])
+ = close_group node_index ds marks [d : group] pi
+
+replaceTwoDimArrElt :: !Int !Int !.e !{!*{!.e}} -> (!.e, !{!.{!.e}})
+replaceTwoDimArrElt ix1 ix2 el arr
+ # (inner_array, arr)
+ = replace arr ix1 {}
+ (el2, inner_array)
+ = replace inner_array ix2 el
+ = (el2, { arr & [ix1] = inner_array })
+/* crashes!
+replaceTwoDimArrElt ix1 ix2 el arr = code
+ { | A:arr el B:ix2 ix1
+ push_b 0 | A:arr el B:ix2 ix1 ix1
+ update_b 2 1 | A:arr el B:ix2 ix2 ix1
+ update_b 0 2 | A:arr el B:ix1 ix2 ix1
+ push_a 1 | A:arr el arr B:ix1 ix2 ix1
+ select _ 1 0 | A:arr el arr.[ix1] B:ix1 ix2
+ push_array 0
+ updatepop_a 0 1
+ replace _ 1 0 | A:arr arr.[ix1]* new_el B:ix1
+ push_a 2 | A:arr arr.[ix1]* new_el arr B:ix1
+ update_a 1 3 | A:new_el arr.[ix1]* new_el arr B:ix1
+ update_a 2 1 | A:new_el arr.[ix1]* arr.[ix1]* arr B:ix1
+ update _ 1 0 | A:new_el arr.[ix1]* arr*
+ update_a 2 1 | A:new_el new_el arr*
+ update_a 0 2 | A:arr* new_el arr*
+ pop_a 1 | A:arr* new_el
+ }
+*/ \ No newline at end of file