diff options
author | Samuel Mimram <smimram@debian.org> | 2008-07-25 15:12:53 +0200 |
---|---|---|
committer | Samuel Mimram <smimram@debian.org> | 2008-07-25 15:12:53 +0200 |
commit | a0cfa4f118023d35b767a999d5a2ac4b082857b4 (patch) | |
tree | dabcac548e299fee1da464c93b3dba98484f45b1 /checker/checker.ml | |
parent | 2281410e38ef99d025ea77194585a9bc019fdaa9 (diff) |
Imported Upstream version 8.2~beta3+dfsgupstream/8.2.beta3+dfsg
Diffstat (limited to 'checker/checker.ml')
-rw-r--r-- | checker/checker.ml | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/checker/checker.ml b/checker/checker.ml new file mode 100644 index 00000000..1c7ace12 --- /dev/null +++ b/checker/checker.ml @@ -0,0 +1,376 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(* $Id: coqtop.ml 10153 2007-09-28 18:00:45Z glondu $ *) + +open Pp +open Util +open System +open Flags +open Names +open Term +open Check + +let coq_root = id_of_string "Coq" +let parse_dir s = + let len = String.length s in + let rec decoupe_dirs dirs n = + if n>=len then dirs else + let pos = + try + String.index_from s n '.' + with Not_found -> len + in + let dir = String.sub s n (pos-n) in + decoupe_dirs (dir::dirs) (pos+1) + in + decoupe_dirs [] 0 +let dirpath_of_string s = + match parse_dir s with + [] -> invalid_arg "dirpath_of_string" + | dir -> make_dirpath (List.map id_of_string dir) +let path_of_string s = + match parse_dir s with + [] -> invalid_arg "dirpath_of_string" + | l::dir -> {dirpath=dir; basename=l} + +let (/) = Filename.concat + +let get_version_date () = + try + let ch = open_in (Coq_config.coqlib^"/revision") in + let ver = input_line ch in + let rev = input_line ch in + (ver,rev) + with _ -> (Coq_config.version,Coq_config.date) + +let print_header () = + let (ver,rev) = (get_version_date ()) in + Printf.printf "Welcome to Chicken %s (%s)\n" ver rev; + flush stdout + +(* Adding files to Coq loadpath *) + +let add_path ~unix_path:dir ~coq_root:coq_dirpath = + if exists_dir dir then + begin + Check.add_load_path (dir,coq_dirpath) + end + else + msg_warning (str ("Cannot open " ^ dir)) + +let convert_string d = + try id_of_string d + with _ -> + if_verbose warning + ("Directory "^d^" cannot be used as a Coq identifier (skipped)"); + flush_all (); + failwith "caught" + +let add_rec_path ~unix_path:dir ~coq_root:coq_dirpath = + let dirs = all_subdirs dir in + let prefix = repr_dirpath coq_dirpath in + if dirs <> [] then + let convert_dirs (lp,cp) = + (lp,Names.make_dirpath + ((List.map convert_string (List.rev cp))@prefix)) in + let dirs = map_succeed convert_dirs dirs in + begin + List.iter Check.add_load_path dirs + end + else + msg_warning (str ("Cannot open " ^ dir)) + +(* By the option -include -I or -R of the command line *) +let includes = ref [] +let push_include (s, alias) = includes := (s,alias,false) :: !includes +let push_rec_include (s, alias) = includes := (s,alias,true) :: !includes + +let check_coq_overwriting p = + if string_of_id (list_last (repr_dirpath p)) = "Coq" then + error "The \"Coq\" logical root directory is reserved for the Coq library" + +let set_default_include d = + push_include (d, Check.default_root_prefix) +let set_default_rec_include d = + let p = Check.default_root_prefix in + check_coq_overwriting p; + push_rec_include (d, p) + +(* Initializes the LoadPath according to COQLIB and Coq_config *) +let init_load_path () = + let coqlib = + (* variable COQLIB overrides the default library *) + getenv_else "COQLIB" + (if Coq_config.local || !Flags.boot then Coq_config.coqtop + else Coq_config.coqlib) in + let user_contrib = coqlib/"user-contrib" in + let contrib = coqlib/"contrib" in + (* first user-contrib *) + if Sys.file_exists user_contrib then + add_rec_path user_contrib Check.default_root_prefix; + (* then contrib *) + add_rec_path contrib (Names.make_dirpath [coq_root]); + (* then standard library *) +(* List.iter + (fun (s,alias) -> + add_rec_path (coqlib/s) ([alias; coq_root])) + theories_dirs_map;*) + add_rec_path (coqlib/"theories") (Names.make_dirpath[coq_root]); + (* then current directory *) + add_path "." Check.default_root_prefix; + (* additional loadpath, given with -I -include -R options *) + List.iter + (fun (s,alias,reci) -> + if reci then add_rec_path s alias else add_path s alias) + (List.rev !includes); + includes := [] + + +let set_debug () = Flags.debug := true + +let engagement = ref None +let set_engagement c = engagement := Some c +let engage () = + match !engagement with Some c -> Safe_typing.set_engagement c | None -> () + + +let admit_list = ref ([] : section_path list) +let add_admit s = + admit_list := path_of_string s :: !admit_list + +let norec_list = ref ([] : section_path list) +let add_norec s = + norec_list := path_of_string s :: !norec_list + +let compile_list = ref ([] : section_path list) +let add_compile s = + compile_list := path_of_string s :: !compile_list + +(*s Parsing of the command line. + We no longer use [Arg.parse], in order to use share [Usage.print_usage] + between coqtop and coqc. *) + +let compile_files () = + Check.recheck_library + ~norec:(List.rev !norec_list) + ~admit:(List.rev !admit_list) + ~check:(List.rev !compile_list) + +let version () = + Printf.printf "The Coq Proof Checker, version %s (%s)\n" + Coq_config.version Coq_config.date; + Printf.printf "compiled on %s\n" Coq_config.compile_date; + exit 0 + +(* print the usage of coqtop (or coqc) on channel co *) + +let print_usage_channel co command = + output_string co command; + output_string co "Coq options are:\n"; + output_string co +" -I dir add directory dir in the include path + -include dir (idem) + -R dir coqdir recursively map physical dir to logical coqdir + + -admit module load module and dependencies without checking + -norec module check module but admit dependencies without checking + + -where print Coq's standard library location and exit + -v print Coq version and exit + + -h, --help print this list of options +" + +(* print the usage on standard error *) + +let print_usage = print_usage_channel stderr + +let print_usage_coqtop () = + print_usage "Usage: coqchk <options>\n\n" + +let usage () = + print_usage_coqtop (); + flush stderr; + exit 1 + +let warning s = msg_warning (str s) + +open Type_errors + +let anomaly_string () = str "Anomaly: " +let report () = (str "." ++ spc () ++ str "Please report.") + +let print_loc loc = + if loc = dummy_loc then + (str"<unknown>") + else + let loc = unloc loc in + (int (fst loc) ++ str"-" ++ int (snd loc)) +let guill s = "\""^s^"\"" + +let where s = + if !Flags.debug then (str"in " ++ str s ++ str":" ++ spc ()) else (mt ()) + +let rec explain_exn = function + | Stream.Failure -> + hov 0 (anomaly_string () ++ str "uncaught Stream.Failure.") + | Stream.Error txt -> + hov 0 (str "Syntax error: " ++ str txt) + | Token.Error txt -> + hov 0 (str "Syntax error: " ++ str txt) + | Sys_error msg -> + hov 0 (anomaly_string () ++ str "uncaught exception Sys_error " ++ str (guill msg) ++ report() ) + | UserError(s,pps) -> + hov 1 (str "User error: " ++ where s ++ pps) + | Out_of_memory -> + hov 0 (str "Out of memory") + | Stack_overflow -> + hov 0 (str "Stack overflow") + | Anomaly (s,pps) -> + hov 1 (anomaly_string () ++ where s ++ pps ++ report ()) + | Match_failure(filename,pos1,pos2) -> + hov 1 (anomaly_string () ++ str "Match failure in file " ++ str (guill filename) ++ + if Sys.ocaml_version = "3.06" then + (str " from character " ++ int pos1 ++ + str " to " ++ int pos2) + else + (str " at line " ++ int pos1 ++ + str " character " ++ int pos2) + ++ report ()) + | Not_found -> + hov 0 (anomaly_string () ++ str "uncaught exception Not_found" ++ report ()) + | Failure s -> + hov 0 (anomaly_string () ++ str "uncaught exception Failure " ++ str (guill s) ++ report ()) + | Invalid_argument s -> + hov 0 (anomaly_string () ++ str "uncaught exception Invalid_argument " ++ str (guill s) ++ report ()) + | Sys.Break -> + hov 0 (fnl () ++ str "User interrupt.") + | Univ.UniverseInconsistency (o,u,v) -> + let msg = + if !Flags.debug (*!Constrextern.print_universes*) then + spc() ++ str "(cannot enforce" ++ spc() ++ (*Univ.pr_uni u ++*) spc() ++ + str (match o with Univ.Lt -> "<" | Univ.Le -> "<=" | Univ.Eq -> "=") + ++ spc() ++ (*Univ.pr_uni v ++*) str")" + else + mt() in + hov 0 (str "Error: Universe inconsistency" ++ msg ++ str ".") + | TypeError(ctx,te) -> +(* hov 0 (str "Error:" ++ spc () ++ Himsg.explain_type_error ctx *) + (* te)*) + hov 0 (str "Type error") + + | Indtypes.InductiveError e -> + hov 0 (str "Error related to inductive types") +(* let ctx = Check.get_env() in + hov 0 + (str "Error:" ++ spc () ++ Himsg.explain_inductive_error ctx e)*) + | Stdpp.Exc_located (loc,exc) -> + hov 0 ((if loc = dummy_loc then (mt ()) + else (str"At location " ++ print_loc loc ++ str":" ++ fnl ())) + ++ explain_exn exc) + | Assert_failure (s,b,e) -> + hov 0 (anomaly_string () ++ str "assert failure" ++ spc () ++ + (if s <> "" then + if Sys.ocaml_version = "3.06" then + (str ("(file \"" ^ s ^ "\", characters ") ++ + int b ++ str "-" ++ int e ++ str ")") + else + (str ("(file \"" ^ s ^ "\", line ") ++ int b ++ + str ", characters " ++ int e ++ str "-" ++ + int (e+6) ++ str ")") + else + (mt ())) ++ + report ()) + | reraise -> + hov 0 (anomaly_string () ++ str "Uncaught exception " ++ + str (Printexc.to_string reraise)++report()) + +let parse_args() = + let rec parse = function + | [] -> () + | "-impredicative-set" :: rem -> + set_engagement Declarations.ImpredicativeSet; parse rem + + | ("-I"|"-include") :: d :: rem -> set_default_include d; parse rem + | ("-I"|"-include") :: [] -> usage () + + | "-R" :: d :: p :: rem -> + push_rec_include (d, dirpath_of_string p);parse rem + | "-R" :: ([] | [_]) -> usage () + + | "-debug" :: rem -> set_debug (); parse rem + + | "-where" :: _ -> + print_endline (getenv_else "COQLIB" Coq_config.coqlib); exit 0 + + | ("-?"|"-h"|"-H"|"-help"|"--help") :: _ -> usage () + + | ("-v"|"--version") :: _ -> version () + + | ("-m" | "--memory") :: rem -> Check_stat.memory_stat := true; parse rem + + | ("-o" | "-output-context") :: rem -> + Check_stat.output_context := true; parse rem + + | "-no-hash-consing" :: rem -> Flags.hash_cons_proofs := false; parse rem + + | "-admit" :: s :: rem -> add_admit s; parse rem + | "-admit" :: [] -> usage () + + | "-norec" :: s :: rem -> add_norec s; parse rem + | "-norec" :: [] -> usage () + + | "-silent" :: rem -> + Flags.make_silent true; parse rem + + | s :: _ when s<>"" && s.[0]='-' -> + msgnl (str "Unknown option " ++ str s); exit 1 + | s :: rem -> add_compile s; parse rem + in + try + parse (List.tl (Array.to_list Sys.argv)) + with + | UserError(_,s) as e -> begin + try + Stream.empty s; exit 1 + with Stream.Failure -> + msgnl (explain_exn e); exit 1 + end + | e -> begin msgnl (explain_exn e); exit 1 end + + +(* To prevent from doing the initialization twice *) +let initialized = ref false + +let init() = + if not !initialized then begin + initialized := true; + Sys.catch_break false; (* Ctrl-C is fatal during the initialisation *) + try + parse_args(); + if_verbose print_header (); + init_load_path (); + engage (); + with e -> + flush_all(); + message "Error during initialization :"; + msgnl (explain_exn e); + exit 1 + end + +let run () = + try + compile_files (); + flush_all() + with e -> + (Pp.ppnl(explain_exn e); + flush_all(); + exit 1) + +let start () = init(); run(); exit 0 |