Skip to content

Commit 6ab615d

Browse files
committed
Monomorphize Declarations
1 parent 3ca38a4 commit 6ab615d

File tree

1 file changed

+69
-137
lines changed
  • effekt/shared/src/main/scala/effekt/core

1 file changed

+69
-137
lines changed

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

Lines changed: 69 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ object Mono extends Phase[CoreTransformed, CoreTransformed] {
1515
core match {
1616
case ModuleDecl(path, includes, declarations, externs, definitions, exports) => {
1717
// Find constraints in the definitions
18-
val constraints = findConstraints(definitions)(using new MonoFindContext)
18+
val monoFindContext = MonoFindContext()
19+
val constraints = findConstraints(definitions)(using monoFindContext)
20+
val declConstraints = declarations map (findConstraints(_)(using monoFindContext))
1921
// println("Constraints")
2022
// constraints.foreach(c => println(c))
2123
// println()
@@ -34,9 +36,12 @@ object Mono extends Phase[CoreTransformed, CoreTransformed] {
3436
)
3537
)
3638

37-
val monoDefs = monomorphize(definitions)(using MonoContext(solution, monoNames))
39+
var monoContext = MonoContext(solution, monoNames)
40+
val monoDecls = declarations flatMap (monomorphize(_)(using monoContext))
41+
val monoDefs = monomorphize(definitions)(using monoContext)
42+
// monoDecls.foreach(decl => println(util.show(decl)))
3843
// monoDefs.foreach(defn => println(util.show(defn)))
39-
val newModuleDecl = ModuleDecl(path, includes, declarations, externs, monoDefs, exports)
44+
val newModuleDecl = ModuleDecl(path, includes, monoDecls, externs, monoDefs, exports)
4045
return Some(CoreTransformed(source, tree, mod, newModuleDecl))
4146
}
4247
}
@@ -82,12 +87,28 @@ def findConstraints(definition: Toplevel)(using ctx: MonoFindContext): Constrain
8287
case Toplevel.Def(id, block) => ???
8388
case Toplevel.Val(id, tpe, binding) => ???
8489

90+
def findConstraints(declaration: Declaration)(using ctx: MonoFindContext): Constraints = declaration match
91+
case Data(id, List(), constructors) => List.empty
92+
case Data(id, tparams, constructors) =>
93+
tparams.zipWithIndex.foreach(ctx.extendTypingContext(_, _, id))
94+
constructors.map((constr =>
95+
Constraint(((constr.fields map (_.tpe)) map findId).toVector, constr.id)))
96+
case Interface(id, List(), properties) => List.empty
97+
case Interface(id, tparams, properties) =>
98+
tparams.zipWithIndex.foreach(ctx.extendTypingContext(_, _, id))
99+
List.empty
100+
85101
def findConstraints(block: Block)(using ctx: MonoFindContext): Constraints = block match
86102
case BlockVar(id, annotatedTpe, annotatedCapt) => ???
87103
case BlockLit(tparams, cparams, vparams, bparams, body) => ???
88104
case Unbox(pure) => ???
89105
case New(impl) => ???
90106

107+
def findConstraints(constructor: Constructor)(using ctx: MonoFindContext): Constraints = constructor match
108+
case Constructor(id, List()) => List.empty
109+
case Constructor(id, fields) =>
110+
List(Constraint(((fields map (_.tpe)) map findId).toVector, id))
111+
91112
def findConstraints(stmt: Stmt)(using ctx: MonoFindContext): Constraints = stmt match
92113
case Let(id, annotatedTpe, binding, body) => findConstraints(binding) ++ findConstraints(body)
93114
case Return(expr) => findConstraints(expr)
@@ -100,6 +121,7 @@ def findConstraints(expr: Expr)(using ctx: MonoFindContext): Constraints = expr
100121
case DirectApp(b, List(), vargs, bargs) => List.empty
101122
case ValueVar(id, annotatedType) => List.empty
102123
case Literal(value, annotatedType) => List.empty
124+
case Make(data, tag, targs, vargs) => List(Constraint(data.targs.map(findId).toVector, data.name))
103125
case o => println(o); ???
104126

105127
def findId(vt: ValueType)(using ctx: MonoFindContext): TypeArg = vt match
@@ -115,10 +137,10 @@ def solveConstraints(constraints: Constraints): Solution =
115137

116138
while (true) {
117139
val previousSolved = solved
118-
vecConstraints.foreach((sym, tas) =>
119-
val sol = solveConstraints(sym).map(bs => bs.toVector)
120-
solved += (sym -> sol)
121-
)
140+
vecConstraints.foreach((sym, tas) =>
141+
val sol = solveConstraints(sym).map(bs => bs.toVector)
142+
solved += (sym -> sol)
143+
)
122144
if (previousSolved == solved) return solved
123145
}
124146

@@ -162,10 +184,35 @@ def monomorphize(toplevel: Toplevel)(using ctx: MonoContext): List[Toplevel] = t
162184
case Toplevel.Def(id, block) => ???
163185
case Toplevel.Val(id, tpe, binding) => ???
164186

187+
def monomorphize(decl: Declaration)(using ctx: MonoContext): List[Declaration] = decl match
188+
case Data(id, List(), constructors) => List(decl)
189+
case Data(id, tparams, constructors) =>
190+
val monoTypes = ctx.solution.getOrElse(id, Set.empty).toList
191+
monoTypes.map(baseTypes =>
192+
val replacementTparams = tparams.zip(baseTypes).toMap
193+
ctx.replacementTparams ++= replacementTparams
194+
val newConstructors = constructors map {
195+
case Constructor(id, List()) => Constructor(id, List.empty)
196+
case Constructor(id, fields) => Constructor(id, fields map monomorphize)
197+
}
198+
Declaration.Data(ctx.names(id, baseTypes), List.empty, newConstructors)
199+
)
200+
case Interface(id, List(), properties) => List(decl)
201+
case Interface(id, tparams, properties) =>
202+
val monoTypes = ctx.solution.getOrElse(id, Set.empty).toList
203+
monoTypes.map(baseTypes =>
204+
val replacementTparams = tparams.zip(baseTypes).toMap
205+
ctx.replacementTparams ++= replacementTparams
206+
Declaration.Interface(ctx.names(id, baseTypes), List.empty, properties)
207+
)
208+
165209
def monomorphize(block: Block)(using ctx: MonoContext): Block = block match
166210
case b: BlockVar => monomorphize(b)
167211
case o => println(o); ???
168212

213+
def monomorphize(field: Field)(using ctx: MonoContext): Field = field match
214+
case Field(id, tpe) => Field(id, monomorphize(tpe))
215+
169216
def monomorphize(blockVar: BlockVar, replacementId: FunctionId)(using ctx: MonoContext): BlockVar = blockVar match
170217
case BlockVar(id, BlockType.Function(List(), cparams, vparams, bparams, result), annotatedCapt) => blockVar
171218
// TODO: What is in annotated captures. Does it need to be handled?
@@ -176,26 +223,30 @@ def monomorphize(blockVar: BlockVar, replacementId: FunctionId)(using ctx: MonoC
176223

177224
def monomorphize(stmt: Stmt)(using ctx: MonoContext): Stmt = stmt match
178225
case Return(expr) => Return(monomorphize(expr))
179-
case Val(id, annotatedTpe, binding, body) => Val(id, monomorphize(annotatedTpe), monomorphize(binding), monomorphize(body))
226+
case Val(id, annotatedTpe, binding, body) =>
227+
Val(id, monomorphize(annotatedTpe), monomorphize(binding), monomorphize(body))
180228
case App(callee: BlockVar, targs, vargs, bargs) =>
181-
val replacementId = replacementIdFromTargs(callee.id, targs)
182-
App(monomorphize(callee, replacementId), List.empty, vargs map monomorphize, bargs map monomorphize)
229+
val replacementData = replacementDataFromTargs(callee.id, targs)
230+
App(monomorphize(callee, replacementData.name), List.empty, vargs map monomorphize, bargs map monomorphize)
183231
case Let(id, annotatedTpe, binding, body) => Let(id, monomorphize(annotatedTpe), monomorphize(binding), monomorphize(body))
184232
case If(cond, thn, els) => If(monomorphize(cond), monomorphize(thn), monomorphize(els))
185233
case o => println(o); ???
186234

187235
def monomorphize(expr: Expr)(using ctx: MonoContext): Expr = expr match
188236
case DirectApp(b, targs, vargs, bargs) =>
189-
val replacementId = replacementIdFromTargs(b.id, targs)
190-
DirectApp(monomorphize(b, replacementId), List.empty, vargs map monomorphize, bargs map monomorphize)
237+
val replacementData = replacementDataFromTargs(b.id, targs)
238+
DirectApp(monomorphize(b, replacementData.name), List.empty, vargs map monomorphize, bargs map monomorphize)
191239
case o => println(o); ???
192240

193241
def monomorphize(pure: Pure)(using ctx: MonoContext): Pure = pure match
194242
case ValueVar(id, annotatedType) => ValueVar(id, monomorphize(annotatedType))
195243
case PureApp(b, targs, vargs) =>
196-
val replacementId = replacementIdFromTargs(b.id, targs)
197-
PureApp(monomorphize(b, replacementId), List.empty, vargs map monomorphize)
244+
val replacementData = replacementDataFromTargs(b.id, targs)
245+
PureApp(monomorphize(b, replacementData.name), List.empty, vargs map monomorphize)
198246
case Literal(value, annotatedType) => Literal(value, monomorphize(annotatedType))
247+
case Make(data, tag, targs, vargs) =>
248+
val replacementData = replacementDataFromTargs(data.name, data.targs)
249+
Make(replacementData, tag, List.empty, vargs map monomorphize)
199250
case o => println(o); ???
200251

201252
def monomorphize(valueParam: ValueParam)(using ctx: MonoContext): ValueParam = valueParam match
@@ -212,7 +263,7 @@ def monomorphize(blockType: BlockType)(using ctx: MonoContext): BlockType = bloc
212263

213264
def monomorphize(valueType: ValueType)(using ctx: MonoContext): ValueType = valueType match
214265
case ValueType.Var(name) => ValueType.Var(ctx.replacementTparams(name).tpe)
215-
case ValueType.Data(name, targs) => ValueType.Data(name, targs)
266+
case ValueType.Data(name, targs) => replacementDataFromTargs(name, targs)
216267
case o => println(o); ???
217268

218269
var monoCounter = 0
@@ -227,131 +278,12 @@ def freshMonoName(baseId: Id, tpes: Vector[TypeArg.Base]): Id =
227278
val tpesString = tpes.map(tpe => tpe.tpe.name.name).mkString
228279
Id(baseId.name.name + tpesString + monoCounter)
229280

230-
def replacementIdFromTargs(id: FunctionId, targs: List[ValueType])(using ctx: MonoContext): FunctionId =
231-
if (targs.isEmpty) return id
281+
def replacementDataFromTargs(id: FunctionId, targs: List[ValueType])(using ctx: MonoContext): ValueType.Data =
282+
if (targs.isEmpty) return ValueType.Data(id, targs)
232283
var baseTypes: List[TypeArg.Base] = List.empty
233284
targs.foreach({
234285
case ValueType.Data(name, targs) => baseTypes :+= TypeArg.Base(name)
235286
case ValueType.Var(name) => baseTypes :+= ctx.replacementTparams(name)
236287
case ValueType.Boxed(tpe, capt) =>
237288
})
238-
ctx.names((id, baseTypes.toVector))
239-
240-
// Old stuff
241-
242-
// type PolyConstraints = Map[Id, Set[PolyType]]
243-
// type PolyConstraintsSolved = Map[Id, Set[PolyType.Base]]
244-
// type PolyConstraintSingle = Map[Id, PolyType.Base]
245-
246-
// class MonoContext(val solvedConstraints: PolyConstraintsSolved, var monoDefs: Map[Id, Map[List[PolyType.Base], (Id, Block)]] = Map.empty)
247-
248-
249-
250-
// // TODO: The following two are awful and surely doing redundant work.
251-
// def generator(xs: List[Set[PolyConstraintSingle]]): List[Set[PolyConstraintSingle]] = xs.foldRight(List(Set.empty)) { (next, combinations) =>
252-
// (for (a <- next; as <- combinations) yield as + a).toList
253-
// }
254-
255-
// def gen(xs: PolyConstraintsSolved) = {
256-
// (for ((id, constrs) <- xs) yield (for (c <- constrs) yield Map((id -> c)))).toList
257-
// }
258-
259-
// def monoVparams(vparams: List[ValueType]): List[PolyType.Base] = vparams map monoVparam
260-
261-
// def monoVparams(vparams: List[ValueParam]): List[PolyType.Base] = vparams.map(vp => monoVparam(vp.tpe))
262-
263-
// def monoVparam(valueType: ValueType): PolyType.Base = valueType match {
264-
// case ValueType.Boxed(tpe, capt) => ???
265-
// case ValueType.Data(name, targs) => PolyType.Base(name)
266-
// case ValueType.Var(name) => ???
267-
// }
268-
269-
// def monomorphize(decl: ModuleDecl)(using ctx: MonoContext): ModuleDecl = decl match
270-
// case ModuleDecl(path, includes, declarations, externs, definitions, exports) =>
271-
// ModuleDecl(path, includes, declarations, externs, definitions flatMap monomorphize, exports)
272-
273-
// def monomorphize(definition: Toplevel)(using ctx: MonoContext): List[Toplevel] = definition match {
274-
// case Toplevel.Def(id, block) => monomorphize(block, id).map((newId, newBlock) => Toplevel.Def(newId, newBlock)).toList
275-
// case Toplevel.Val(id, tpe, binding) => ???
276-
// }
277-
278-
// def monomorphize(block: Block, baseId: Id)(using ctx: MonoContext): List[(Id, Block)] = block match {
279-
// case BlockLit(List(), cparams, vparams, bparams, body) => {
280-
// val monoBody = monomorphize(body, Map.empty)
281-
// val monoBlock = BlockLit(List.empty, cparams, vparams, bparams, monoBody)
282-
283-
// List((baseId, monoBlock))
284-
// }
285-
// case BlockLit(tparams, cparams, vparams, bparams, body) => {
286-
// // TODO: There is some redundancy here, but it works for now
287-
// val relevantConstraints = tparams.map(tp => Map(tp -> ctx.solvedConstraints.getOrElse(tp, Set.empty)).filter((_, s) => !s.isEmpty))
288-
// val splitConstraints = relevantConstraints.flatMap(gen)
289-
// val combinations = generator(splitConstraints)
290-
// val flattened = combinations.map(c => c.flatten.toMap)
291-
// val res = flattened.map(f => {
292-
// ctx.monoDefs.getOrElse(baseId, {
293-
// // TODO: Not really happy with this
294-
// val baseTypes = monoVparams(vparams)
295-
296-
// val newId = freshMonoName(baseId, f.values.toList)
297-
// val newVparams = vparams.map(monomorphize(_, f))
298-
// val newBlock = BlockLit(List(), cparams, newVparams, bparams, monomorphize(body, f))
299-
// ctx.monoDefs += (baseId -> Map(baseTypes -> (newId, newBlock)))
300-
// (newId, newBlock)
301-
// })
302-
// })
303-
// // res
304-
// ???
305-
// }
306-
// case BlockVar(id, annotatedTpe, annotatedCapt) => ???
307-
// case New(impl) => ???
308-
// case Unbox(pure) => ???
309-
// }
310-
311-
// def monomorphize(stmt: Stmt, replacementTparam: Map[Id, PolyType.Base])(using ctx: MonoContext): Stmt = stmt match {
312-
// case Return(expr) => Return(monomorphize(expr, replacementTparam))
313-
// case Val(id, annotatedTpe, binding, body) => Val(id, annotatedTpe, monomorphize(binding, replacementTparam), monomorphize(body, replacementTparam))
314-
// case App(callee, List(), vargs, bargs) => App(callee, List(), vargs, bargs)
315-
// case App(callee, targs, vargs, bargs) => {
316-
// // TODO: This does not seem correct, but I need the base id of the BlockVar to monomorphize
317-
// // Not sure if doing everything in one go is possible to do correctly
318-
// callee match {
319-
// case BlockVar(id, annotatedTpe, annotatedCapt) => {
320-
// // TODO: What if the block has not been generated yet?
321-
// // We don't use names of blocks but pass entire blocks
322-
// val baseTypes = targs map monoVparam
323-
// val genCallee = ctx.monoDefs.getOrElse((id, baseTypes), ???)
324-
// val f = App(genCallee._2, List(), vargs, bargs)
325-
// println(f)
326-
// f
327-
// }
328-
// case _ => ???
329-
// }
330-
// }
331-
// case Let(id, annotatedTpe, binding, body) => Let(id, annotatedTpe, monomorphize(binding, replacementTparam), monomorphize(body, replacementTparam))
332-
// case If(cond, thn, els) => If(monomorphize(cond, replacementTparam), monomorphize(thn, replacementTparam), monomorphize(els, replacementTparam))
333-
// case o => println(o); ???
334-
// }
335-
336-
// def monomorphize(expr: Expr, replacementTparam: Map[Id, PolyType.Base]): Expr = expr match {
337-
// case DirectApp(b, List(), vargs, bargs) => DirectApp(b, List(), vargs, bargs)
338-
// case o => println(o); ???
339-
// }
340-
341-
// def monomorphize(pure: Pure, replacementTparam: Map[Id, PolyType.Base]): Pure = pure match
342-
// case ValueVar(id, annotatedType) => ValueVar(id, monomorphize(annotatedType, replacementTparam))
343-
// case Literal(value, annotatedType) => pure
344-
// case o => println(o); ???
345-
346-
// def monomorphize(vparam: ValueParam, replacementTparam: Map[Id, PolyType.Base]): ValueParam = vparam match {
347-
// case ValueParam(id, tpe) => ValueParam(id, monomorphize(tpe, replacementTparam))
348-
// }
349-
350-
// def monomorphize(valueType: ValueType, replacementTparam: Map[Id, PolyType.Base]): ValueType = valueType match
351-
// case ValueType.Var(name) => replacementTparam.get(name).get.toValueType
352-
// case ValueType.Data(name, targs) => valueType
353-
// case ValueType.Boxed(tpe, capt) => ???
354-
355-
// TODO: After solving the constraints it would be helpful to know
356-
// which functions have which tparams
357-
// so we can generate the required monomorphic functions
289+
ValueType.Data(ctx.names((id, baseTypes.toVector)), List.empty)

0 commit comments

Comments
 (0)