6 |
6 |
7 signature COMMAND = |
7 signature COMMAND = |
8 sig |
8 sig |
9 type blob = (string * (SHA1.digest * string list) option) Exn.result |
9 type blob = (string * (SHA1.digest * string list) option) Exn.result |
10 val read_file: Path.T -> Position.T -> Path.T -> Token.file |
10 val read_file: Path.T -> Position.T -> Path.T -> Token.file |
11 val read: (unit -> theory) -> Path.T -> blob list -> Token.T list -> Toplevel.transition |
11 val read: Keyword.keywords -> Path.T-> (unit -> theory) -> blob list -> Token.T list -> |
|
12 Toplevel.transition |
12 type eval |
13 type eval |
13 val eval_eq: eval * eval -> bool |
14 val eval_eq: eval * eval -> bool |
14 val eval_running: eval -> bool |
15 val eval_running: eval -> bool |
15 val eval_finished: eval -> bool |
16 val eval_finished: eval -> bool |
16 val eval_result_state: eval -> Toplevel.state |
17 val eval_result_state: eval -> Toplevel.state |
17 val eval: (unit -> theory) -> Path.T -> blob list -> Token.T list -> eval -> eval |
18 val eval: Keyword.keywords -> Path.T -> (unit -> theory) -> blob list -> Token.T list -> |
|
19 eval -> eval |
18 type print |
20 type print |
19 val print: bool -> (string * string list) list -> string -> |
21 val print: bool -> (string * string list) list -> Keyword.keywords -> string -> |
20 eval -> print list -> print list option |
22 eval -> print list -> print list option |
21 type print_fn = Toplevel.transition -> Toplevel.state -> unit |
23 type print_fn = Toplevel.transition -> Toplevel.state -> unit |
22 type print_function = |
24 type print_function = |
23 {command_name: string, args: string list, exec_id: Document_ID.exec} -> |
25 {keywords: Keyword.keywords, command_name: string, args: string list, exec_id: Document_ID.exec} -> |
24 {delay: Time.time option, pri: int, persistent: bool, strict: bool, print_fn: print_fn} option |
26 {delay: Time.time option, pri: int, persistent: bool, strict: bool, print_fn: print_fn} option |
25 val print_function: string -> print_function -> unit |
27 val print_function: string -> print_function -> unit |
26 val no_print_function: string -> unit |
28 val no_print_function: string -> unit |
27 type exec = eval * print list |
29 type exec = eval * print list |
28 val no_exec: exec |
30 val no_exec: exec |
118 (case Position.get_id (Position.thread_data ()) of |
120 (case Position.get_id (Position.thread_data ()) of |
119 NONE => I |
121 NONE => I |
120 | SOME exec_id => Position.put_id exec_id); |
122 | SOME exec_id => Position.put_id exec_id); |
121 in {src_path = src_path, lines = lines, digest = digest, pos = file_pos} end |
123 in {src_path = src_path, lines = lines, digest = digest, pos = file_pos} end |
122 |
124 |
123 fun resolve_files master_dir blobs toks = |
125 fun resolve_files keywords master_dir blobs toks = |
124 (case Outer_Syntax.parse_spans toks of |
126 (case Outer_Syntax.parse_spans toks of |
125 [span] => span |
127 [span] => span |
126 |> Command_Span.resolve_files (fn cmd => fn (path, pos) => |
128 |> Command_Span.resolve_files keywords (fn cmd => fn (path, pos) => |
127 let |
129 let |
128 fun make_file src_path (Exn.Res (file_node, NONE)) = |
130 fun make_file src_path (Exn.Res (file_node, NONE)) = |
129 Exn.interruptible_capture (fn () => |
131 Exn.interruptible_capture (fn () => |
130 read_file_node file_node master_dir pos src_path) () |
132 read_file_node file_node master_dir pos src_path) () |
131 | make_file src_path (Exn.Res (file_node, SOME (digest, lines))) = |
133 | make_file src_path (Exn.Res (file_node, SOME (digest, lines))) = |
132 (Position.reports [(pos, Markup.language_path), (pos, Markup.path file_node)]; |
134 (Position.reports [(pos, Markup.language_path), (pos, Markup.path file_node)]; |
133 Exn.Res (blob_file src_path lines digest file_node)) |
135 Exn.Res (blob_file src_path lines digest file_node)) |
134 | make_file _ (Exn.Exn e) = Exn.Exn e; |
136 | make_file _ (Exn.Exn e) = Exn.Exn e; |
135 val src_paths = Keyword.command_files cmd path; |
137 val src_paths = Keyword.command_files keywords cmd path; |
136 in |
138 in |
137 if null blobs then |
139 if null blobs then |
138 map2 make_file src_paths (map (K (Exn.Res ("", NONE))) src_paths) |
140 map2 make_file src_paths (map (K (Exn.Res ("", NONE))) src_paths) |
139 else if length src_paths = length blobs then |
141 else if length src_paths = length blobs then |
140 map2 make_file src_paths blobs |
142 map2 make_file src_paths blobs |
143 |> Command_Span.content |
145 |> Command_Span.content |
144 | _ => toks); |
146 | _ => toks); |
145 |
147 |
146 in |
148 in |
147 |
149 |
148 fun read init master_dir blobs span = |
150 fun read keywords master_dir init blobs span = |
149 let |
151 let |
150 val syntax = #2 (Outer_Syntax.get_syntax ()); |
152 val syntax = #2 (Outer_Syntax.get_syntax ()); |
151 val command_reports = Outer_Syntax.command_reports syntax; |
153 val command_reports = Outer_Syntax.command_reports syntax; |
152 |
154 |
153 val proper_range = Token.range_of (#1 (take_suffix Token.is_improper span)); |
155 val proper_range = Token.range_of (#1 (take_suffix Token.is_improper span)); |
159 val (is_malformed, token_reports) = Thy_Syntax.reports_of_tokens span; |
161 val (is_malformed, token_reports) = Thy_Syntax.reports_of_tokens span; |
160 val _ = Position.reports_text (token_reports @ maps command_reports span); |
162 val _ = Position.reports_text (token_reports @ maps command_reports span); |
161 in |
163 in |
162 if is_malformed then Toplevel.malformed pos "Malformed command syntax" |
164 if is_malformed then Toplevel.malformed pos "Malformed command syntax" |
163 else |
165 else |
164 (case Outer_Syntax.read_spans syntax (resolve_files master_dir blobs span) of |
166 (case Outer_Syntax.read_spans syntax (resolve_files keywords master_dir blobs span) of |
165 [tr] => Toplevel.modify_init init tr |
167 [tr] => Toplevel.modify_init init tr |
166 | [] => Toplevel.ignored (#1 (Token.range_of span)) |
168 | [] => Toplevel.ignored (#1 (Token.range_of span)) |
167 | _ => Toplevel.malformed (#1 proper_range) "Exactly one command expected") |
169 | _ => Toplevel.malformed (#1 proper_range) "Exactly one command expected") |
168 handle ERROR msg => Toplevel.malformed (#1 proper_range) msg |
170 handle ERROR msg => Toplevel.malformed (#1 proper_range) msg |
169 end; |
171 end; |
189 fun eval_result (Eval {eval_process, ...}) = memo_result eval_process; |
191 fun eval_result (Eval {eval_process, ...}) = memo_result eval_process; |
190 val eval_result_state = #state o eval_result; |
192 val eval_result_state = #state o eval_result; |
191 |
193 |
192 local |
194 local |
193 |
195 |
194 fun reset_state tr st0 = Toplevel.setmp_thread_position tr (fn () => |
196 fun reset_state keywords tr st0 = Toplevel.setmp_thread_position tr (fn () => |
195 let |
197 let |
196 val name = Toplevel.name_of tr; |
198 val name = Toplevel.name_of tr; |
197 val res = |
199 val res = |
198 if Keyword.is_theory_body name then Toplevel.reset_theory st0 |
200 if Keyword.is_theory_body keywords name then Toplevel.reset_theory st0 |
199 else if Keyword.is_proof name then Toplevel.reset_proof st0 |
201 else if Keyword.is_proof keywords name then Toplevel.reset_proof st0 |
200 else NONE; |
202 else NONE; |
201 in |
203 in |
202 (case res of |
204 (case res of |
203 NONE => st0 |
205 NONE => st0 |
204 | SOME st => (Output.error_message (Toplevel.type_error tr st0 ^ " -- using reset state"); st)) |
206 | SOME st => (Output.error_message (Toplevel.type_error tr st0 ^ " -- using reset state"); st)) |
205 end) (); |
207 end) (); |
206 |
208 |
207 fun run int tr st = |
209 fun run keywords int tr st = |
208 if Goal.future_enabled 1 andalso Keyword.is_diag (Toplevel.name_of tr) then |
210 if Goal.future_enabled 1 andalso Keyword.is_diag keywords (Toplevel.name_of tr) then |
209 (Execution.fork {name = "Toplevel.diag", pos = Toplevel.pos_of tr, pri = ~1} |
211 (Execution.fork {name = "Toplevel.diag", pos = Toplevel.pos_of tr, pri = ~1} |
210 (fn () => Toplevel.command_exception int tr st); ([], SOME st)) |
212 (fn () => Toplevel.command_exception int tr st); ([], SOME st)) |
211 else Toplevel.command_errors int tr st; |
213 else Toplevel.command_errors int tr st; |
212 |
214 |
213 fun check_cmts span tr st' = |
215 fun check_cmts span tr st' = |
228 fun proof_status tr st = |
230 fun proof_status tr st = |
229 (case try Toplevel.proof_of st of |
231 (case try Toplevel.proof_of st of |
230 SOME prf => status tr (Proof.status_markup prf) |
232 SOME prf => status tr (Proof.status_markup prf) |
231 | NONE => ()); |
233 | NONE => ()); |
232 |
234 |
233 fun eval_state span tr ({malformed, state, ...}: eval_state) = |
235 fun eval_state keywords span tr ({malformed, state, ...}: eval_state) = |
234 if malformed then |
236 if malformed then |
235 {failed = true, malformed = malformed, command = tr, state = Toplevel.toplevel} |
237 {failed = true, malformed = malformed, command = tr, state = Toplevel.toplevel} |
236 else |
238 else |
237 let |
239 let |
238 val _ = Multithreading.interrupted (); |
240 val _ = Multithreading.interrupted (); |
239 |
241 |
240 val malformed' = Toplevel.is_malformed tr; |
242 val malformed' = Toplevel.is_malformed tr; |
241 val st = reset_state tr state; |
243 val st = reset_state keywords tr state; |
242 |
244 |
243 val _ = status tr Markup.running; |
245 val _ = status tr Markup.running; |
244 val (errs1, result) = run true tr st; |
246 val (errs1, result) = run keywords true tr st; |
245 val errs2 = (case result of NONE => [] | SOME st' => check_cmts span tr st'); |
247 val errs2 = (case result of NONE => [] | SOME st' => check_cmts span tr st'); |
246 val errs = errs1 @ errs2; |
248 val errs = errs1 @ errs2; |
247 val _ = List.app (Future.error_message (Toplevel.pos_of tr)) errs; |
249 val _ = List.app (Future.error_message (Toplevel.pos_of tr)) errs; |
248 in |
250 in |
249 (case result of |
251 (case result of |
260 in {failed = false, malformed = malformed', command = tr, state = st'} end) |
262 in {failed = false, malformed = malformed', command = tr, state = st'} end) |
261 end; |
263 end; |
262 |
264 |
263 in |
265 in |
264 |
266 |
265 fun eval init master_dir blobs span eval0 = |
267 fun eval keywords master_dir init blobs span eval0 = |
266 let |
268 let |
267 val exec_id = Document_ID.make (); |
269 val exec_id = Document_ID.make (); |
268 fun process () = |
270 fun process () = |
269 let |
271 let |
270 val tr = |
272 val tr = |
271 Position.setmp_thread_data (Position.id_only (Document_ID.print exec_id)) |
273 Position.setmp_thread_data (Position.id_only (Document_ID.print exec_id)) |
272 (fn () => read init master_dir blobs span |> Toplevel.exec_id exec_id) (); |
274 (fn () => read keywords master_dir init blobs span |> Toplevel.exec_id exec_id) (); |
273 in eval_state span tr (eval_result eval0) end; |
275 in eval_state keywords span tr (eval_result eval0) end; |
274 in Eval {exec_id = exec_id, eval_process = memo exec_id process} end; |
276 in Eval {exec_id = exec_id, eval_process = memo exec_id process} end; |
275 |
277 |
276 end; |
278 end; |
277 |
279 |
278 |
280 |
286 val print_eq = op = o pairself print_exec_id; |
288 val print_eq = op = o pairself print_exec_id; |
287 |
289 |
288 type print_fn = Toplevel.transition -> Toplevel.state -> unit; |
290 type print_fn = Toplevel.transition -> Toplevel.state -> unit; |
289 |
291 |
290 type print_function = |
292 type print_function = |
291 {command_name: string, args: string list, exec_id: Document_ID.exec} -> |
293 {keywords: Keyword.keywords, command_name: string, args: string list, exec_id: Document_ID.exec} -> |
292 {delay: Time.time option, pri: int, persistent: bool, strict: bool, print_fn: print_fn} option; |
294 {delay: Time.time option, pri: int, persistent: bool, strict: bool, print_fn: print_fn} option; |
293 |
295 |
294 local |
296 local |
295 |
297 |
296 val print_functions = |
298 val print_functions = |
308 |
310 |
309 val overlay_ord = prod_ord string_ord (list_ord string_ord); |
311 val overlay_ord = prod_ord string_ord (list_ord string_ord); |
310 |
312 |
311 in |
313 in |
312 |
314 |
313 fun print command_visible command_overlays command_name eval old_prints = |
315 fun print command_visible command_overlays keywords command_name eval old_prints = |
314 let |
316 let |
315 val print_functions = Synchronized.value print_functions; |
317 val print_functions = Synchronized.value print_functions; |
316 |
318 |
317 fun make_print name args {delay, pri, persistent, strict, print_fn} = |
319 fun make_print name args {delay, pri, persistent, strict, print_fn} = |
318 let |
320 let |
336 make_print name args {delay = NONE, pri = 0, persistent = false, |
338 make_print name args {delay = NONE, pri = 0, persistent = false, |
337 strict = false, print_fn = fn _ => fn _ => reraise exn}; |
339 strict = false, print_fn = fn _ => fn _ => reraise exn}; |
338 |
340 |
339 fun new_print name args get_pr = |
341 fun new_print name args get_pr = |
340 let |
342 let |
341 val params = {command_name = command_name, args = args, exec_id = eval_exec_id eval}; |
343 val params = |
|
344 {keywords = keywords, |
|
345 command_name = command_name, |
|
346 args = args, |
|
347 exec_id = eval_exec_id eval}; |
342 in |
348 in |
343 (case Exn.capture (Runtime.controlled_execution NONE get_pr) params of |
349 (case Exn.capture (Runtime.controlled_execution NONE get_pr) params of |
344 Exn.Res NONE => NONE |
350 Exn.Res NONE => NONE |
345 | Exn.Res (SOME pr) => SOME (make_print name args pr) |
351 | Exn.Res (SOME pr) => SOME (make_print name args pr) |
346 | Exn.Exn exn => SOME (bad_print name args exn)) |
352 | Exn.Exn exn => SOME (bad_print name args exn)) |
383 print_fn = fn _ => fn _ => Execution.fork_prints exec_id} |
389 print_fn = fn _ => fn _ => Execution.fork_prints exec_id} |
384 else NONE); |
390 else NONE); |
385 |
391 |
386 val _ = |
392 val _ = |
387 print_function "print_state" |
393 print_function "print_state" |
388 (fn {command_name, ...} => |
394 (fn {keywords, command_name, ...} => |
389 if Keyword.is_printed command_name then |
395 if Keyword.is_printed keywords command_name then |
390 SOME {delay = NONE, pri = 1, persistent = false, strict = true, |
396 SOME {delay = NONE, pri = 1, persistent = false, strict = true, |
391 print_fn = fn _ => fn st => if Toplevel.is_proof st then Toplevel.print_state st else ()} |
397 print_fn = fn _ => fn st => if Toplevel.is_proof st then Toplevel.print_state st else ()} |
392 else NONE); |
398 else NONE); |
393 |
399 |
394 |
400 |