@@ -12,6 +12,12 @@ type TermId = Uid[Term]
12
12
type TypeVarId = Uid [TypeVar ]
13
13
type Cnstr = ProdStrat -> ConsStrat
14
14
15
+ /** Performs defunctionalization on selections on objects using simple-sub as for control-flow analysis.
16
+ * First we traverse the program and process all terms, constraining them to Producers and Consumers.
17
+ * During the constraining, we keep track of the input points of selection terms.
18
+ * Lastly, we rewrite selection terms by generating pattern matches on their possible inputs.
19
+ */
20
+
15
21
16
22
enum ProdStrat (using val euid : TermId ) {
17
23
case NoProd ()(using TermId )
@@ -61,8 +67,6 @@ class SimpleDef(debug: Debug) {
61
67
})
62
68
}
63
69
64
- var log : Str => Unit = (s) => ()
65
- var constraints : Ls [Cnstr ] = Nil
66
70
val termMap = new IdentityHashMap [Term , TermId ]().asScala
67
71
val varsName = mutable.Map .empty[TypeVarId , Str ]
68
72
val vuid = Uid .TypeVar .State ()
@@ -80,14 +84,17 @@ class SimpleDef(debug: Debug) {
80
84
freshVar(n.name)
81
85
82
86
def apply (p : TypingUnit )(using ctx : Context = Context (Map (), Map ())): (Ls [Var -> ProdStrat ], ProdStrat ) =
87
+ // Top-level def prototypes
83
88
val vars : Map [Var , ProdVar ] = p.rawEntities.collect {
84
89
case fun : NuFunDef =>
85
90
fun.nme -> freshVar(fun.name)(using noExprId)._1
86
91
}.toMap
92
+ // Top-level constructor prototypes
87
93
val constructorPrototypes : Map [Var , Cnstr ] = p.rawEntities.collect {
88
94
case ty : NuTypeDef =>
89
95
ty.nameVar -> freshVar(ty.nameVar)(using noExprId)
90
96
}.toMap
97
+ // Prototypes of constructor outputs, used for inheritance
91
98
val objectPrototypes : Map [Var , Cnstr ] = p.rawEntities.collect {
92
99
case ty : NuTypeDef =>
93
100
ty.nameVar -> freshVar(ty.nameVar)(using noExprId)
@@ -166,8 +173,9 @@ class SimpleDef(debug: Debug) {
166
173
}
167
174
}
168
175
(vars.toList, tys.lastOption.getOrElse(ProdObj (Some (Var (" prim$Unit" )), Nil )(using noExprId)))
169
-
176
+
170
177
val termToProdType = mutable.Map .empty[TermId , ProdStrat ]
178
+ // Selection terms -> Object types that they Consume
171
179
val selTermToType = mutable.Map .empty[TermId , ConsObj ]
172
180
173
181
def builtinOps : Map [Var , ProdFun ] = {
@@ -264,11 +272,8 @@ class SimpleDef(debug: Debug) {
264
272
apply(TypingUnit (stmts))._2
265
273
case Bra (false , term) =>
266
274
process(term)
267
- case CaseOf (trm, cases) =>
268
- val scrutRes = process(trm)
269
- val sv = freshVar(s " ${t.uid}_caseres " )(using t.uid)
275
+ case CaseOf (trm, cases) => // TODO
270
276
???
271
- // TODO
272
277
case Eqn (lhs, rhs) =>
273
278
process(lhs)
274
279
process(rhs)
@@ -277,6 +282,7 @@ class SimpleDef(debug: Debug) {
277
282
debug.outdent()
278
283
registerTermToType(t, res)
279
284
285
+ // TODO
280
286
def processCases (scrut : ProdVar , cs : CaseBranches )(using ctx : Context , resCons : ConsVar ): Unit =
281
287
cs match
282
288
case Wildcard (body) =>
@@ -351,10 +357,12 @@ class SimpleDef(debug: Debug) {
351
357
case other => lastWords(s " Could not constrain ${other}" )
352
358
}
353
359
360
+ // Selection terms -> Producers that they consume
354
361
lazy val selToResTypes : Map [TermId , Set [ProdStrat ]] = selTermToType.map((termId, cons) =>
355
362
(termId, cons.selectionSource)
356
363
).toMap
357
364
365
+ // Rewrite terms, replacing selections with pattern matches if they only select on objects
358
366
def rewriteTerm (t : Term ): Term =
359
367
def objSetToMatchBranches (receiver : Var , fieldName : Var , objSet : List [ProdObj ], acc : CaseBranches = NoCases )(using funcApp : Option [Term ] = None ): CaseBranches =
360
368
objSet match
0 commit comments