home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / modules / moduleutil.sml < prev    next >
Encoding:
Text File  |  1993-02-06  |  27.2 KB  |  774 lines

  1. structure ModuleUtil : MODULEUTIL = struct
  2.  
  3. local
  4.   open Modules  ErrorMsg Variables Access Types TypesUtil PrintUtil Symbol;
  5.   val DEBUG = true;
  6. in
  7.  
  8. (* error given back by looking up function when they fail *)
  9. exception UnboundComponent of spath
  10. (* error given back by the same functions when an error structure is found *)
  11. exception ErrorStructure
  12.  
  13. (* compiler bugs *)
  14. fun error s = impossible ("ModuleUtil: "^s);
  15.  
  16. (* a symbol for an undefined structure variable *)
  17. val bogusSTRvar =
  18.   STRvar{name=Symbol.strSymbol "Bogus", access=SLOT 0, binding=ERROR_STR}
  19.  
  20. (* a symbol for an undefined functor variable *)
  21. val bogusFCTvar = 
  22.   FCTvar{name=Symbol.fctSymbol "Bogus", access=SLOT 0, binding=ERROR_FCT}
  23.  
  24. (* the last element of a list *)
  25. fun last [x] = x
  26.   | last nil = error "last"
  27.   | last (h :: t) = last t
  28.  
  29. (* gives back the lvar (if any) declared by a binding *)
  30. fun lvarOfBinding(VARbind(VALvar{access=PATH(p),...})) = SOME(last p)
  31.   | lvarOfBinding(CONbind(DATACON{rep=VARIABLE(PATH(p)),...})) = SOME(last p)
  32.   | lvarOfBinding(CONbind(DATACON{rep=VARIABLEc(PATH(p)),...})) = SOME(last p)
  33.   | lvarOfBinding(STRbind(STRvar{name,access=PATH(p),...})) = SOME(last p)
  34.   | lvarOfBinding(FCTbind(FCTvar{name,access=PATH(p),...})) = SOME(last p)
  35.   | lvarOfBinding _ = NONE
  36.  
  37. val bogusCONbind = CONbind bogusCON
  38.  
  39. (* gets the stamp of a structure *)
  40. fun getStrStamp (SIMPLE{stamp,...}) = stamp
  41.   | getStrStamp (INSTANCE{origin=SELF stamp,...}) = stamp
  42.   | getStrStamp (INSTANCE{origin=str,...})= getStrStamp str
  43.   | getStrStamp (APPLY{res,...}) = getStrStamp res
  44.   | getStrStamp _ = error "getStrStamp wrong origin"
  45.  
  46. (* gets the stamp of a signature *)
  47. fun getSignStamp (SIG{stamp,...}) = stamp
  48.   | getSignStamp _ = Stamps.null
  49.  
  50. (* gets the stamp of a functor *)
  51. fun getFctStamp (FCT{stamp,...}) = stamp
  52.   | getFctStamp (FCT_INSTANCE{fct,...}) = getFctStamp fct
  53.   | getFctStamp ERROR_FCT = Stamps.null
  54.   | getFctStamp _ = error "getFctStamp"
  55.  
  56.  
  57. (* equality of signatures *)
  58. fun eqSign (a,b) = getSignStamp a = getSignStamp b
  59. (* equality of functor signatures (for printing only) *)
  60. fun eqFsig (FSIG{argument=a1,body=b1,...},FSIG{argument=a2,body=b2,...}) =
  61.       eqSign(a1,a2) andalso eqSign(b1,b2)
  62.   | eqFsig _ = false
  63.  
  64. (* gets the origin of a structure *)
  65. fun getOrigin (str as INSTANCE{origin = SELF _, ...}) = str
  66.   | getOrigin (INSTANCE{origin, ...}) = origin
  67.   | getOrigin str = str
  68.  
  69. (* equality of the origins of two structures (always true if one of the
  70.    argument is unelaborated (ERROR_STR) *)
  71. fun eqOrigin (x,y) =
  72.   case (getOrigin x,getOrigin y)
  73.   of (ERROR_STR,_) => true
  74.    | (_,ERROR_STR) => true
  75.    | (ox,oy) => getStrStamp ox = getStrStamp oy
  76.  
  77. (* basic function to make a new structure *)
  78. fun mkStructure (env,path)=
  79.   SIMPLE {stamp=Stamps.newFree(),env=env,path=path}
  80.  
  81. (* compose a thinning and a translation vector *)
  82. fun compose (NONE,r) = r
  83.   | compose (SOME(v,result),trans) =
  84.       let val trans' : Access.access array =
  85.          Array.arrayoflist(map (fn VALtrans(access,_,_) => access
  86.                    | _ => error "compose") trans)
  87.       fun replace (PATH [slot,lv]) = Array.sub(trans',slot)
  88.         | replace (access as INLINE _) = access
  89.         | replace _ = error "compose"
  90.       in map (fn VALtrans(access,t,s) => VALtrans(replace access,t,s)
  91.            | THINtrans(access,t,l) => THINtrans(replace access,t,l)
  92.            | v => v) result
  93.       end
  94.  
  95. (* appends two dynamic access path *)
  96. fun appendAccess (SLOT s, l) = PATH (s :: l)
  97.   | appendAccess (acc as INLINE _, l) = acc
  98.   | appendAccess (acc,_) =
  99.        (* hack so that we can print structures w/ bogus access paths *)
  100.         if !System.Control.internals then acc
  101.         else error "appendAccess"
  102.  
  103. (* translate a numeric path to the corresponding type in a given structure *)
  104. fun transPosTycon str path =
  105.     let fun f ([pos],INSTANCE{types,...}) = Array.sub(types,pos)
  106.       | f (h::t,INSTANCE{subStrs,...}) = f(t,Array.sub(subStrs,h))
  107.       | f (_,ERROR_STR) = ERRORtyc
  108.       | f (path,APPLY{res,...}) = f(path,res)
  109.       | f _ = error "transPosTycon 1"
  110.      in f (path,str) handle Array.Subscript =>
  111.            (System.Print.say "path: ";
  112.         PrintUtil.prIntPath path;
  113.         error "transPosTycon 2")
  114.     end
  115.  
  116. (* translate a numeric path to the corresponding functor *)
  117. fun transPosFct str path =
  118.     let fun f ([pos],INSTANCE{subFcts,...}) = Array.sub(subFcts,pos)
  119.       | f (h::t,INSTANCE{subStrs,...}) =  f(t,Array.sub(subStrs,h))
  120.       | f (_,ERROR_STR) = ERROR_FCT
  121.       | f (path,APPLY{res,...}) = f(path,res)
  122.       | f _ = error "transPosFct 1"
  123.      in f (path,str) handle Array.Subscript =>
  124.         (System.Print.say "path: ";
  125.          PrintUtil.prIntPath path;
  126.          error "transPosFct 2")
  127.     end
  128.  
  129. (* translate a numeric acces path into the corresponding structure *)
  130. fun transPosStr str path =
  131.     let fun f ([],str) = str
  132.       | f (h::t,INSTANCE{subStrs,...}) = f(t,Array.sub(subStrs,h))
  133.       | f (p,APPLY{res,...}) = f(p,res)
  134.       | f (_,ERROR_STR) = ERROR_STR
  135.       | f _ = error "transPosStr 1"
  136.      in f (path,str) handle Array.Subscript =>
  137.         (System.Print.say "path: ";
  138.          PrintUtil.prIntPath path;
  139.          error "transPosStr 2")
  140.     end
  141.  
  142. (* translate a type in a given context *)
  143. fun transType (str as INSTANCE {subStrs, types,...}) =
  144.     let fun findFormTyc(path, tycIndex) = transPosTycon str (path@[tycIndex])
  145.  
  146.     fun transTycon (RELtyc {pos=tycAddress,...}) = findFormTyc tycAddress
  147.       | transTycon tyc = tyc
  148.  
  149.     fun transType0 ty =
  150.         case ty
  151.         of VARty _ => ty
  152.          | IBOUND _ => ty
  153.          | CONty (tc, tl) =>
  154.          mkCONty (transTycon tc, map transType0 tl)
  155.          | POLYty {sign, tyfun=TYFUN {arity, body}, abs} =>
  156.          POLYty{sign=sign,
  157.             tyfun=TYFUN{arity=arity,body=transType0 body},
  158.             abs=abs}
  159.          | UNDEFty => ty
  160.          | WILDCARDty => ty
  161.      in transType0 end
  162.   | transType (SIMPLE _) = (fn ty => ty)
  163.   | transType (APPLY{res,...}) = transType res
  164.   | transType _ = error "transtype"
  165.  
  166. (* transBindingINSTANCE: Structure array * tycon array * int list
  167.                -> Modules.binding -> Modules.binding
  168.  
  169.    The binding argument is assumed to be from the environment of
  170.    signature of the structure (which must be an INSTANCE), so its access,
  171.    if any, will be a SLOT, an OPEN, or INLINE.
  172.    transBindingINSTANCE interprets types of value and constructor bindings,
  173.    and adjusts access info to make it absolute (i.e. relative to the
  174.    top-level dynamic environment).  The int list argument is the access
  175.    path of the structure argument. *)
  176.  
  177. fun transBindingINSTANCE (str,subStrs,types,subFcts,apath) binding =
  178.     let val transType = transType str
  179.     (* invariant: Any structure binding in the sign of an
  180.        INSTANCE structure is a FORMAL *)
  181.      in case binding
  182.     of VARbind (VALvar {access, name, typ}) =>
  183.         VARbind (VALvar {access=appendAccess (access, apath),
  184.                  name=name,typ=ref(transType(!typ))})
  185.      | VARbind (OVLDvar _) => error "Modules.transBindingINSTANCE"
  186.      | VARbind ERRORvar => binding
  187.      | CONbind (DATACON {name, const, typ, rep, sign}) =>
  188.            CONbind (DATACON {name=name, const=const,
  189.                  rep=
  190.                  case rep
  191.                  of VARIABLE access =>
  192.                      VARIABLE (appendAccess(access,apath))
  193.                   | VARIABLEc access =>
  194.                      VARIABLEc (appendAccess (access,apath))
  195.                   | _ => rep,
  196.                  sign=sign,
  197.                  typ=transType typ})
  198.      | TYCbind (FORMtyc {pos, ...}) => TYCbind (Array.sub(types,pos))
  199.      | TYCbind (OPENFORMtyc {pos=(path,pos), ...}) =>
  200.           TYCbind (transPosTycon str (path @ [pos]))
  201.      | SIGbind _ => binding
  202.      | STRbind (STRvar {name, access, binding=STR_FORMAL{pos, ...}}) =>
  203.            STRbind (STRvar {access=appendAccess (access, apath),
  204.                 name=name,binding=Array.sub(subStrs,pos)})
  205.      | STRbind (STRvar {name, access, binding=STR_OPEN{pos, ...}}) =>
  206.            STRbind (STRvar {access=appendAccess (access, apath),
  207.                 name=name,binding=transPosStr str pos})
  208.      | FCTbind (FCTvar {name, access, binding=FCT_FORMAL{pos, ...}}) =>
  209.            FCTbind (FCTvar {access=appendAccess (access, apath),
  210.                 name=name,binding=Array.sub(subFcts,pos)})
  211.      | FCTbind (FCTvar {name, access, binding=FCT_OPEN{pos, ...}}) =>
  212.            FCTbind (FCTvar {access=appendAccess (access, apath),
  213.                 name=name,binding=transPosFct str pos})
  214.      | _ => binding
  215.    end
  216.  
  217. (* transBindingSIMPLE: int list -> Modules.binding -> Modules.binding
  218.  * just adjusts access fields of bindings.  bindings assumed to come
  219.  * from a SIMPLE structure, and the int list is its top-level access path 
  220.  *)
  221.  
  222. fun transBindingSIMPLE apath binding =
  223.     case binding
  224.      of VARbind (VALvar {access, name, typ}) =>
  225.       VARbind (VALvar {access=appendAccess (access, apath),
  226.                name=name,typ=typ})
  227.       | CONbind (DATACON {name, const, typ, rep, sign}) =>
  228.       CONbind (DATACON {name=name, const=const, sign=sign,
  229.                 rep=
  230.                 case rep
  231.                 of VARIABLE access =>
  232.                  VARIABLE(appendAccess (access, apath))
  233.                  | VARIABLEc access =>
  234.                  VARIABLEc(appendAccess(access,apath))
  235.                  | rep => rep,
  236.                 typ=typ})
  237.       | STRbind (STRvar {name, access, binding}) =>
  238.       STRbind (STRvar {access=appendAccess (access, apath),
  239.                name=name,binding=binding})
  240.       | FCTbind (FCTvar {name, access, binding}) =>
  241.       FCTbind (FCTvar {access=appendAccess (access, apath),
  242.                name=name,binding=binding})
  243.       | binding => binding
  244.  
  245. (* convert formal bindings to opened, doesn't recompute types. *)
  246.  
  247. fun transBindingFORMAL (relpath,spath) binding = 
  248.     case binding
  249.     of TYCbind(FORMtyc{name,pos,spec}) =>
  250.          TYCbind(OPENFORMtyc{pos=(relpath,pos),spec=spec,
  251.                  name=spath@[name]})
  252.      | STRbind (STRvar{name,access,binding=STR_FORMAL{pos,spec}}) =>
  253.          STRbind(STRvar{name=name,access=access,
  254.                 binding=STR_OPEN{pos=relpath@[pos],spec=spec,
  255.                            name=spath@[name]}})
  256.      | FCTbind (FCTvar{name,access,binding=FCT_FORMAL{pos,spec}}) =>
  257.          FCTbind(FCTvar{name=name,access=access,
  258.                 binding=FCT_OPEN{pos=relpath@[pos],spec=spec,
  259.                            name=spath@[name]}})
  260.      | _ => binding
  261.  
  262. (* err: raise an exception when an unbound component in 
  263.    the symbolic path is found.  It is passed the remainder
  264.    of the symbolic path, including the unbound component.
  265.    From this it computes the symbolic path to the unbound
  266.    component. *)
  267.  
  268. fun err spath (r as (h::t)) =
  269.       let fun g (0,_) = [h]
  270.         | g (i,h::t) = h :: g(i-1,t)
  271.         | g _ = error "err"
  272.       in raise UnboundComponent(g(length spath-length r,spath)) end
  273.   | err spath _ = error "spath"
  274.  
  275. (* find a binding, adjust its access paths and interpret its types.*)
  276.  
  277. fun lookBinding (topStr,spath,apath) : binding =
  278.    let val err' = err spath
  279.        fun get (str, [sym], apath) =
  280.     ((case str
  281.         of SIMPLE {env,...} =>
  282.            (transBindingSIMPLE apath (Env.look(env,sym)))
  283.          | INSTANCE {subStrs,types,subFcts,sign=SIG{env,...},...} =>
  284.            (transBindingINSTANCE(str,subStrs,types,subFcts,apath) 
  285.                        (Env.look(!env,sym)))
  286.          | APPLY{res,...} => get (res,[sym],apath)
  287.          | ERROR_STR => raise ErrorStructure
  288.          | _ => (error ("lookBinding 1 "^Symbol.name sym)))
  289.       handle Env.Unbound => raise UnboundComponent spath)
  290.      | get (str, spath as (h::t), apath) =
  291.          let fun get_str str path =
  292.             (case str
  293.               of SIMPLE {env,...} =>
  294.               (case Env.look(env,h)
  295.                of STRbind(STRvar
  296.                 {access=SLOT slot,binding=str,...}) =>
  297.                   (str,slot::path)
  298.                 | _ => error "lookBinding 2 ")
  299.                | INSTANCE{sign=SIG{env,...},subStrs,...} =>
  300.               (case Env.look(!env,h)
  301.                of STRbind(STRvar{binding=STR_FORMAL{pos,...},
  302.                          access=SLOT slot, ...}) =>
  303.                 (Array.sub(subStrs,pos),slot::path)
  304.                 | STRbind(STRvar{binding=STR_OPEN{pos,...},
  305.                          access=SLOT slot, ...}) =>
  306.                 (transPosStr str pos,slot::path)
  307.                 | _ => (error "lookBinding 3"))
  308.                | APPLY{res,...} => get_str res path
  309.                | ERROR_STR => raise ErrorStructure
  310.                | _ => error "lookUnadjusted 2")
  311.              handle Env.Unbound => err' spath
  312.          val (str', apath') = get_str str apath
  313.           in get(str', t, apath')
  314.          end
  315.       | get _ = error "Modules.lookBinding DD95"
  316.     in get (topStr,spath,apath)
  317.     end
  318.  
  319. local
  320.  fun lookBinding' (topStr,spath) : binding =
  321.    let val err' = err spath
  322.        fun get (str, [sym]) =
  323.     ((case str
  324.         of SIMPLE {env,...} =>
  325.              Env.look(env,sym)
  326.          | INSTANCE {subStrs,types,subFcts,sign=SIG{env,...},...} =>
  327.              transBindingINSTANCE(str,subStrs,types,subFcts,[]) 
  328.                        (Env.look(!env,sym))
  329.          | APPLY{res,...} => get (res,[sym])
  330.          | ERROR_STR => raise ErrorStructure
  331.          | _ => (error ("lookBinding' 1 "^Symbol.name sym)))
  332.       handle Env.Unbound => raise UnboundComponent spath)
  333.      | get (str, spath as (h::t)) =
  334.          let fun get_str str =
  335.           (case str
  336.             of SIMPLE {env,...} =>
  337.             (case Env.look(env,h)
  338.              of STRbind(STRvar{binding=str,...}) => str
  339.               | _ => error "lookBinding' 4")
  340.              | INSTANCE{sign=SIG{env,...},subStrs,...} =>
  341.             (case Env.look(!env,h)
  342.              of STRbind(STRvar{binding=STR_FORMAL{pos,...},...}) =>
  343.                   Array.sub(subStrs,pos)
  344.               | STRbind(STRvar{binding=STR_OPEN{pos,...}, ...}) =>
  345.                   transPosStr str pos
  346.               | _ => error "lookBinding' 3")
  347.              | APPLY{res,...} => get_str res
  348.              | ERROR_STR => raise ErrorStructure
  349.              | _ => error "lookBinding' 2")
  350.            handle Env.Unbound => err' spath
  351.          val str' = get_str str
  352.           in get(str', t) end
  353.       | get _ = error "Modules.lookBinding DD95"
  354.     in get (topStr,spath) end
  355.  
  356. in
  357. (* lookBindingSTR: look up a structure binding, but don't adjust
  358.    access paths.*)
  359.  
  360. fun lookBindingSTR (str,spath) =
  361.     (case lookBinding' (str,spath)
  362.      of STRbind str => str
  363.       | _ => error "lookBindingSTR")
  364.     handle ErrorStructure => bogusSTRvar
  365.  
  366. (* lookBindTYC: look up a type binding *)
  367.  
  368. fun lookBindingTYC (str,spath) =
  369.     (case lookBinding' (str,spath)
  370.      of TYCbind tyc => tyc
  371.       | _ => error "lookBindingTYC")
  372.     handle ErrorStructure => ERRORtyc
  373. end
  374.  
  375. (* builds an environment from a structure *)
  376. fun makeEnv (str as INSTANCE{sign=SIG{env,...},subStrs,types,subFcts, ...}, apath) =
  377.       Env.open' (!env, transBindingINSTANCE(str,subStrs,types,subFcts,apath), Env.empty)
  378.   | makeEnv (str as SIMPLE{env, ...}, apath) =
  379.       Env.open' (env, transBindingSIMPLE(apath), Env.empty)
  380.   | makeEnv (ERROR_STR, _) = Env.empty
  381.   | makeEnv (INSTANCE{sign=FULL_SIG,...}, _) = 
  382.       error "makeEnv 1"
  383.   | makeEnv (APPLY{res,...},apath) = makeEnv (res,apath)
  384.   | makeEnv _ = error "makeEnv 2"
  385.  
  386. (* should be in Symbol *)
  387. val symbolToName = fn s => Symbol.nameSpaceToString(Symbol.nameSpace s)
  388.  
  389. (* look for a signature (necessaraly top) *)
  390. fun lookSIG (env,id,err) = 
  391.     (case Env.look(env,id) 
  392.      of SIGbind(SIGvar{binding,...}) => binding
  393.       | _ => error "lookSIG")
  394.     handle Env.Unbound =>
  395.          (err COMPLAIN ("unbound signature: "^Symbol.name id) nullErrorBody;
  396.           ERROR_SIG)
  397.      | Bind =>
  398.           error 
  399.         ("lookSIG: bind exception looking up "
  400.          ^ Symbol.name id^" in name space "^symbolToName id)
  401.  
  402. (* look for a functor signature *)
  403. fun lookFSIG (env,id,err) = 
  404.     (case Env.look(env,id) 
  405.      of  FSIGbind(FSIGvar{binding,...}) => binding
  406.       | _ => error "lookFSIG")
  407.     handle Env.Unbound =>
  408.              (err COMPLAIN ("unbound funsig: "^Symbol.name id) nullErrorBody;
  409.           ERROR_FSIG)
  410.      | Bind =>
  411.          error
  412.            ("lookFSIG: bind exception looking up "
  413.         ^ Symbol.name id^" in name space "^symbolToName id)
  414.  
  415. (* fixity bindings *)
  416.  
  417. fun lookFIX (env,id) =
  418.     let val binding = 
  419.       case Env.look(env,id)
  420.       of FIXbind(FIXvar{binding,...}) => binding
  421.        | _ => error "lookFIX"
  422.     in binding
  423.     end handle Env.Unbound =>  Fixity.NONfix
  424.          | Bind => error ("lookFix: bind exception looking up "^Symbol.name id^" in name space "^symbolToName id)
  425.  
  426.  
  427. (* lookFormalBinding: given a symbolic path, find a formal binding.
  428.    Also return a relative path to it.*)
  429.  
  430. fun lookFormalBinding(env,spath) : binding * int list =
  431.     let val err' = err spath
  432.     fun get (env,[id],p) =
  433.           ((Env.look (env,id),rev p)
  434.            handle Env.Unbound => raise (UnboundComponent spath))
  435.       | get (env,spath as (first::rest),p) =
  436.          ((case Env.look (env,first)
  437.           of STRbind(STRvar{binding=STR_FORMAL{pos,
  438.                            spec=SIG{env,kind,...}},
  439.                 ...}) =>
  440.            get(!env,rest,
  441.                case !kind of EMBEDDED => p | _ => pos::p)
  442.            | STRbind(STRvar{binding=STR_FORMAL{spec=ERROR_SIG,...},...}) =>
  443.              raise ErrorStructure
  444.            | STRbind(STRvar{binding=ERROR_STR,...}) =>
  445.            raise ErrorStructure
  446.            | _ => error "lookFormalBinding 1")
  447.           handle Env.Unbound => err' spath)
  448.       | get _ = error "lookFormalBinding 2"
  449.     in get (env,spath,[])
  450.      end
  451.  
  452. (* lookGen: generic lookup function for identifiers which may occur 
  453.    in:
  454.        1. environments
  455.        2. actual structure environments
  456.        3. signature parsing environments *)
  457.  
  458. fun lookGen (extract,errorVal) (env,path,err) =
  459.     (case path
  460.      of [id] => extract ((Env.look(env,id),nil,path)
  461.             handle Env.Unbound => raise UnboundComponent path)
  462.       | first::rest =>
  463.       let val strvar = 
  464.         (case Env.look(env,first)
  465.          of STRbind(STRvar strvar) => strvar
  466.           | obj =>  error "lookGen 3")
  467.         handle Env.Unbound => raise UnboundComponent [first]
  468.       in case strvar
  469.          of {binding=str,access=PATH p,...} =>
  470.              extract (lookBinding (str,rest, p),nil,path)
  471.           | {binding=STR_FORMAL{pos,spec=SIG{env,kind,...}},...} =>
  472.         let val (binding,relpath) = lookFormalBinding(!env,rest)
  473.         in extract (binding,case !kind 
  474.                     of EMBEDDED => relpath
  475.                      | _ => pos :: relpath,path)
  476.         end
  477.           | {binding=STR_OPEN{pos,spec=SIG{env,...},name},...} =>
  478.          let val (binding,relpath) = lookFormalBinding (!env,rest)
  479.          in extract (binding,pos @ relpath,name@rest)
  480.          end
  481.           | {binding=ERROR_STR,...} => raise ErrorStructure
  482.           | {binding=STR_FORMAL{spec=ERROR_SIG,...},...} =>
  483.                    raise ErrorStructure
  484.           | _ => error "lookGen 1"
  485.        end
  486.        | _ => error "lookGen 2")
  487.     handle UnboundComponent spath => 
  488.       let val badsym = last spath
  489.       in err COMPLAIN ("unbound "^symbolToName badsym^": "^
  490.                Symbol.name badsym^
  491.                (case path
  492.                   of _ :: _ :: _ => " in path "^formatQid path
  493.                    | _ => ""))
  494.              nullErrorBody;
  495.          errorVal
  496.       end
  497.      | ErrorStructure => errorVal
  498.      | Bind => error ("bind exception: lookGen: looking up "^formatQid path^" as a "^symbolToName (last path))
  499.      | exn => raise exn
  500.  
  501. (* look for a variable or a constructor (simple path) *)
  502. fun lookShortVARCON (arg as (env,name,err)) =
  503.       Env.look(env,name)
  504.       handle Env.Unbound => 
  505.            (err COMPLAIN ("unbound "^symbolToName name^" "^
  506.                   Symbol.name name)
  507.             nullErrorBody;
  508.         bogusCONbind)
  509.  
  510. (* look for a variable or a constructor (complete path) *)
  511. val lookVARCON = lookGen (fn (x,_,_) => x,bogusCONbind)
  512.  
  513. (* look for a structure *)
  514. val lookSTR = lookGen (fn (STRbind sv,_,_) => sv
  515.             | _ => error "lookSTR",
  516.                bogusSTRvar)
  517.  
  518. (* look for a functor *)
  519. val lookFCT = lookGen (fn (FCTbind sv,_,_) => sv
  520.             | _ => error "lookSTR",
  521.                bogusFCTvar)
  522.  
  523. (* look for a type *)
  524. val lookTYC =
  525.     lookGen (fn (TYCbind (FORMtyc{pos,spec,...}),relpath,name) =>
  526.               RELtyc{name=name,pos=(relpath,pos)}
  527.            | (TYCbind tyc,_,_)=> tyc
  528.            | _ => error "lookTYC",
  529.          ERRORtyc)
  530.  
  531. (* tycon lookup with arity checking *)
  532.  
  533. fun checkArity(tycon, arity,err,result) =
  534.     case tycon
  535.     of ERRORtyc => result
  536.      | _ =>
  537.        if tyconArity(tycon) <> arity
  538.        then (err COMPLAIN ("type constructor "^(Symbol.name(tycName(tycon)))^
  539.              " has the wrong number of arguments: "^makestring arity)
  540.            nullErrorBody;
  541.         ERRORtyc)
  542.        else result
  543.  
  544. fun lookArTYC ((env,normEnv),qid: symbol list, arity: int, err) =
  545.     let val normQid = Normalize.normalize(normEnv,qid)
  546.     in
  547.     lookGen (fn (TYCbind (FORMtyc {pos,spec,...}),relpos,name) =>
  548.             checkArity(spec,arity,err,
  549.                  RELtyc{name=name,pos=(relpos,pos)})
  550.           | (TYCbind (OPENFORMtyc {pos,spec,name,...}),[],_) =>
  551.             checkArity(spec,arity,err,
  552.                  RELtyc{name=name,pos=pos})
  553.           | (TYCbind (OPENFORMtyc _),_,_) =>
  554.              error "lookArTyc 1"
  555.           | (TYCbind tyc,_,_) => checkArity(tyc,arity,err,tyc)
  556.           | _ => error "lookArTyc 2",
  557.         ERRORtyc)  (env,normQid,err)
  558.     end
  559.  
  560. (* looking for an exception *)
  561. fun lookEXN (env,path,err) =
  562.     let val binding =
  563.       case path
  564.       of [id] => (Env.look(env,id)
  565.               handle Env.Unbound => raise UnboundComponent path)
  566.        | first::rest =>
  567.          (let val binding = case Env.look(env,first)
  568.             of STRbind(STRvar binding) => binding
  569.              | _ => error "ModuleUtl.lookExn 3"
  570.           in case binding
  571.               of {binding=str,access=PATH p,...} =>
  572.                    (lookBinding (str,rest, p))
  573.                | {binding=ERROR_STR,...} => raise ErrorStructure
  574.                | _ => error "lookExn 1"
  575.           end
  576.           handle Env.Unbound => raise UnboundComponent [first])
  577.        | _ => error "lookExn 2"
  578.    in case binding
  579.       of CONbind c =>
  580.        (case c
  581.         of DATACON {rep=VARIABLE _,...} => c
  582.          | DATACON {rep=VARIABLEc _,...} => c
  583.          | _ => (err COMPLAIN ("found data constructor \
  584.                   \instead of exception")
  585.             nullErrorBody;
  586.              bogusEXN))
  587.        | VARbind _ =>
  588.           (err COMPLAIN ("found variable instead of exception")
  589.              nullErrorBody;
  590.            bogusEXN)
  591.        | _ => error ("lookEXN: looking up " ^formatQid path
  592.            ^ " as a " ^ symbolToName (last path))
  593.    end
  594.     handle UnboundComponent spath => 
  595.         (err COMPLAIN ("unbound " ^
  596.               (if length path=length spath then "exception "
  597.                else "structure ") ^
  598.               Symbol.name (last spath)^
  599.               (case path
  600.                of _ :: _ :: _ => " in path "^formatQid path
  601.                 | _ => ""))
  602.            nullErrorBody;
  603.          bogusEXN)
  604.      | ErrorStructure => bogusEXN
  605.      | exn => raise exn
  606.  
  607. fun openSigStructure (bindEnv,spath,baseEnv,complainer) =
  608.   let fun makeEnv (str as INSTANCE{sign=SIG{env,...},subStrs,types,subFcts, ...},_,_) =
  609.        Env.open' (!env, transBindingINSTANCE(str,subStrs,types,subFcts,[]), baseEnv)
  610.     | makeEnv (str as SIMPLE{env, ...},_,_) =
  611.          Env.open' (env, fn x =>x, baseEnv)
  612.     | makeEnv (ERROR_STR, _,_) = Env.empty
  613.     | makeEnv (STR_FORMAL{pos,spec=SIG {env,kind,...}},relpath,name) =
  614.          let val relpath' = case !kind
  615.                 of EMBEDDED => relpath
  616.                  | _ => relpath @ [pos]
  617.          in Env.open'(!env,transBindingFORMAL (relpath',name),baseEnv)
  618.          end
  619.     | makeEnv (STR_FORMAL{spec=ERROR_SIG,...},_,_) = baseEnv
  620.     | makeEnv (STR_OPEN{pos,spec=SIG{env,...},name},nil,_) =
  621.           Env.open'(!env,transBindingFORMAL (pos,name),baseEnv)
  622.     | makeEnv (STR_OPEN{spec=ERROR_SIG,...},nil,_) = baseEnv
  623.     | makeEnv (STR_OPEN _,_,_) =
  624.           error "openSigStructure.makeEnv.OPENFORMAL"
  625.     | makeEnv _ = error "openSigStructure.makeEnv"
  626.   in lookGen(fn (STRbind (STRvar{binding,...}),relpath,name) =>
  627.            makeEnv(binding,relpath,name)
  628.           | _ => error "openSigStructure",
  629.           bindEnv) (bindEnv,spath,complainer)
  630.   end
  631.  
  632. fun openStructureVar (env,STRvar{access=PATH p,binding=str,...}) : env =
  633.       Env.atop (makeEnv (str, p), env)
  634.      (* will generate spurious error messages unless we give up completely *)
  635.   | openStructureVar (env,STRvar{binding=ERROR_STR,...}) = env 
  636.   | openStructureVar _ = error "openStructureVar"
  637.  
  638. (* findPath:  convert symbolic path names to a printable string in the
  639.   context of an environment.
  640.  
  641.   Its arguments are the path name in reverse order, a static semantic value,
  642.   an equality function on static semantic values, and a lookup function
  643.   mapping paths to their bindings (if any) in an environment.   The second
  644.   argument of the lookup function is a function which is called if there
  645.   is no binding for a path name in the environment.
  646.  
  647.   It looks up each suffix of the path name, going from shortest to longest
  648.   suffix,in the current environment until it finds one whose lookup value
  649.   equals the static semantic value argument.  It then converts that suffix
  650.   to a string.  If it doesn't find any suffix, it returns "?" concatenated
  651.   with the full path name.
  652.  
  653.   Example:
  654.      Given A.B.t as a path, and a lookup function for an
  655.      environment, this function tries:
  656.            t
  657.            B.t
  658.            A.B.t
  659.      If none of these work, it returns ?.A.B.t
  660.  
  661.   Note: the symbolic path is passed in reverse order because that is
  662.   the way all symbolic path names are stored within static semantic objects.
  663.  *)
  664.     
  665. fun findPath (p,elem0,eq,look) =
  666.   let fun try(name::untried,tried) =
  667.         (let val elem = look (name :: tried,fn _ => raise Env.Unbound)
  668.          in if eq(elem0,elem)
  669.         then formatQid(name::tried)
  670.         else try(untried,name::tried)
  671.           end handle Env.Unbound => try(untried,name::tried))
  672.     | try([],tried) = "?." ^ formatQid tried
  673.    in try(p,[])
  674.   end
  675.  
  676. (* sortEnvBindings: sort the bindings in an environment for printing
  677.   purposes.  The bindings are sorted in the following order:
  678.          signatures
  679.          functors
  680.          structures
  681.          types
  682.          constructors
  683.          values
  684.          fixity declarations
  685.  It is only correct to sort environments which have no duplicate bindings.
  686.  All routines which build structure environments maintain this
  687.  invariant, so it is ok to sort any structure environment using
  688.  this function.
  689. *)
  690.  
  691. local
  692.   open Symbol
  693.    fun binderGt(bind1: symbol * Modules.binding,
  694.         bind2: symbol * Modules.binding) =
  695.     case (bind1,bind2)
  696.       of ((n1,FIXbind _),(n2,FIXbind _)) => symbolGt(n1,n2)
  697.        | ((_,FIXbind _),_) => true
  698.        | (_,(_,FIXbind _)) => false
  699.        | ((n1,VARbind _),(n2,VARbind _)) => symbolGt(n1,n2)
  700.        | ((_,VARbind _),_) => true
  701.        | (_,(_,VARbind _)) => false
  702.        | ((n1,CONbind _),(n2,CONbind _)) => symbolGt(n1,n2)
  703.        | ((_,CONbind _),_) => true
  704.        | (_,(_,CONbind _)) => false
  705.        | ((n1,TYCbind _),(n2,TYCbind _)) => symbolGt(n1,n2)
  706.        | ((_,TYCbind _),_) => true
  707.        | (_,(_,TYCbind _)) => false
  708.        | ((n1,STRbind _),(n2,STRbind _)) => symbolGt(n1,n2)
  709.        | ((_,STRbind _),_) => true
  710.        | (_,(_,STRbind _)) => false
  711.        | ((n1,FCTbind _),(n2,FCTbind _)) => symbolGt(n1,n2)
  712.        | ((_,FCTbind _),_) => true
  713.        | (_,(_,FCTbind _)) => false
  714.        | ((n1,SIGbind _),(n2,SIGbind _)) => symbolGt(n1,n2)
  715.        | ((_,SIGbind _),_) => true
  716.        | (_,(_,SIGbind _)) => false
  717.        | ((n1,FSIGbind _),(n2,FSIGbind _)) => symbolGt(n1,n2)
  718. in
  719.   fun sortEnvBindings env =
  720.        let val bl : (Symbol.symbol * Modules.binding) list ref = ref nil
  721.        in Env.app(fn b => bl := b :: !bl) env;
  722.       Sort.sort binderGt (!bl)
  723.        end
  724. end
  725.  
  726.   (* notInitialLowerCase:  this function not currently used.  It could be
  727.      used to detect anomalous noncapitalization of constructors. *)
  728.  
  729.   fun notInitialLowerCase string =
  730.       (* string does NOT start with lower-case alpha *)
  731.       let val firstchar = ordof(string,0)
  732.        in firstchar < Ascii.lc_a orelse firstchar > Ascii.lc_z
  733.        end
  734.  
  735. fun getStrPath (SIMPLE {path, ...}) = path
  736.   | getStrPath (INSTANCE {path,...}) = path
  737.   | getStrPath _ = []
  738.  
  739. fun getStrPos str (sym: Symbol.symbol) = 
  740.     case lookBindingSTR(str,[sym]) of
  741.     (STRvar {binding=(STR_FORMAL {pos,...}),...}) => pos
  742.       | _ => error "Instantiate:getStrPos"
  743.  
  744. fun getStrTPos str sym =
  745.     case lookBindingTYC (str,[sym]) of
  746.     (FORMtyc {pos, ...}) => pos
  747.       | _ => error "Instantiate:getStrTPos"
  748.  
  749. fun getSigPosGen (SIG {env, ...}) sym =
  750.        (Env.look(!env,sym)
  751.         handle Env.Unbound => error "instantiate:getSigPos 1")
  752.   | getSigPosGen _ _ = error "instantiate:getSigPos 2"
  753.  
  754. fun getSigTPos (SIG {env, ...}) sym =
  755.     (case Env.look(!env,sym) of
  756.      TYCbind (FORMtyc {pos, ...}) => pos
  757.        | _ => error "instantiate:getSigTPos.1")
  758.   | getSigTPos _ _ = error "instantiate:getSigPos.2"
  759.  
  760. fun getSigPos (sign as SIG {env, ...}) sym =
  761.    ((case Env.look(!env,sym) of
  762.      (STRbind (STRvar {binding=STR_FORMAL {pos, ...},...})) => pos
  763.        | _ => 
  764.            error "Instantiate:getSigPos.1")
  765.     handle Env.Unbound => 
  766.       (error ("Instantiate:getSigPos.2"^(Symbol.name sym))))
  767.   | getSigPos _ _ = error "Instantiate:getSigPos.2"
  768.  
  769. fun eqSignature (SIG {stamp=s1,...}, SIG {stamp=s2,...}) = s1=s2
  770.   | eqSignature _ = false
  771.  
  772. end
  773. end  (* structure ModuleUtil *)
  774.