123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132(** 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)!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], forcing
compilation of up-to-date files if [force] is true. *)letcompile:?force:bool->Path.t->Sign.t=fun?(force=false)->compile_with~handle:Command.handle~force(** [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:?force:bool->string->Sign.t=fun?(force=false)fname->Package.apply_configfname;compile~force(path_of_fileLpLexer.escapefname)(** 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->?force:bool->Path.t->Sign.t=fun?lm?st?(force=false)->apply_cfg?lm?st(compile~force)letcompile_file:?lm:Path.t*string->?st:Console.State.t->?force:bool->string->Sign.t=fun?lm?st?(force=false)->apply_cfg?lm?st(compile_file~force)end