Skip to content

Commit 2a765eb

Browse files
committed
Implement find constraints for subset
1 parent 8041f0b commit 2a765eb

File tree

1 file changed

+82
-1
lines changed
  • effekt/shared/src/main/scala/effekt/core

1 file changed

+82
-1
lines changed

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

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,94 @@ package core
33

44
import effekt.context.Context
55
import effekt.lexer.TokenKind
6+
import effekt.context.assertions.asDataType
7+
8+
// import scala.collection.mutable
69

710
object Mono extends Phase[CoreTransformed, CoreTransformed] {
811

912
override val phaseName: String = "mono"
1013

1114
override def run(input: CoreTransformed)(using Context): Option[CoreTransformed] = {
15+
input match {
16+
case CoreTransformed(source, tree, mod, core) => {
17+
core match {
18+
case ModuleDecl(path, includes, declarations, externs, definitions, exports) => {
19+
val polys = findConstraints(definitions)
20+
polys.foreach(p => println(p))
21+
println()
22+
}
23+
}
24+
}
25+
}
1226
Some(input)
1327
}
28+
}
29+
30+
// TODO: We probably want some kind of graph data structure instead of the map, for better performance in cycle detection later.
31+
// This works for now
32+
// TODO: Consider using unique IDs instead of Symbol for keys.
33+
// This works, but might give weird output when debugging
34+
// if the same symbol name is used twice
35+
// TODO: After solving the constraints it would be helpful to know
36+
// which functions have which tparams
37+
// so we can generate the required monomorphic functions
38+
type PolyConstraint = Map[symbols.Symbol, Set[symbols.Symbol]]
39+
type PolyConstraintEntry = (symbols.Symbol, Set[symbols.Symbol])
40+
41+
def appendConstraint(map: PolyConstraint, sym: symbols.Symbol, tpe: ValueType): PolyConstraintEntry =
42+
val currentFlow = map.getOrElse(sym, Set())
43+
tpe match {
44+
// Ignore self cycling types A -> A
45+
case ValueType.Data(name, targs) if name != sym => (sym -> currentFlow.incl(name))
46+
case ValueType.Var(name) if name != sym => (sym -> (currentFlow.incl(name)))
47+
// TODO: What do we do with boxed types?
48+
case o@ValueType.Boxed(tpe, capt) =>
49+
println("Hit boxed type: " + o)
50+
(sym -> currentFlow)
51+
case _ => (sym -> currentFlow) // self cycling flow
52+
}
1453

15-
}
54+
def findConstraintRec(value: Val, typeFlow: PolyConstraint): PolyConstraint =
55+
var newTypeFlow = typeFlow
56+
value.binding match {
57+
case App(callee, targ :: targs, vargs, bargs) =>
58+
callee match {
59+
case BlockVar(id, annotatedTpe, annotatedCapt) =>
60+
annotatedTpe match {
61+
case BlockType.Function(tparam :: tparams, cparams, vparams, bparams, result) =>
62+
newTypeFlow += appendConstraint(newTypeFlow, tparam, targ)
63+
case _ =>
64+
}
65+
case _ =>
66+
}
67+
case _ =>
68+
}
69+
value.body match {
70+
case v@Val(_, _, _, _) => findConstraintRec(v, newTypeFlow)
71+
case _ => newTypeFlow
72+
}
73+
74+
def findConstraints(definitions: List[Toplevel]): PolyConstraint =
75+
var typeFlow: PolyConstraint = Map()
76+
definitions.foreach {
77+
case Toplevel.Def(id, block) =>
78+
block match
79+
case BlockLit(tparam :: tparams, cparams, vparams, bparams, body) =>
80+
body match {
81+
case v@Val(id, annotatedTpe, binding, body) =>
82+
typeFlow ++= findConstraintRec(v, typeFlow)
83+
case Return(expr) =>
84+
typeFlow += appendConstraint(typeFlow, tparam, expr.tpe)
85+
case _ =>
86+
}
87+
case BlockLit(tparams, cparams, vparams, bparams, body) =>
88+
body match {
89+
case v@Val(id, annotatedTpe, binding, body) =>
90+
typeFlow ++= findConstraintRec(v, typeFlow)
91+
case _ =>
92+
}
93+
case _ =>
94+
case _ =>
95+
}
96+
typeFlow

0 commit comments

Comments
 (0)