238 |
238 |
239 (** global state -- document structure and execution process **) |
239 (** global state -- document structure and execution process **) |
240 |
240 |
241 abstype state = State of |
241 abstype state = State of |
242 {versions: version Inttab.table, (*version_id -> document content*) |
242 {versions: version Inttab.table, (*version_id -> document content*) |
243 commands: (string * Toplevel.transition future) Inttab.table, (*command_id -> name * transition*) |
243 commands: (string * Token.T list future) Inttab.table, (*command_id -> name * span*) |
244 execution: version_id * Future.group} (*current execution process*) |
244 execution: version_id * Future.group} (*current execution process*) |
245 with |
245 with |
246 |
246 |
247 fun make_state (versions, commands, execution) = |
247 fun make_state (versions, commands, execution) = |
248 State {versions = versions, commands = commands, execution = execution}; |
248 State {versions = versions, commands = commands, execution = execution}; |
271 handle Inttab.UNDEF _ => err_undef "document version" id; |
271 handle Inttab.UNDEF _ => err_undef "document version" id; |
272 |
272 |
273 |
273 |
274 (* commands *) |
274 (* commands *) |
275 |
275 |
|
276 fun tokenize_command id text = |
|
277 Position.setmp_thread_data (Position.id_only id) |
|
278 (fn () => Thy_Syntax.parse_tokens (#1 (Outer_Syntax.get_syntax ())) (Position.id id) text) (); |
|
279 |
276 fun define_command (id: command_id) name text = |
280 fun define_command (id: command_id) name text = |
277 map_state (fn (versions, commands, execution) => |
281 map_state (fn (versions, commands, execution) => |
278 let |
282 let |
279 val id_string = print_id id; |
|
280 val future = |
283 val future = |
281 (singleton o Future.forks) |
284 (singleton o Future.forks) |
282 {name = "Document.define_command", group = SOME (Future.new_group NONE), |
285 {name = "Document.define_command", group = SOME (Future.new_group NONE), |
283 deps = [], pri = ~1, interrupts = false} |
286 deps = [], pri = ~1, interrupts = false} |
284 (fn () => |
287 (fn () => tokenize_command (print_id id) text); |
285 Position.setmp_thread_data (Position.id_only id_string) |
|
286 (fn () => Outer_Syntax.read_command (Position.id id_string) text) ()); |
|
287 val commands' = |
288 val commands' = |
288 Inttab.update_new (id, (name, future)) commands |
289 Inttab.update_new (id, (name, future)) commands |
289 handle Inttab.DUP dup => err_dup "command" dup; |
290 handle Inttab.DUP dup => err_dup "command" dup; |
290 in (versions, commands', execution) end); |
291 in (versions, commands', execution) end); |
291 |
292 |
406 |
407 |
407 fun new_exec state bad_init command_id' (execs, command_exec, init) = |
408 fun new_exec state bad_init command_id' (execs, command_exec, init) = |
408 if bad_init andalso is_none init then NONE |
409 if bad_init andalso is_none init then NONE |
409 else |
410 else |
410 let |
411 let |
411 val (name, tr0) = the_command state command_id' ||> Future.join; |
412 val (name, span) = the_command state command_id' ||> Future.join; |
412 val (modify_init, init') = |
413 val (modify_init, init') = |
413 if Keyword.is_theory_begin name then |
414 if Keyword.is_theory_begin name then |
414 (Toplevel.modify_init (the_default illegal_init init), NONE) |
415 (Toplevel.modify_init (the_default illegal_init init), NONE) |
415 else (I, init); |
416 else (I, init); |
416 val exec_id' = new_id (); |
417 val exec_id' = new_id (); |
417 val tr = tr0 |
418 val exec_id'_string = print_id exec_id'; |
418 |> modify_init |
419 val tr = |
419 |> Toplevel.put_id (print_id exec_id'); |
420 Position.setmp_thread_data (Position.id_only exec_id'_string) |
420 val exec' = snd (snd command_exec) |> Lazy.map (fn (st, _) => run_command tr st); |
421 (fn () => |
|
422 #1 (Outer_Syntax.read_span (#2 (Outer_Syntax.get_syntax ())) span) |
|
423 |> modify_init |
|
424 |> Toplevel.put_id exec_id'_string); |
|
425 val exec' = snd (snd command_exec) |> Lazy.map (fn (st, _) => run_command (tr ()) st); |
421 val command_exec' = (command_id', (exec_id', exec')); |
426 val command_exec' = (command_id', (exec_id', exec')); |
422 in SOME (command_exec' :: execs, command_exec', init') end; |
427 in SOME (command_exec' :: execs, command_exec', init') end; |
423 |
428 |
424 fun make_required nodes = |
429 fun make_required nodes = |
425 let |
430 let |