Skip to content

Commit 49cfe83

Browse files
committed
Emit monomorphized definitions
1 parent 0001362 commit 49cfe83

File tree

1 file changed

+83
-3
lines changed
  • effekt/shared/src/main/scala/effekt/core

1 file changed

+83
-3
lines changed

effekt/shared/src/main/scala/effekt/core/Mono.scala

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,17 @@ object Mono extends Phase[CoreTransformed, CoreTransformed] {
3131
val solvedConstraints = solveConstraints(filtered)
3232
println("Solved constraints")
3333
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)
3439
} else {
3540
println("Cycle detected, skipping solveConstraints")
3641
}
3742
println()
43+
44+
3845
}
3946
}
4047
}
@@ -43,6 +50,77 @@ object Mono extends Phase[CoreTransformed, CoreTransformed] {
4350
}
4451
}
4552

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+
46124
// TODO: After solving the constraints it would be helpful to know
47125
// which functions have which tparams
48126
// so we can generate the required monomorphic functions
@@ -55,10 +133,12 @@ enum PolyType {
55133
case Base(tpe) => tpe
56134
case Var(sym) => sym
57135
}
58-
}
59136

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+
}
62142

63143
def solveConstraints(constraints: PolyConstraints): PolyConstraintsSolved =
64144
var solved: PolyConstraintsSolved = Map()

0 commit comments

Comments
 (0)