Annotation of researchv10no/cmd/sml/src/typing/sigmatch.sml, revision 1.1

1.1     ! root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
        !             2: (* sigmatch.sml *)
        !             3: 
        !             4: structure SigMatch : SIGMATCH = struct
        !             5: 
        !             6: structure Basics = Basics
        !             7: 
        !             8: open List2 PrintUtil ErrorMsg Access Stampset Basics BareAbsyn BasicTypes
        !             9:      EnvAccess EnvAccess.Env TypesUtil PrintType ModUtil
        !            10: 
        !            11: (* debug print functions *)
        !            12: val prIntPath = printClosedSequence ("[",",","]") (print:int->unit)
        !            13: fun prSymPath spath = printSequence "." printSym (rev spath)
        !            14: 
        !            15: val symName = Symbol.name
        !            16: val anonName = Symbol.symbol "Anon"
        !            17: fun for a b = app b a
        !            18: 
        !            19: exception CompareTypes
        !            20: exception REFtyc
        !            21: val refstamp = tycStamp(!refTycon)
        !            22: and arraystamp = tycStamp(!arrayTycon)
        !            23: 
        !            24: fun compType(specty, specsign:polysign, actty, actsign:polysign, actarity): unit =
        !            25:     let val env = array(actarity,UNDEFty)
        !            26:        fun comp(ty1, VARty(ref(INSTANTIATED(ty2)))) =
        !            27:              comp(ty1,ty2)
        !            28:          | comp(ty1, FLEXRECORDty(ref(CLOSED ty2))) = comp(ty1,ty2)
        !            29:          | comp(ty1, VARty(ref(IBOUND i))) =
        !            30:             (case env sub i
        !            31:                of UNDEFty =>
        !            32:                    let val {weakness=aw,eq=ae} = nth(actsign,i)
        !            33:                     in if aw < infinity
        !            34:                        then let fun checkweak(VARty(ref(IBOUND n))) =
        !            35:                                        let val {weakness=sw,...} = nth(specsign,n)
        !            36:                                         in if sw > aw then raise CompareTypes
        !            37:                                            else ()
        !            38:                                        end
        !            39:                                    | checkweak(CONty(_,args)) = app checkweak args
        !            40:                                    | checkweak _ = impossible "compType/checkweak"
        !            41:                              in checkweak ty1
        !            42:                             end
        !            43:                        else ();
        !            44:                        if ae 
        !            45:                        then checkEqTySig(ty1,specsign)
        !            46:                             handle CHECKEQ => raise CompareTypes
        !            47:                        else ();
        !            48:                        update(env,i,ty1)
        !            49:                    end
        !            50:                 | ty => if equalType(ty1,ty)
        !            51:                         then ()
        !            52:                         else raise CompareTypes)
        !            53:          | comp(ty1 as CONty(ref tycon, args), ty2 as CONty(ref tycon', args')) =
        !            54:              if eqTycon(tycon,tycon')
        !            55:              then app2 comp (args,args')
        !            56:              else (comp(reduceType ty1, ty2)
        !            57:                    handle ReduceType =>
        !            58:                      comp(ty1, reduceType ty2)
        !            59:                      handle ReduceType => raise CompareTypes)
        !            60:          | comp(_, ERRORty) = ()
        !            61:          | comp _ = raise CompareTypes
        !            62:      in comp(specty,actty)
        !            63:     end
        !            64: 
        !            65: fun compareTypes(spec: ty, actual: ty, name) : unit =
        !            66:     let fun error() =
        !            67:            (complain "value type in structure doesn't match signature spec";
        !            68:             PrintType.resetPrintType();
        !            69:             print ("  name: " ^ symName name ^ "\n  spec:   ");
        !            70:             PrintType.printType(spec);
        !            71:             print "\n  actual: ";
        !            72:             PrintType.printType(actual); newline())
        !            73:      in case spec
        !            74:          of POLYty{sign,tyfun=TYFUN{body,...}} =>
        !            75:              (case actual
        !            76:                 of POLYty{sign=sign',tyfun=TYFUN{arity,body=body'}} =>
        !            77:                      (compType(body,sign,body',sign',arity)
        !            78:                       handle CompareTypes => error())
        !            79:                  | _ => error())
        !            80:           | ERRORty => ()
        !            81:           | _ =>
        !            82:              (case actual
        !            83:                 of POLYty{sign,tyfun=TYFUN{arity,body}} =>
        !            84:                      (compType(spec,[],body,sign,arity)
        !            85:                       handle CompareTypes => error())
        !            86:                  | _ => if equalType(spec,actual)
        !            87:                         then ()
        !            88:                         else error())
        !            89:     end
        !            90: 
        !            91: 
        !            92: (* making abstraction structures *)
        !            93: 
        !            94: fun abstract(sgn as STRstr{kind=SIGkind{stamps={strStamps=sigStrStamps,
        !            95:                                                tycStamps=sigTycStamps},
        !            96:                                        ...},
        !            97:                           ...},
        !            98:             str, {strStamps, tycStamps}) =
        !            99:     let val transStrStamp = join(strStamps,sigStrStamps)
        !           100:        val transTycStamp = join(tycStamps,sigTycStamps)
        !           101:        fun abstractTyc(sigtyc,strtyc) =
        !           102:            case sigtyc
        !           103:              of TYCON{kind=DATAtyc _,...} => strtyc
        !           104:               | _ => let val stamp = tycStamp sigtyc
        !           105:                       in if tycFixed(stamp)
        !           106:                          then strtyc
        !           107:                          else setTycStamp(transTycStamp(stamp),sigtyc)
        !           108:                      end
        !           109:        fun abstractStr(STRstr{stamp,sign,table,env,...},
        !           110:                        str as STRstr{env=env',...}) =
        !           111:              if strFixed stamp
        !           112:              then str
        !           113:              else let val newenv as REL{s,t} = abstractEnv(env,env')
        !           114:                       val newstr = STRstr{stamp=transStrStamp(stamp),
        !           115:                                           env=newenv,
        !           116:                                           sign=sign,table=table,
        !           117:                                           kind=STRkind{path=[]}} (* ??? def of kind *)
        !           118:                    in ArrayExt.app((setParent newstr), s, 2);
        !           119:                       newstr
        !           120:                   end
        !           121:          | abstractStr (INDstr i,_) =
        !           122:              impossible ("3437 in sigmatch: " ^makestring i)
        !           123:          | abstractStr _ = impossible "9833 in sigmatch (abstractStr)"
        !           124:        and abstractEnv(REL{s=sSig,t=tSig}:strenv, REL{s=sStr,t=tStr}:strenv) =
        !           125:            let val sNew = array(Array.length sSig, NULLstr)
        !           126:                val tNew = array(Array.length tSig, NULLtyc)
        !           127:                fun foreachStr i =
        !           128:                    (update(sNew,i,abstractStr(sSig sub i, sStr sub i));
        !           129:                     foreachStr(i+1))
        !           130:                fun foreachTyc i =
        !           131:                    (update(tNew,i,abstractTyc(tSig sub i, tStr sub i));
        !           132:                     foreachTyc(i+1))
        !           133:             in foreachStr 2  (* ignoring parent and parameter slots *)
        !           134:                handle Subscript =>
        !           135:                foreachTyc 0
        !           136:                handle Subscript =>
        !           137:                REL{s=sNew,t=tNew}
        !           138:            end
        !           139:      in        abstractStr(sgn,str)
        !           140:     end
        !           141:   | abstract _ = impossible "8375 in sigmatch (abstract)"
        !           142: 
        !           143: (* signature matching *)
        !           144: 
        !           145: fun matchx (parent: Structure)
        !           146:           (mapfns as {mapstr,mapstr1,maptyc})
        !           147:           (abs, path, stamps,
        !           148:            sgn as STRstr{stamp,sign,...},
        !           149:            str as STRstr{stamp=stamp',sign=sign',table,env,...},
        !           150:            param: Structure) 
        !           151:           : Structure * thinning =
        !           152:       if strFixed(stamp) andalso stamp <> stamp'
        !           153:       then (print "fixed signature stamp: "; print stamp;
        !           154:            print "\nstructure stamp: "; print stamp';
        !           155:            print "\npath: "; prSymPath path; print "\n";
        !           156:            condemn "fixed signature doesn't agree with structure")
        !           157:       else if sign = sign'
        !           158:       then (mapstr(sgn,str);
        !           159:            (if abs then abstract(sgn,str,stamps) else str, NONE))
        !           160:       else let val v = mkLvar()
        !           161:               val _ = (openStr(); openOld({path=[v],strenv=env},table))
        !           162:               val (str',transl) =
        !           163:                     realizex parent mapfns (abs,path,stamps,stamp',sgn,param)
        !           164:            in closeStr();
        !           165:               (str',SOME(v,transl))
        !           166:           end
        !           167:   | matchx _ _ _ = impossible "843 in sigmatch"
        !           168: 
        !           169: and realizex (parent: Structure)
        !           170:             (mapfns as {mapstr1,maptyc,mapstr})
        !           171:             (abs, path, stamps, strStamp,
        !           172:              sgn as STRstr{stamp = boundStamp, sign, table,
        !           173:                            env = sigenv as REL{s=sSig,t=tSig},
        !           174:                            kind = SIGkind{bindings,share,...},...},
        !           175:              param: Structure)
        !           176:             : Structure * trans list =
        !           177:     let val sNew = array(Array.length sSig, NULLstr)
        !           178:        val tNew = array(Array.length tSig, NULLtyc)
        !           179:        val newenv = REL{s=sNew,t=tNew}
        !           180:         val newstr = STRstr{stamp=strStamp,sign=sign,table=table,env=newenv,
        !           181:                            kind=STRkind{path=path}}
        !           182:         fun checkSpec spec =
        !           183:            case spec
        !           184:              of STRbind(STRvar{name=[id],binding=INDstr i,...}) =>
        !           185:                   let val STRvar{access,binding=str',...} =
        !           186:                            lookSTRlocal id
        !           187:                            handle Unbound =>
        !           188:                              condemn("unmatched structure spec: " ^ symName id)
        !           189:                       val (str,thin) = matchx newstr mapfns
        !           190:                                            (false, id::path, stamps,
        !           191:                                             sSig sub i, str',NULLstr)
        !           192:                    in update(sNew,i,str);
        !           193:                       [case thin
        !           194:                          of NONE => VALtrans access
        !           195:                           | SOME(v,transl) => THINtrans(access,v,transl)]
        !           196:                   end
        !           197:               | TYCbind(ref(INDtyc i)) =>
        !           198:                  let val sigTycon = tSig sub i
        !           199:                      val name = tycName sigTycon
        !           200:                      val strTycon = !(lookTYClocal name) 
        !           201:                                     handle Unbound =>
        !           202:                                       condemn("unmatched type spec: "^
        !           203:                                                symName(name))
        !           204:                      val s = tycStamp sigTycon
        !           205:                      val s' = tycStamp strTycon
        !           206:                   in update(tNew,i,strTycon);
        !           207:                      if tycFixed s andalso s <> s'
        !           208:                      then if equalTycon(sigTycon,strTycon)
        !           209:                           then maptyc(s,strTycon)
        !           210:                           else condemn("bad match for fixed type spec "
        !           211:                                        ^ symName(name))
        !           212:                      else (case (sigTycon, strTycon)
        !           213:                             of (TYCON{arity,kind=DATAtyc dcons,...},
        !           214:                                 TYCON{arity=arity',kind=DATAtyc dcons',...}) =>
        !           215:                                  if arity = arity'
        !           216:                                     andalso length(dcons) = length(dcons')
        !           217:                                  then maptyc(s,strTycon)
        !           218:                                  else condemn("mismatching datatype spec: "
        !           219:                                               ^ symName(name))
        !           220:                              | (TYCON{kind=DATAtyc _,...}, _) => 
        !           221:                                  condemn("unmatched datatype spec: "^symName(name))
        !           222:                              | (TYCON{arity,kind=ABStyc,eq,...}, _) =>
        !           223:                                  if arity <> tyconArity(strTycon)
        !           224:                                  then condemn("mismatching tycon arities: "
        !           225:                                               ^ symName(name))
        !           226:                                  else if (!eq=YES) andalso not(isEqTycon(strTycon))
        !           227:                                  then condemn("mismatched eqtype spec: "
        !           228:                                               ^ symName(name))
        !           229:                                  else maptyc(s,strTycon)
        !           230:                              | _ => impossible "realizex/checkSpec/TYCbind");
        !           231:                       nil
        !           232:                   end
        !           233:               | CONbind(DATACON{name,typ,rep=VARIABLE _,const,...}) =>
        !           234:                   let val DATACON{typ=typ',rep=VARIABLE(access),...} =
        !           235:                             lookCONlocal name
        !           236:                             handle Unbound =>
        !           237:                              condemn ("unmatched exception spec: "^symName(name))
        !           238:                             | Bind =>
        !           239:                              condemn ("unmatched exception spec: "^symName(name))
        !           240:                    in compareTypes(typeInContext(!typ,newenv),!typ',name);
        !           241:                       [VALtrans access]
        !           242:                   end
        !           243:               | CONbind(DATACON{name,typ,...}) =>
        !           244:                   let val DATACON{typ=typ',...} =
        !           245:                             lookCONlocal name
        !           246:                             handle Unbound =>
        !           247:                              condemn ("unmatched data constructor spec: "
        !           248:                                       ^symName(name))
        !           249:                    in compareTypes(typeInContext(!typ,newenv),!typ',name);
        !           250:                       nil
        !           251:                   end
        !           252:               | VARbind(VALvar{name=[id],typ,...}) =>
        !           253:                  (case (lookVARCONlocal id
        !           254:                          handle Unbound =>
        !           255:                            condemn("unmatched val spec: "^symName(id)))
        !           256:                     of VARbind(VALvar{access,typ=typ',...}) =>
        !           257:                          (* no propagation of INLINE access!! *)
        !           258:                         (compareTypes(typeInContext(!typ,newenv),!typ',id);
        !           259:                          [case access of INLINE _ => VALtrans access
        !           260:                                        | PATH _ => VALtrans access
        !           261:                                        | LVAR _  => 
        !           262:                                           if !ErrorMsg.anyErrors
        !           263:                                           then VALtrans access
        !           264:                                           else impossible "sigmatch.1"
        !           265:                                        | _ => impossible "sigmatch.2"])
        !           266:                      | CONbind(dcon as DATACON{typ=typ',...}) =>
        !           267:                          (compareTypes(typeInContext(!typ,newenv),!typ',id);
        !           268:                           [CONtrans dcon])
        !           269:                      | _ => impossible "sigmatch.476")
        !           270:               | _ => nil (* nonchecked binding (FIXbind) *)
        !           271:         fun checkList (a::rest) =
        !           272:              (checkSpec a handle Syntax => nil) @ checkList rest
        !           273:           | checkList nil = nil
        !           274: 
        !           275:        val _ = update(sNew,0,parent)  (* define parent before checking specs *)
        !           276:        val _ = update(sNew,1,param)   (* ditto for param *)
        !           277:        val trans = checkList bindings
        !           278:        val _ = Sharing.checkSharing(table,newenv,share)
        !           279:        val str = if abs then abstract(sgn,newstr,stamps) else newstr
        !           280:      in mapstr1(boundStamp,str);
        !           281:        linkParents str;  (* should be redundant *)
        !           282:        (str, trans)
        !           283:     end
        !           284:   | realizex _ _ _ = impossible "783 in sigmatch"
        !           285: 
        !           286: val defaultMapfns = 
        !           287:     let fun ignore _ = ()
        !           288:      in {mapstr=ignore,mapstr1=ignore,maptyc=ignore}
        !           289:     end
        !           290: 
        !           291: val match0 = matchx NULLstr
        !           292: val match = matchx NULLstr defaultMapfns
        !           293: val realize = realizex NULLstr defaultMapfns
        !           294: 
        !           295: end (* structure SigMatch *)

unix.superglobalmegacorp.com

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