123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295(**************************************************************************)(* *)(* ACG development toolkit *)(* *)(* Copyright 2008-2021 INRIA *)(* *)(* More information on "http://acg.gforge.inria.fr/" *)(* License: CeCILL, see the LICENSE file or "http://www.cecill.info" *)(* Authors: see the AUTHORS file *)(* *)(* *)(* *)(* *)(* $Rev:: $: Revision of last commit *)(* $Author:: $: Author of last commit *)(* $Date:: $: Date of last commit *)(* *)(**************************************************************************)openUtilsLibopenLogicopenInterfacemoduletypeEnvironment_sig=sigexceptionSignature_not_foundofstringexceptionLexicon_not_foundofstringexceptionEntry_not_foundofstringmoduleSignature1:Signature_sigwithtypeterm=Lambda.Lambda.termmoduleLexicon:Interface.Lexicon_sigwithtypeSignature.t=Signature1.tandtypeSignature.term=Signature1.termandtypeSignature.stype=Signature1.stypetypettypeentry=|SignatureofSignature1.t|LexiconofLexicon.tvalempty:tvalinsert:?overwrite:bool->entry->to_be_dumped:bool->t->tvalget_signature:string->t->Signature1.tvalget_lexicon:string->t->Lexicon.tvalget:string->t->entryvalappend:?overwrite:bool->t->t->tvaliter:(entry->unit)->t->unitvalfold:(entry->'a->'a)->'a->t->'avalsig_number:t->intvallex_number:t->intvalchoose_signature:t->Signature1.toptionvalcompatible_version:t->boolvalread:string->stringlist->toptionvalwrite:string->t->unitvalselect:string->t->tvalunselect:t->tvalfocus:t->entryoptionend(*
module Make (Lex:Interface.Lexicon_sig) =
*)moduleLex=Acg_lexicon.Data_LexiconmoduleEnvironment=structmoduleLexicon=LexmoduleSg=Lex.SignaturemoduleSignature1=SgexceptionSignature_not_foundofstringexceptionLexicon_not_foundofstringexceptionEntry_not_foundofstringmoduleEnv=Utils.StringMaptypeto_be_dumped=booltypeentry=|SignatureofSg.t|LexiconofLex.tmoduleDep=DependencyManager.Make(structtypet=entryletto_string=function|Signatures->fst(Sg.names)|Lexiconl->fst(Lex.namel)letcomparee1e2=String.compare(to_stringe1)(to_stringe2)end)typet={map:(entry*to_be_dumped)Env.t;sig_number:int;lex_number:int;focus:entryoption;version:string;dependencies:Dep.t}letempty={map=Env.empty;sig_number=0;lex_number=0;focus=None;version=Version.version;dependencies=Dep.empty}letcheck_versione=letv=e.versioninif(v<>Version.version)thenraise(Error.Error(Error.Version_error(Error.Outdated_version(v,Version.version))))else()letappend?(overwrite=false)e1e2=let()=check_versione1inlet()=check_versione2inleterased_sig=ref0inleterased_lex=ref0inletnew_map=Env.merge(funkv1v2->matchv1,v2,overwritewith|None,None,_->None|None,Somev,_->Somev|Somev,None,_->Somev|Some(Lexicon_,_),Somev2,true->let()=erased_lex:=!erased_lex+1inSomev2|Some(Signature_,_),Somev2,true->let()=erased_sig:=!erased_sig+1inSomev2|Some(_,_),Some(v2,_),false->matchv2with|Signaturesg->let_,pos=Sg.namesginraise(Error.Error(Error.Env_error(Error.Duplicated_entryk,pos)))|Lexiconlex->let_,pos=Lex.namelexinraise(Error.Error(Error.Env_error(Error.Duplicated_entryk,pos))))e1.mape2.mapin{map=new_map;sig_number=e1.sig_number+e2.sig_number-!erased_sig;lex_number=e1.lex_number+e2.lex_number-!erased_lex;focus=(matche2.focuswith|Somee->Somee|None->e1.focus);version=Version.version;dependencies=Dep.mergee1.dependenciese2.dependencies}letupdate_dependencieslexm=matchLex.get_dependencieslexwith|Lex.Signatures(s1,s2)->Dep.add_dependency(Lexiconlex)(Signatures1)(Dep.add_dependency(Lexiconlex)(Signatures2)m)|Lex.Lexicons(l1,l2)->Dep.add_dependency(Lexiconlex)(Lexiconl1)(Dep.add_dependency(Lexiconlex)(Lexiconl2)m)letinsert?(overwrite=false)d~to_be_dumped:dumpe=matchdwith|Signatures->letname,(p1,p2)=Sg.namesinif(not(Env.memnamee.map))||overwritethen{ewithmap=Env.addname(d,dump)e.map;sig_number=e.sig_number+1}elseraise(Error.Error(Error.Env_error(Error.Duplicated_signaturename,(p1,p2))))|Lexiconl->letname,(p1,p2)=Lex.namelinifnot(Env.memnamee.map)||overwritethen{ewithmap=Env.addname(d,dump)e.map;lex_number=e.lex_number+1;dependencies=update_dependenciesle.dependencies}elseraise(Error.Error(Error.Env_error(Error.Duplicated_lexiconname,(p1,p2))))letiterf{map=e;_}=Env.iter(fun_(d,_)->fd)eletfoldfa{map=e;_}=Env.fold(fun_(d,_)acc->fdacc)ealetsig_number{sig_number=n;_}=nletlex_number{lex_number=n;_}=nletget_signatures{map=e;_}=matchEnv.findsewith|Signaturesg,_->sg|Lexicon_,_->raise(Signature_not_founds)|exceptionNot_found->raise(Signature_not_founds)letget_lexicons{map=e;_}=matchEnv.findsewith|Signature_,_->raise(Lexicon_not_founds)|Lexiconlex,_->lex|exceptionNot_found->raise(Lexicon_not_founds)letgets{map=e;_}=tryletdata,_=Env.findseindatawith|Not_found->raise(Entry_not_founds)letcompatible_version{version;_}=version=Version.versionletstampv=Printf.sprintf"acg object file version %s"vletreadfilenamedirs=tryletfile=(Utils.find_filefilenamedirs)inletin_ch=open_infileinletfirst_line=input_linein_chiniffirst_line=(stampVersion.version)thenlet()=Printf.printf"Loading object file \"%s\"...\n%!"fileinletnew_env=input_valuein_chinlet()=Printf.printf"Done.\n%!"inlet()=close_inin_chinSomenew_envelseletobject_version=Scanf.sscanffirst_line"acg object file version %s"(funs->s)inleterr=Error.Version_error(Error.Outdated_version(object_version,Version.version))inlet()=Printf.fprintfstderr"Error: %s\n%!"(Error.error_msgerrfilename)inNonewith|Scanf.Scan_failure_->leterr=Error.System_error(Printf.sprintf"\"%s\" is not recognized as an acg object file"filename)inlet()=Printf.fprintfstderr"Error: %s\n%!"(Error.error_msgerrfilename)inNone|Utils.No_file(_,msg)->leterr=Error.System_error(Printf.sprintf"No such file \"%s\" in %s"filenamemsg)inlet()=Printf.fprintfstderr"Error: %s\n%!"(Error.error_msgerrfilename)inNoneletwritefilenameenv=let()=Logs.debug(funm->m"The environment currently has %d signature(s) and %d lexicon(s)."(sig_numberenv)(lex_numberenv))inletnew_env=Env.fold(fun_(d,dump)acc->ifdumpthen(* all data are inserted with the [false] value as [to_be_dumped] *)insertd~to_be_dumped:falseaccelseacc)env.mapemptyinletout_ch=open_outfilenameinlet()=Printf.fprintfout_ch"%s\n"(stampVersion.version)inlet()=output_valueout_ch{new_envwithdependencies=env.dependencies}inclose_outout_chletselectnamee={ewithfocus=Some(getnamee)}letunselecte={ewithfocus=None}letfocus{focus=f;_}=fexceptionSigofSg.tletchoose_signature{map=e;_}=trylet()=Env.fold(fun_ca->matchcwith|Signatures,_->raise(Sigs)|Lexicon_,_->a)e()inNonewith|Sigs->Somesend