]> matita.cs.unibo.it Git - helm.git/blob - matita/matitaWiki.ml
tagged 0.5.0-rc1
[helm.git] / matita / matitaWiki.ml
1 (* Copyright (C) 2004-2005, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://helm.cs.unibo.it/
24  *)
25
26 (* $Id: matitacLib.ml 7090 2006-12-12 14:04:59Z fguidi $ *)
27
28 open Printf
29
30 open GrafiteTypes
31
32 exception AttemptToInsertAnAlias
33
34
35 (** {2 Initialization} *)
36
37 let grafite_status = (ref [] : GrafiteTypes.status list ref)
38 let lexicon_status = (ref [] : LexiconEngine.status list ref)
39
40 let run_script is eval_function  =
41   let lexicon_status',grafite_status' = 
42     match !lexicon_status,!grafite_status with
43     | ss::_, s::_ -> ss,s
44     | _,_ -> assert false
45   in
46   let cb = fun _ _ -> () in
47   let matita_debug = Helm_registry.get_bool "matita.debug" in
48   try
49    match eval_function lexicon_status' grafite_status' is cb with
50       [] -> raise End_of_file
51     | ((grafite_status'',lexicon_status''),None)::_ ->
52        lexicon_status := lexicon_status''::!lexicon_status;
53        grafite_status := grafite_status''::!grafite_status
54     | (s,Some _)::_ -> raise AttemptToInsertAnAlias
55   with
56   | GrafiteEngine.Drop  
57   | End_of_file
58   | CicNotationParser.Parse_error _
59   | HExtlib.Localized _ as exn -> raise exn
60   | exn -> 
61       if not matita_debug then
62        HLog.error (snd (MatitaExcPp.to_string exn)) ;
63       raise exn
64
65 let clean_exit n =
66   match !grafite_status with
67      [] -> exit n
68    | grafite_status::_ ->
69        let baseuri = GrafiteTypes.get_baseuri grafite_status in
70        LibraryClean.clean_baseuris ~verbose:false [baseuri];
71        exit n
72
73 let terminate n =
74  let terminator = String.make 1 (Char.chr 249) in
75  let prompt =
76   (match n with
77      None -> "-1"
78    | Some n -> string_of_int n) ^ terminator
79  in
80   print_endline prompt;
81   prerr_endline prompt
82 ;;
83
84 let outer_syntax_parser () =
85  let text = ref "" in
86  let tag = ref `Do in
87  let callbacks =
88   { XmlPushParser.default_callbacks with
89     XmlPushParser.start_element =
90      (Some
91        (fun name attrs ->
92          match name with
93             "pgip" -> ()
94           | "doitem" -> tag := `Do
95           | "undoitem" -> tag := `Undo
96           | _ -> assert false)) ;
97     XmlPushParser.character_data =
98      (Some (fun s -> text := !text ^ s)) ;
99     XmlPushParser.end_element =
100      (Some
101        (function
102            "pgip" -> raise (XmlPushParser.Parse_error "EOC")
103          | "doitem"
104          | "undoitem" -> ()
105          | _ -> assert false))
106   }
107  in
108   let parse = XmlPushParser.create_parser callbacks in
109     try
110      XmlPushParser.parse parse (`Channel stdin) ;
111      raise End_of_file
112     with
113        XmlPushParser.Parse_error "no element found" -> raise End_of_file
114      | XmlPushParser.Parse_error "EOC" ->
115         match !tag with
116            `Do -> `Do !text
117          | `Undo ->
118              try
119               `Undo (int_of_string !text)
120              with
121               Failure _ -> assert false
122 ;;
123
124 let include_paths =
125  lazy (Helm_registry.get_list Helm_registry.string "matita.includes")
126 ;;
127   
128 let rec interactive_loop () = 
129   (* every loop is terminated by a terminator both on stdout and stderr *)
130   let interactive_loop n = terminate n; interactive_loop () in
131   try
132    match outer_syntax_parser () with
133       `Undo n ->
134         let rec drop =
135          function
136             0,l -> l
137           | n,_::l -> drop (n-1,l)
138           | _,[] -> assert false
139         in
140          let to_be_dropped = List.length !lexicon_status - n in
141          let safe_hd = function [] -> assert false | he::_ -> he in
142          let cur_lexicon_status = safe_hd !lexicon_status in
143          let cur_grafite_status = safe_hd !grafite_status in
144           lexicon_status := drop (to_be_dropped, !lexicon_status) ;
145           grafite_status := drop (to_be_dropped, !grafite_status) ;
146           let lexicon_status = safe_hd !lexicon_status in
147           let grafite_status = safe_hd !grafite_status in
148            LexiconSync.time_travel
149             ~present:cur_lexicon_status ~past:lexicon_status;
150            GrafiteSync.time_travel
151             ~present:cur_grafite_status ~past:grafite_status;
152            interactive_loop (Some n)
153     | `Do command ->
154         let str = Ulexing.from_utf8_string command in
155         let watch_statuses lexicon_status grafite_status =
156          match grafite_status.GrafiteTypes.proof_status with
157             GrafiteTypes.Incomplete_proof
158              {GrafiteTypes.proof = uri,metasenv,_subst,bo,ty,attrs ;
159               GrafiteTypes.stack = stack } ->
160               let open_goals = Continuationals.Stack.open_goals stack in
161               print_endline
162                (String.concat "\n"
163                  (List.map
164                    (fun i ->
165                      ApplyTransformation.txt_of_cic_sequent 80 metasenv
166                       ~map_unicode_to_tex:(Helm_registry.get_bool
167                         "matita.paste_unicode_as_tex")
168                       (List.find (fun (j,_,_) -> j=i) metasenv)
169                    ) open_goals))
170           | _ -> ()
171         in
172          run_script str 
173            (MatitaEngine.eval_from_stream ~first_statement_only:true 
174            ~include_paths:(Lazy.force include_paths) ~watch_statuses) ;
175          interactive_loop (Some (List.length !lexicon_status))
176   with 
177    | GrafiteEngine.Macro (floc,_) ->
178       let x, y = HExtlib.loc_of_floc floc in
179        HLog.error
180         (sprintf "A macro has been found in a script at %d-%d" x y);
181        interactive_loop None
182    | Sys.Break -> HLog.error "user break!"; interactive_loop None
183    | GrafiteTypes.Command_error _ -> interactive_loop None
184    | HExtlib.Localized (floc,CicNotationParser.Parse_error err) ->
185       let x, y = HExtlib.loc_of_floc floc in
186        HLog.error (sprintf "Parse error at %d-%d: %s" x y err);
187        interactive_loop None
188    | End_of_file as exn -> raise exn
189    | exn -> HLog.error (Printexc.to_string exn); interactive_loop None
190
191
192 let main () = 
193   MatitaInit.initialize_all ();
194   HLog.set_log_callback
195    (fun tag msg ->
196      let s =
197       match tag with
198          `Debug -> "<div style='color:blue'>Debug: " ^ msg ^ "</div><br/>\n"
199        | `Message -> "<div style='color:green'>Info: " ^ msg ^ "</div><br/>\n"
200        | `Warning -> "<div style='color:yellow'>Warn: " ^ msg ^ "</div><br/>\n"
201        | `Error -> "<div style='color:red'>Error: " ^ msg ^ "</div><br/>\n"
202      in
203       output_string stderr s;
204       flush stderr
205    );
206   (* must be called after init since args are set by cmdline parsing *)
207   let system_mode =  Helm_registry.get_bool "matita.system" in
208   let include_paths =
209    Helm_registry.get_list Helm_registry.string "matita.includes" in
210   grafite_status := [GrafiteSync.init "cic:/matita/tests/"];
211   lexicon_status :=
212    [CicNotation2.load_notation ~include_paths
213      BuildTimeConf.core_notation_script] ;
214   Sys.catch_break true;
215   let origcb = HLog.get_log_callback () in
216   let origcb t s = origcb t ((if system_mode then "[S] " else "") ^ s) in
217   let newcb tag s =
218     match tag with
219     | `Debug -> ()
220     | `Message | `Warning | `Error -> origcb tag s
221   in
222   HLog.set_log_callback newcb;
223   let matita_debug = Helm_registry.get_bool "matita.debug" in
224   try
225     (try
226       interactive_loop ()
227      with
228       | End_of_file -> ()
229       | GrafiteEngine.Drop -> clean_exit 1
230     );
231     let proof_status,moo_content_rev,lexicon_content_rev = 
232       match !lexicon_status,!grafite_status with
233       | ss::_, s::_ ->
234          s.proof_status, s.moo_content_rev,
235           ss.LexiconEngine.lexicon_content_rev
236       | _,_ -> assert false
237     in
238     if proof_status <> GrafiteTypes.No_proof then
239      begin
240       HLog.error
241        "there are still incomplete proofs at the end of the script";
242       clean_exit 2
243      end
244     else
245      begin
246        let baseuri =
247         GrafiteTypes.get_baseuri 
248            (match !grafite_status with
249              [] -> assert false
250            | s::_ -> s)
251        in
252        let moo_fname = 
253          LibraryMisc.obj_file_of_baseuri 
254            ~must_exist:false ~baseuri ~writable:true 
255        in
256        let lexicon_fname= 
257          LibraryMisc.lexicon_file_of_baseuri 
258           ~must_exist:false ~baseuri ~writable:true 
259        in
260        GrafiteMarshal.save_moo moo_fname moo_content_rev;
261        LexiconMarshal.save_lexicon lexicon_fname lexicon_content_rev;
262        exit 0
263      end
264   with 
265   | exn ->
266       if matita_debug then raise exn;
267       clean_exit 3