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

1.1     ! root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
        !             2: signature MC = sig
        !             3:        structure A : BAREABSYN
        !             4:        structure L : LAMBDA
        !             5:        val matchCompile : (A.pat * L.lexp) list -> L.lexp
        !             6:        val bindCompile : (A.pat * L.lexp) list -> L.lexp
        !             7:        end
        !             8: 
        !             9: structure MC : MC = struct
        !            10: 
        !            11: structure A : BAREABSYN = BareAbsyn
        !            12: structure L : LAMBDA = Lambda
        !            13: 
        !            14: open A L
        !            15: open Access Basics ErrorMsg
        !            16: 
        !            17: val printDepth = System.Control.Print.printDepth
        !            18: 
        !            19: val patsUsed : int list ref = ref []
        !            20: val maybeUsed : int list ref = ref []
        !            21: val results : (lvar * lvar list) list ref = ref []
        !            22: 
        !            23: fun mark(taglist,tag : int) =
        !            24:     let fun newtag[] = [tag]
        !            25:          | newtag(taglist as (t::more)) =
        !            26:                if tag = t then taglist
        !            27:                else if tag < t then tag :: taglist
        !            28:                else t :: newtag more
        !            29:     in taglist := newtag (!taglist)
        !            30:     end
        !            31: 
        !            32: fun unused rules =
        !            33:     let fun find([],[],_) = []
        !            34:          | find([],_::r,i) = i :: find([],r,i+1)
        !            35:          | find(taglist as tag::tags,_::r,i) =
        !            36:                if tag = i
        !            37:                then find(tags,r,i+1)
        !            38:                else i :: find(taglist,r,i+1)
        !            39:          | find _ = ErrorMsg.impossible "unused in mc"
        !            40:     in  find(!patsUsed,rules,0)
        !            41:     end
        !            42: fun redundant rules =
        !            43:        if length rules = length (!patsUsed) then []
        !            44:        else unused rules
        !            45: fun areNotRedundant () =
        !            46:        case !maybeUsed of
        !            47:          [] => ()
        !            48:        | (tag::_) => (mark(patsUsed,tag); maybeUsed := [])
        !            49: fun areRedundant () = maybeUsed := []
        !            50: 
        !            51: fun bind(x,v,(bindings,tag)) = ((v,x)::bindings,tag)
        !            52: 
        !            53: fun layer (x,CONSTRAINTpat(pat,_),rhs) = layer(x,pat,rhs)
        !            54:   | layer (x,VARpat(VALvar{access=LVAR v,...}),rhs) = bind(x,v,rhs)
        !            55:   | layer _ = impossible "bad layered pattern in mc"
        !            56: 
        !            57: fun convert(bindings,tag) =
        !            58:        let val (f,free) = nth(!results,tag)
        !            59:            fun order [] = []
        !            60:              | order (v::tl) =
        !            61:                let fun f [] = ErrorMsg.impossible "convert in translate/mc.sml"
        !            62:                      | f ((w,z)::tl) = if v=w then z else f tl
        !            63:                in  f bindings :: order tl
        !            64:                end
        !            65:            val args = order free
        !            66:        in  mark(patsUsed,tag); APP(VAR f,RECORD(map VAR args))
        !            67:        end
        !            68: fun convertDefault(bindings,tag) =
        !            69:        let val (f,free) = nth(!results,tag)
        !            70:            fun order [] = []
        !            71:              | order (v::tl) =
        !            72:                let fun f [] = ErrorMsg.impossible "convertD in translate/mc.sml"
        !            73:                      | f ((w,z)::tl) = if v=w then z else f tl
        !            74:                in  f bindings :: order tl
        !            75:                end
        !            76:            val args = order free
        !            77:        in  mark(maybeUsed,tag); APP(VAR f,RECORD(map VAR args))
        !            78:        end
        !            79: 
        !            80: val rec freevars =
        !            81:        fn VARpat(VALvar{access=LVAR v,...}) => [v]
        !            82:         | RECORDpat{pats=ref pats,...} => SortedList.foldmerge(map freevars pats)
        !            83:         | APPpat(_,pat) => freevars pat
        !            84:         | CONSTRAINTpat(pat,_) => freevars pat
        !            85:         | LAYEREDpat(l,r) => SortedList.merge(freevars l,freevars r)
        !            86:         | _ => []
        !            87: 
        !            88: fun setup rules =
        !            89:   let val arg = mkLvar()
        !            90:       fun t(i,(pat,result)::more) =
        !            91:          let val (header,r) = t(i+1,more)
        !            92:              val record = mkLvar()
        !            93:              val returnit = mkLvar()
        !            94:              val free = freevars pat
        !            95:              fun f(_,[]) = result
        !            96:                | f(i,v::tl) = APP(FN(v,f(i+1,tl)),SELECT(i,VAR record))
        !            97:          in results := (returnit,free) :: !results;
        !            98:             (fn l => header(APP(FN(returnit,l),FN(record,f(0,free)))),
        !            99:              (pat,([],i)) :: r)
        !           100:          end
        !           101:        | t _ = (fn x => x,[])
        !           102:   in  patsUsed := []; maybeUsed := [];
        !           103:       let val (header,r) = t(0,rules)
        !           104:       in (fn l => FN(arg,header(APP(l,VAR arg))),r)
        !           105:       end
        !           106:   end
        !           107: 
        !           108: fun bindfields(record,fields,e)=
        !           109:   let fun select(i, []) = e
        !           110:         | select(i, x::xs) = APP(FN(x,select(i+1,xs)),SELECT(i,VAR record))
        !           111:   in  select(0,fields)
        !           112:   end
        !           113: 
        !           114: fun andSwitch x =
        !           115: let
        !           116: fun andS [] = ([],[])
        !           117:   | andS ((p::fields,rhs)::more) =
        !           118:      (case p of
        !           119:        INTpat i =>
        !           120:        let val (cases,default) = andS more
        !           121:            fun addto ((switch as (INTcon j,pats))::more) =
        !           122:                    if i = j then ((INTcon i,(fields,rhs)::pats)::more)
        !           123:                    else switch :: addto more
        !           124:              | addto [] = [(INTcon i,(fields,rhs)::default)]
        !           125:              | addto _ = impossible "983 type error in match compiler"
        !           126:        in  (addto cases,default)
        !           127:        end
        !           128:      | REALpat r =>
        !           129:        let val (cases,default) = andS more
        !           130:        fun addto ((switch as (REALcon s,pats))::more) =
        !           131:                if r = s then ((REALcon r,(fields,rhs)::pats)::more)
        !           132:                else switch :: addto more
        !           133:          | addto [] = [(REALcon r,(fields,rhs)::default)]
        !           134:          | addto _ = impossible "48 type error in match compiler"
        !           135:        in  (addto cases,default)
        !           136:        end
        !           137:      | STRINGpat s =>
        !           138:        let val (cases,default) = andS more
        !           139:            fun addto ((switch as (STRINGcon t,pats))::more) =
        !           140:                  if s = t then ((STRINGcon s,(fields,rhs)::pats)::more)
        !           141:                  else switch :: addto more
        !           142:              | addto [] = [(STRINGcon s,(fields,rhs)::default)]
        !           143:              | addto _ = impossible "482 type error in match compiler"
        !           144:        in  (addto cases,default)
        !           145:        end
        !           146:      | CONpat(dcon as DATACON{name=r1,...}) =>
        !           147:        let val (cases,default) = andS more
        !           148:          fun addto ((switch as (DATAcon(DATACON {name=r2,...}),pats))::more) =
        !           149:                  if Symbol.eq(r1,r2)
        !           150:                    then (DATAcon dcon,(fields,rhs)::pats)::more
        !           151:                    else switch :: addto more
        !           152:            | addto [] = [(DATAcon dcon,(fields,rhs)::default)]
        !           153:            | addto _ = impossible "87 type error in match compiler"
        !           154:        in  (addto cases,default)
        !           155:        end
        !           156:      | APPpat(dcon as DATACON{name=r1,...},p) =>
        !           157:        let val (cases,default) = andS more
        !           158:        fun addto ((switch as (DATAcon(DATACON {name=r2,...}),pats))::more) =
        !           159:                if Symbol.eq(r1,r2)
        !           160:                then ((DATAcon dcon,(p::fields,rhs)::pats)::more)
        !           161:                else switch :: addto more
        !           162:          | addto [] =
        !           163:                let fun addwild (fields,rhs) = (WILDpat::fields,rhs)
        !           164:                in  [(DATAcon dcon,(p::fields,rhs)::(map addwild default))]
        !           165:                end
        !           166:          | addto _ = impossible "444 type error in match compiler"
        !           167:        in  (addto cases,default)
        !           168:        end
        !           169:      | WILDpat =>
        !           170:        let val (cases,default) = andS more
        !           171:        fun addto (((con as DATAcon(DATACON{const=false,...})),pats)::more) =
        !           172:                (con,(WILDpat::fields,rhs)::pats) :: addto more
        !           173:          | addto ((con,pats)::more) =
        !           174:                (con,(fields,rhs)::pats) :: addto more
        !           175:          | addto [] = []
        !           176:        in  (addto cases,(fields,rhs)::default)
        !           177:        end
        !           178:      | VARpat(VALvar{access=LVAR v,...}) => 
        !           179:        andS ((WILDpat::fields,bind(x,v,rhs))::more)
        !           180:      | LAYEREDpat(v,p) => andS((p::fields,layer(x,v,rhs))::more)
        !           181:      | CONSTRAINTpat(p,_) => andS((p::fields,rhs)::more)
        !           182:      | _ => impossible "andS in mc")
        !           183:   | andS _ = impossible "andS2 in mc"
        !           184: in  andS
        !           185: end
        !           186: 
        !           187: fun orSwitch x =
        !           188: let fun diffPats samefn =
        !           189:        let fun diff [] = []
        !           190:              | diff ((hd as (p,rhs))::more) =
        !           191:                 case p of
        !           192:                    WILDpat => [hd]
        !           193:                  | VARpat(VALvar{access=LVAR v,...}) => [(WILDpat,bind(x,v,rhs))]
        !           194:                  | LAYEREDpat(v,p) =>
        !           195:                        diff ((p,layer(x,v,rhs))::more)
        !           196:                  | CONSTRAINTpat(p,_) =>
        !           197:                        diff ((p,rhs)::more)
        !           198:                  | _ => (if samefn p then diff more else hd::diff more)
        !           199:                          handle Match =>
        !           200:                            impossible "orS.diff: type error in match compiler"
        !           201:        in  diff
        !           202:        end
        !           203: fun orS [] =  impossible "orSwitch [] in mc"
        !           204:   | orS (arg as (p,rhs)::more) =
        !           205:      case p of
        !           206:       INTpat i =>
        !           207:        let val (cases,default) = orS (diffPats (fn INTpat j => i=j) arg)
        !           208:        in  ((INTcon i,convert rhs)::cases,default)
        !           209:        end
        !           210:     | REALpat r =>
        !           211:        let val (cases,default) = orS (diffPats (fn REALpat s => r=s) arg)
        !           212:        in  ((REALcon r,convert rhs)::cases,default)
        !           213:        end
        !           214:     | STRINGpat s =>
        !           215:        let val (cases,default) = orS (diffPats (fn STRINGpat t => s=t) arg)
        !           216:        in  ((STRINGcon s,convert rhs)::cases,default)
        !           217:        end
        !           218:     | WILDpat => ([],SOME(convert rhs))
        !           219:     | VARpat(VALvar{access=LVAR v,...}) => ([],SOME(convert(bind(x,v,rhs))))
        !           220:     | CONSTRAINTpat(p,_) => orS ((p,rhs)::more)
        !           221:     | LAYEREDpat(v,p) => orS ((p,layer(x,v,rhs))::more)
        !           222:     | _ => impossible "orS in mc"
        !           223: in  orS
        !           224: end
        !           225: 
        !           226: fun mcand (arg as ([_],_)::_,[x]) =
        !           227:        let val singlelist = fn ([pat],rhs) => (pat,rhs)
        !           228:                              | _ => impossible "singlelist in match compiler"
        !           229:        in  APP(mcor (map singlelist arg), VAR x)
        !           230:        end
        !           231:   | mcand (arg as (p::fields,rhs)::more,xl as x::xs) =
        !           232:     let fun mconto (con as DATAcon(con1 as DATACON{const = false,...}),pats) =
        !           233:             let val new = mkLvar ()
        !           234:             in  (con,APP(FN(new,mcand (MCopt.opt (pats,new::xs))),DECON (con1,VAR x)))
        !           235:             end
        !           236:          | mconto (con as DATAcon(DATACON {const = true,...}),pats) =
        !           237:             (con,mcand (MCopt.opt (pats,xs)))
        !           238:          | mconto _ = impossible "mconto in mc"
        !           239:     in
        !           240:      case p of
        !           241:        WILDpat => mcand([(fields,rhs)],xs)
        !           242:      | VARpat(VALvar{access=LVAR v,...}) => mcand([(fields,bind(x,v,rhs))],xs)
        !           243:      | LAYEREDpat(v,p) => mcand(((p::fields,layer(x,v,rhs))::more),xl)
        !           244:      | CONSTRAINTpat(p,_) => mcand((p::fields,rhs)::more,xl)
        !           245:      | APPpat(DATACON{sign = [_],...},_) =>
        !           246:        let val newx = mkLvar()
        !           247:            val ([(DATAcon dcon,list)],_) = andSwitch x arg
        !           248:        in  APP(FN(newx,mcand(MCopt.opt(list,newx::xs))),DECON(dcon,VAR x))
        !           249:        end
        !           250:      | APPpat(DATACON{sign,...},_) =>
        !           251:        let val (cases,default) = andSwitch x arg
        !           252:        in  SWITCH(VAR x,
        !           253:                   map mconto cases,
        !           254:                   if length cases = length sign then NONE
        !           255:                       else SOME (mcand (MCopt.opt (default,xs))))
        !           256:        end
        !           257:      | CONpat(DATACON{sign=[_],...}) => mcand([(fields,rhs)],xs)
        !           258:      | CONpat(DATACON{sign,...}) =>
        !           259:        let val (cases,default) = andSwitch x arg
        !           260:        in  SWITCH(VAR x,
        !           261:                   map mconto cases,
        !           262:                   if length cases = length sign then NONE
        !           263:                       else SOME (mcand (MCopt.opt (default,xs))))
        !           264:        end
        !           265:      | RECORDpat{pats=ref [],...} => mcand([(fields,rhs)],xs)
        !           266:      | RECORDpat{pats,...} =>
        !           267:        let val newfields = map (fn _ => mkLvar()) (!pats)
        !           268:            val wild = map (fn _ => WILDpat) newfields
        !           269:            fun expand [] = []
        !           270:              | expand ((p::fields,rhs)::more) =
        !           271:                 (case p of
        !           272:                   RECORDpat{pats,...} => (!pats@fields,rhs) :: expand more
        !           273:                 | LAYEREDpat(v,p) => expand ((p::fields,layer(x,v,rhs))::more)
        !           274:                 | CONSTRAINTpat(p,_) => expand ((p::fields,rhs)::more)
        !           275:                 | WILDpat => (wild@fields,rhs) :: expand more
        !           276:                 | VARpat(VALvar{access=LVAR v,...}) =>
        !           277:                            (wild@fields,bind(x,v,rhs)) :: expand more
        !           278:                 |  _ => impossible "mcand.expand in mc")
        !           279:              | expand _ = impossible "mcand.expand2 in mc"
        !           280:            in  bindfields(x,newfields,mcand(MCopt.opt(expand arg,newfields@xs)))
        !           281:            end
        !           282:      | _ => (* INTpat,REALpat,STRINGpat; possibly bad VARpats *)
        !           283:        let val (cases,default) = andSwitch x arg
        !           284:        in  SWITCH(VAR x,
        !           285:                   map (fn (con,pats) => (con,mcand(MCopt.opt(pats,xs)))) cases,
        !           286:                   SOME(mcand(MCopt.opt(default,xs))))
        !           287:        end
        !           288:     end
        !           289:   | mcand _ = impossible "mcand in mc"
        !           290: 
        !           291: and conSwitch x =
        !           292: let
        !           293: fun conS [] = ([],NONE)
        !           294:   | conS (arg as (p,rhs)::more) =
        !           295:      case p of
        !           296:        CONpat(dcon as DATACON{name=r1,...}) =>
        !           297:        let fun diff [] = []
        !           298:              | diff ((hd as (p,rhs))::more) =
        !           299:                 case p of
        !           300:                  CONpat(DATACON{name=r2,...}) =>
        !           301:                        if Symbol.eq(r1,r2) then diff more
        !           302:                        else (hd::diff more)
        !           303:                | APPpat (_,_) => hd::diff more
        !           304:                | WILDpat => [hd]
        !           305:                | VARpat _ => [hd]
        !           306:                | CONSTRAINTpat(p,_) => diff ((p,rhs)::more)
        !           307:                | LAYEREDpat(v,p) => diff ((p,layer(x,v,rhs))::more)
        !           308:                | _ => impossible "conS.diff: type error in match compiler"
        !           309:            val (cases,default) = conS (diff more)
        !           310:        in  ((DATAcon dcon,convert rhs)::cases,default)
        !           311:        end
        !           312:      | APPpat(dcon as DATACON{name=r1,...},_) =>
        !           313:        let fun divide [] = ([],[])
        !           314:              | divide ((hd as (p,rhs))::more) =
        !           315:                case p of
        !           316:                  CONpat _ =>
        !           317:                      let val (same,diff) = divide more
        !           318:                      in  (same,hd::diff)
        !           319:                      end
        !           320:                | APPpat(DATACON{name=r2,...},p) =>
        !           321:                      let val (same,diff) = divide more 
        !           322:                      in  if Symbol.eq(r1,r2)
        !           323:                          then ((p,rhs)::same,diff)
        !           324:                          else (same,hd::diff)
        !           325:                      end
        !           326:                | WILDpat => ([hd],[hd])
        !           327:                | VARpat(VALvar{access=LVAR v,...}) =>
        !           328:                        ([(WILDpat,bind(x,v,rhs))],[hd])
        !           329:                | CONSTRAINTpat(p,_) => divide ((p,rhs)::more)
        !           330:                | LAYEREDpat(v,p) => divide ((p,layer(x,v,rhs))::more)
        !           331:                | _ => impossible "conS.divide: type error in match compiler"
        !           332:            val con = DATAcon dcon
        !           333:             val (same,diff) = divide arg
        !           334:            val lexp = mcor same            (* Order imp. here:  side- *)
        !           335:            val (cases,default) = conS diff (* effects in redund. chk. *)
        !           336:         in  ((con,APP(lexp,DECON(dcon,VAR x)))::cases,default)
        !           337:         end
        !           338:      | WILDpat => ([],SOME(convertDefault rhs))
        !           339:      | VARpat(VALvar{access=LVAR v,...}) =>
        !           340:                        ([],SOME(convertDefault(bind(x,v,rhs))))
        !           341:      | LAYEREDpat(v,p) => conS ((p,layer(x,v,rhs))::more)
        !           342:      | CONSTRAINTpat(p,_) => conS ((p,rhs)::more)
        !           343:      | _ => impossible "conS: type error in match compiler"
        !           344: in  conS
        !           345: end
        !           346: 
        !           347: and mcor [] = impossible "mcor.[] in mc"
        !           348:   | mcor (arg as (p,rhs)::more) =
        !           349:       let val x = mkLvar()
        !           350:       in  case p of
        !           351:              CONpat(DATACON{sign=[],...}) => (* exception *)
        !           352:                let val (cases,default) = conSwitch x arg
        !           353:                in  areNotRedundant();
        !           354:                    FN(x,SWITCH(VAR x,cases,default))
        !           355:                end
        !           356:            | APPpat (DATACON{sign=[],...},_) => (* exn *)
        !           357:                let val (cases,default) = conSwitch x arg
        !           358:                in  areNotRedundant();
        !           359:                    FN(x,SWITCH(VAR x,cases,default))
        !           360:                end
        !           361:            | CONpat(DATACON{sign=[_],...}) => FN(x, convert rhs)
        !           362:            | CONpat(DATACON{sign,...}) =>
        !           363:                let val (cases,default) = conSwitch x arg
        !           364:                in  FN(x,SWITCH(VAR x, cases,
        !           365:                        (if length cases = length sign
        !           366:                           then (areRedundant(); NONE)
        !           367:                           else (areNotRedundant(); default))))
        !           368:                end
        !           369:            | APPpat(DATACON{sign=[_],...},_) =>
        !           370:                let val ([(con,lexp)],_) = conSwitch x arg
        !           371:                in  areRedundant();
        !           372:                    FN(x,lexp)
        !           373:                end
        !           374:            | APPpat(DATACON{sign,...},_) =>
        !           375:                let val (cases,default) = conSwitch x arg
        !           376:                in  FN(x,SWITCH(VAR x, cases,
        !           377:                       (if length cases = length sign
        !           378:                        then (areRedundant(); NONE)
        !           379:                        else (areNotRedundant(); default))))
        !           380:                end
        !           381:            | INTpat _ =>
        !           382:                let val (cases,default) = orSwitch x arg
        !           383:                in  FN(x,SWITCH(VAR x,cases,default))
        !           384:                end
        !           385:            | REALpat _ =>
        !           386:                let val (cases,default) = orSwitch x arg
        !           387:                in  FN(x,SWITCH(VAR x,cases,default))
        !           388:                end
        !           389:            | STRINGpat _ =>
        !           390:                let val (cases,default) = orSwitch x arg
        !           391:                in  FN(x,SWITCH(VAR x,cases,default))
        !           392:                end
        !           393:            | RECORDpat{pats=ref [],...} => FN(x, convert rhs)
        !           394:            | RECORDpat{pats,...} =>
        !           395:                let val newfields = map (fn _ => mkLvar()) (!pats)
        !           396:                    val wild = map (fn _ => WILDpat) newfields
        !           397:                    fun expand [] = []
        !           398:                      | expand ((p,rhs)::more) =
        !           399:                         case p of
        !           400:                          RECORDpat{pats,...} => (!pats,rhs) :: expand more
        !           401:                        | LAYEREDpat(v,p) => expand ((p,layer(x,v,rhs))::more)
        !           402:                        | CONSTRAINTpat(p,_) => expand ((p,rhs)::more)
        !           403:                        | WILDpat => [(wild,rhs)]
        !           404:                        | VARpat(VALvar{access=LVAR v,...}) =>
        !           405:                              [(wild,bind(x,v,rhs))]
        !           406:                        | _ => impossible "mcor.expand in mc"
        !           407:                in  FN(x,bindfields(x,newfields,mcand(MCopt.opt(expand arg,newfields))))
        !           408:                end
        !           409:            | WILDpat => FN(x, convert rhs)
        !           410:            | VARpat(VALvar{access=LVAR v,...}) => FN(x,convert(bind(x,v,rhs)))
        !           411:            | LAYEREDpat(v,p) => FN(x,APP(mcor((p,layer(x,v,rhs))::more),VAR x))
        !           412:            | CONSTRAINTpat(p,_) => mcor((p,rhs)::more)
        !           413:            | _ => impossible "mcor: type error in match compiler"
        !           414:       end (* fun mcor *)
        !           415: 
        !           416: open PrintUtil
        !           417: fun matchPrint [] _ _ = ()
        !           418:   | matchPrint [(pat,_)] _ _ = () (* never print last rule *)
        !           419:   | matchPrint ((pat,_)::more) [] _ =
        !           420:        (print "        "; PrintAbsyn.printPat(pat,!printDepth); print " => ...\n";
        !           421:         matchPrint more [] 0)
        !           422:   | matchPrint ((pat,_)::more) (taglist as (tag::tags)) i =
        !           423:        if i = tag
        !           424:        then (print "  -->   "; PrintAbsyn.printPat(pat,!printDepth);
        !           425:              print " => ...\n"; matchPrint more tags (i+1))
        !           426:        else (print "        "; PrintAbsyn.printPat(pat,!printDepth);
        !           427:              print " => ...\n"; matchPrint more taglist (i+1))
        !           428: 
        !           429: fun bindPrint ((pat,_)::_) =
        !           430:       (print "        "; PrintAbsyn.printPat(pat,!printDepth); print " = ...\n")
        !           431:   | bindPrint _ = impossible "bindPrint in mc"
        !           432: 
        !           433: fun noVarsIn ((pat,_)::_) =
        !           434:        let fun var WILDpat = true (* might want to flag this *)
        !           435:              | var (VARpat _) = true
        !           436:              | var (LAYEREDpat _) = true
        !           437:              | var (CONSTRAINTpat(p,_)) = var p
        !           438:              | var (APPpat(_,p)) = var p
        !           439:              | var (RECORDpat{pats=ref patlist,...}) = exists var patlist
        !           440:              | var _ = false
        !           441:        in  not(var pat)
        !           442:        end
        !           443:   | noVarsIn _ = impossible "noVarsIn in mc"
        !           444: 
        !           445: open System.Control.MC
        !           446: 
        !           447: fun genCompile(flag1,warning1,flag2,test,warning2,printer) rules = 
        !           448: let val (header,rules') = setup rules
        !           449:     val match = header(mcor rules')
        !           450:     val unused = redundant rules
        !           451:     val last = length rules - 1
        !           452:     val printit = if !flag1 andalso not(exists (fn i => i=last) unused)
        !           453:                  then (warn(warning1 ^ " not exhaustive"); true)
        !           454:                  else false
        !           455:     val printit = if !flag2 andalso test(rules,unused,last)
        !           456:                  then (warn warning2; true)
        !           457:                  else printit
        !           458: in  if !printArgs
        !           459:        then (warn "MC called with:"; MCprint.printMatch rules)
        !           460:        else ();
        !           461:     if printit
        !           462:        then printer(rules,unused)
        !           463:        else ();
        !           464:     if !printRet
        !           465:        then (print "MC:  returns with\n"; MCprint.printLexp match; newline())
        !           466:        else ();
        !           467:     match
        !           468: end handle Syntax => (warn "MC called with:"; MCprint.printMatch rules;
        !           469:                      raise Syntax)
        !           470: 
        !           471: val bindCompile = 
        !           472:     genCompile(bindExhaustive,
        !           473:               "binding",
        !           474:               bindContainsVar,
        !           475:               fn (rules,unused,last) => noVarsIn rules,
        !           476:               "binding contains no variables",
        !           477:               fn(rules,unused) => bindPrint rules)
        !           478: 
        !           479: val matchCompile = 
        !           480:     genCompile(matchExhaustive,
        !           481:               "match",
        !           482:               matchRedundant,
        !           483:               fn(rules,unused,last) => exists (fn i => i<last) unused,
        !           484:               "redundant patterns in match",
        !           485:               fn(rules,unused) => matchPrint rules unused 0)
        !           486: 
        !           487: end (* struct MC *)

unix.superglobalmegacorp.com

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