fun blob_file src_path lines digest file_node = let val file_pos =
Position.file file_node |>
(case Position.id_of (Position.thread_data ()) of
NONE => I
| SOME exec_id => Position.put_id exec_id); in {src_path = src_path, lines = lines, digest = digest, pos = file_pos} end
fun resolve_files master_dir (blobs, blobs_index) toks =
(case Outer_Syntax.parse_spans toks of
[Command_Span.Span (Command_Span.Command_Span _, _)] =>
(casetry (nth toks) blobs_index of
SOME tok => let val source = Token.input_of tok; val pos = Input.pos_of source; val delimited = Input.is_delimited source;
fun make_file (Exn.Res {file_node, src_path, content}) = letval _ = Position.report pos (Markup.language_path delimited) in case content of
NONE =>
Exn.result (fn () =>
Resources.read_file_node file_node master_dir (src_path, pos)) ()
| SOME (digest, lines) => Exn.Res (blob_file src_path lines digest file_node) end
| make_file (Exn.Exn e) = Exn.Exn e; val files = map make_file blobs; in
toks |> map_index (fn (i, tok) => if i = blobs_index then Token.put_files files tok else tok) end
| NONE => toks)
| _ => toks);
fun reports_of_token keywords tok = let val malformed_symbols =
Input.source_explode (Token.input_of tok)
|> map_filter (fn (sym, pos) => if Symbol.is_malformed sym then SOME ((pos, Markup.bad ()), "Malformed symbolic character") else NONE); val is_malformed = Token.is_error tok orelse not (null malformed_symbols); val reports = Token.reports keywords tok @ Token.completion_report tok @ malformed_symbols; in (is_malformed, reports) end;
in
fun read_thy st = Toplevel.theory_of st handle Toplevel.UNDEF => Pure_Syn.bootstrap_thy;
fun read keywords thy master_dir init blobs_info span = let val command_reports = Outer_Syntax.command_reports thy; val token_reports = map (reports_of_token keywords) span; val _ = Position.reports_text (maps #2 token_reports @ maps command_reports span);
val core_range = Token.core_range_of span; val tr = ifexists #1 token_reports then Toplevel.malformed (#1 core_range) "Malformed command syntax" else Outer_Syntax.parse_span thy init (resolve_files master_dir blobs_info span); val _ = if Toplevel.is_ignored tr orelse Toplevel.is_malformed tr then () else let val name = Toplevel.name_of tr; val kind = the_default "" (Keyword.command_kind (Thy_Header.get_keywords thy) name); val is_begin = exists Token.is_begin span; val markup = Markup.command_span {name = name, kind = kind, is_begin = is_begin}; in Position.report (#1 core_range) markup end; in tr end;
end;
fun read_span keywords st master_dir init =
Command_Span.content #> read keywords (read_thy st) master_dir init ([], ~1);
(* eval *)
type eval_state = {failed: bool, command: Toplevel.transition, state: Toplevel.state};
fun init_eval_state opt_thy =
{failed = false,
command = Toplevel.empty,
state = Toplevel.make_state opt_thy};
fun eval_command_id (Eval {command_id, ...}) = command_id;
fun eval_exec_id (Eval {exec_id, ...}) = exec_id; val eval_eq = op = o apply2 eval_exec_id;
val eval_running = Execution.is_running_exec o eval_exec_id; fun eval_finished (Eval {eval_process, ...}) = Lazy.is_finished eval_process;
fun eval_result (Eval {eval_process, ...}) =
Exn.release (Lazy.finished_result eval_process);
val eval_result_command = #command o eval_result; val eval_result_state = #state o eval_result;
local
fun reset_state keywords tr st0 = Toplevel.setmp_thread_position tr (fn () => let val name = Toplevel.name_of tr; val res = if Keyword.is_theory_body keywords name then Toplevel.reset_theory st0 elseif Keyword.is_proof keywords name then Toplevel.reset_proof st0 elseif Keyword.is_theory_end keywords name then
(case Toplevel.reset_notepad st0 of
NONE => Toplevel.reset_theory st0
| some => some) else NONE; in
(case res of
NONE => st0
| SOME st => (Output.error_message (Toplevel.type_error tr ^ " -- using reset state"); st)) end) ();
fun run keywords int tr st = if Future.proofs_enabled 1 andalso Keyword.is_diag keywords (Toplevel.name_of tr) then let val (tr1, tr2) = Toplevel.fork_presentation tr; val _ =
Execution.fork {name = "Toplevel.diag", pos = Toplevel.pos_of tr, pri = ~1}
(fn () => Toplevel.command_exception int tr1 st); in Toplevel.command_errors int tr2 st end else Toplevel.command_errors int tr st;
fun check_comments ctxt =
Document_Output.check_comments ctxt o Input.source_explode o Token.input_of;
fun check_token_comments ctxt tok =
(case Exn.result (fn () => check_comments ctxt tok) () of
Exn.Res () => []
| Exn.Exn exn => Runtime.exn_messages exn);
fun report_indent tr st =
(casetry Toplevel.proof_of st of
SOME prf => letval keywords = Thy_Header.get_keywords (Proof.theory_of prf) in if Keyword.command_kind keywords (Toplevel.name_of tr) = SOME Keyword.prf_script then
(casetry (Thm.nprems_of o #goal o Proof.goal) prf of
NONE => ()
| SOME 0 => ()
| SOME n => letval report = YXML.output_markup_only (Markup.command_indent (n - 1)); in Toplevel.setmp_thread_position tr (fn () => Output.report [report]) () end) else () end
| NONE => ());
fun status tr m =
Toplevel.setmp_thread_position tr (fn () => Output.status [YXML.output_markup_only m]) ();
fun eval_state keywords span tr ({state, ...}: eval_state) = let val _ = Isabelle_Thread.expose_interrupt ();
val st = reset_state keywords tr state;
val _ = report_indent tr st; val _ = status tr Markup.running; val (errs1, result) = run keywords true tr st; val errs2 =
(case result of
NONE => []
| SOME st' => check_span_comments (Toplevel.presentation_context st') span tr); val errs = errs1 @ errs2; val _ = List.app (Future.error_message (Toplevel.pos_of tr)) errs; in
(case result of
NONE => let val _ = status tr Markup.failed; val _ = status tr Markup.finished; val _ = if null errs then (status tr Markup.canceled; Isabelle_Thread.raise_interrupt ()) else (); in {failed = true, command = tr, state = st} end
| SOME st' => let val _ = if Keyword.is_theory_end keywords (Toplevel.name_of tr) andalso
can (Toplevel.end_theory Position.none) st' then status tr Markup.finalized else (); val _ = status tr Markup.finished; in {failed = false, command = tr, state = st'} end) end;
in
fun eval keywords master_dir init blobs_info command_id span eval0 = let val exec_id = Document_ID.make (); funprocess () = let val eval_state0 = eval_result eval0; val thy = read_thy (#state eval_state0); val tr =
Position.setmp_thread_data (Position.id_only (Document_ID.print exec_id))
(fn () =>
read keywords thy master_dir init blobs_info span |> Toplevel.exec_id exec_id) (); in eval_state keywords span tr eval_state0 end; in
Eval {command_id = command_id, exec_id = exec_id,
eval_process = Lazy.lazy_name "Command.eval"process} end;
fun run_process execution_id exec_id process = letval group = Future.worker_subgroup () in if Execution.running execution_id exec_id [group] then
ignore (task_context group (fn () => Lazy.force_result {strict = true} process) ()) else () end;
fun ignore_process process =
Lazy.is_running process orelse Lazy.is_finished process;
fun run_eval execution_id (Eval {exec_id, eval_process, ...}) = if Lazy.is_finished eval_process then () else run_process execution_id exec_id eval_process;
fun fork_print execution_id deps (Print {name, delay, pri, exec_id, print_process, ...}) = let val group = Future.worker_subgroup (); fun fork () =
ignore ((singleton o Future.forks)
{name = name, group = SOME group, deps = deps, pri = pri, interrupts = true}
(fn () => if ignore_process print_process then () else run_process execution_id exec_id print_process)); in
(case delay of
NONE => fork ()
| SOME d => ignore (Event_Timer.request {physical = true} (Time.now () + d) fork)) end;
fun run_print execution_id (print as Print {exec_id, print_process, ...}) = if ignore_process print_process then () elseif parallel_print printthen fork_print execution_id [] print else run_process execution_id exec_id print_process;
fun exec_parallel_prints execution_id deps (exec as (Eval {eval_process, ...}, prints)) = if Lazy.is_finished eval_process then (List.app (fork_print execution_id deps) prints; NONE) else SOME exec;
end;
end;
(* common print functions *)
val _ =
Command.print_function "Execution.print"
(fn {args, exec_id, ...} => if null args then
SOME {delay = NONE, pri = Task_Queue.urgent_pri + 2, persistent = false, strict = false,
print_fn = fn _ => fn _ => Execution.fork_prints exec_id} else NONE);
val _ =
Command.print_function "print_state"
(fn {keywords, command_name, ...} => if Options.default_bool \<^system_option>\<open>editor_output_state\<close>
andalso Keyword.is_printed keywords command_name then
SOME {delay = NONE, pri = Task_Queue.urgent_pri + 1, persistent = false, strict = false,
print_fn = fn _ => fn st => if Toplevel.is_proof st then Output.state (Pretty.strings_of (Pretty.chunks (Toplevel.pretty_state st))) else ()} else NONE);
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.