src/Pure/PIDE/command.ML
changeset 52572 2fb1f9cf80d3
parent 52571 344527354323
child 52586 7a0935571a23
equal deleted inserted replaced
52571:344527354323 52572:2fb1f9cf80d3
     8 sig
     8 sig
     9   type eval_process
     9   type eval_process
    10   type eval = {exec_id: Document_ID.exec, eval_process: eval_process}
    10   type eval = {exec_id: Document_ID.exec, eval_process: eval_process}
    11   val eval_result_state: eval -> Toplevel.state
    11   val eval_result_state: eval -> Toplevel.state
    12   type print_process
    12   type print_process
    13   type print = {name: string, pri: int, exec_id: Document_ID.exec, print_process: print_process}
    13   type print =
       
    14    {name: string, pri: int, persistent: bool,
       
    15     exec_id: Document_ID.exec, print_process: print_process}
    14   type exec = eval * print list
    16   type exec = eval * print list
    15   val no_exec: exec
    17   val no_exec: exec
    16   val exec_ids: exec option -> Document_ID.exec list
    18   val exec_ids: exec option -> Document_ID.exec list
    17   val stable_eval: eval -> bool
    19   val stable_eval: eval -> bool
    18   val stable_print: print -> bool
    20   val stable_print: print -> bool
    19   val read: (unit -> theory) -> Token.T list -> Toplevel.transition
    21   val read: (unit -> theory) -> Token.T list -> Toplevel.transition
    20   val eval: (unit -> theory) -> Token.T list -> eval -> eval
    22   val eval: (unit -> theory) -> Token.T list -> eval -> eval
    21   val print: bool -> string -> eval -> print list -> print list option
    23   val print: bool -> string -> eval -> print list -> print list option
    22   type print_fn = Toplevel.transition -> Toplevel.state -> unit
    24   type print_fn = Toplevel.transition -> Toplevel.state -> unit
    23   val print_function: {name: string, pri: int} -> (string -> print_fn option) -> unit
    25   val print_function: {name: string, pri: int, persistent: bool} ->
       
    26     ({command_name: string} -> print_fn option) -> unit
    24   val no_print_function: string -> unit
    27   val no_print_function: string -> unit
    25   val execute: exec -> unit
    28   val execute: exec -> unit
    26 end;
    29 end;
    27 
    30 
    28 structure Command: COMMAND =
    31 structure Command: COMMAND =
    84 
    87 
    85 fun eval_result ({eval_process, ...}: eval) = memo_result eval_process;
    88 fun eval_result ({eval_process, ...}: eval) = memo_result eval_process;
    86 val eval_result_state = #state o eval_result;
    89 val eval_result_state = #state o eval_result;
    87 
    90 
    88 type print_process = unit memo;
    91 type print_process = unit memo;
    89 type print = {name: string, pri: int, exec_id: Document_ID.exec, print_process: print_process};
    92 type print =
       
    93  {name: string, pri: int, persistent: bool,
       
    94   exec_id: Document_ID.exec, print_process: print_process};
    90 
    95 
    91 type exec = eval * print list;
    96 type exec = eval * print list;
    92 val no_exec: exec = ({exec_id = Document_ID.none, eval_process = memo_value init_eval_state}, []);
    97 val no_exec: exec = ({exec_id = Document_ID.none, eval_process = memo_value init_eval_state}, []);
    93 
    98 
    94 fun exec_ids (NONE: exec option) = []
    99 fun exec_ids (NONE: exec option) = []
   208 
   213 
   209 type print_fn = Toplevel.transition -> Toplevel.state -> unit;
   214 type print_fn = Toplevel.transition -> Toplevel.state -> unit;
   210 
   215 
   211 local
   216 local
   212 
   217 
   213 type print_function = string * (int * (string -> print_fn option));
   218 type print_function = string * (int * bool * ({command_name: string} -> print_fn option));
   214 val print_functions = Synchronized.var "Command.print_functions" ([]: print_function list);
   219 val print_functions = Synchronized.var "Command.print_functions" ([]: print_function list);
   215 
   220 
   216 fun print_error tr e =
   221 fun print_error tr e =
   217   (Toplevel.setmp_thread_position tr o Runtime.controlled_execution) e () handle exn =>
   222   (Toplevel.setmp_thread_position tr o Runtime.controlled_execution) e () handle exn =>
   218     List.app (Future.error_msg (Toplevel.pos_of tr)) (ML_Compiler.exn_messages_ids exn);
   223     List.app (Future.error_msg (Toplevel.pos_of tr)) (ML_Compiler.exn_messages_ids exn);
   219 
   224 
   220 in
   225 in
   221 
   226 
   222 fun print command_visible command_name eval old_prints =
   227 fun print command_visible command_name eval old_prints =
   223   let
   228   let
   224     fun new_print (name, (pri, get_print_fn)) =
   229     fun new_print (name, (pri, persistent, get_fn)) =
   225       let
   230       let
   226         fun make_print strict print_fn =
   231         fun make_print strict print_fn =
   227           let
   232           let
   228             val exec_id = Document_ID.make ();
   233             val exec_id = Document_ID.make ();
   229             fun process () =
   234             fun process () =
   232                 val tr = Toplevel.exec_id exec_id command;
   237                 val tr = Toplevel.exec_id exec_id command;
   233               in
   238               in
   234                 if failed andalso not strict then ()
   239                 if failed andalso not strict then ()
   235                 else print_error tr (fn () => print_fn tr st')
   240                 else print_error tr (fn () => print_fn tr st')
   236               end;
   241               end;
   237           in {name = name, pri = pri, exec_id = exec_id, print_process = memo process} end;
   242           in
       
   243            {name = name, pri = pri, persistent = persistent,
       
   244             exec_id = exec_id, print_process = memo process}
       
   245           end;
   238       in
   246       in
   239         (case Exn.capture (Runtime.controlled_execution get_print_fn) command_name of
   247         (case Exn.capture (Runtime.controlled_execution get_fn) {command_name = command_name} of
   240           Exn.Res NONE => NONE
   248           Exn.Res NONE => NONE
   241         | Exn.Res (SOME print_fn) => SOME (make_print false print_fn)
   249         | Exn.Res (SOME print_fn) => SOME (make_print false print_fn)
   242         | Exn.Exn exn => SOME (make_print true (fn _ => fn _ => reraise exn)))
   250         | Exn.Exn exn => SOME (make_print true (fn _ => fn _ => reraise exn)))
   243       end;
   251       end;
   244 
   252 
   246       if command_visible then
   254       if command_visible then
   247         rev (Synchronized.value print_functions) |> map_filter (fn pr =>
   255         rev (Synchronized.value print_functions) |> map_filter (fn pr =>
   248           (case find_first (equal (fst pr) o #name) old_prints of
   256           (case find_first (equal (fst pr) o #name) old_prints of
   249             SOME print => if stable_print print then SOME print else new_print pr
   257             SOME print => if stable_print print then SOME print else new_print pr
   250           | NONE => new_print pr))
   258           | NONE => new_print pr))
   251       else filter stable_print old_prints;
   259       else filter (fn print => #persistent print andalso stable_print print) old_prints;
   252   in
   260   in
   253     if eq_list (op = o pairself #exec_id) (old_prints, new_prints) then NONE
   261     if eq_list (op = o pairself #exec_id) (old_prints, new_prints) then NONE
   254     else SOME new_prints
   262     else SOME new_prints
   255   end;
   263   end;
   256 
   264 
   257 fun print_function {name, pri} f =
   265 fun print_function {name, pri, persistent} f =
   258   Synchronized.change print_functions (fn funs =>
   266   Synchronized.change print_functions (fn funs =>
   259    (if not (AList.defined (op =) funs name) then ()
   267    (if not (AList.defined (op =) funs name) then ()
   260     else warning ("Redefining command print function: " ^ quote name);
   268     else warning ("Redefining command print function: " ^ quote name);
   261     AList.update (op =) (name, (pri, f)) funs));
   269     AList.update (op =) (name, (pri, persistent, f)) funs));
   262 
   270 
   263 fun no_print_function name =
   271 fun no_print_function name =
   264   Synchronized.change print_functions (filter_out (equal name o #1));
   272   Synchronized.change print_functions (filter_out (equal name o #1));
   265 
   273 
   266 end;
   274 end;
   267 
   275 
   268 val _ =
   276 val _ =
   269   print_function {name = "print_state", pri = 0} (fn command_name => SOME (fn tr => fn st' =>
   277   print_function {name = "print_state", pri = 0, persistent = true}
   270     let
   278     (fn {command_name} => SOME (fn tr => fn st' =>
   271       val is_init = Keyword.is_theory_begin command_name;
   279       let
   272       val is_proof = Keyword.is_proof command_name;
   280         val is_init = Keyword.is_theory_begin command_name;
   273       val do_print =
   281         val is_proof = Keyword.is_proof command_name;
   274         not is_init andalso
   282         val do_print =
   275           (Toplevel.print_of tr orelse (is_proof andalso Toplevel.is_proof st'));
   283           not is_init andalso
   276     in if do_print then Toplevel.print_state false st' else () end));
   284             (Toplevel.print_of tr orelse (is_proof andalso Toplevel.is_proof st'));
       
   285       in if do_print then Toplevel.print_state false st' else () end));
   277 
   286 
   278 
   287 
   279 (* overall execution process *)
   288 (* overall execution process *)
   280 
   289 
   281 fun run_print ({name, pri, print_process, ...}: print) =
   290 fun run_print ({name, pri, print_process, ...}: print) =