
open Misc BasicIO Nonstdio Fnlib Config Mixture Const Globals Location;

(* Compiled signatures *)

type CSig =
{
  uMode:       Mode, (* whether to interpret the unit as a structure or topdec *)
  uName:       string,  (* the normalized basename of the filename *)
  uIdent:      string ref,  (* the (non-normalized) 
			   ML structure and signature identifier 
			   for the unit if uMode = STRmode *)
  uIBas:       (string,InfixStatus) Hasht.t,
  uVarEnv:     (string, VarInfo) Hasht.t,
  uTyEnv:      (string, TyInfo) Hasht.t, 
  uModEnv:     (string, ModInfo) Hasht.t,   
  uFunEnv:     (string, FunInfo) Hasht.t,   
  uSigEnv:     (string, SigInfo) Hasht.t,    
  (* uTyNameSet is the set of names introduced in the unit's implementation, 
     or the set of names bound in the unit's interface (if any).
     All type name levels should be 0 (this is ensured in rectifySignature before writing.) 
  *)
  uTyNameSet:    TyNameSet ref,  
  (* The optional Str uStrOpt comes from the unit's optional interface.
     It is the body of the signature to be matched against.
   *)
  uStrOpt:     RecStr option ref, 
  uStamp:      SigStamp option ref,
                    (* present, if this signature comes from a .ui file *)
  uMentions:   (string, SigStamp) Hasht.t
};



fun iBasOfSig       (cu : CSig) = #uIBas cu
and varEnvOfSig     (cu : CSig) = #uVarEnv cu
and tyEnvOfSig      (cu : CSig) = #uTyEnv cu
and modEnvOfSig      (cu : CSig) = #uModEnv cu
and funEnvOfSig      (cu : CSig) = #uFunEnv cu
and sigEnvOfSig      (cu : CSig) = #uSigEnv cu
and tyNameSetOfSig   (cu : CSig) = #uTyNameSet cu
and strOptOfSig      (cu : CSig) = #uStrOpt cu
and modeOfSig   (cu : CSig) = #uMode cu
;

(* The table of unit signatures already loaded in memory *)

type SigTable = (string, CSig) Hasht.t;

fun mkSigTable() = (Hasht.new 37 : SigTable);
val dummySigTable = (Hasht.new 0 : SigTable);

val pervSigTable = (Hasht.new 7 : SigTable);

val currentSigTable = ref dummySigTable;

fun newSig nm id mode : CSig =
{
  uName = nm,
  uMode = mode,
  uIdent = ref id,
  uIBas = Hasht.new 7,
  uVarEnv     = Hasht.new 17,
  uTyEnv      = Hasht.new 7,
  uModEnv     = Hasht.new 7,
  uFunEnv     = Hasht.new 7,
  uSigEnv     = Hasht.new 7,
  uTyNameSet  = ref [],
  uStrOpt     = ref NONE,
  uMentions   = Hasht.new 13,
  uStamp      = ref NONE
};

(* the current order of unit signatures *)


(* Current signature *)

val dummySig = newSig "" "" STRmode;

val currentSig = ref dummySig;

val dummyInfixBasis = (Hasht.new 0 : (string, InfixStatus) Hasht.t);

val currentInfixBasis = ref dummyInfixBasis;

val currentTypeStamp = ref 0;
val currentExcStamp = ref 0;
val currentValStamp = ref 0;

val dummyRenEnv = (Hasht.new 0 : (string, int) Hasht.t);

val currentRenEnv = ref dummyRenEnv;

(* To load a signature from a file *)

(*
fun readSig name =
  let val filename = find_in_path (name ^ ".ui")
      val is = open_in_bin filename
  in
    let
      val sigStamp = input(is, 22)
      val () = if size sigStamp < 22 then raise Fail "sigStamp" else ()
      val cu = (input_value is : CSig)
      val {uStamp, uName, ...} = cu
    in
      close_in is;
      uStamp := SOME sigStamp;
      if name <> uName then (
        msgIBlock 0;
        errPrompt "File "; msgString filename;
        msgString " contains the signature of unit ";
        msgString uName; msgEOL();
        errPrompt "instead of the signature of unit ";
        msgString name; msgEOL();
        msgEBlock();
        raise Toplevel)
      else ();
      cu
    end
    handle Fail _ =>
      (close_in is;
       msgIBlock 0;
       errPrompt "Corrupted compiled signature file: ";
       msgString filename; msgEOL();
       msgEBlock();
       raise Toplevel)
  end;
*)
fun readSig filename =
  let 
      val name = normalizedUnitName(Filename.basename filename)
      val filename = find_in_path (filename ^ ".ui")
      val is = open_in_bin filename
  in
    let
      val sigStamp = input(is, 22)
      val () = if size sigStamp < 22 then raise Fail "sigStamp" else ()
      val cu = (input_value is : CSig)
      val {uStamp, uName, ...} = cu
    in
      close_in is;
      uStamp := SOME sigStamp;
      if name <> uName then (
        msgIBlock 0;
        errPrompt "File "; msgString filename;
        msgString " contains the signature of unit ";
        msgString uName; msgEOL();
        errPrompt "instead of the signature of unit ";
        msgString name; msgEOL();
        msgEBlock();
        raise Toplevel)
      else ();
      cu
    end
    handle Fail _ =>
      (close_in is;
       msgIBlock 0;
       errPrompt "Corrupted compiled signature file: ";
       msgString filename; msgEOL();
       msgEBlock();
       raise Toplevel)
  end;

fun readAndMentionSig filename =
  let val cu = readSig filename in
    (case !(#uStamp cu) of
         NONE => ()
       | SOME stamp =>
           let val mentions = #uMentions (!currentSig) in
             ignore(Hasht.find mentions (#uName(cu)))
             handle Subscript => Hasht.insert mentions (#uName(cu)) stamp
           end);
    cu
  end;

(* To find a pervasive signature by its name *)

fun findPervSig uname =
  Hasht.find pervSigTable uname
  handle Subscript =>
    fatalError "findPervSig"
;

(* To find a signature by its name *)

fun findSig loc uname =
  Hasht.find pervSigTable uname
  handle Subscript =>
    (Hasht.find (!currentSigTable) uname
     handle Subscript =>
       (if #uName(!currentSig) = "Top" then
          (ignore(Hasht.find (!watchDog) uname)
           handle Subscript =>
             errorMsg loc ("Cannot access unit " ^ uname ^
                           " before it has been loaded."))
        else ();
        let val cu =
          readSig uname
            handle Fail msg => errorMsg loc msg
        in
          Hasht.insert (!currentSigTable) uname cu; cu
        end))
;

(* --- The current state of the compiler --- *)

val pervasiveInfixTable =
  (Hasht.new 7 : (string, InfixStatus) Hasht.t);

val pervasiveInfixBasis = ref (NILenv : InfixBasis);
val pervasiveStaticT = ref ([]:TyNameSet);
val pervasiveStaticVE   = ref (NILenv : VarEnv);
val pervasiveStaticTE   = ref (NILenv : TyEnv);
val pervasiveStaticME   = ref (NILenv : ModEnv);
val pervasiveStaticFE   = ref (NILenv : FunEnv);
val pervasiveStaticGE   = ref (NILenv : SigEnv);

(* cvr: TODO at the moment there are no pervasive modules functors
   or signatures but there probably should be *) 
fun initPervasiveEnvironments() =
( pervasiveInfixBasis := mk1TopEnv pervasiveInfixTable;
  pervasiveStaticT    := [];
  pervasiveStaticVE   := NILenv;
  pervasiveStaticTE   := NILenv;
  pervasiveStaticME   := NILenv;
  pervasiveStaticFE   := NILenv;
  pervasiveStaticGE   := NILenv;
  List.app
    (fn uname =>
       let val cu = findPervSig uname in
	 pervasiveInfixBasis := bindTopInEnv (!pervasiveInfixBasis) (#uIBas cu);
         pervasiveStaticT :=
            (!pervasiveStaticT) @ (!(#uTyNameSet cu));
         pervasiveStaticVE :=
             bindTopInEnv (!pervasiveStaticVE) (#uVarEnv cu);
         pervasiveStaticTE :=
             bindTopInEnv (!pervasiveStaticTE) (#uTyEnv cu);
         pervasiveStaticME :=
             bindTopInEnv (!pervasiveStaticME) (#uModEnv cu);
         pervasiveStaticFE :=
             bindTopInEnv (!pervasiveStaticFE) (#uFunEnv cu);
         pervasiveStaticGE :=
             bindTopInEnv (!pervasiveStaticGE) (#uSigEnv cu)
       end)
    pervasiveOpenedUnits
);

(* Find and mention a signature *)

fun findAndMentionSig loc uname =
  let val cu = findSig loc uname in
    (case !(#uStamp cu) of
         NONE => ()
       | SOME stamp =>
           let val mentions = #uMentions (!currentSig) in
             ignore(Hasht.find mentions uname)
             handle Subscript => Hasht.insert mentions uname stamp
           end);
    cu
  end;

val initialInfixBasis  = ref (NILenv : InfixBasis);
val initialStaticT   = ref ([]:TyNameSet);
val initialStaticVE   = ref (NILenv : VarEnv);
val initialStaticTE   = ref (NILenv : TyEnv);
val initialStaticME   = ref (NILenv : ModEnv);
val initialStaticFE   = ref (NILenv : FunEnv);
val initialStaticGE   = ref (NILenv : SigEnv);

fun initInitialEnvironments context =
( initialInfixBasis   := !pervasiveInfixBasis;
  initialStaticT    := !pervasiveStaticT;
  initialStaticVE   := !pervasiveStaticVE;
  initialStaticTE   := !pervasiveStaticTE;
  initialStaticME   := !pervasiveStaticME;
  initialStaticFE   := !pervasiveStaticFE;
  initialStaticGE   := !pervasiveStaticGE;
  List.app
    (fn uname =>
       let val cu = findAndMentionSig nilLocation uname in
	 initialInfixBasis   := bindTopInEnv (!initialInfixBasis) (#uIBas cu);
         initialStaticT := (!initialStaticT) @ (!(#uTyNameSet cu));
         initialStaticTE := bindTopInEnv (!initialStaticTE) (#uTyEnv cu);
         initialStaticVE := bindTopInEnv (!initialStaticVE) (#uVarEnv cu);
         initialStaticME := bindTopInEnv (!initialStaticME) (#uModEnv cu);
         initialStaticFE := bindTopInEnv (!initialStaticFE) (#uFunEnv cu);
         initialStaticGE := bindTopInEnv (!initialStaticGE) (#uSigEnv cu)
       end)
    (!preopenedPreloadedUnits);
  List.app
    (fn filename =>
       let val cu = readAndMentionSig filename in
	   case #uMode cu of
	     STRmode => 
	        let val id = !(#uIdent cu)
		    val T = !(tyNameSetOfSig cu) 
		in
		   (case !(strOptOfSig cu) of
			NONE => ()
		      | SOME RS =>
			    (initialStaticGE := 
			     bindInEnv (!initialStaticGE) 
			               id
				       {qualid = {qual = "",id=[id]},
					info = (LAMBDAsig (T,
							   STRmod RS))}));
		    initialStaticT := (!initialStaticT) @ T;
		    initialStaticME :=
               	        bindInEnv (!initialStaticME) 
			          id 
				  {qualid = {qual = #uName cu,id=[]},
				   info = NONrec (STRstr(mk1TopEnv (modEnvOfSig cu),
							 mk1TopEnv(funEnvOfSig cu),
							 mk1TopEnv(sigEnvOfSig cu), (* should be NILenv *)
							 mk1TopEnv(tyEnvOfSig cu),
							 mk1TopEnv(varEnvOfSig cu)))}
		  end
	   | TOPDECmode =>
		 (initialInfixBasis := bindTopInEnv (!initialInfixBasis) (#uIBas cu);
		  initialStaticT := (!initialStaticT) @ (!(#uTyNameSet cu));
		  initialStaticTE := bindTopInEnv (!initialStaticTE) (#uTyEnv cu);
		  initialStaticVE := bindTopInEnv (!initialStaticVE) (#uVarEnv cu);
		  initialStaticME := bindTopInEnv (!initialStaticME) (#uModEnv cu);
		  initialStaticFE := bindTopInEnv (!initialStaticFE) (#uFunEnv cu);
		  initialStaticGE := bindTopInEnv (!initialStaticGE) (#uSigEnv cu))
       end)
    context
);

fun extendInitialSigEnv (SOME ({uMode = STRmode,
				uIdent = ref id, 
				uTyNameSet = ref T,
				uStrOpt = ref (SOME RS),
				...}:CSig)) =
    (initialStaticGE := bindInEnv (!initialStaticGE) 
                                  id
				  {qualid = {qual = "",id=[id]},
				   info = (LAMBDAsig (T,STRmod RS))})
| extendInitialSigEnv _ = ();



(* To put aside the current toplevel unit while compiling another unit. *)

fun protectCurrentUnit fct =
  let
    val saved_currentSigTable = !currentSigTable
    val saved_currentSig = !currentSig
    val saved_currentTypeStamp = !currentTypeStamp
    val saved_currentExcStamp = !currentExcStamp
    val saved_currentValStamp = !currentValStamp
    val saved_currentRenEnv = !currentRenEnv
    val saved_InfixBasis = !initialInfixBasis
    val saved_initialStaticT = !initialStaticT
    val saved_initialStaticVE = !initialStaticVE
    val saved_initialStaticTE = !initialStaticTE
    val saved_initialStaticME = !initialStaticME
    val saved_initialStaticFE = !initialStaticFE
    val saved_initialStaticGE = !initialStaticGE
  in
    (
    fct();
    currentSigTable := saved_currentSigTable;
    currentSig := saved_currentSig;
    currentTypeStamp := saved_currentTypeStamp;
    currentExcStamp := saved_currentExcStamp;
    currentValStamp := saved_currentValStamp;
    currentRenEnv := saved_currentRenEnv;
    initialInfixBasis := saved_InfixBasis;
    initialStaticT := saved_initialStaticT;
    initialStaticVE := saved_initialStaticVE;
    initialStaticTE := saved_initialStaticTE;
    initialStaticME := saved_initialStaticME;
    initialStaticFE := saved_initialStaticFE;
    initialStaticGE := saved_initialStaticGE
    )
    handle x =>
      (
      currentSigTable := saved_currentSigTable;
      currentSig := saved_currentSig;
      currentTypeStamp := saved_currentTypeStamp;
      currentExcStamp := saved_currentExcStamp;
      currentValStamp := saved_currentValStamp;
      currentRenEnv := saved_currentRenEnv;
      initialInfixBasis := saved_InfixBasis;
      initialStaticT := saved_initialStaticT;
      initialStaticVE := saved_initialStaticVE;
      initialStaticTE := saved_initialStaticTE;
      initialStaticME := saved_initialStaticME;
      initialStaticFE := saved_initialStaticFE;
      initialStaticGE := saved_initialStaticGE;
      raise x
      )
  end;

fun currentUnitName() =
  #uName(!currentSig)
;


fun mkGlobalName id =
  { qual = #uName(!currentSig), id = [id] }
;

fun isUnitName {qual, id} = id = [];

fun isGlobalName {qual, id} = not(qual = currentUnitName() orelse qual = "");

fun mkLocalName id = 
  { qual = "", id = [id]}
;
fun mkName onTop = 
  if onTop then mkGlobalName else mkLocalName;
;
fun mkGlobalInfo id info =
  { qualid = mkGlobalName id, info = info }
;

fun mkUniqueGlobalName (id, stamp) =
  ({ qual = #uName(!currentSig), id = [id] }, stamp)
;

fun newTypeStamp() =
(
  incr currentTypeStamp;
  !currentTypeStamp
);

fun newTyNameStamp() =
(
  incr currentTypeStamp;
  (currentUnitName (),!currentTypeStamp)
);

fun newExcStamp() =
(
  incr currentExcStamp;
  !currentExcStamp
);

fun newValStamp() =
(
  incr currentValStamp;
  !currentValStamp
);

(* Additions to the unit being compiled *)

fun add_global_info sel_fct id info =
  let val tbl = sel_fct (!currentSig) in
    Hasht.insert tbl id info
  end
;

(* cvr: modified to set local to global qualifiers *)
fun add_qualified_info sel_fct i (info as {qualid = {qual,id},info = info'}) =
  let val tbl = sel_fct (!currentSig) in
    if qual = "" orelse qual = currentUnitName() 
    then Hasht.insert tbl i {qualid={qual = currentUnitName(), id = id}, info = info'} 
    else Hasht.insert tbl i info 
  end
;


val add_InfixBasis  = add_global_info iBasOfSig
and add_VarEnv   = add_qualified_info varEnvOfSig
and add_TyEnv    = add_global_info tyEnvOfSig
and add_ModEnv    = add_qualified_info modEnvOfSig
and add_FunEnv    = add_qualified_info funEnvOfSig
and add_SigEnv    = add_qualified_info sigEnvOfSig
;

(* Additions to the unit being compiled *)
(* without redefining names that are already bound! *)

(* cvr: these functions should all be redundant now that
   signature elaboration is done properly *)

fun extend_InfixBasis id info =
  let val tbl = iBasOfSig (!currentSig) in
    (ignore (Hasht.find tbl id);
     msgIBlock 0;
     errPrompt "The fixity status of ";
     msgString id; msgString " cannot be redefined in a signature.";
     msgEOL();
     msgEBlock();
     raise Toplevel)
    handle Subscript =>
      (* Hasht.insert tbl id info *)
      add_InfixBasis id info
  end;

fun extend_VarEnv id info =
  let val tbl = varEnvOfSig (!currentSig) in
    (ignore (Hasht.find tbl id);
     msgIBlock 0;
     errPrompt "Value identifier ";
     msgString id; msgString " cannot be redefined in a signature.";
     msgEOL();
     msgEBlock();
     raise Toplevel)
    handle Subscript =>
      (* Hasht.insert tbl id info *)
      add_VarEnv id info
  end;

fun extend_TyEnv id info =
  let val tbl = tyEnvOfSig (!currentSig) in
    (ignore (Hasht.find tbl id);
     msgIBlock 0;
     errPrompt "Type constructor ";
     msgString id; msgString " cannot be redefined in a signature.";
     msgEOL();
     msgEBlock();
     raise Toplevel)
    handle Subscript =>
       Hasht.insert tbl id info
  end;

fun extend_ModEnv id info =
  let val tbl = modEnvOfSig (!currentSig) in
    (ignore (Hasht.find tbl id);
     msgIBlock 0;
     errPrompt "Module identifier ";
     msgString id; msgString " cannot be redefined in a signature.";
     msgEOL();
     msgEBlock();
     raise Toplevel)
    handle Subscript =>
      (* Hasht.insert tbl id info *)
      add_ModEnv id info
  end;

fun extend_FunEnv id info =
  let val tbl = funEnvOfSig (!currentSig) in
    (ignore (Hasht.find tbl id);
     msgIBlock 0;
     errPrompt "Functor identifier ";
     msgString id; msgString " cannot be redefined in a signature.";
     msgEOL();
     msgEBlock();
     raise Toplevel)
    handle Subscript =>
  (*  Hasht.insert tbl id info *)
      add_FunEnv id info
  end;

fun extend_SigEnv id info =
  let val tbl = sigEnvOfSig (!currentSig) in
    (ignore (Hasht.find tbl id);
     msgIBlock 0;
     errPrompt "Signature identifier";
     msgString id; msgString " cannot be redefined in a signature.";
     msgEOL();
     msgEBlock();
     raise Toplevel)
    handle Subscript =>
  (*  Hasht.insert tbl id info *)
      add_SigEnv id info
  end;


(* We have to compare the whole qualids, because in exported *)
(* TyNames all stamps are reset to 0. Therefore, different   *)
(* exported TyNames may have equal stamps. *)

fun isEqTN (tn1 : TyName) (tn2 : TyName) =
 (*  #qualid tn1 = #qualid tn2 andalso*)
  #tnStamp (!(#info tn1)) = #tnStamp (!(#info tn2))
;

fun updateCurrentInfixBasis iBas =
  traverseEnv add_InfixBasis (revEnv iBas)
;

fun updateCurrentStaticT T = 
    (tyNameSetOfSig (!currentSig) := (!(tyNameSetOfSig (!currentSig))) @ T)

fun extendCurrentStaticS S = 
    let val strOpt = strOptOfSig (!currentSig) 
    in (* cvr: TODO check for duplicate specs? *)
    strOpt := (case !strOpt of
                 NONE => SOME (NONrec S)
	      |  SOME (NONrec S') => SOME (NONrec (SEQstr (S',S)))
	      |  SOME (RECrec _) => fatalError "extendCurrentStaticS")
    end;

fun extendCurrentStaticIBas iBas =
  traverseEnv extend_InfixBasis (revEnv iBas)
;

fun extendCurrentStaticVE VE =
  traverseEnv extend_VarEnv (revEnv VE)
;

fun updateCurrentStaticVE VE =
  traverseEnv add_VarEnv (revEnv VE)
;

fun updateCurrentStaticTE TE =
  traverseEnv add_TyEnv (revEnv TE)
;

fun extendCurrentStaticTE TE =
  traverseEnv extend_TyEnv (revEnv TE)
;

fun extendCurrentStaticME ME =
  traverseEnv extend_ModEnv (revEnv ME)
;

fun updateCurrentStaticME ME =
  traverseEnv add_ModEnv (revEnv ME)
;

fun extendCurrentStaticFE FE =
  traverseEnv extend_FunEnv (revEnv FE)
;

fun updateCurrentStaticFE FE =
  traverseEnv add_FunEnv (revEnv FE)
;

fun extendCurrentStaticGE GE =
  traverseEnv extend_SigEnv (revEnv GE)
;

fun updateCurrentStaticGE GE =
  traverseEnv add_SigEnv (revEnv GE)
;

(*
fun mkGlobalInfixBasis() =
  bindTopInEnv pervasiveInfixBasis (!currentInfixBasis)
;
*)

fun mkGlobalInfixBasis() =
  bindTopInEnv (!initialInfixBasis) (#uIBas (!currentSig));
;

fun mkGlobalT() = (!initialStaticT) @ (!(#uTyNameSet (!currentSig)))

fun mkGlobalVE() =
  bindTopInEnv (!initialStaticVE) (#uVarEnv (!currentSig))
;

fun mkGlobalTE() =
  bindTopInEnv (!initialStaticTE) (#uTyEnv (!currentSig))
;


fun mkGlobalME() =
  bindTopInEnv (!initialStaticME) (#uModEnv (!currentSig))
;
fun mkGlobalFE() =
  bindTopInEnv (!initialStaticFE) (#uFunEnv (!currentSig))
;
fun mkGlobalGE() =
  bindTopInEnv (!initialStaticGE) (#uSigEnv (!currentSig))
;

fun execToplevelOpen loc uname =
  let val cu = findAndMentionSig loc uname in
    updateCurrentInfixBasis (mk1TopEnv (#uIBas cu));
    updateCurrentStaticT  (!(#uTyNameSet cu)); (* tynames  assumed to have level 0 *)
    updateCurrentStaticVE (mk1TopEnv (#uVarEnv cu));
    updateCurrentStaticTE (mk1TopEnv (#uTyEnv cu));
    updateCurrentStaticME (mk1TopEnv (#uModEnv cu));
    updateCurrentStaticFE (mk1TopEnv (#uFunEnv cu));
    updateCurrentStaticGE (mk1TopEnv (#uSigEnv cu))
  end;

fun print_qual "" = () 
  | print_qual qual = (msgString qual; msgString ".");

fun print_id [] = ()
  | print_id [i] = msgString i
  | print_id (i::id) = 
            (print_id id;  msgString "." ; msgString i);

fun printHiddenId id =
  (msgString "?{"; print_id id; msgString "}")
;
(* cvr: revise printVQ to deal with real long ids*)

fun printVQ q =
  let val {qual, id} = q
      fun printHidden() =
            if qual <> #uName(!currentSig) then
              (print_qual qual; 
               print_id id)
            else
              printHiddenId id
  in
      (if #qual(#qualid (lookupEnv (mkGlobalVE()) (hd id))) = qual then 
        print_id id
      else
        printHidden())
    handle Subscript =>
      printHidden()
  end;


(* cvr: TODO see above *)

fun mkInfixBasis() = (Hasht.new 13 : (string, InfixStatus) Hasht.t);
fun mkRenEnv() = (Hasht.new 113 : (string, int) Hasht.t);

fun startCompilingUnit uname uident umode =
(
  currentSigTable := mkSigTable();
  currentSig := newSig uname uident umode;
  currentInfixBasis := mkInfixBasis();
  currentTypeStamp := 0;
  currentExcStamp := 0;
  currentValStamp := 0;
  currentRenEnv := mkRenEnv()
);


fun rectifyTyNameSet (T:TyNameSet) = app (fn tn => setTnLevel (#info tn) 0) T;

fun rectifyVarEnv VE =
  let
    val excRen = ref( [] : (QualifiedIdent * (QualifiedIdent * int)) list )
  in
  (* Hasht.apply (fn id => fn {qualid, info = (sc,status)} => 
          case status of 
            EXNname ei =>
              (case #exconTag(!ei) of
                   NONE => () 
                 | SOME (name, stamp) =>
                     if #qual(qualid) = #uName(!currentSig) then
                       excRen := (qualid, (name, stamp)) :: !excRen
                     else ()
                     )
          | _ => ())
      VE; *)
    (!excRen)
  end;


fun rectifySignature() =
  let val _ = rectifyTyNameSet (!(#uTyNameSet(!currentSig)))
      val excRenList = rectifyVarEnv (#uVarEnv(!currentSig))
      val valRenList =
        foldEnv (fn id => fn stamp => fn acc => (id,stamp)::acc)
                [] (mk1TopEnv (!currentRenEnv))
  in
    currentRenEnv := dummyRenEnv;
    (excRenList, valRenList)
  end;





















