Annotation of researchv10no/cmd/sml/src/translate/mcopt.sml, revision 1.1

1.1     ! root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
        !             2: signature MCOPT =
        !             3:   sig
        !             4:     structure Absyn : BAREABSYN
        !             5:     structure Access : ACCESS
        !             6:     type rhs
        !             7:     val opt : (Absyn.pat list * rhs) list * Access.lvar list ->
        !             8:               (Absyn.pat list * rhs) list * Access.lvar list
        !             9:   end
        !            10: 
        !            11: structure MCopt : MCOPT = struct
        !            12: 
        !            13: structure Absyn : BAREABSYN = Absyn
        !            14: structure Lambda : LAMBDA = Lambda
        !            15: structure Access : ACCESS = Access
        !            16: open Basics Absyn Lambda
        !            17: open PrintUtil PrintBasics PrintAbsyn MCprint ErrorMsg
        !            18: 
        !            19: type rhs = (Access.lvar * Access.lvar) list * int (* bindings and tag *)
        !            20: 
        !            21: fun cons2 (hd::hds,tl::tls) = (hd::tl)::cons2(hds,tls)
        !            22:   | cons2 (hd::hds,[]) = [hd]::cons2(hds,[])
        !            23:   | cons2 ([],[]) = []
        !            24:   | cons2 _ =  impossible "cons2 in mcopt"
        !            25: 
        !            26: infixr cons2
        !            27: 
        !            28: (* take a list of record patterns and return the list
        !            29:    of the tail fields of each record pattern *)
        !            30: fun tl2 ([_]::_) = []
        !            31:   | tl2 ((_::tl)::pats) = tl::(tl2 pats)
        !            32:   | tl2 [] = []
        !            33:   | tl2 _ = impossible "tl2 in mcopt"
        !            34: 
        !            35: (* take a list of record patterns and return the list
        !            36:    of the first field of each record pattern *)
        !            37: fun hd2 ((hd::_)::pats) = hd::(hd2 pats)
        !            38:   | hd2 [] = []
        !            39:   | hd2 _ = impossible "hd2 in mcopt"
        !            40: 
        !            41: fun combine(relf::relfs,irrelf::irrelfs) = (relf@irrelf)::(combine(relfs,irrelfs))
        !            42:   | combine([],[]) = []
        !            43:   | combine([],irrel) = irrel
        !            44:   | combine(rel,[]) = rel
        !            45: fun addtail (fields::pats,rhs::tl) = (fields,rhs)::addtail(pats,tl)
        !            46:   | addtail ([],[]) = []
        !            47:   | addtail _ = impossible "addtail in mcopt"
        !            48: fun strip ((fields,rhs)::pats) =
        !            49:     let val (fl,tl) = strip pats in  (fields::fl,rhs::tl) end
        !            50:   | strip [] = ([],[])
        !            51: 
        !            52: fun branch_factor fs =
        !            53:  let fun existsPat f =
        !            54:       let val rec ePat =
        !            55:           fn [] => false
        !            56:             | VARpat _::more => ePat more
        !            57:             | WILDpat::more => ePat more
        !            58:             | LAYEREDpat (_,p)::more => ePat (p::more)
        !            59:             | CONSTRAINTpat (p,_)::more => ePat (p::more)
        !            60:             | p::more => (f p orelse ePat more
        !            61:                         handle Match => impossible "ePat in mcopt")
        !            62:       in  ePat
        !            63:       end
        !            64:      fun within(p,plist) =
        !            65:        case p
        !            66:          of APPpat(DATACON{name=r1,...},_) =>
        !            67:                existsPat (fn APPpat(DATACON{name=r2,...},_) => Symbol.eq(r1,r2)
        !            68:                            | CONpat _ => false) plist
        !            69:          | CONpat(DATACON{name=r1,...}) =>
        !            70:                existsPat (fn CONpat(DATACON{name=r2,...}) => Symbol.eq(r1,r2)
        !            71:                            | APPpat _ => false) plist
        !            72:          | INTpat i => existsPat (fn INTpat j => i=j) plist
        !            73:          | REALpat r => existsPat (fn REALpat s => r=s) plist
        !            74:          | STRINGpat s => existsPat (fn STRINGpat t => s=t) plist
        !            75:          | VARpat _ => true
        !            76:          | WILDpat => true
        !            77:          | LAYEREDpat (_,p) => within (p,plist)
        !            78:          | CONSTRAINTpat (p,_) => within (p,plist)
        !            79:          |  _ => impossible "within in mcopt"
        !            80:  in  length (fold (fn(a::_,b) => if within(a,b) then b else a::b) fs [])
        !            81:  end
        !            82: 
        !            83: fun arity ((hd::_)::_) = 
        !            84:       let val rec ar =
        !            85:           fn INTpat _ => 1
        !            86:            | REALpat _ => 1
        !            87:            | STRINGpat _ => 1
        !            88:            | VARpat _ => 0
        !            89:            | WILDpat => 0
        !            90:            | RECORDpat{pats=ref pats,...} => length pats
        !            91:            | APPpat (_,p) => 1 + ar p
        !            92:            | CONpat _ => 1
        !            93:            | LAYEREDpat (_,p) => ar p
        !            94:            | CONSTRAINTpat (p,_) => ar p
        !            95:       in  ar hd
        !            96:       end
        !            97:   | arity _ = impossible "arity in mcopt"
        !            98: 
        !            99: exception Record
        !           100: val rec relevant =
        !           101:  fn VARpat _ => false
        !           102:   | WILDpat => false (* any var always matches so never relevant *)
        !           103:   | RECORDpat{pats=ref [],...} => false (* unit isDCB never relevant *)
        !           104:   | RECORDpat _ => raise Record (* otherwise, immediately expand records *)
        !           105:   | LAYEREDpat (_,p) => relevant p
        !           106:   | CONSTRAINTpat (p,_) => relevant p
        !           107:     (* if only one data constructor, no need to test *)
        !           108:   | CONpat(DATACON{sign = [_],...}) => false
        !           109:   | APPpat(DATACON{sign = [_],...},p) => relevant p
        !           110:   | _ => true (* everything else is relevant *)
        !           111: 
        !           112: fun rel fs = fold (fn (a::_,b) => if relevant a then b else b+1) fs 0
        !           113:        
        !           114: (* a record should be immediately expanded by mcand so that
        !           115:    the nested fields can be considered as well;
        !           116:    don't bother to look at the rest of the fields,
        !           117:    and leave the record at the end of relf.
        !           118:    otherwise, just check the relevant.
        !           119: *)
        !           120: local
        !           121: fun r_o([],[],relf,relx,irrelf,irrelx) = (relf,relx,irrelf,irrelx)
        !           122:   | r_o(arg as (hd::_)::_,x::xs,relf,relx,irrelf,irrelx) =
        !           123:     ((if relevant hd
        !           124:       then r_o(tl2 arg,xs,(hd2 arg) cons2 relf,x::relx,irrelf,irrelx)
        !           125:       else r_o(tl2 arg,xs,relf,relx,(hd2 arg) cons2 irrelf,x::irrelx))
        !           126:      handle Record =>
        !           127:       ((hd2 arg) cons2 [],[x],combine(relf,combine(tl2 arg,irrelf)),relx@xs@irrelx))
        !           128:   | r_o _ = impossible "r_o in mcopt"
        !           129: in fun rel_order(a,x) = r_o(a,x,[],[],[],[])
        !           130: end
        !           131: 
        !           132: local
        !           133: fun gen_order f =
        !           134:     let fun order([],[],_,bestf,bestx,otherfs,otherxs) =
        !           135:            (bestf,bestx,otherfs,otherxs)
        !           136:           | order(argp,x::xs,old,bestf,bestx,otherfs,otherxs) =
        !           137:            let val head = hd2 argp
        !           138:                val tail = tl2 argp
        !           139:                val new = f argp
        !           140:            in if Integer.<(new,old)
        !           141:               then order(tail,xs,new,head cons2 [],[x],
        !           142:                          combine(bestf,otherfs),bestx@otherxs)
        !           143:               else if new > old
        !           144:               then order(tail,xs,old,bestf,bestx,head cons2 otherfs,x::otherxs)
        !           145:               else order(tail,xs,old,head cons2 bestf,x::bestx,otherfs,otherxs)
        !           146:            end
        !           147:          | order _ = impossible "order in mcopt"
        !           148:     in fn(a,x::xs) =>
        !           149:        let val hd = hd2 a
        !           150:           val tl = tl2 a
        !           151:           val bestf = hd cons2 []
        !           152:        in order(tl,xs,f bestf,bestf,[x],[],[])
        !           153:        end
        !           154:     end
        !           155: in
        !           156: val relevance_order = gen_order rel
        !           157: val branch_order = gen_order branch_factor
        !           158: val arity_order = gen_order arity
        !           159: end
        !           160: 
        !           161: (* OPT:  rearrange the fields of a tuple into a better order to evaluate.
        !           162:         use the relevant test.  if there are no relevant fields,
        !           163:         then the first pattern will match - don't bother returning
        !           164:         the rest.  if one of the fields is a record, return it first
        !           165:         so it is expanded.  if the relevant test does not isolate
        !           166:         one field, use the branch factor test, then the arity test. *)
        !           167: 
        !           168: fun opt (arg as ([],_)) = arg
        !           169:   | opt (pl as hd::_,xl) =
        !           170:     let val (pats,tl) = strip pl
        !           171:        val (relf,relx,irrelf,irrelx) = rel_order(pats,xl)
        !           172:     in case relf of
        !           173:          [] => ([hd],xl)
        !           174:        | [_]::_ => (addtail(combine(relf,irrelf),tl),relx@irrelx)
        !           175:        | _ =>
        !           176:         let val (rf,rx,irf,irx) = relevance_order(relf,relx)
        !           177:             val rrest = combine(irf,irrelf)
        !           178:             val rrestx = irx@irrelx
        !           179:         in case rf of
        !           180:              [_]::_ => (addtail(combine(rf,rrest),tl),rx@rrestx)
        !           181:            | _ =>
        !           182:              let val (branchf,branchx,branchfs,branchxs) = branch_order(rf,rx)
        !           183:                  val brest = combine(branchfs,rrest)
        !           184:                  val brestx = branchxs@rrestx
        !           185:              in case branchf of
        !           186:                   [_]::_ => (addtail(combine(branchf,brest),tl),branchx@brestx)
        !           187:                 | _ => let val (arityf,arityx,arityfs,arityxs) =
        !           188:                                arity_order(branchf,branchx)
        !           189:                        in (addtail(combine(arityf,combine(arityfs,brest)),tl),
        !           190:                            arityx@arityxs@brestx)
        !           191:                        end
        !           192:              end
        !           193:         end
        !           194:     end
        !           195: 
        !           196: end (* structure MCopt *)

unix.superglobalmegacorp.com

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