@@ -3,13 +3,94 @@ package core
3
3
4
4
import effekt .context .Context
5
5
import effekt .lexer .TokenKind
6
+ import effekt .context .assertions .asDataType
7
+
8
+ // import scala.collection.mutable
6
9
7
10
object Mono extends Phase [CoreTransformed , CoreTransformed ] {
8
11
9
12
override val phaseName : String = " mono"
10
13
11
14
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
+ }
12
26
Some (input)
13
27
}
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
+ }
14
53
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