src/Pure/PIDE/document.ML
changeset 38421 6cfc6fce7bfb
parent 38419 f9dc924e54f8
child 38448 62d16c415019
equal deleted inserted replaced
38420:7bdf6c79a2db 38421:6cfc6fce7bfb
   157 
   157 
   158 
   158 
   159 (** global state -- document structure and execution process **)
   159 (** global state -- document structure and execution process **)
   160 
   160 
   161 abstype state = State of
   161 abstype state = State of
   162  {versions: version Inttab.table,                   (*version_id -> document content*)
   162  {versions: version Inttab.table,                     (*version_id -> document content*)
   163   commands: Toplevel.transition Inttab.table,       (*command_id -> transition function*)
   163   commands: Toplevel.transition future Inttab.table,  (*command_id -> transition (future parsing)*)
   164   execs: Toplevel.state option lazy Inttab.table,   (*exec_id -> execution process*)
   164   execs: Toplevel.state option lazy Inttab.table,     (*exec_id -> execution process*)
   165   execution: unit future list}                      (*global execution process*)
   165   execution: unit future list}                        (*global execution process*)
   166 with
   166 with
   167 
   167 
   168 fun make_state (versions, commands, execs, execution) =
   168 fun make_state (versions, commands, execs, execution) =
   169   State {versions = versions, commands = commands, execs = execs, execution = execution};
   169   State {versions = versions, commands = commands, execs = execs, execution = execution};
   170 
   170 
   171 fun map_state f (State {versions, commands, execs, execution}) =
   171 fun map_state f (State {versions, commands, execs, execution}) =
   172   make_state (f (versions, commands, execs, execution));
   172   make_state (f (versions, commands, execs, execution));
   173 
   173 
   174 val init_state =
   174 val init_state =
   175   make_state (Inttab.make [(no_id, empty_version)],
   175   make_state (Inttab.make [(no_id, empty_version)],
   176     Inttab.make [(no_id, Toplevel.empty)],
   176     Inttab.make [(no_id, Future.value Toplevel.empty)],
   177     Inttab.make [(no_id, Lazy.value (SOME Toplevel.toplevel))],
   177     Inttab.make [(no_id, Lazy.value (SOME Toplevel.toplevel))],
   178     []);
   178     []);
   179 
   179 
   180 
   180 
   181 (* document versions *)
   181 (* document versions *)
   196 
   196 
   197 fun define_command (id: command_id) text =
   197 fun define_command (id: command_id) text =
   198   map_state (fn (versions, commands, execs, execution) =>
   198   map_state (fn (versions, commands, execs, execution) =>
   199     let
   199     let
   200       val id_string = print_id id;
   200       val id_string = print_id id;
   201       val tr =
   201       val tr = Future.fork_pri 2 (fn () =>
   202         Position.setmp_thread_data (Position.id_only id_string)
   202         Position.setmp_thread_data (Position.id_only id_string)
   203           (fn () => Outer_Syntax.prepare_command (Position.id id_string) text) ();
   203           (fn () => Outer_Syntax.prepare_command (Position.id id_string) text) ());
   204       val commands' =
   204       val commands' =
   205         Inttab.update_new (id, Toplevel.put_id id_string tr) commands
   205         Inttab.update_new (id, tr) commands
   206           handle Inttab.DUP dup => err_dup "command" dup;
   206           handle Inttab.DUP dup => err_dup "command" dup;
   207     in (versions, commands', execs, execution) end);
   207     in (versions, commands', execs, execution) end);
   208 
   208 
   209 fun the_command (State {commands, ...}) (id: command_id) =
   209 fun the_command (State {commands, ...}) (id: command_id) =
   210   (case Inttab.lookup commands id of
   210   (case Inttab.lookup commands id of
   211     NONE => err_undef "command" id
   211     NONE => err_undef "command" id
   212   | SOME tr => tr);
   212   | SOME tr => tr);
       
   213 
       
   214 fun join_commands (State {commands, ...}) =
       
   215   Inttab.fold (fn (_, tr) => fn () => ignore (Future.join_result tr)) commands ();
   213 
   216 
   214 
   217 
   215 (* command executions *)
   218 (* command executions *)
   216 
   219 
   217 fun define_exec (id: exec_id) exec =
   220 fun define_exec (id: exec_id) exec =
   242 
   245 
   243 fun new_exec name (id: command_id) (exec_id, updates, state) =
   246 fun new_exec name (id: command_id) (exec_id, updates, state) =
   244   let
   247   let
   245     val exec = the_exec state exec_id;
   248     val exec = the_exec state exec_id;
   246     val exec_id' = new_id ();
   249     val exec_id' = new_id ();
   247     val tr = Toplevel.put_id (print_id exec_id') (the_command state id);
   250     val tr = the_command state id;
   248     val exec' =
   251     val exec' =
   249       Lazy.lazy (fn () =>
   252       Lazy.lazy (fn () =>
   250         (case Lazy.force exec of
   253         (case Lazy.force exec of
   251           NONE => NONE
   254           NONE => NONE
   252         | SOME st => Toplevel.run_command name tr st));
   255         | SOME st =>
       
   256             let val exec_tr = Toplevel.put_id (print_id exec_id') (Future.join tr)
       
   257             in Toplevel.run_command name exec_tr st end));
   253     val state' = define_exec exec_id' exec' state;
   258     val state' = define_exec exec_id' exec' state;
   254   in (exec_id', (id, exec_id') :: updates, state') end;
   259   in (exec_id', (id, exec_id') :: updates, state') end;
   255 
   260 
   256 in
   261 in
   257 
   262 
   275 
   280 
   276     (* FIXME proper node deps *)
   281     (* FIXME proper node deps *)
   277     val (rev_updates, new_version', state') =
   282     val (rev_updates, new_version', state') =
   278       fold update_node (node_names_of new_version) ([], new_version, state);
   283       fold update_node (node_names_of new_version) ([], new_version, state);
   279     val state'' = define_version new_id new_version' state';
   284     val state'' = define_version new_id new_version' state';
       
   285 
       
   286     val _ = join_commands state'';  (* FIXME async!? *)
   280   in (rev rev_updates, state'') end;
   287   in (rev rev_updates, state'') end;
   281 
   288 
   282 end;
   289 end;
   283 
   290 
   284 
   291