22 Header of node_header | |
22 Header of node_header | |
23 Perspective of command_id list |
23 Perspective of command_id list |
24 type edit = string * node_edit |
24 type edit = string * node_edit |
25 type state |
25 type state |
26 val init_state: state |
26 val init_state: state |
27 val define_command: command_id -> string -> state -> state |
27 val define_command: command_id -> string -> string -> state -> state |
28 val join_commands: state -> state |
28 val join_commands: state -> state |
29 val cancel_execution: state -> Future.task list |
29 val cancel_execution: state -> Future.task list |
30 val update_perspective: version_id -> version_id -> string -> command_id list -> state -> state |
30 val update_perspective: version_id -> version_id -> string -> command_id list -> state -> state |
31 val update: version_id -> version_id -> edit list -> state -> |
31 val update: version_id -> version_id -> edit list -> state -> |
32 ((command_id * exec_id option) list * (string * command_id option) list) * state |
32 ((command_id * exec_id option) list * (string * command_id option) list) * state |
231 (** global state -- document structure and execution process **) |
231 (** global state -- document structure and execution process **) |
232 |
232 |
233 abstype state = State of |
233 abstype state = State of |
234 {versions: version Inttab.table, (*version_id -> document content*) |
234 {versions: version Inttab.table, (*version_id -> document content*) |
235 commands: |
235 commands: |
236 Toplevel.transition future Inttab.table * (*command_id -> transition (future parsing)*) |
236 (string * Toplevel.transition future) Inttab.table * (*command_id -> name * transition*) |
237 Toplevel.transition future list, (*recent commands to be joined*) |
237 Toplevel.transition future list, (*recent commands to be joined*) |
238 execs: (command_id * (Toplevel.state * unit lazy) lazy) Inttab.table, |
238 execs: (command_id * (Toplevel.state * unit lazy) lazy) Inttab.table, |
239 (*exec_id -> command_id with eval/print process*) |
239 (*exec_id -> command_id with eval/print process*) |
240 execution: Future.group} (*global execution process*) |
240 execution: Future.group} (*global execution process*) |
241 with |
241 with |
246 fun map_state f (State {versions, commands, execs, execution}) = |
246 fun map_state f (State {versions, commands, execs, execution}) = |
247 make_state (f (versions, commands, execs, execution)); |
247 make_state (f (versions, commands, execs, execution)); |
248 |
248 |
249 val init_state = |
249 val init_state = |
250 make_state (Inttab.make [(no_id, empty_version)], |
250 make_state (Inttab.make [(no_id, empty_version)], |
251 (Inttab.make [(no_id, Future.value Toplevel.empty)], []), |
251 (Inttab.make [(no_id, (Toplevel.name_of Toplevel.empty, Future.value Toplevel.empty))], []), |
252 Inttab.make [(no_id, (no_id, Lazy.value (Toplevel.toplevel, no_print)))], |
252 Inttab.make [(no_id, (no_id, Lazy.value (Toplevel.toplevel, no_print)))], |
253 Future.new_group NONE); |
253 Future.new_group NONE); |
254 |
254 |
255 |
255 |
256 (* document versions *) |
256 (* document versions *) |
267 | SOME version => version); |
267 | SOME version => version); |
268 |
268 |
269 |
269 |
270 (* commands *) |
270 (* commands *) |
271 |
271 |
272 fun define_command (id: command_id) text = |
272 fun define_command (id: command_id) name text = |
273 map_state (fn (versions, (commands, recent), execs, execution) => |
273 map_state (fn (versions, (commands, recent), execs, execution) => |
274 let |
274 let |
275 val id_string = print_id id; |
275 val id_string = print_id id; |
276 val tr = |
276 val tr = |
277 Future.fork_pri 2 (fn () => |
277 Future.fork_pri 2 (fn () => |
278 Position.setmp_thread_data (Position.id_only id_string) |
278 Position.setmp_thread_data (Position.id_only id_string) |
279 (fn () => Outer_Syntax.read_command (Position.id id_string) text) ()); |
279 (fn () => Outer_Syntax.read_command (Position.id id_string) text) ()); |
280 val commands' = |
280 val commands' = |
281 Inttab.update_new (id, tr) commands |
281 Inttab.update_new (id, (name, tr)) commands |
282 handle Inttab.DUP dup => err_dup "command" dup; |
282 handle Inttab.DUP dup => err_dup "command" dup; |
283 in (versions, (commands', tr :: recent), execs, execution) end); |
283 in (versions, (commands', tr :: recent), execs, execution) end); |
284 |
284 |
285 fun the_command (State {commands, ...}) (id: command_id) = |
285 fun the_command (State {commands, ...}) (id: command_id) = |
286 (case Inttab.lookup (#1 commands) id of |
286 (case Inttab.lookup (#1 commands) id of |
287 NONE => err_undef "command" id |
287 NONE => err_undef "command" id |
288 | SOME tr => tr); |
288 | SOME command => command); |
289 |
289 |
290 val join_commands = |
290 val join_commands = |
291 map_state (fn (versions, (commands, recent), execs, execution) => |
291 map_state (fn (versions, (commands, recent), execs, execution) => |
292 (Future.join_results recent; (versions, (commands, []), execs, execution))); |
292 (Future.join_results recent; (versions, (commands, []), execs, execution))); |
293 |
293 |
398 val visible' = visible andalso common' <> last_visible; |
398 val visible' = visible andalso common' <> last_visible; |
399 in (common', visible') end; |
399 in (common', visible') end; |
400 |
400 |
401 fun new_exec state init command_id' (execs, exec) = |
401 fun new_exec state init command_id' (execs, exec) = |
402 let |
402 let |
403 val command' = the_command state command_id'; |
403 val (_, tr0) = the_command state command_id'; |
404 val exec_id' = new_id (); |
404 val exec_id' = new_id (); |
405 val exec' = |
405 val exec' = |
406 snd exec |> Lazy.map (fn (st, _) => |
406 snd exec |> Lazy.map (fn (st, _) => |
407 let val tr = |
407 let val tr = |
408 Future.join command' |
408 Future.join tr0 |
409 |> Toplevel.modify_init init |
409 |> Toplevel.modify_init init |
410 |> Toplevel.put_id (print_id exec_id'); |
410 |> Toplevel.put_id (print_id exec_id'); |
411 in run_command tr st end) |
411 in run_command tr st end) |
412 |> pair command_id'; |
412 |> pair command_id'; |
413 in ((exec_id', exec') :: execs, exec') end; |
413 in ((exec_id', exec') :: execs, exec') end; |