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 join_commands: state -> unit |
28 val join_commands: state -> unit |
28 val cancel_execution: state -> Future.task list |
29 val cancel_execution: state -> Future.task list |
29 val define_command: command_id -> string -> state -> state |
|
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 edit: version_id -> version_id -> edit list -> state -> (command_id * exec_id) list * state |
31 val edit: version_id -> version_id -> edit list -> state -> (command_id * exec_id) list * state |
32 val execute: version_id -> state -> state |
32 val execute: version_id -> state -> state |
33 val state: unit -> state |
33 val state: unit -> state |
34 val change_state: (state -> state) -> unit |
34 val change_state: (state -> state) -> unit |
73 Node {header = header, perspective = perspective, entries = entries, result = result}; |
73 Node {header = header, perspective = perspective, entries = entries, result = result}; |
74 |
74 |
75 fun map_node f (Node {header, perspective, entries, result}) = |
75 fun map_node f (Node {header, perspective, entries, result}) = |
76 make_node (f (header, perspective, entries, result)); |
76 make_node (f (header, perspective, entries, result)); |
77 |
77 |
78 val no_perspective: perspective = (K false, []); |
78 fun make_perspective ids : perspective = |
|
79 (Inttab.defined (Inttab.make (map (rpair ()) ids)), ids); |
|
80 |
|
81 val no_perspective = make_perspective []; |
79 val no_print = Lazy.value (); |
82 val no_print = Lazy.value (); |
80 val no_result = Lazy.value Toplevel.toplevel; |
83 val no_result = Lazy.value Toplevel.toplevel; |
81 |
84 |
82 val empty_node = |
85 val empty_node = |
83 make_node (Exn.Exn (ERROR "Bad theory header"), no_perspective, Entries.empty, no_result); |
86 make_node (Exn.Exn (ERROR "Bad theory header"), no_perspective, Entries.empty, no_result); |
91 fun get_header (Node {header, ...}) = header; |
94 fun get_header (Node {header, ...}) = header; |
92 fun set_header header = |
95 fun set_header header = |
93 map_node (fn (_, perspective, entries, result) => (header, perspective, entries, result)); |
96 map_node (fn (_, perspective, entries, result) => (header, perspective, entries, result)); |
94 |
97 |
95 fun get_perspective (Node {perspective, ...}) = perspective; |
98 fun get_perspective (Node {perspective, ...}) = perspective; |
96 fun set_perspective perspective = |
99 fun set_perspective ids = |
97 let val pred = Inttab.defined (Inttab.make (map (rpair ()) perspective)) in |
100 map_node (fn (header, _, entries, result) => (header, make_perspective ids, entries, result)); |
98 map_node (fn (header, _, entries, result) => (header, (pred, perspective), entries, result)) |
|
99 end; |
|
100 |
101 |
101 fun map_entries f (Node {header, perspective, entries, result}) = |
102 fun map_entries f (Node {header, perspective, entries, result}) = |
102 make_node (header, perspective, f entries, result); |
103 make_node (header, perspective, f entries, result); |
103 fun fold_entries start f (Node {entries, ...}) = Entries.fold start f entries; |
104 fun fold_entries start f (Node {entries, ...}) = Entries.fold start f entries; |
104 fun first_entry start P (Node {entries, ...}) = Entries.get_first start P entries; |
105 fun first_entry start P (Node {entries, ...}) = Entries.get_first start P entries; |
343 fun is_changed node' ((_, id), exec) = |
344 fun is_changed node' ((_, id), exec) = |
344 (case try (the_entry node') id of |
345 (case try (the_entry node') id of |
345 NONE => true |
346 NONE => true |
346 | SOME exec' => exec' <> exec); |
347 | SOME exec' => exec' <> exec); |
347 |
348 |
348 fun init_theory deps (name, node) = |
349 fun init_theory deps name node = |
349 let |
350 let |
350 val (thy_name, imports, uses) = Exn.release (get_header node); |
351 val (thy_name, imports, uses) = Exn.release (get_header node); |
351 (* FIXME provide files via Scala layer *) |
352 (* FIXME provide files via Scala layer *) |
352 val (dir, files) = |
353 val (dir, files) = |
353 if ML_System.platform_is_cygwin then (Path.current, []) |
354 if ML_System.platform_is_cygwin then (Path.current, []) |
354 else (Path.dir (Path.explode name), map (apfst Path.explode) uses); |
355 else (Path.dir (Path.explode name), map (apfst Path.explode) uses); |
355 |
356 |
356 val parents = |
357 val parents = |
357 imports |> map (fn import => |
358 imports |> map (fn import => |
358 (case Thy_Info.lookup_theory import of |
359 (case Thy_Info.lookup_theory import of (* FIXME more robust!? *) |
359 SOME thy => thy |
360 SOME thy => thy |
360 | NONE => |
361 | NONE => |
361 get_theory (Position.file_only import) |
362 get_theory (Position.file_only import) |
362 (#2 (Future.join (the (AList.lookup (op =) deps import)))))); |
363 (#2 (Future.join (the (AList.lookup (op =) deps import)))))); |
363 in Thy_Load.begin_theory dir thy_name imports files parents end; |
364 in Thy_Load.begin_theory dir thy_name imports files parents end; |
364 |
365 |
365 fun new_exec (command_id, command) (assigns, execs, exec) = |
366 fun new_exec state init command_id (assigns, execs, exec) = |
366 let |
367 let |
|
368 val command = the_command state command_id; |
367 val exec_id' = new_id (); |
369 val exec_id' = new_id (); |
368 val exec' = exec |> Lazy.map (fn (st, _) => |
370 val exec' = exec |> Lazy.map (fn (st, _) => |
369 let val tr = Toplevel.put_id (print_id exec_id') (Future.join command) |
371 let val tr = |
|
372 Future.join command |
|
373 |> Toplevel.modify_init init |
|
374 |> Toplevel.put_id (print_id exec_id'); |
370 in run_command tr st end); |
375 in run_command tr st end); |
371 in ((command_id, exec_id') :: assigns, (exec_id', (command_id, exec')) :: execs, exec') end; |
376 in ((command_id, exec_id') :: assigns, (exec_id', (command_id, exec')) :: execs, exec') end; |
372 |
377 |
373 in |
378 in |
374 |
379 |
383 (fn deps => fn (name, node) => |
388 (fn deps => fn (name, node) => |
384 (case first_entry NONE (is_changed (node_of old_version name)) node of |
389 (case first_entry NONE (is_changed (node_of old_version name)) node of |
385 NONE => Future.value (([], [], []), node) |
390 NONE => Future.value (([], [], []), node) |
386 | SOME ((prev, id), _) => |
391 | SOME ((prev, id), _) => |
387 let |
392 let |
388 fun init () = init_theory deps (name, node); |
393 fun init () = init_theory deps name node; |
389 fun get_command id = |
|
390 (id, the_command state id |> Future.map (Toplevel.modify_init init)); |
|
391 in |
394 in |
392 (singleton o Future.forks) |
395 (singleton o Future.forks) |
393 {name = "Document.edit", group = NONE, |
396 {name = "Document.edit", group = NONE, |
394 deps = map (Future.task_of o #2) deps, pri = 2, interrupts = false} |
397 deps = map (Future.task_of o #2) deps, pri = 2, interrupts = false} |
395 (fn () => |
398 (fn () => |
397 val prev_exec = |
400 val prev_exec = |
398 (case prev of |
401 (case prev of |
399 NONE => no_id |
402 NONE => no_id |
400 | SOME prev_id => the_default no_id (the_entry node prev_id)); |
403 | SOME prev_id => the_default no_id (the_entry node prev_id)); |
401 val (assigns, execs, last_exec) = |
404 val (assigns, execs, last_exec) = |
402 fold_entries (SOME id) (new_exec o get_command o #2 o #1) |
405 fold_entries (SOME id) (new_exec state init o #2 o #1) |
403 node ([], [], #2 (the_exec state prev_exec)); |
406 node ([], [], #2 (the_exec state prev_exec)); |
404 val node' = node |
407 val node' = node |
405 |> fold update_entry assigns |
408 |> fold update_entry assigns |
406 |> set_result (Lazy.map #1 last_exec); |
409 |> set_result (Lazy.map #1 last_exec); |
407 in ((assigns, execs, [(name, node')]), node') end) |
410 in ((assigns, execs, [(name, node')]), node') end) |