@@ -31,10 +31,17 @@ object Mono extends Phase[CoreTransformed, CoreTransformed] {
31
31
val solvedConstraints = solveConstraints(filtered)
32
32
println(" Solved constraints" )
33
33
solvedConstraints.foreach(sc => println(sc))
34
+
35
+ println()
36
+ val monomorphized = monomorphize(core)(using MonoContext (solvedConstraints))
37
+ println(" Mono definitions" )
38
+ monomorphized.definitions.foreach(println)
34
39
} else {
35
40
println(" Cycle detected, skipping solveConstraints" )
36
41
}
37
42
println()
43
+
44
+
38
45
}
39
46
}
40
47
}
@@ -43,6 +50,77 @@ object Mono extends Phase[CoreTransformed, CoreTransformed] {
43
50
}
44
51
}
45
52
53
+ type PolyConstraints = Map [Id , Set [PolyType ]]
54
+ type PolyConstraintsSolved = Map [Id , Set [PolyType .Base ]]
55
+ type PolyConstraintSingle = Map [Id , PolyType .Base ]
56
+
57
+ class MonoContext (val solvedConstraints : PolyConstraintsSolved )
58
+
59
+ var monoCounter = 0
60
+ def freshMonoName (baseId : Id , tpe : PolyType .Base ): Id =
61
+ monoCounter += 1
62
+ Id (baseId.name.name + tpe.tpe.name.name + monoCounter)
63
+
64
+ def freshMonoName (baseId : Id , tpes : List [PolyType .Base ]): Id =
65
+ monoCounter += 1
66
+ var tpesString = " "
67
+ tpes.foreach(tpe => tpesString += tpe.tpe.name.name)
68
+ Id (baseId.name.name + tpesString + monoCounter)
69
+
70
+ // TODO: The following two are awful and surely doing redundant work.
71
+ def generator (xs : List [Set [PolyConstraintSingle ]]): List [Set [PolyConstraintSingle ]] = xs.foldRight(List (Set .empty)) { (next, combinations) =>
72
+ (for (a <- next; as <- combinations) yield as + a).toList
73
+ }
74
+
75
+ def gen (xs : PolyConstraintsSolved ) = {
76
+ (for ((id, constrs) <- xs) yield (for (c <- constrs) yield Map ((id -> c)))).toList
77
+ }
78
+
79
+ def monomorphize (decl : ModuleDecl )(using ctx : MonoContext ): ModuleDecl = decl match
80
+ case ModuleDecl (path, includes, declarations, externs, definitions, exports) =>
81
+ ModuleDecl (path, includes, declarations, externs, definitions flatMap monomorphize, exports)
82
+
83
+ def monomorphize (definition : Toplevel )(using ctx : MonoContext ): List [Toplevel ] = definition match {
84
+ case Toplevel .Def (id, block) => monomorphize(block, id).map((newId, newBlock) => Toplevel .Def (newId, newBlock)).toList
85
+ case Toplevel .Val (id, tpe, binding) => ???
86
+ }
87
+
88
+ def monomorphize (block : Block , baseId : Id )(using ctx : MonoContext ): Map [Id , Block ] = block match {
89
+ case BlockLit (List (), cparams, vparams, bparams, body) => Map (baseId -> block)
90
+ case BlockLit (tparams, cparams, vparams, bparams, body) => {
91
+ // TODO: There is some redundancy here, but it works for now
92
+ val relevantConstraints = tparams.map(tp => Map (tp -> ctx.solvedConstraints.getOrElse(tp, Set .empty)).filter((_, s) => ! s.isEmpty))
93
+ val splitConstraints = relevantConstraints.flatMap(gen)
94
+ val combinations = generator(splitConstraints)
95
+ val flattened = combinations.map(c => c.flatten.toMap)
96
+ flattened.map(f => {
97
+ val newId = freshMonoName(baseId, f.values.toList)
98
+ (newId -> BlockLit (List (), cparams, vparams.map(monomorphize(_, f)), bparams, monomorphize(body, f)))
99
+ }).toMap
100
+ }
101
+ case BlockVar (id, annotatedTpe, annotatedCapt) => ???
102
+ case New (impl) => ???
103
+ case Unbox (pure) => ???
104
+ }
105
+
106
+ def monomorphize (stmt : Stmt , replacementTparam : Map [Id , PolyType .Base ]): Stmt = stmt match {
107
+ case Return (expr) => Return (monomorphize(expr, replacementTparam))
108
+ case _ => ???
109
+ }
110
+
111
+ def monomorphize (pure : Pure , replacementTparam : Map [Id , PolyType .Base ]): Pure = pure match
112
+ case ValueVar (id, annotatedType) => ValueVar (id, monomorphize(annotatedType, replacementTparam))
113
+ case _ => ???
114
+
115
+ def monomorphize (vparam : ValueParam , replacementTparam : Map [Id , PolyType .Base ]): ValueParam = vparam match {
116
+ case ValueParam (id, tpe) => ValueParam (id, monomorphize(tpe, replacementTparam))
117
+ }
118
+
119
+ def monomorphize (valueType : ValueType , replacementTparam : Map [Id , PolyType .Base ]): ValueType = valueType match
120
+ case ValueType .Var (name) => replacementTparam.get(name).get.toValueType
121
+ case ValueType .Data (name, targs) => ???
122
+ case ValueType .Boxed (tpe, capt) => ???
123
+
46
124
// TODO: After solving the constraints it would be helpful to know
47
125
// which functions have which tparams
48
126
// so we can generate the required monomorphic functions
@@ -55,10 +133,12 @@ enum PolyType {
55
133
case Base (tpe) => tpe
56
134
case Var (sym) => sym
57
135
}
58
- }
59
136
60
- type PolyConstraints = Map [Id , Set [PolyType ]]
61
- type PolyConstraintsSolved = Map [Id , Set [PolyType .Base ]]
137
+ def toValueType : ValueType = this match {
138
+ case Base (tpe) => ValueType .Data (tpe, List .empty)
139
+ case Var (sym) => ValueType .Var (sym)
140
+ }
141
+ }
62
142
63
143
def solveConstraints (constraints : PolyConstraints ): PolyConstraintsSolved =
64
144
var solved : PolyConstraintsSolved = Map ()
0 commit comments