@@ -14,12 +14,21 @@ object Mono extends Phase[CoreTransformed, CoreTransformed] {
14
14
case CoreTransformed (source, tree, mod, core) => {
15
15
core match {
16
16
case ModuleDecl (path, includes, declarations, externs, definitions, exports) => {
17
+ // Find constraints in the definitions
17
18
val constraints = findConstraints(definitions)
18
19
println(" Constraints" )
19
20
constraints.foreach(c => println(c))
20
21
println()
21
- if (! hasCycle(constraints)) {
22
- val solvedConstraints = solveConstraints(constraints)
22
+
23
+ // Filter out self referencing constraints
24
+ val filtered = constraints.map((id, tpes) => (id, tpes.filter(tpe => tpe.toSymbol != id)))
25
+ println(" Filtered" )
26
+ filtered.foreach(f => println(f))
27
+ println()
28
+
29
+ // Solve if constraints are non-cyclic
30
+ if (! hasCycle(filtered)) {
31
+ val solvedConstraints = solveConstraints(filtered)
23
32
println(" Solved constraints" )
24
33
solvedConstraints.foreach(sc => println(sc))
25
34
} else {
@@ -67,63 +76,58 @@ def solveConstraints(constraints: PolyConstraints): PolyConstraints =
67
76
68
77
solved
69
78
70
- def appendConstraint (map : PolyConstraints , sym : Id , tpe : ValueType ): PolyConstraintEntry =
71
- val currentFlow = map.getOrElse(sym, Set ())
72
- println(" Append: " + tpe + " , " + sym)
73
- tpe match {
74
- // Ignore self cycling types A -> A
75
- case ValueType .Data (name, targs) if name != sym => (sym -> (currentFlow + PolyType .Base (name)))
76
- case ValueType .Var (name) if name != sym => (sym -> (currentFlow + PolyType .Var (name)))
77
- // TODO: What do we do with boxed types?
78
- case o@ ValueType .Boxed (tpe, capt) =>
79
- println(" Hit boxed type: " + o)
80
- (sym -> currentFlow)
81
- case _ => (sym -> currentFlow) // self cycling flow
82
- }
83
-
84
- def findConstraintRec (value : Val , typeFlow : PolyConstraints ): PolyConstraints =
85
- var newTypeFlow = typeFlow
86
- value.binding match {
87
- case App (callee, targ :: targs, vargs, bargs) =>
88
- callee match {
89
- case BlockVar (id, annotatedTpe, annotatedCapt) =>
90
- annotatedTpe match {
91
- case BlockType .Function (tparam :: tparams, cparams, vparams, bparams, result) =>
92
- newTypeFlow += appendConstraint(newTypeFlow, tparam, targ)
93
- case _ =>
94
- }
95
- case _ =>
96
- }
97
- case _ =>
98
- }
99
- value.body match {
100
- case v@ Val (_, _, _, _) => findConstraintRec(v, newTypeFlow)
101
- case _ => newTypeFlow
102
- }
79
+ def combineConstraints (a : PolyConstraints , b : PolyConstraints ): PolyConstraints = {
80
+ a ++ b.map { case (k, v) => k -> (v ++ a.getOrElse(k, Iterable .empty)) }
81
+ }
103
82
104
83
def findConstraints (definitions : List [Toplevel ]): PolyConstraints =
105
- var typeFlow : PolyConstraints = Map ()
106
- definitions.foreach {
107
- case Toplevel .Def (id, block) =>
108
- block match
109
- case BlockLit (tparam :: tparams, cparams, vparams, bparams, body) =>
110
- body match {
111
- case v@ Val (id, annotatedTpe, binding, body) =>
112
- typeFlow ++= findConstraintRec(v, typeFlow)
113
- case Return (expr) =>
114
- typeFlow += appendConstraint(typeFlow, tparam, expr.tpe)
115
- case _ =>
116
- }
117
- case BlockLit (tparams, cparams, vparams, bparams, body) =>
118
- body match {
119
- case v@ Val (id, annotatedTpe, binding, body) =>
120
- typeFlow ++= findConstraintRec(v, typeFlow)
121
- case _ =>
122
- }
123
- case _ =>
124
- case _ =>
125
- }
126
- typeFlow
84
+ definitions.map(findConstraints).reduce(combineConstraints)
85
+
86
+ def findConstraints (toplevel : Toplevel ): PolyConstraints = toplevel match {
87
+ case Toplevel .Def (id, block) => findConstraints(block, List .empty)
88
+ case Toplevel .Val (id, tpe, binding) => ???
89
+ }
90
+
91
+ def findConstraints (block : Block , targs : List [ValueType ]): PolyConstraints = block match {
92
+ case BlockLit (tparam :: tparams, cparams, vparams, bparams, body) => findConstraints(body, tparam :: tparams)
93
+ case BlockLit (List (), cparams, vparams, bparams, body) => findConstraints(body, List .empty)
94
+ case BlockVar (id, annotatedTpe, annotatedCapt) => findConstraints(annotatedTpe, targs)
95
+ case New (impl) => ???
96
+ case Unbox (pure) => ???
97
+ case _ => Map .empty
98
+ }
99
+
100
+ def findConstraints (stmt : Stmt , tparams : List [Id ]): PolyConstraints = stmt match {
101
+ case App (callee, targs, vargs, bargs) => findConstraints(callee, targs)
102
+ case Return (expr) if ! tparams.isEmpty => Map (tparams.head -> Set (findPolyType(expr.tpe)))
103
+ case Return (expr) => Map .empty
104
+ case Val (id, annotatedTpe, binding, body) => combineConstraints(findConstraints(binding, tparams), findConstraints(body, tparams))
105
+ // TODO: Let & If case is wrong, but placeholders are required as they are used in print
106
+ case Let (id, annotatedTpe, binding, body) => Map .empty
107
+ case If (cond, thn, els) => Map .empty
108
+ case o => println(o); ???
109
+ }
110
+
111
+ def findConstraints (value : Val ): PolyConstraints = value match {
112
+ // TODO: List.empty might be wrong
113
+ case Val (id, annotatedTpe, binding, body) => combineConstraints(findConstraints(binding, List .empty), findConstraints(body, List .empty))
114
+ }
115
+
116
+ def findConstraints (blockType : BlockType , targs : List [ValueType ]): PolyConstraints = blockType match {
117
+ case BlockType .Function (tparams, cparams, vparams, bparams, result) => tparams.zip(targs).map((id, tpe) => (id -> Set (findPolyType(tpe)))).toMap
118
+ case BlockType .Interface (name, targs) => ???
119
+ }
120
+
121
+ def findPolyType (blockType : BlockType , targs : List [ValueType ]): List [PolyType ] = blockType match {
122
+ case BlockType .Function (tparams, cparams, vparams, bparams, result) => ???
123
+ case BlockType .Interface (name, targs) => ???
124
+ }
125
+
126
+ def findPolyType (valueType : ValueType ): PolyType = valueType match {
127
+ case ValueType .Boxed (tpe, capt) => ???
128
+ case ValueType .Data (name, targs) => PolyType .Base (name)
129
+ case ValueType .Var (name) => PolyType .Var (name)
130
+ }
127
131
128
132
def hasCycle (constraints : PolyConstraints ): Boolean =
129
133
var visited : Set [Id ] = Set ()
0 commit comments