src/Pure/PIDE/document.ML
changeset 44673 2fa51ac191bc
parent 44660 90bab3febb6c
child 44674 bad4f9158c80
equal deleted inserted replaced
44672:07dad1433cd7 44673:2fa51ac191bc
    28   val cancel_execution: state -> Future.task list
    28   val cancel_execution: state -> Future.task list
    29   val update_perspective: version_id -> version_id -> string -> command_id list -> state -> state
    29   val update_perspective: version_id -> version_id -> string -> command_id list -> state -> state
    30   val update: version_id -> version_id -> edit list -> state ->
    30   val update: version_id -> version_id -> edit list -> state ->
    31     ((command_id * exec_id option) list * (string * command_id option) list) * state
    31     ((command_id * exec_id option) list * (string * command_id option) list) * state
    32   val execute: version_id -> state -> state
    32   val execute: version_id -> state -> state
       
    33   val remove_versions: version_id list -> state -> state
    33   val state: unit -> state
    34   val state: unit -> state
    34   val change_state: (state -> state) -> unit
    35   val change_state: (state -> state) -> unit
    35 end;
    36 end;
    36 
    37 
    37 structure Document: DOCUMENT =
    38 structure Document: DOCUMENT =
   237 abstype state = State of
   238 abstype state = State of
   238  {versions: version Inttab.table,  (*version_id -> document content*)
   239  {versions: version Inttab.table,  (*version_id -> document content*)
   239   commands: (string * Toplevel.transition future) Inttab.table,  (*command_id -> name * transition*)
   240   commands: (string * Toplevel.transition future) Inttab.table,  (*command_id -> name * transition*)
   240   execs: (command_id * (Toplevel.state * unit lazy) lazy) Inttab.table,
   241   execs: (command_id * (Toplevel.state * unit lazy) lazy) Inttab.table,
   241     (*exec_id -> command_id with eval/print process*)
   242     (*exec_id -> command_id with eval/print process*)
   242   execution: Future.group}  (*global execution process*)
   243   execution: version_id * Future.group}  (*current execution process*)
   243 with
   244 with
   244 
   245 
   245 fun make_state (versions, commands, execs, execution) =
   246 fun make_state (versions, commands, execs, execution) =
   246   State {versions = versions, commands = commands, execs = execs, execution = execution};
   247   State {versions = versions, commands = commands, execs = execs, execution = execution};
   247 
   248 
   248 fun map_state f (State {versions, commands, execs, execution}) =
   249 fun map_state f (State {versions, commands, execs, execution}) =
   249   make_state (f (versions, commands, execs, execution));
   250   make_state (f (versions, commands, execs, execution));
   250 
   251 
       
   252 val empty_commands =
       
   253   Inttab.make [(no_id, (Toplevel.name_of Toplevel.empty, Future.value Toplevel.empty))];
       
   254 val empty_execs = Inttab.make [(no_id, (no_id, Lazy.value (Toplevel.toplevel, no_print)))];
       
   255 val empty_execution = (no_id, Future.new_group NONE);
       
   256 
   251 val init_state =
   257 val init_state =
   252   make_state (Inttab.make [(no_id, empty_version)],
   258   make_state (Inttab.make [(no_id, empty_version)], empty_commands, empty_execs, empty_execution);
   253     Inttab.make [(no_id, (Toplevel.name_of Toplevel.empty, Future.value Toplevel.empty))],
       
   254     Inttab.make [(no_id, (no_id, Lazy.value (Toplevel.toplevel, no_print)))],
       
   255     Future.new_group NONE);
       
   256 
   259 
   257 
   260 
   258 (* document versions *)
   261 (* document versions *)
   259 
   262 
   260 fun define_version (id: version_id) version =
   263 fun define_version (id: version_id) version =
   265 
   268 
   266 fun the_version (State {versions, ...}) (id: version_id) =
   269 fun the_version (State {versions, ...}) (id: version_id) =
   267   (case Inttab.lookup versions id of
   270   (case Inttab.lookup versions id of
   268     NONE => err_undef "document version" id
   271     NONE => err_undef "document version" id
   269   | SOME version => version);
   272   | SOME version => version);
       
   273 
       
   274 fun delete_version (id: version_id) versions = Inttab.delete id versions
       
   275   handle Inttab.UNDEF _ => err_undef "document version" id;
   270 
   276 
   271 
   277 
   272 (* commands *)
   278 (* commands *)
   273 
   279 
   274 fun define_command (id: command_id) name text =
   280 fun define_command (id: command_id) name text =
   307   | SOME exec => exec);
   313   | SOME exec => exec);
   308 
   314 
   309 
   315 
   310 (* document execution *)
   316 (* document execution *)
   311 
   317 
   312 fun cancel_execution (State {execution, ...}) = Future.cancel_group execution;
   318 fun cancel_execution (State {execution, ...}) = Future.cancel_group (#2 execution);
   313 
   319 
   314 end;
   320 end;
   315 
   321 
   316 
   322 
   317 
   323 
   551                 if #1 (get_perspective node) command_id
   557                 if #1 (get_perspective node) command_id
   552                 then ignore (Lazy.future Future.default_params print)
   558                 then ignore (Lazy.future Future.default_params print)
   553                 else ();
   559                 else ();
   554             in () end;
   560             in () end;
   555 
   561 
   556       val execution = Future.new_group NONE;
   562       val group = Future.new_group NONE;
   557       val _ =
   563       val _ =
   558         nodes_of version |> Graph.schedule
   564         nodes_of version |> Graph.schedule
   559           (fn deps => fn (name, node) =>
   565           (fn deps => fn (name, node) =>
   560             (singleton o Future.forks)
   566             (singleton o Future.forks)
   561               {name = "theory:" ^ name, group = SOME (Future.new_group (SOME execution)),
   567               {name = "theory:" ^ name, group = SOME (Future.new_group (SOME group)),
   562                 deps = map (Future.task_of o #2) deps, pri = 1, interrupts = false}
   568                 deps = map (Future.task_of o #2) deps, pri = 1, interrupts = false}
   563               (iterate_entries (fn (_, exec) => fn () => SOME (force_exec node exec)) node));
   569               (iterate_entries (fn (_, exec) => fn () => SOME (force_exec node exec)) node));
   564 
   570 
   565     in (versions, commands, execs, execution) end);
   571     in (versions, commands, execs, (version_id, group)) end);
       
   572 
       
   573 
       
   574 (* remove versions *)
       
   575 
       
   576 fun remove_versions ids state = state |> map_state (fn (versions, _, _, execution) =>
       
   577   let
       
   578     val _ = member (op =) ids (#1 execution) andalso
       
   579       error ("Attempt to remove execution version " ^ print_id (#1 execution));
       
   580 
       
   581     val versions' = fold delete_version ids versions;
       
   582     val (commands', execs') =
       
   583       (versions', (empty_commands, empty_execs)) |->
       
   584         Inttab.fold (fn (_, version) => nodes_of version |>
       
   585           Graph.fold (fn (_, (node, _)) => node |>
       
   586             iterate_entries (fn ((_, id), exec) => fn (commands, execs) =>
       
   587               let
       
   588                 val commands' = Inttab.insert (K true) (id, the_command state id) commands;
       
   589                 val execs' =
       
   590                   (case exec of
       
   591                     NONE => execs
       
   592                   | SOME exec_id => Inttab.insert (K true) (exec_id, the_exec state exec_id) execs);
       
   593               in SOME (commands', execs') end)));
       
   594   in (versions', commands', execs', execution) end);
   566 
   595 
   567 
   596 
   568 
   597 
   569 (** global state **)
   598 (** global state **)
   570 
   599