+ let l = MQ.elim ~dbd uri in
+ let entry = `Whelp (TAPp.pp_macro_cic (TA.WElim (loc, term)), l) in
+ guistuff.mathviewer#show_uri_list ~reuse:true ~entry l;
+ [], parsed_text_length
+ | TA.WHint (loc, term) ->
+ let term = disambiguate term status in
+ let s = ((None,[0,[],term], Cic.Meta (0,[]) ,term),0) in
+ let l = List.map fst (MQ.experimental_hint ~dbd s) in
+ let entry = `Whelp (TAPp.pp_macro_cic (TA.WHint (loc, term)), l) in
+ guistuff.mathviewer#show_uri_list ~reuse:true ~entry l;
+ [], parsed_text_length
+ (* REAL macro *)
+ | TA.Hint loc ->
+ let s = MatitaMisc.get_proof_status status in
+ let l = List.map fst (MQ.experimental_hint ~dbd s) in
+ let selected = guistuff.urichooser l in
+ (match selected with
+ | [] -> [], parsed_text_length
+ | [uri] ->
+ let ast =
+ TA.Executable (loc,
+ (TA.Tactical (loc,
+ TA.Tactic (loc,
+ TA.Apply (loc, CicNotationPt.Uri (UriManager.string_of_uri uri,None))))))
+ in
+ let new_status = MatitaEngine.eval_ast status ast in
+ let extra_text =
+ comment parsed_text ^
+ "\n" ^ TAPp.pp_statement ast
+ in
+ [ new_status , extra_text ], parsed_text_length
+ | _ ->
+ MatitaLog.error
+ "The result of the urichooser should be only 1 uri, not:\n";
+ List.iter (
+ fun u -> MatitaLog.error (UriManager.string_of_uri u ^ "\n")
+ ) selected;
+ assert false)
+ | TA.Check (_,term) ->
+ let metasenv = MatitaMisc.get_proof_metasenv status in
+ let context = MatitaMisc.get_proof_context status in
+ let interps =
+ MatitaDisambiguator.disambiguate_term ~dbd ~context ~metasenv
+ ~aliases:status.aliases ~universe:(Some status.multi_aliases) term
+ in
+ let _, metasenv , term, ugraph =
+ match interps with
+ | [x], _ -> x
+ | _ -> assert false
+ in
+ let ty,_ = CTC.type_of_aux' metasenv context term ugraph in
+ let t_and_ty = Cic.Cast (term,ty) in
+ guistuff.mathviewer#show_entry (`Cic (t_and_ty,metasenv));
+ [], parsed_text_length
+(* | TA.Abort _ ->
+ let rec go_back () =
+ let status = script#status.proof_status in
+ match status with
+ | No_proof -> ()
+ | _ -> script#retract ();go_back()
+ in
+ [], parsed_text_length, Some go_back
+ | TA.Redo (_, Some i) -> [], parsed_text_length,
+ Some (fun () -> for j = 1 to i do advance () done)
+ | TA.Redo (_, None) -> [], parsed_text_length,
+ Some (fun () -> advance ())
+ | TA.Undo (_, Some i) -> [], parsed_text_length,
+ Some (fun () -> for j = 1 to i do script#retract () done)
+ | TA.Undo (_, None) -> [], parsed_text_length,
+ Some (fun () -> script#retract ()) *)
+ (* TODO *)
+ | TA.Quit _ -> failwith "not implemented"
+ | TA.Print (_,kind) -> failwith "not implemented"
+ | TA.Search_pat (_, search_kind, str) -> failwith "not implemented"
+ | TA.Search_term (_, search_kind, term) -> failwith "not implemented"
+
+
+let eval_executable guistuff status user_goal unparsed_text parsed_text script
+ ex
+=
+ let module TA = GrafiteAst in
+ let module TAPp = GrafiteAstPp in
+ let module MD = MatitaDisambiguator in
+ let module ML = MatitacleanLib in
+ let parsed_text_length = String.length parsed_text in
+ match ex with
+ | TA.Command (loc, _) | TA.Tactical (loc, _) ->
+ (try
+ (match MatitaMisc.baseuri_of_baseuri_decl (TA.Executable (loc,ex)) with
+ | None -> ()
+ | Some u ->
+ if not (MatitaMisc.is_empty u) then
+ match
+ guistuff.ask_confirmation
+ ~title:"Baseuri redefinition"
+ ~message:(
+ "Baseuri " ^ u ^ " already exists.\n" ^
+ "Do you want to redefine the corresponding "^
+ "part of the library?")
+ with
+ | `YES -> MatitacleanLib.clean_baseuris [u]
+ | `NO -> ()
+ | `CANCEL -> raise MatitaTypes.Cancel);
+ eval_with_engine
+ guistuff status user_goal parsed_text (TA.Executable (loc, ex))
+ with MatitaTypes.Cancel -> [], 0)
+ | TA.Macro (_,mac) ->
+ eval_macro guistuff status unparsed_text parsed_text script mac
+
+let rec eval_statement baseoffset parsedlen error_tag (buffer : GText.buffer)
+ guistuff status user_goal script unparsed_text
+=
+ if Pcre.pmatch ~rex:only_dust_RE unparsed_text then raise Margin;
+ let st =
+ try
+ GrafiteParser.parse_statement (Ulexing.from_utf8_string unparsed_text)
+ with
+ CicNotationParser.Parse_error (floc,err) as exc ->
+ let (x, y) = CicNotationPt.loc_of_floc floc in
+ let x = parsedlen + x in
+ let y = parsedlen + y in
+ let x' = baseoffset + x in
+ let y' = baseoffset + y in
+ let x_iter = buffer#get_iter (`OFFSET x') in
+ let y_iter = buffer#get_iter (`OFFSET y') in
+ buffer#apply_tag error_tag ~start:x_iter ~stop:y_iter;
+ let id = ref None in
+ id :=
+ Some
+ (buffer#connect#changed
+ ~callback:(
+ fun () ->
+ buffer#remove_tag error_tag ~start:buffer#start_iter
+ ~stop:buffer#end_iter;
+ match !id with
+ None -> assert false (* a race condition occurred *)
+ | Some id ->
+ (new GObj.gobject_ops buffer#as_buffer)#disconnect id));
+ let flocb,floce = floc in
+ let floc =
+ {flocb with Lexing.pos_cnum = x}, {floce with Lexing.pos_cnum = y } in
+ raise (CicNotationParser.Parse_error (floc,err))
+ in
+ let text_of_loc loc =
+ let parsed_text_length = snd (CicNotationPt.loc_of_floc loc) in
+ let parsed_text = safe_substring unparsed_text 0 parsed_text_length in
+ parsed_text, parsed_text_length
+ in
+ match st with
+ | GrafiteAst.Comment (loc, _) ->
+ let parsed_text, parsed_text_length = text_of_loc loc in
+ let remain_len = String.length unparsed_text - parsed_text_length in
+ let s = String.sub unparsed_text parsed_text_length remain_len in
+ let s,len =
+ eval_statement baseoffset (parsedlen + parsed_text_length) error_tag
+ buffer guistuff status user_goal script s
+ in
+ (match s with
+ | (status, text) :: tl ->
+ ((status, parsed_text ^ text)::tl), (parsed_text_length + len)
+ | [] -> [], 0)
+ | GrafiteAst.Executable (loc, ex) ->
+ let parsed_text, parsed_text_length = text_of_loc loc in
+ eval_executable guistuff status user_goal unparsed_text parsed_text
+ script ex
+
+let fresh_script_id =
+ let i = ref 0 in
+ fun () -> incr i; !i
+
+class script ~(source_view: GSourceView.source_view)
+ ~(init: MatitaTypes.status)
+ ~(mathviewer: MatitaTypes.mathViewer)
+ ~set_star
+ ~ask_confirmation
+ ~urichooser
+ ~develcreator
+ () =
+let buffer = source_view#buffer in
+let source_buffer = source_view#source_buffer in
+object (self)
+ val scriptId = fresh_script_id ()
+
+ val guistuff = {
+ mathviewer = mathviewer;
+ urichooser = urichooser;
+ ask_confirmation = ask_confirmation;
+ develcreator = develcreator;
+ filenamedata = (None, None)}
+
+ method private getFilename =
+ match guistuff.filenamedata with Some f,_ -> f | _ -> assert false
+
+ method private ppFilename =
+ match guistuff.filenamedata with
+ | Some f,_ -> f
+ | None,_ -> sprintf ".unnamed%d.ma" scriptId
+
+ initializer
+ ignore (GMain.Timeout.add ~ms:300000
+ ~callback:(fun _ -> self#_saveToBackupFile ();true));
+ ignore (buffer#connect#modified_changed
+ (fun _ -> set_star (Filename.basename self#ppFilename) buffer#modified))
+
+ val mutable statements = []; (** executed statements *)
+ val mutable history = [ init ];
+ (** list of states before having executed statements. Head element of this
+ * list is the current state, last element is the state at the beginning of
+ * the script.
+ * Invariant: this list length is 1 + length of statements *)
+
+ (** goal as seen by the user (i.e. metano corresponding to current tab) *)
+ val mutable userGoal = ~-1
+
+ (** text mark and tag representing locked part of a script *)
+ val locked_mark =
+ buffer#create_mark ~name:"locked" ~left_gravity:true buffer#start_iter
+ val locked_tag = buffer#create_tag [`BACKGROUND "lightblue"; `EDITABLE false]
+ val error_tag = buffer#create_tag [`UNDERLINE `SINGLE; `FOREGROUND "red"]
+
+ method locked_mark = locked_mark
+ method locked_tag = locked_tag
+
+ (* history can't be empty, the invariant above grant that it contains at
+ * least the init status *)
+ method status = match history with hd :: _ -> hd | _ -> assert false
+
+ method private _advance ?statement () =
+ let s = match statement with Some s -> s | None -> self#getFuture in
+ MatitaLog.debug ("evaluating: " ^ first_line s ^ " ...");
+ let (entries, parsed_len) =
+ eval_statement (buffer#get_iter_at_mark (`MARK locked_mark))#offset 0
+ error_tag buffer guistuff self#status userGoal self s
+ in
+ let (new_statuses, new_statements) = List.split entries in
+ history <- List.rev new_statuses @ history;
+ statements <- List.rev new_statements @ statements;
+ let start = buffer#get_iter_at_mark (`MARK locked_mark) in
+ let new_text = String.concat "" new_statements in
+ if statement <> None then
+ buffer#insert ~iter:start new_text
+ else
+ if new_text <> String.sub s 0 parsed_len then
+ begin
+ let stop = start#copy#forward_chars parsed_len in
+ buffer#delete ~start ~stop;
+ buffer#insert ~iter:start new_text;