% This file creates a bootstrapped version of ML with a self-referential
  top environment:  First use "build.ml" to build a new set of files.
  The next bit of highly dubious code makes sure that the hash table holding
  the environment uses the new functions defined in this bootstrap.  
  NB.  If the representation of the environment has changed then file
  bsys.ml should be used as it builds the environment from new.  bsysref.ml
  can then be used on the resulting system to create a self-referential
  environment.   
%


if isl(!AnalFudgeType) then
   InitMLState()  %AM: (unfortunately) for its side effect with new code%
else
   EmptyMLState( `Junk`, HTML );

%AM: but for the next comment the next two lines are args to RecMLState%
let NewMLState = EmptyMLState( `Hyper-Transfer-ML`, HTML );
let OldMLState = forgettype(CurrentMLState()): MLState';

%Now for some extremely dubious code to patch up printing that is necessary 
 to get around alan's dubious code in mlanal and InitMLState ... 
%
let SmashTypePrintFn(atom,prfun) =
         let topenv = TopEnvOfSysState(OldMLState)
         enc oldtyp = fst(RetrieveTypFromTop(atom, topenv.Typ, 
                                             (\x.failwith `Oh Dear`)))
         enc oldinfo = ((repTypTerm' oldtyp) as TypAbsOper).AbsInfo
          in oldinfo.AbsPrintFn := prfun;

SmashTypePrintFn(AtomBool,   InitPrintFns.Bool);
SmashTypePrintFn(AtomList,   InitPrintFns.Star);
SmashTypePrintFn(AtomInt,    InitPrintFns.Int);
SmashTypePrintFn(AtomFloat,  InitPrintFns.Real);
SmashTypePrintFn(AtomString, InitPrintFns.String);
SmashTypePrintFn(AtomArrow,  InitPrintFns.Fun);
SmashTypePrintFn(AtomCross,  InitPrintFns.Tuple);
SmashTypePrintFn(absAtom' `Dynamic`,  InitPrintFns.Dynamic);
SmashTypePrintFn(AtomXn,    InitPrintFns.ADT);

%end of dubious bit %

%AM: the next 3 lines should be inside RecMLState when we figure how%
let (use,CurrentMLState,ML,ExportMLState,ExportML,ExportFunction,it) =
  (NewUse NewMLState, (\().NewMLState), NewML,
   NewExportMLState, NewExportMLState NewMLState, NewExportFunction, ());

let RecMLState( oldMLState: MLState', newMLState: MLState' ): MLState' =
% A comment to be inserted by AM %
    let _ = UpdateTopEnvOfSysState(newMLState,CopyFromTopEnv( %AM: necessary?%
                                             TopEnvOfSysState(oldMLState),
					     [],[]))
    enc _ = NewUse newMLState [`syntax.ml`]
    enc _ = NewML(newMLState)
    in newMLState;

NewExportMLState (RecMLState(OldMLState, NewMLState))
                 (`phase3.exp`,
                  `System with recursive environment`,
                   [] );
