@@ -17,6 +17,8 @@ object Mono extends Phase[CoreTransformed, CoreTransformed] {
17
17
val polys = findConstraints(definitions)
18
18
polys.foreach(p => println(p))
19
19
println()
20
+ println(" Has cycle: " + hasCycle(polys))
21
+ println()
20
22
}
21
23
}
22
24
}
@@ -30,8 +32,13 @@ object Mono extends Phase[CoreTransformed, CoreTransformed] {
30
32
// so we can generate the required monomorphic functions
31
33
32
34
enum PolyType {
33
- case Var (val sym : symbols.Symbol )
34
35
case Base (val tpe : symbols.Symbol )
36
+ case Var (val sym : symbols.Symbol )
37
+
38
+ def toSymbol : symbols.Symbol = this match {
39
+ case Base (tpe) => tpe
40
+ case Var (sym) => sym
41
+ }
35
42
}
36
43
37
44
type PolyConstraints = Map [symbols.Symbol , Set [PolyType ]]
@@ -94,29 +101,25 @@ def findConstraints(definitions: List[Toplevel]): PolyConstraints =
94
101
}
95
102
typeFlow
96
103
97
- object PolyGraphCalc {
98
- var visited : Set [symbols.Symbol ] = Set ()
99
- var recStack : Set [symbols.Symbol ] = Set ()
104
+ def hasCycle ( constraints : PolyConstraints ) : Boolean =
105
+ var visited : Set [symbols.Symbol ] = Set ()
106
+ var recStack : Set [symbols.Symbol ] = Set ()
100
107
101
- def hasCycle (vertex : symbols.Symbol , adjacency : PolyConstraints ): Boolean =
102
- if (recStack.contains(vertex)) return true
108
+ def hasCycleHelper (vertex : symbols.Symbol ): Boolean =
109
+ if (recStack.contains(vertex)) return true
110
+ if (visited.contains(vertex)) return false
103
111
104
- if (visited.contains(vertex)) return false
112
+ visited += vertex
113
+ recStack += vertex
105
114
106
- visited += vertex
107
- recStack += vertex
115
+ var cycleFound = false
116
+ constraints.getOrElse( vertex, Set ()).foreach(v => cycleFound |= hasCycleHelper(v.toSymbol))
108
117
109
- adjacency.foreach((v, edges) => if (hasCycle(v, adjacency)) return true )
118
+ recStack -= vertex
110
119
111
- recStack -= vertex
112
- false
113
-
114
- def hasCycle (constraints : PolyConstraints ): Boolean =
115
- visited = Set ()
116
- recStack = Set ()
117
-
118
- constraints.keys.foreach(v => if (hasCycle(v, constraints)) return true )
119
-
120
- false
121
- }
120
+ cycleFound
121
+
122
+ var cycleFound = false
123
+ constraints.keys.foreach(v => cycleFound |= ! visited.contains(v) && hasCycleHelper(v))
122
124
125
+ cycleFound
0 commit comments