Annotation of researchv10no/cmd/sml/src/translate/mc.sml, revision 1.1.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.