123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141(** High-level compilation functions. *)openLplibopenTimedopenCommonopenErroropenLibraryopenParsingopenCoreopenSignopenTerm(** [gen_obj] indicates whether we should generate object files when compiling
source files. The default behaviour is not te generate them. *)letgen_obj=Stdlib.reffalse(** [compile_with ~handle ~force mp] compiles the file corresponding to module
path [mp] using function [~handle] to process commands. Module [mp] is
processed when it is necessary, i.e. the corresponding object file does not
exist, or it must be updated, or [~force] is [true]. In that case, the
produced signature is stored in the corresponding object file if the option
[--gen_obj] or [-c] is set. *)letreccompile_with:handle:(Command.compiler->Sig_state.t->Syntax.p_command->Sig_state.t)->force:bool->Command.compiler=fun~handle~forcemp->letbase=file_of_pathmpinletsrc()=(* Searching for source is delayed because we may not need it
in case of "ghost" signatures (such as for unification rules). *)letlp_src=base^lp_src_extensioninletdk_src=base^dk_src_extensioninmatch(Sys.file_existslp_src,Sys.file_existsdk_src)with|(false,false)->fatal_no_pos"File \"%s.lp\" (or .dk) not found."base|(true,true)->wrnNone"Both \"%s\" and \"%s\" exist. We take \"%s\"."lp_srcdk_srclp_src;lp_src|(true,false)->lp_src|(false,true)->dk_srcinletobj=base^obj_extensioninifList.memmp!loadingthenbeginfatal_msg"Circular dependencies detected in \"%s\".@."(src());fatal_msg"Dependency stack for module %a:@."Path.ppmp;List.iter(fatal_msg"- %a@."Path.pp)!loading;fatal_no_pos"Build aborted."end;matchPath.Map.find_optmp!loadedwith|Somesign->sign|None->ifforce||Extra.more_recent(src())objthenbeginletforced=ifforcethen" (forced)"else""inletsrc=src()inConsole.out1"Loading \"%s\"%s ..."srcforced;loading:=mp::!loading;letsign=Sig_state.create_signmpinletsig_st=Stdlib.ref(Sig_state.of_signsign)in(* [sign] is added to [loaded] before processing the commands so that it
is possible to qualify the symbols of the current modules. *)loaded:=Path.Map.addmpsign!loaded;Stdlib.(Tactic.admitted:=-1);letconsumecmd=Stdlib.(sig_st:=handle(compile_with~handle~force:false)!sig_stcmd)inDebug.stream_iterconsume(Parser.parse_filesrc);Sign.strip_privatesign;ifStdlib.(!gen_obj)thenSign.writesignobj;loading:=List.tl!loading;signendelsebeginConsole.out1"Loading \"%s\" ..."(src());letsign=Sign.readobjinletcompilemp_=ignore(compile_with~handle~force:falsemp)inPath.Map.itercompile!(sign.sign_deps);loaded:=Path.Map.addmpsign!loaded;Sign.linksign;(* Since Unif_rule.sign is always assumed to be already loaded, we need
to explicitly update the decision tree of Unif_rule.equiv since it is
not done in linking which normally follows loading. *)letsm=Path.Map.findUnif_rule.path!(sign.sign_deps)inifExtra.StrMap.memUnif_rule.equiv.sym_namesmthenTree.update_dtreeUnif_rule.equiv[];signend(** [compile force mp] compiles module path [mp] using [compile_with], forcing
compilation of up-to-date files if [force] is true. *)letcompileforce=compile_with~handle:Command.handle~force(** [recompile] indicates whether we should recompile files who have an object
file that is already up to date. Note that this flag only applies to files
that are given on the command line explicitly, not their dependencies. *)letrecompile=Stdlib.reffalse(** [compile_file fname] looks for a package configuration file for
[fname] and compiles [fname]. It is the main compiling function. It
is called from the main program exclusively. *)letcompile_file:string->Sign.t=funfname->Package.apply_configfname;(* Compute the module path (checking the extension). *)letmp=path_of_fileLpLexer.escapefnamein(* Run compilation. *)compileStdlib.(!recompile)mp(** The functions provided in this module perform the same computations as the
ones defined earlier, but restore the console state and the library
mappings when they have finished. An optional library mapping or console
state can be passed as argument to change the settings. *)modulePureUpToSign=struct(** [apply_cfg ?lm ?st f x] is the same as [f x] except that the console
state and {!val:Library.lib_mappings} are restored after the evaluation
of [f x]. [?lm] allows to set the library mappings and [?st] to set the
console state. *)letapply_cfg:?lm:Path.t*string->?st:Console.State.t->('a->'b)->'a->'b=fun?lm?stfx->letlib_mappings=!Library.lib_mappingsinConsole.State.push();Option.iterLibrary.add_mappinglm;Option.iterConsole.State.applyst;letrestore()=Library.lib_mappings:=lib_mappings;Console.State.pop()intryletres=fxinrestore();reswithe->restore();raiseeletcompile:?lm:Path.t*string->?st:Console.State.t->bool->Path.t->Sign.t=fun?lm?stforcemp->letf(force,mp)=compileforcempinapply_cfg?lm?stf(force,mp)letcompile_file:?lm:Path.t*string->?st:Console.State.t->string->Sign.t=fun?lm?st->apply_cfg?lm?stcompile_fileend