239 |
239 |
240 end; |
240 end; |
241 |
241 |
242 |
242 |
243 |
243 |
244 (** global state -- document structure and execution process **) |
244 (** document state -- content structure and execution process **) |
245 |
245 |
246 abstype state = State of |
246 abstype state = State of |
247 {versions: version Inttab.table, (*version_id -> document content*) |
247 {versions: version Inttab.table, (*version_id -> document content*) |
248 commands: (string * Token.T list lazy) Inttab.table, (*command_id -> named span*) |
248 commands: (string * Token.T list lazy) Inttab.table, (*command_id -> named span*) |
249 execution: version_id * Future.group * bool Unsynchronized.ref} (*current execution process*) |
249 execution: version_id * Future.group * bool Unsynchronized.ref} (*current execution process*) |
314 fun execute version_id state = |
314 fun execute version_id state = |
315 state |> map_state (fn (versions, commands, _) => |
315 state |> map_state (fn (versions, commands, _) => |
316 let |
316 let |
317 val version = the_version state version_id; |
317 val version = the_version state version_id; |
318 |
318 |
|
319 fun run node command_id exec = |
|
320 let |
|
321 val (_, print) = Command.memo_eval exec; |
|
322 val _ = |
|
323 if visible_command node command_id |
|
324 then ignore (Lazy.future Future.default_params print) |
|
325 else (); |
|
326 in () end; |
|
327 |
319 val group = Future.new_group NONE; |
328 val group = Future.new_group NONE; |
320 val running = Unsynchronized.ref true; |
329 val running = Unsynchronized.ref true; |
321 |
|
322 fun run _ _ NONE = () |
|
323 | run node command_id (SOME (_, exec)) = |
|
324 let |
|
325 val (_, print) = Command.memo_eval exec; |
|
326 val _ = |
|
327 if visible_command node command_id |
|
328 then ignore (Lazy.future Future.default_params print) |
|
329 else (); |
|
330 in () end; |
|
331 |
330 |
332 val _ = |
331 val _ = |
333 nodes_of version |> Graph.schedule |
332 nodes_of version |> Graph.schedule |
334 (fn deps => fn (name, node) => |
333 (fn deps => fn (name, node) => |
335 if not (visible_node node) andalso finished_theory node then |
334 if not (visible_node node) andalso finished_theory node then |
337 else |
336 else |
338 (singleton o Future.forks) |
337 (singleton o Future.forks) |
339 {name = "theory:" ^ name, group = SOME (Future.new_group (SOME group)), |
338 {name = "theory:" ^ name, group = SOME (Future.new_group (SOME group)), |
340 deps = map (Future.task_of o #2) deps, pri = 1, interrupts = false} |
339 deps = map (Future.task_of o #2) deps, pri = 1, interrupts = false} |
341 (fn () => |
340 (fn () => |
342 iterate_entries (fn ((_, id), exec) => fn () => |
341 iterate_entries (fn ((_, id), opt_exec) => fn () => |
343 if ! running then SOME (run node id exec) else NONE) node ())); |
342 (case opt_exec of |
|
343 SOME (_, exec) => if ! running then SOME (run node id exec) else NONE |
|
344 | NONE => NONE)) node ())); |
344 |
345 |
345 in (versions, commands, (version_id, group, running)) end); |
346 in (versions, commands, (version_id, group, running)) end); |
346 |
347 |
347 |
348 |
348 |
349 |