1 (* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 * Copyright (C) 1997-2000 NEC Research Institute.
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
9 functor Monomorphise (S: MONOMORPHISE_STRUCTS): MONOMORPHISE =
17 structure Xcases = Cases
21 structure Xlambda = Lambda
22 structure XprimExp = PrimExp
23 structure Xprogram = Program
24 structure Xtype = Type
25 structure XvarExp = VarExp
30 structure Scases = Cases
34 structure Slambda = Lambda
35 structure SprimExp = PrimExp
36 structure Sprogram = Program
37 structure Stype = Type
38 structure SvarExp = VarExp
45 val getOrAdd: 'a t * Stype.t vector * (unit -> 'a) -> 'a
46 val toList: 'a t -> (Stype.t vector * 'a) list
49 type 'a t = (Stype.t vector * Word.t * 'a) HashSet.t
52 val generator: Word.t = 0wx5555
53 val base = Random.word ()
56 Vector.fold (ts, base, fn (t, w) =>
57 Word.xorb (w * generator, Stype.hash t))
59 Vector.equals (ts, ts', Stype.equals)
62 fun new () : 'a t = HashSet.new {hash = #2}
64 fun getOrAdd (c, ts, th) =
68 (#3 o HashSet.lookupOrInsert)
69 (c, hash, fn (ts', _, _) => equal (ts, ts'),
70 fn () => (ts, hash, th ()))
73 fun toList c = HashSet.fold (c, [], fn ((ts, _, v), l) => (ts, v) :: l)
76 fun monomorphise (Xprogram.T {datatypes, body, ...}): Sprogram.t =
78 val {get = getVar: Var.t -> (Stype.t vector -> SvarExp.t),
80 Property.getSet (Var.plist, Property.initRaise ("var", Var.layout))
83 ("Monomorphise.setVar", Var.layout, Layout.ignore, Unit.layout)
87 ("Monomorphise.getVar", Var.layout, Layout.ignore)
89 val {get = getCon: Con.t -> (Stype.t vector -> Con.t),
90 set = setCon, destroy = destroyCon} =
91 Property.destGetSet (Con.plist, Property.initRaise ("mono", Con.layout))
92 val {get = getTycon: Tycon.t -> Stype.t vector -> Stype.t,
93 set = setTycon, destroy = destroyTycon} =
94 Property.destGetSet (Tycon.plist,
95 Property.initRaise ("mono", Tycon.layout))
97 List.foreach (Tycon.prims, fn {tycon = t, ...} =>
98 setTycon (t, fn ts => Stype.con (t, ts)))
99 val {set = setTyvar, get = getTyvar: Tyvar.t -> Stype.t, ...} =
100 Property.getSet (Tyvar.plist,
101 Property.initRaise ("tyvar", Tyvar.layout))
104 ("Monomorphise.getTyvar", Tyvar.layout, Stype.layout)
108 ("Monomorphise.setTyvar", Tyvar.layout, Stype.layout, Unit.layout)
110 fun setTyvars (tyvs, tys) = Vector.foreach2 (tyvs, tys, setTyvar)
113 ("Monomorphise.setTyvars", Vector.layout Tyvar.layout, Vector.layout Stype.layout, Unit.layout)
115 fun monoType (t: Xtype.t): Stype.t =
118 con = fn (c, ts) => getTycon c ts}
121 ("Monomorphise.monoType", Xtype.layout, Stype.layout)
123 fun monoTypeOpt (to: Xtype.t option): Stype.t option =
126 | SOME t => SOME (monoType t)
127 fun monoTypes ts = Vector.map (ts, monoType)
128 fun monoVar (x: Var.t, ts: Xtype.t vector): SvarExp.t = getVar x (monoTypes ts)
131 ("Monomorphise.monoVar",
132 Var.layout, Vector.layout Xtype.layout, SvarExp.layout)
134 fun monoCon (c: Con.t, ts: Xtype.t vector): Con.t = getCon c (monoTypes ts)
137 ("Monomorphise.monoCon",
138 Con.layout, Vector.layout Xtype.layout, Con.layout)
140 (* It is necessary to create new variables for monomorphic variables
141 * because they still may have type variables in their type.
143 fun renameMono (x, t) =
146 val ve = SvarExp.mono x'
150 else Error.bug "Monomorphise.renameMono: expected monomorphic instance"
151 val _ = setVar (x, inst)
157 ("Monomorphise.renameMono",
158 Var.layout, Xtype.layout, Layout.tuple2 (Var.layout, Stype.layout))
160 fun monoPat (Xpat.T {con, targs, arg}): Spat.t =
162 val con = monoCon (con, targs)
164 Spat.T {con = con, targs = Vector.new0 (),
167 | SOME x => SOME (renameMono x))}
171 ("Monomorphise.monoPat", Xpat.layout, Spat.layout)
175 ("Monomorphise.monoExp", Xexp.layout, Sexp.layout)
178 ("Monomorphise.monoDec",
179 Xdec.layout, fn (_: unit -> Sdec.t list) => Layout.empty)
180 (*------------------------------------*)
182 (*------------------------------------*)
183 val newDbs: {tyvars: Tyvar.t vector,
184 types: Stype.t vector,
189 used: bool} ref vector} list ref = ref []
192 (datatypes, fn {tyvars, tycon, cons} =>
194 val cache = Cache.new ()
200 if Tycon.equals (tycon, Tycon.bool)
202 Vector.map (cons, fn {con, ...} =>
203 ref {con = con, typ = NONE,
207 Vector.map (cons, fn {con, arg} =>
208 ref {con = con, typ = arg,
214 ty = Stype.con (tycon, Vector.new0 ()),
216 val _ = List.push (newDbs, db)
220 val _ = setTycon (tycon, #ty o instantiate)
223 (cons, fn (n, {con, ...}) =>
224 setCon (con, fn ts =>
226 val r as ref {con, typ, used} =
227 Vector.sub (#cons (instantiate ts), n)
229 else let val con = Con.new con
230 in r := {con = con, typ = typ,
237 val _ = monoCon (Con.truee, Vector.new0 ())
238 val _ = monoCon (Con.falsee, Vector.new0 ())
249 fn ({tyvars, types, tycon, cons, ...}, ac) =>
253 (cons, fn ref {con, typ, used} =>
255 then (setTyvars (tyvars, types)
257 arg = monoTypeOpt typ})
260 if Vector.isEmpty cons
261 then Vector.new1 {con = Con.newNoname (), arg = NONE}
263 in {tycon = tycon, tyvars = Vector.new0 (), cons = cons}
267 (*------------------------------------*)
269 (*------------------------------------*)
270 fun monoVarExp (XvarExp.T {var, targs}) =
274 ("Monomorphise.monoVarExp", XvarExp.layout, SvarExp.layout)
276 fun monoVarExps xs = Vector.map (xs, monoVarExp)
277 fun monoExp (arg: Xexp.t): Sexp.t =
281 val {decs, result} = Xexp.dest e
283 List.fold (decs, [], fn (dec, thunks) => monoDec dec :: thunks)
284 val result = monoVarExp result
286 List.fold (thunks, [], fn (thunk, decs) => thunk () @ decs)
288 Sexp.make {decs = decs,
291 and monoPrimExp (e: XprimExp.t): SprimExp.t =
293 XprimExp.App {func, arg} =>
294 SprimExp.App {func = monoVarExp func, arg = monoVarExp arg}
295 | XprimExp.Case {test, cases, default} =>
300 Scases.Con (Vector.map (cases, fn (pat, exp) =>
301 (monoPat pat, monoExp exp)))
302 | Xcases.Word (s, v) =>
304 (s, Vector.map (v, fn (c, e) => (c, monoExp e)))
308 {test = monoVarExp test,
310 default = Option.map (default, fn (e, r) =>
313 | XprimExp.ConApp {con, targs, arg} =>
314 let val con = monoCon (con, targs)
315 in SprimExp.ConApp {con = con, targs = Vector.new0 (),
316 arg = Option.map (arg, monoVarExp)}
318 | XprimExp.Const c => SprimExp.Const c
319 | XprimExp.Handle {try, catch, handler} =>
320 SprimExp.Handle {try = monoExp try,
321 catch = renameMono catch,
322 handler = monoExp handler}
323 | XprimExp.Lambda l => SprimExp.Lambda (monoLambda l)
324 | XprimExp.PrimApp {prim, targs, args} =>
325 SprimExp.PrimApp {args = monoVarExps args,
326 prim = Prim.map (prim, monoType),
327 targs = monoTypes targs}
328 | XprimExp.Profile e => SprimExp.Profile e
329 | XprimExp.Raise {exn, extend} =>
330 SprimExp.Raise {exn = monoVarExp exn, extend = extend}
331 | XprimExp.Select {tuple, offset} =>
332 SprimExp.Select {tuple = monoVarExp tuple, offset = offset}
333 | XprimExp.Tuple xs => SprimExp.Tuple (monoVarExps xs)
334 | XprimExp.Var x => SprimExp.Var (monoVarExp x)
335 and monoLambda l: Slambda.t =
337 val {arg, argType, body, mayInline} = Xlambda.dest l
338 val (arg, argType) = renameMono (arg, argType)
340 Slambda.make {arg = arg,
343 mayInline = mayInline}
345 (*------------------------------------*)
347 (*------------------------------------*)
348 and monoDec arg: unit -> Sdec.t list =
352 Xdec.MonoVal {var, ty, exp} =>
354 val (var, ty) = renameMono (var, ty)
357 [Sdec.MonoVal {var = var,
359 exp = monoPrimExp exp}]
361 | Xdec.PolyVal {var, tyvars, ty, exp} =>
363 val cache = Cache.new ()
367 (setTyvars (tyvars, ts)
368 ; Cache.getOrAdd (cache, ts, fn () =>
369 SvarExp.mono (Var.new var))))
373 (Cache.toList cache, [], fn ((ts, ve), decs) =>
374 (setVar (var, fn _ => ve)
376 val _ = setTyvars (tyvars, ts)
378 val {decs = decs', result} = Sexp.dest (monoExp exp)
381 @ (Sdec.MonoVal {var = SvarExp.var ve,
383 exp = SprimExp.Var result} :: decs)
386 | Xdec.Fun {tyvars, decs} =>
388 val cache = Cache.new ()
391 (decs, fn (n, {var, ...}) =>
394 (setTyvars (tyvars, ts)
395 ; Vector.sub (Cache.getOrAdd
397 Vector.map (decs, SvarExp.mono o Var.new o #var)),
402 (Cache.toList cache, fn (ts, xs) =>
403 (Vector.foreach2 (decs, xs, fn ({var, ...}, ve) =>
404 setVar (var, fn _ => ve))
406 {tyvars = Vector.new0 (),
408 (decs, xs, fn ({ty, lambda, ...}, ve) =>
410 val _ = setTyvars (tyvars, ts)
412 val lambda = monoLambda lambda
414 {var = SvarExp.var ve,
419 | Xdec.Exception {con, arg} =>
422 if Con.equals (con, Con.overflow)
424 (* We avoid renaming Overflow because the closure
425 * converter needs to recognize it. This is not
426 * safe in general, but is OK in this case because
427 * we know there is only one Overflow excon.
431 val _ = setCon (con, fn _ => con')
434 [Sdec.Exception {con = con',
435 arg = monoTypeOpt arg}]
437 (*------------------------------------*)
438 (* main code for monomorphise *)
439 (*------------------------------------*)
440 val body = monoExp body
441 val datatypes = finishDbs []
443 Sprogram.T {datatypes = Vector.fromList datatypes,
446 val _ = Sprogram.clear program
447 val _ = destroyCon ()
448 val _ = destroyTycon ()