comparison src/mono_reduce.sml @ 2224:5709482a2afd

Merge.
author Ziv Scully <ziv@mit.edu>
date Thu, 11 Dec 2014 02:05:41 -0500
parents 0d48cfb59b29
children 9e9c915f554c
comparison
equal deleted inserted replaced
2223:9410959d296f 2224:5709482a2afd
37 structure U = MonoUtil 37 structure U = MonoUtil
38 38
39 structure IM = IntBinaryMap 39 structure IM = IntBinaryMap
40 structure IS = IntBinarySet 40 structure IS = IntBinarySet
41 41
42 structure SS = BinarySetFn(struct
43 type ord_key = string
44 val compare = String.compare
45 end)
42 46
43 fun simpleTypeImpure tsyms = 47 fun simpleTypeImpure tsyms =
44 U.Typ.exists (fn TFun _ => true 48 U.Typ.exists (fn TFun _ => true
45 | TDatatype (n, _) => IS.member (tsyms, n) 49 | TDatatype (n, _) => IS.member (tsyms, n)
46 | _ => false) 50 | _ => false)
205 | (PPrim p, EPrim p') => 209 | (PPrim p, EPrim p') =>
206 if Prim.equal (p, p') then 210 if Prim.equal (p, p') then
207 Yes env 211 Yes env
208 else 212 else
209 No 213 No
214
215 | (PPrim (Prim.String (_, s)), _) =>
216 let
217 fun lengthLb (e : exp) =
218 case #1 e of
219 EStrcat (e1, e2) => lengthLb e1 + lengthLb e2
220 | EPrim (Prim.String (_, s)) => size s
221 | _ => 0
222 in
223 if lengthLb e > size s then
224 No
225 else
226 Maybe
227 end
210 228
211 | (PCon (_, PConVar n1, po), ECon (_, PConVar n2, eo)) => 229 | (PCon (_, PConVar n1, po), ECon (_, PConVar n2, eo)) =>
212 if n1 = n2 then 230 if n1 = n2 then
213 case (po, eo) of 231 case (po, eo) of
214 (NONE, NONE) => Yes env 232 (NONE, NONE) => Yes env
576 | (TSignal _, _) => e 594 | (TSignal _, _) => e
577 | _ => 595 | _ =>
578 case e' of 596 case e' of
579 (ECase _, _) => e 597 (ECase _, _) => e
580 | _ => doSub ()) 598 | _ => doSub ())
599
600 fun isRecord () =
601 case #1 e' of
602 ERecord _ => true
603 | _ => false
604
605 fun whichProj i (e : exp) =
606 case #1 e of
607 EPrim _ => SOME SS.empty
608 | ERel i' => if i' = i then NONE else SOME SS.empty
609 | ENamed _ => SOME SS.empty
610 | ECon (_, _, NONE) => SOME SS.empty
611 | ECon (_, _, SOME e') => whichProj i e'
612 | ENone _ => SOME SS.empty
613 | ESome (_, e') => whichProj i e'
614 | EFfi _ => SOME SS.empty
615 | EFfiApp (_, _, es) => whichProjs i (map #1 es)
616 | EApp (e1, e2) => whichProjs i [e1, e2]
617 | EAbs (_, _, _, e) => whichProj (i + 1) e
618 | EUnop (_, e1) => whichProj i e1
619 | EBinop (_, _, e1, e2) => whichProjs i [e1, e2]
620 | ERecord xets => whichProjs i (map #2 xets)
621 | EField ((ERel i', _), s) =>
622 if i' = i then
623 SOME (SS.singleton s)
624 else
625 SOME SS.empty
626 | EField (e1, _) => whichProj i e1
627 | ECase (e1, pes, _) =>
628 whichProjs' i ((0, e1)
629 :: map (fn (p, e) => (patBinds p, e)) pes)
630 | EStrcat (e1, e2) => whichProjs i [e1, e2]
631 | EError (e1, _) => whichProj i e1
632 | EReturnBlob {blob = NONE, mimeType = e2, ...} => whichProj i e2
633 | EReturnBlob {blob = SOME e1, mimeType = e2, ...} => whichProjs i [e1, e2]
634 | ERedirect (e1, _) => whichProj i e1
635 | EWrite e1 => whichProj i e1
636 | ESeq (e1, e2) => whichProjs i [e1, e2]
637 | ELet (_, _, e1, e2) => whichProjs' i [(0, e1), (1, e2)]
638 | EClosure (_, es) => whichProjs i es
639 | EQuery {query = e1, body = e2, initial = e3, ...} =>
640 whichProjs' i [(0, e1), (2, e2), (0, e3)]
641 | EDml (e1, _) => whichProj i e1
642 | ENextval e1 => whichProj i e1
643 | ESetval (e1, e2) => whichProjs i [e1, e2]
644 | EUnurlify (e1, _, _) => whichProj i e1
645 | EJavaScript (_, e1) => whichProj i e1
646 | ESignalReturn e1 => whichProj i e1
647 | ESignalBind (e1, e2) => whichProjs i [e1, e2]
648 | ESignalSource e1 => whichProj i e1
649 | EServerCall (e1, _, _, _) => whichProj i e1
650 | ERecv (e1, _) => whichProj i e1
651 | ESleep e1 => whichProj i e1
652 | ESpawn e1 => whichProj i e1
653
654 and whichProjs i es =
655 whichProjs' i (map (fn e => (0, e)) es)
656
657 and whichProjs' i es =
658 case es of
659 [] => SOME SS.empty
660 | (n, e) :: es' =>
661 case (whichProj (i + n) e, whichProjs' i es') of
662 (SOME m1, SOME m2) =>
663 if SS.isEmpty (SS.intersection (m1, m2)) then
664 SOME (SS.union (m1, m2))
665 else
666 NONE
667 | _ => NONE
581 in 668 in
582 if impure env e' then 669 if impure env e' then
583 let 670 let
584 val effs_e' = summarize 0 e' 671 val effs_e' = summarize 0 e'
585 val effs_e' = List.filter (fn x => x <> UseRel) effs_e' 672 val effs_e' = List.filter (fn x => x <> UseRel) effs_e'
634 andalso not (freeInAbs b) then 721 andalso not (freeInAbs b) then
635 trySub () 722 trySub ()
636 else 723 else
637 e 724 e
638 end 725 end
639 else if countFree 0 0 b > 1 andalso not (!fullMode) andalso not (passive e') then 726 else if countFree 0 0 b > 1
727 andalso not (!fullMode)
728 andalso not (passive e')
729 andalso not (isRecord () andalso Option.isSome (whichProj 0 b)) then
640 e 730 e
641 else 731 else
642 trySub () 732 trySub ()
643 end 733 end
644 734