Annotation of researchv10no/cmd/sml/src/codegen/opt.sml, revision 1.1

1.1     ! root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
        !             2: (* structure Opt: extended by NICK, to add a new lambda-lifting function,
        !             3:    bareCloseTop, a more general form of closeTop. *)
        !             4: 
        !             5: structure CGoptions = System.Control.CG
        !             6: 
        !             7: signature OPT =
        !             8: sig
        !             9:   structure L : LAMBDA sharing L=Lambda
        !            10:   structure A : ACCESS sharing A=Access
        !            11:   val reduce : L.lexp -> L.lexp
        !            12:   exception BadSwitch
        !            13:   val switch : L.lexp -> L.lexp
        !            14:   val hoist : L.lexp -> L.lexp
        !            15:   val closestr : (int -> string) * L.lexp * int list -> L.lexp
        !            16:   val bareCloseTop:
        !            17:     {lambda: L.lexp, looker: int, extras: int list, keepFree: int list} -> L.lexp
        !            18:        (* bareCloseTop is a more general form of closetop. It is passed an already
        !            19:           existing looker lvar, and also a keepFree list of lvars which it must
        !            20:           keep free (they'll be abstracted later). *)
        !            21: 
        !            22:   val closetop : L.lexp * int list -> L.lexp
        !            23:   val closeModDecl: L.lexp * A.lvar list * int list -> L.lexp
        !            24:        (* closeModDecl will be obselete when I finish the new moduleComp, but I'll
        !            25:           keep it here for the old moduleComp. *)
        !            26:   exception Freevars
        !            27:   val free : L.lexp -> A.lvar -> A.lvar list
        !            28:   val mix0free : L.lexp -> A.lvar -> A.lvar list * A.lvar list
        !            29:   val alphaConvert : L.lexp -> L.lexp
        !            30:   val mapfree : (A.lvar -> L.lexp) -> (L.lexp -> L.lexp)
        !            31:   val pure : L.lexp -> bool
        !            32: end
        !            33: 
        !            34: structure Opt : OPT =
        !            35: struct
        !            36: 
        !            37: structure A : ACCESS = Access
        !            38: structure L : LAMBDA = Lambda
        !            39: 
        !            40: open A Basics L
        !            41: 
        !            42: fun root [v] = v | root (_::p) = root p
        !            43:   | root _ = ErrorMsg.impossible "root [] in codegen/opt";
        !            44: 
        !            45: exception Freevars
        !            46: 
        !            47: fun mapfree lookfree =
        !            48:    let val m = Intmap.new(32, Freevars) : lexp Intmap.intmap
        !            49:       val add = Intmap.add m
        !            50:       fun look v = Intmap.map m v
        !            51:                   handle Freevars =>
        !            52:                      let val x = lookfree v in add(v,x); x end
        !            53:       fun copycon (DATAcon(DATACON{rep=(VARIABLE(Access.PATH p)),const,name,typ,sign})) =
        !            54:            let fun f [v] = let val VAR w = look v in [w] end
        !            55:                  | f (i::r) = i::(f r) 
        !            56:             in DATAcon(DATACON{rep=(VARIABLE (Access.PATH(f p))),const=const,
        !            57:                            name=name,typ=typ,sign=sign})
        !            58:            end
        !            59:         | copycon c = c
        !            60:       fun newvar v = let val w = dupLvar v in add(v,VAR w); w end          
        !            61:       val rec f =
        !            62:         fn VAR v => look v
        !            63:           | FN(v,b) => FN(newvar v, f b)
        !            64:          | FIX(vl,el,b) => FIX(map newvar vl, map f el, f b)
        !            65:          | APP(a,b) => APP(f a, f b)
        !            66:          | SELECT(i,a) => SELECT(i, f a)
        !            67:          | RECORD l => RECORD(map f l)
        !            68:          | SWITCH(a, l, SOME d) => 
        !            69:                        SWITCH(f a, map(fn(c,x)=>(copycon c, f x))l, SOME(f d))
        !            70:          | SWITCH(a, l, NONE) => 
        !            71:                        SWITCH(f a,map(fn(c,x)=>(copycon c, f x))l,NONE)
        !            72:          | HANDLE(a,b) => HANDLE(f a, f b)
        !            73:          | RAISE x => RAISE(f x)
        !            74:          | e as INT _ => e
        !            75:          | e as STRING _ => e
        !            76:          | e as REAL _ => e
        !            77:          | e as PRIM _ => e
        !            78:     in f
        !            79:    end
        !            80: 
        !            81: val alphaConvert = mapfree VAR
        !            82: 
        !            83: val simple = fn VAR _ => true
        !            84:              | RECORD [] => true
        !            85:              | INT _ => true
        !            86:              | STRING s => size s = 1
        !            87:              | _ => false
        !            88: 
        !            89: fun all f = not o (exists (not o f))
        !            90: 
        !            91: val rec pure =
        !            92:           fn VAR _ => true
        !            93:            | APP(FN(_,a),b) => pure a andalso pure b
        !            94:            | FIX(vl,el,b) => pure b
        !            95:            | APP(PRIM P.callcc, FN(_,b)) => pure b
        !            96:            | APP(PRIM i, z) => Prim.pure i andalso pure z
        !            97:            | FN _ => true
        !            98:            | INT _ => true
        !            99:            | REAL _ => true
        !           100:            | PRIM _ => true
        !           101:            | STRING _ => true
        !           102:            | SELECT(_, x) => pure x
        !           103:            | RECORD l => all pure l
        !           104:            | SWITCH(a, l, NONE) => pure a andalso all (pure o #2) l
        !           105:            | SWITCH(a, l, SOME d) => pure a andalso pure d andalso
        !           106:                                      all (pure o #2) l
        !           107:            | _ => false
        !           108: 
        !           109: exception BadSwitch
        !           110: 
        !           111: fun testint i = fn INTcon j => i=j
        !           112:                 | DATAcon(DATACON{rep=(CONSTANT j),...}) => i=j
        !           113:                 | STRINGcon j => size j = 1 andalso i = ord j
        !           114:                 | DATAcon(DATACON{rep=(TRANSU),...}) => true
        !           115:                 | _ => false
        !           116: val testboxed   = fn DATAcon(DATACON{rep=(TRANSB),...}) => true
        !           117:                   | DATAcon(DATACON{rep=(TRANSPARENT),...}) => true
        !           118:                   | DATAcon(DATACON{rep=(TAGGED j),...}) => raise BadSwitch
        !           119:                   | DATAcon(DATACON{rep=(VARIABLE j),...}) => raise BadSwitch
        !           120:                   | _ => false
        !           121: fun testtag i = fn DATAcon(DATACON{rep=(TRANSB),...}) => true
        !           122:                 | DATAcon(DATACON{rep=(TRANSPARENT),...}) => true
        !           123:                 | DATAcon(DATACON{rep=(TAGGED j),...}) => i=j
        !           124:                 | _ => false
        !           125: fun teststring s = fn STRINGcon j => s=j
        !           126:                    | _ => false
        !           127: 
        !           128: fun switch(SWITCH(e,l,d)) =
        !           129:        let val test = case e
        !           130:                    of INT i => testint i
        !           131:                     | STRING s => if size s = 1 then testint(ord s)
        !           132:                                        else teststring s
        !           133:                     | RECORD[_,INT i] => testtag i
        !           134:                     | RECORD [] => testtag 0
        !           135:                     | RECORD _ => testboxed
        !           136:                     | FN _ => testboxed
        !           137:                     | FIX _ => testboxed
        !           138:                     | REAL _ => testboxed
        !           139:                     | _ => raise BadSwitch
        !           140:            fun f ((c,x)::r) = if test c then x else f r
        !           141:               | f [] = case d
        !           142:                          of SOME z => z
        !           143:                           | NONE => ErrorMsg.impossible "no default"
        !           144:          in f l
        !           145:         end
        !           146: 
        !           147: fun reduce exp =
        !           148:       let val clicked = ref false
        !           149:          fun click() = clicked := true
        !           150:          exception Reducemap
        !           151:          val t = Intmap.new(32, Reducemap) : lexp Intmap.intmap
        !           152:          val set = Intmap.add t
        !           153:          val set = fn x as (v, VAR w) => (sameName(v,w); set x)
        !           154:                     | x => set x
        !           155:          val unset = Intmap.rem t
        !           156:          val imap = Intmap.map t
        !           157:           val s = Intset.new()
        !           158:          val mark = Intset.add s
        !           159:          val marked = Intset.mem s
        !           160:          fun mapvar v = (imap v handle Reducemap => VAR v)
        !           161:          fun makp [v] = ((case imap v of VAR w => makp[w]
        !           162:                                        | _ => (mark v; [v]))
        !           163:                          handle Reducemap => (mark v; [v]))
        !           164:            | makp (i::p) = i :: makp p
        !           165:          val rec makcon =
        !           166:                fn (DATAcon(DATACON{rep=(VARIABLE(PATH p)),
        !           167:                                            name,const,typ,sign}), e) =>
        !           168:                          (DATAcon(DATACON{rep=(VARIABLE(PATH(makp p))),
        !           169:                               name=name,const=const,typ=typ,sign=sign}),
        !           170:                           mak e)
        !           171:                  | (c,e) => (c, mak e)
        !           172:          and mak =
        !           173:             fn FN(v,b as APP(l,VAR w)) =>
        !           174:                 if v=w andalso pure l
        !           175:                  then let val body = mak l
        !           176:                       in  if marked v then FN(v,mak(APP(body,VAR v)))
        !           177:                           else (click(); body)
        !           178:                       end
        !           179:                  else FN(v, mak b)
        !           180:              | APP(FN(v, sw as SWITCH(VAR v',l,d)), e) =>
        !           181:                if v=v' then
        !           182:                let val e' = mak e
        !           183:                    val _ = set(v,e')
        !           184:                 in let val sw' = mak(switch(SWITCH(e',l,d)))
        !           185:                        val _ = unset v
        !           186:                     in if marked v orelse not (pure e')
        !           187:                                 then APP(FN(v,sw'),e') else (click(); sw')
        !           188:                    end
        !           189:                    handle BadSwitch =>
        !           190:                    let val l' = map makcon l
        !           191:                        val d' = case d of NONE => NONE | SOME a => SOME(mak a)
        !           192:                        val _ = unset v
        !           193:                     in if marked v then APP(FN (v, SWITCH(VAR v, l', d')), e')
        !           194:                                    else (click(); SWITCH(e', l', d'))
        !           195:                    end
        !           196:                end
        !           197:                else    let val arg = mak e
        !           198:                            val body = (set(v, arg); mak sw before unset v)
        !           199:                        in  if marked v orelse not(pure arg)
        !           200:                                then APP(FN(v,body),arg)
        !           201:                                else (click(); body)
        !           202:                        end
        !           203:              | APP(FN(v,e'),e) =>
        !           204:                        let val arg = mak e
        !           205:                            val body = (set(v, arg); mak e' before unset v)
        !           206:                        in  if marked v orelse not(pure arg)
        !           207:                                then APP(FN(v,body),arg)
        !           208:                                else (click(); body)
        !           209:                        end
        !           210:              | FIX([],[],b) => (click(); mak b)
        !           211:              | FIX(vl,el,b) => FIX(vl,map (fn FN(v,e) => FN(v,mak e)) el,mak b)
        !           212:              | e as VAR v => (let val e' = imap v
        !           213:                               in  if simple e' then (click(); mak e')
        !           214:                                                else (mark v; e)
        !           215:                               end handle Reducemap => (mark v; e))
        !           216:              | e as SELECT(i, VAR v) =>
        !           217:                              ((case imap v
        !           218:                                of RECORD l =>
        !           219:                                   let val e' = nth(l,i)
        !           220:                                   in  if simple e' then (click(); e')
        !           221:                                                    else (mark v; e)
        !           222:                                   end
        !           223:                                 | ew as VAR w => mak(SELECT(i,ew))
        !           224:                                 | _ => (mark v; e))
        !           225:                                handle Reducemap => (mark v; e))
        !           226:              | FN (w,b) => FN(w,mak b)
        !           227:              | APP (f,a) => APP(mak f, mak a)
        !           228:              | SWITCH(e,l,d) => 
        !           229:                ((case e
        !           230:                  of VAR v => mak(switch(SWITCH(imap v
        !           231:                                handle Reducemap => raise BadSwitch
        !           232:                                  , l, d)))
        !           233:                   | _ => raise BadSwitch
        !           234:                ) handle BadSwitch =>
        !           235:                let val e' = mak e
        !           236:                 in mak(switch(SWITCH(e', l, d)))
        !           237:                   handle BadSwitch => SWITCH(e', map makcon l,
        !           238:                                  case d of NONE => NONE 
        !           239:                                          | SOME a => SOME(mak a))
        !           240:                end)
        !           241:              | RECORD l => RECORD(map mak l)
        !           242:              | SELECT (i,e) => SELECT(i,mak e)
        !           243:              | HANDLE (a,h) => HANDLE(mak a, mak h)
        !           244:              | RAISE e => RAISE(mak e)
        !           245:              | e as INT _ => e
        !           246:              | e as REAL _ => e
        !           247:              | e as STRING _ => e
        !           248:              | e as PRIM _ => e
        !           249:         val exp' = mak exp
        !           250:       in  if !clicked then reduce exp' else exp'
        !           251:       end
        !           252: 
        !           253: (* minimal hoist function:  does not move bindings around, evaluation order
        !           254:    is unchanged. *)
        !           255: fun hoist (FN(v,b)) = FN(v,hoist b)
        !           256:   | hoist (APP(FN(v,b),f as FN _)) = hoist(FIX([v],[f],b))
        !           257:   | hoist (APP(l,r)) = APP(hoist l,hoist r)
        !           258:   | hoist (FIX(vl,bl,FIX(vs,bs,b))) = hoist(FIX(vl@vs,bl@bs,b))
        !           259:   | hoist (FIX(vl,bl,APP(FN(v,b),f as FN _))) = hoist(FIX(v::vl,f::bl,b))
        !           260:   | hoist (FIX(vl,bl,b)) = FIX(vl,map hoist bl, hoist b)
        !           261:   | hoist (SWITCH(e,l,d)) = 
        !           262:        SWITCH(hoist e, map (fn (c,e) => (c, hoist e)) l,
        !           263:               case d of NONE => NONE 
        !           264:                       | SOME a => SOME(hoist a))
        !           265:   | hoist (RECORD l) = RECORD(map hoist l)
        !           266:   | hoist (SELECT (i,e)) = SELECT(i,hoist e)
        !           267:   | hoist (RAISE e) = RAISE(hoist e)
        !           268:   | hoist (HANDLE (a,h)) = HANDLE(hoist a, hoist h)
        !           269:   | hoist x = x
        !           270: 
        !           271: fun freevars e =
        !           272:     let val t = Intset.new()
        !           273:        val set = Intset.add t
        !           274:        val unset = Intset.rem t
        !           275:        val done = Intset.mem t
        !           276:        val free : int list ref = ref []
        !           277:        val rec mak =
        !           278:         fn VAR w => if done w then () else (set w; free := w :: !free)
        !           279:          | FN (w,b) => (set w; mak b; unset w)
        !           280:          | FIX (vl,el,b) => (app set vl; app mak (b::el); app unset vl)
        !           281:          | APP (f,a) => (mak f; mak a)
        !           282:          | SWITCH(e,l,d) => 
        !           283:              (mak e;
        !           284:               app (fn (DATAcon(DATACON{rep=(VARIABLE(PATH p)),...}),e) =>
        !           285:                         (mak(VAR(root p)); mak e)
        !           286:                     | (c,e) => mak e)
        !           287:                   l;
        !           288:               case d of NONE => () | SOME a => mak a)
        !           289:          | RECORD l => app mak l
        !           290:          | SELECT (i,e) => mak e
        !           291:          | HANDLE (a,h) => (mak a; mak h)
        !           292:          | RAISE e => mak e
        !           293:          | INT _ => ()
        !           294:          | REAL _ => ()
        !           295:          | STRING _ => ()
        !           296:          | PRIM _ => ()
        !           297:     in  mak e; !free
        !           298:     end
        !           299: 
        !           300: local val save = (!saveLvarNames before saveLvarNames := true)
        !           301: in
        !           302: val boot_zero = namedLvar(Symbol.symbol "boot_zero") (* receives unit *)
        !           303: val boot_one = namedLvar(Symbol.symbol "boot_one")   (* traverses free list *)
        !           304: val boot_two = namedLvar(Symbol.symbol "boot_two")   (* final bogus arg *)
        !           305: 
        !           306: val (lookLvar, indexerLvar) =
        !           307:         (saveLvarNames := save;
        !           308:         (namedLvar(Symbol.symbol "lookup"),
        !           309:          namedLvar(Symbol.symbol "indexer"))
        !           310:        )
        !           311: end
        !           312: 
        !           313: fun closestr(lookup: int->string, e:lexp, extras : int list) : lexp =
        !           314:     let val fv = extras @ freevars e
        !           315:        val names = map lookup fv
        !           316:     in  if !ErrorMsg.debugging
        !           317:          then app (fn s => (print s; print " ")) names
        !           318:          else ();
        !           319:        FN(dupLvar boot_zero,
        !           320:           RECORD
        !           321:             [fold (fn (v,f) =>
        !           322:                      let val w = dupLvar boot_one
        !           323:                       in FN(w,APP(FN(v,APP(f,SELECT(1,(VAR w)))),
        !           324:                                   SELECT(0,(VAR w))))
        !           325:                      end)
        !           326:                   fv
        !           327:                   (FN(dupLvar boot_two,e)),
        !           328:              fold (fn (s,f) => RECORD[STRING s, f])
        !           329:                   names
        !           330:                   (RECORD [])])
        !           331:     end
        !           332: 
        !           333: fun remove(v :: vs: int list, from: int list) =
        !           334:       let
        !           335:        fun removeV(x :: xs) = if x=v then xs else x :: removeV xs
        !           336:          | removeV [] = []
        !           337:       in
        !           338:        remove(vs, removeV from)
        !           339:       end
        !           340:   | remove([], from) = from
        !           341: 
        !           342: fun bareCloseTop{lambda, looker, extras, keepFree} =
        !           343:   let
        !           344:     val fv = extras @ freevars lambda  (* Free vars plus extras *)
        !           345:     val fv' = remove(keepFree, fv)     (* The ones we actually abstract *)
        !           346:   in
        !           347:     FN(looker,
        !           348:        fold (fn (v, f) => APP(FN(v, f), APP(VAR looker, INT v)))
        !           349:            fv' lambda
        !           350:       )
        !           351:   end
        !           352: 
        !           353: (***
        !           354: val bareCloseTop =
        !           355:   fn (args as {lambda, looker, extras, keepFree}) =>
        !           356:     (print(implode ["bareCloseTop: looker=",
        !           357:                    Integer.makestring looker,
        !           358:                    ", extras=[ ",
        !           359:                    fold (fn (i, s) => makestring i ^ " " ^ s) extras "]",
        !           360:                    ", keepFree=[ ",
        !           361:                    fold (fn (i, s) => makestring i ^ " " ^ s) keepFree "]",
        !           362:                    ", lambda:\n"
        !           363:                   ]
        !           364:          );
        !           365:      MCprint.printLexp lambda;
        !           366:      print ".\n";
        !           367:      let val resultLamb = bareCloseTop args
        !           368:      in
        !           369:        print "bareCloseTop: result:\n";
        !           370:        MCprint.printLexp resultLamb;
        !           371:        print ".\n";
        !           372:        resultLamb
        !           373:      end
        !           374:     )
        !           375:  ***)
        !           376: 
        !           377: fun closetop(e: lexp, extras: int list): lexp =
        !           378:   bareCloseTop{lambda=e, looker=dupLvar lookLvar, extras=extras, keepFree=[]}
        !           379: 
        !           380: fun closeModDecl(lambda: lexp, slotLvars: lvar list, extras: int list): lexp =
        !           381:     let
        !           382:        val looker = dupLvar lookLvar
        !           383:        val indexer = dupLvar indexerLvar
        !           384:        val fv = extras @ freevars lambda
        !           385:            
        !           386:        fun findLvarSlot(lvar: lvar, this :: rest, n) =
        !           387:                if lvar = this then SOME n else findLvarSlot(lvar, rest, n+1)
        !           388:          | findLvarSlot(_, [], _) = NONE
        !           389: 
        !           390:        fun liftVar(freevar, lambda) =
        !           391:            APP(FN(freevar, lambda),
        !           392:                case findLvarSlot(freevar, slotLvars, 0)
        !           393:                  of SOME slot => APP(VAR indexer, INT slot)
        !           394:                   | NONE      => APP(VAR looker, INT freevar)
        !           395:               )
        !           396:     in
        !           397:        FN(looker, FN(indexer, fold liftVar fv lambda))
        !           398:     end
        !           399: 
        !           400: (* free variable analysis *)
        !           401: open SortedList
        !           402: 
        !           403: fun free e =
        !           404: let val vars : lvar list Intmap.intmap = Intmap.new(32, Freevars)
        !           405:     val setvars = Intmap.add vars
        !           406:     val rec freevars =
        !           407:         fn PRIM _ => []
        !           408:          | VAR w => [w]
        !           409:          | APP(FN(w,b),a) => rem(w,merge(freevars b, freevars a))
        !           410:          | APP(f,a) => merge(freevars f, freevars a)
        !           411:          | FN(w,b) => let val z = rem(w,freevars b)
        !           412:                       in  setvars(w,z); z
        !           413:                       end
        !           414:          | FIX([],_,b) => freevars b
        !           415:          | FIX(vl as v::_,el,b) =>
        !           416:            let val z' = foldmerge(map (fn FN(v,a) => rem(v,freevars a)) el)
        !           417:                val uvl = uniq vl
        !           418:                val z = remove(uvl, z')
        !           419:                in  setvars(v,z);
        !           420:                    merge(remove(uvl, freevars b), z)
        !           421:                end
        !           422:          | SWITCH(e,l,d) =>
        !           423:            let fun freevcon(DATAcon(DATACON{rep=(VARIABLE(Access.PATH p)),
        !           424:                                             ...})) = [root p]
        !           425:                  | freevcon _ = []
        !           426:                val zz = (case d of
        !           427:                            NONE => freevars e
        !           428:                          | SOME x => merge(freevars e, freevars x))
        !           429:            in foldmerge(zz::map(fn(c,e')=>merge(freevcon c, freevars e')) l)
        !           430:            end 
        !           431:          | RECORD l => foldmerge(map freevars l)
        !           432:          | SELECT(_,e) => freevars e
        !           433:          | HANDLE(a,h) => merge(freevars a, freevars h)
        !           434:          | RAISE e => freevars e
        !           435:          | INT _ => []
        !           436:          | REAL _ => []
        !           437:          | STRING _ => []
        !           438: in  freevars e;
        !           439:     Intmap.map vars
        !           440: end
        !           441: 
        !           442: fun mix0free e =
        !           443: let val vars : (lvar list * lvar list) Intmap.intmap = Intmap.new(32, Freevars)
        !           444:     val setvars = Intmap.add vars
        !           445:     val rec freevars =
        !           446:         fn PRIM _ => ([],[])
        !           447:          | VAR w => let val f = [w] in (f,f) end
        !           448:          | APP(FN(w,b),e as FN(_,_)) =>
        !           449:                let val (fe,_) = freevars e
        !           450:                    val (fb,cb) = freevars b
        !           451:                in  (merge(rem(w,fb),fe),rem(w,cb))
        !           452:                end
        !           453:          | APP(FN(w,b),a) =>
        !           454:                let val (fa,ca) = freevars a
        !           455:                    val (fb,cb) = freevars b
        !           456:                in  (merge(rem(w,fb),fa),merge(rem(w,cb),ca))
        !           457:                end
        !           458:          | APP(f,a) =>
        !           459:                let val (fa,ca) = freevars a
        !           460:                    val (ff,cf) = freevars f
        !           461:                in  (merge(ff,fa),merge(cf,ca))
        !           462:                end
        !           463:          | FN(v,b) =>
        !           464:                let val (f,c) = freevars b
        !           465:                    val fr = (rem(v,f),rem(v,c))
        !           466:                in  setvars(v,fr); fr
        !           467:                end
        !           468:          | FIX([],_,b) => freevars b
        !           469:          | FIX(vl as v::_,el,b) =>
        !           470:                let val fr as (f,_) =
        !           471:                           fold (fn (x,(f,c)) => (rem(x,f),rem(x,c)))
        !           472:                                 vl 
        !           473:                                 (fold (fn(FN(v,a),(f',c')) =>
        !           474:                                        let val (f,c) = freevars a
        !           475:                                        in  (merge(rem(v,f),f'),
        !           476:                                             merge(rem(v,c),c'))
        !           477:                                        end)
        !           478:                                        el ([],[]))
        !           479:                    val (fb,cb) = freevars b
        !           480:                    val uvl = uniq vl
        !           481:                in  setvars(v,fr); (merge(remove(uvl,fb),f),remove(uvl,cb))
        !           482:                end
        !           483:          | SWITCH(e,l,d) =>
        !           484:                let fun freevcon(DATAcon(DATACON{rep=(VARIABLE(Access.PATH p)),
        !           485:                                                 ...})) = [root p]
        !           486:                      | freevcon _ = []
        !           487:                in  fold (fn ((con,e'),(f,c)) =>
        !           488:                         let val (f',c') = freevars e'
        !           489:                         in  (merge(merge(freevcon con, f'),f),
        !           490:                              merge(merge(freevcon con,c'),c))
        !           491:                         end)
        !           492:                         l
        !           493:                         (let val (fe,ce) = freevars e
        !           494:                              val (fd,cd) = case d of SOME x => freevars x
        !           495:                                                    | NONE => ([],[])
        !           496:                          in  (merge(fe,fd),merge(ce,cd))
        !           497:                          end)
        !           498:                end 
        !           499:          | RECORD l => fold (fn (a,(f,c)) =>
        !           500:                                let val (f',c') = freevars a
        !           501:                                in  (merge(f,f'),merge(c,c'))
        !           502:                                end)
        !           503:                             l ([],[])
        !           504:          | SELECT(_,e) => freevars e
        !           505:          | HANDLE(a,h) =>
        !           506:                let val (fa,ca) = freevars a
        !           507:                    val (fh,ch) = freevars h
        !           508:                in  (merge(fa,fh),merge(ca,ch))
        !           509:                end
        !           510:          | RAISE e => freevars e
        !           511:          | INT _ => ([],[])
        !           512:          | REAL _ => ([],[])
        !           513:          | STRING _ => ([],[])
        !           514: in  freevars e;
        !           515:     Intmap.map vars
        !           516: end
        !           517: 
        !           518: 
        !           519: end (* structure Opt *)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.