11 |
11 |
12 signature BASIC_OUTER_SYNTAX = |
12 signature BASIC_OUTER_SYNTAX = |
13 sig |
13 sig |
14 val main: unit -> unit |
14 val main: unit -> unit |
15 val loop: unit -> unit |
15 val loop: unit -> unit |
|
16 val sync_main: unit -> unit |
|
17 val sync_loop: unit -> unit |
16 val help: unit -> unit |
18 val help: unit -> unit |
17 end; |
19 end; |
18 |
20 |
19 signature OUTER_SYNTAX = |
21 signature OUTER_SYNTAX = |
20 sig |
22 sig |
48 val add_keywords: string list -> unit |
50 val add_keywords: string list -> unit |
49 val add_parsers: parser list -> unit |
51 val add_parsers: parser list -> unit |
50 val theory_header: token list -> (string * string list * (string * bool) list) * token list |
52 val theory_header: token list -> (string * string list * (string * bool) list) * token list |
51 val deps_thy: string -> bool -> Path.T -> string list * Path.T list |
53 val deps_thy: string -> bool -> Path.T -> string list * Path.T list |
52 val load_thy: string -> bool -> bool -> Path.T -> unit |
54 val load_thy: string -> bool -> bool -> Path.T -> unit |
53 val isar: Toplevel.isar |
55 val isar: bool -> Toplevel.isar |
54 end; |
56 end; |
55 |
57 |
56 structure OuterSyntax: OUTER_SYNTAX = |
58 structure OuterSyntax: OUTER_SYNTAX = |
57 struct |
59 struct |
|
60 |
|
61 structure P = OuterParse; |
58 |
62 |
59 |
63 |
60 (** outer syntax **) |
64 (** outer syntax **) |
61 |
65 |
62 (* command keyword classification *) |
66 (* command keyword classification *) |
94 fun parser int_only name comment kind parse = Parser (name, (comment, kind), int_only, parse); |
98 fun parser int_only name comment kind parse = Parser (name, (comment, kind), int_only, parse); |
95 |
99 |
96 |
100 |
97 (* parse command *) |
101 (* parse command *) |
98 |
102 |
99 local open OuterParse in |
103 local |
100 |
104 |
101 fun command_name cmd = |
105 fun command_name cmd = |
102 group "command" |
106 P.group "command" |
103 (position (Scan.one (OuterLex.keyword_pred (is_some o cmd)) >> OuterLex.val_of)); |
107 (P.position (Scan.one (OuterLex.keyword_pred (is_some o cmd)) >> OuterLex.val_of)); |
104 |
108 |
105 fun command_body cmd (name, _) = |
109 fun command_body cmd (name, _) = |
106 let val (int_only, parse) = the (cmd name) |
110 let val (int_only, parse) = the (cmd name) |
107 in !!! (Scan.prompt (name ^ "# ") (parse >> pair int_only)) end; |
111 in P.!!! (Scan.prompt (name ^ "# ") (parse >> pair int_only)) end; |
108 |
112 |
109 fun command cmd = |
113 fun terminator false = Scan.succeed () |
110 $$$ ";" >> K None || |
114 | terminator true = P.group "terminator" (Scan.option P.sync -- P.$$$ ";" >> K ()); |
111 command_name cmd :-- command_body cmd >> (fn ((name, pos), (int_only, f)) => |
115 |
112 Some (Toplevel.empty |> Toplevel.name name |> Toplevel.position pos |> |
116 in |
113 Toplevel.interactive int_only |> f)); |
117 |
|
118 fun command term cmd = |
|
119 P.$$$ ";" >> K None || |
|
120 P.sync >> K None || |
|
121 (command_name cmd :-- command_body cmd) --| terminator term |
|
122 >> (fn ((name, pos), (int_only, f)) => |
|
123 Some (Toplevel.empty |> Toplevel.name name |> Toplevel.position pos |> |
|
124 Toplevel.interactive int_only |> f)); |
114 |
125 |
115 end; |
126 end; |
116 |
127 |
117 |
128 |
118 |
129 |
175 val theory_keyword = OuterParse.$$$ theoryN; |
186 val theory_keyword = OuterParse.$$$ theoryN; |
176 |
187 |
177 |
188 |
178 (* source *) |
189 (* source *) |
179 |
190 |
180 fun no_command cmd = |
191 local |
181 Scan.one ((not o OuterLex.keyword_pred ((is_some o cmd) orf equal ";")) andf OuterLex.not_eof); |
192 |
182 |
193 val no_terminator = |
183 fun recover cmd = |
194 Scan.unless (P.$$$ ";") (Scan.one (OuterLex.not_sync andf OuterLex.not_eof)); |
184 Scan.prompt "recover# " (Scan.one OuterLex.not_eof -- Scan.repeat (no_command cmd)); |
195 |
185 |
196 val recover = Scan.prompt "recover# " (Scan.repeat no_terminator); |
186 fun source do_recover cmd src = |
197 |
|
198 in |
|
199 |
|
200 fun source term do_recover cmd src = |
187 src |
201 src |
188 |> Source.source OuterLex.stopper (Scan.bulk (fn xs => OuterParse.!!! (command (cmd ())) xs)) |
202 |> Source.source OuterLex.stopper |
189 (if do_recover then Some (fn xs => recover (cmd ()) xs) else None) |
203 (Scan.bulk (fn xs => OuterParse.!!! (command term (cmd ())) xs)) |
|
204 (if do_recover then Some recover else None) |
190 |> Source.mapfilter I; |
205 |> Source.mapfilter I; |
|
206 |
|
207 end; |
191 |
208 |
192 |
209 |
193 (* detect header *) |
210 (* detect header *) |
194 |
211 |
195 fun scan_header get_lexicon scan (src, pos) = |
212 fun scan_header get_lexicon scan (src, pos) = |
214 (* deps_thy --- inspect theory header *) |
231 (* deps_thy --- inspect theory header *) |
215 |
232 |
216 val header_lexicon = |
233 val header_lexicon = |
217 Scan.make_lexicon (map Symbol.explode ["(", ")", "+", ":", "=", "files", theoryN]); |
234 Scan.make_lexicon (map Symbol.explode ["(", ")", "+", ":", "=", "files", theoryN]); |
218 |
235 |
219 local open OuterParse in |
236 local |
220 |
237 |
221 val file_name = ($$$ "(" |-- !!! (name --| $$$ ")")) >> rpair false || name >> rpair true; |
238 val file_name = (P.$$$ "(" |-- P.!!! (P.name --| P.$$$ ")")) >> rpair false || P.name >> rpair true; |
222 |
239 |
223 val theory_head = |
240 val theory_head = |
224 (name -- ($$$ "=" |-- enum1 "+" name) -- |
241 (P.name -- (P.$$$ "=" |-- P.enum1 "+" P.name) -- |
225 Scan.optional ($$$ "files" |-- !!! (Scan.repeat1 file_name)) []) |
242 Scan.optional (P.$$$ "files" |-- P.!!! (Scan.repeat1 file_name)) []) |
226 >> (fn ((A, Bs), files) => (A, Bs, files)); |
243 >> (fn ((A, Bs), files) => (A, Bs, files)); |
227 |
244 |
228 val theory_header = theory_head --| (Scan.ahead eof || $$$ ":"); |
245 in |
229 val only_header = theory_keyword |-- theory_head --| Scan.ahead eof; |
246 |
230 val new_header = theory_keyword |-- !!! theory_header; |
247 val theory_header = theory_head --| (Scan.ahead P.eof || P.$$$ ":"); |
|
248 val only_header = theory_keyword |-- theory_head --| Scan.ahead P.eof; |
|
249 val new_header = theory_keyword |-- P.!!! theory_header; |
231 |
250 |
232 val old_header = |
251 val old_header = |
233 name -- ($$$ "=" |-- name -- Scan.repeat ($$$ "+" |-- name)) |
252 P.name -- (P.$$$ "=" |-- P.name -- Scan.repeat (P.$$$ "+" |-- P.name)) |
234 >> (fn (A, (B, Bs)) => (A, B :: Bs, []: (string * bool) list)); |
253 >> (fn (A, (B, Bs)) => (A, B :: Bs, []: (string * bool) list)); |
235 |
254 |
236 end; |
255 end; |
237 |
256 |
238 fun deps_thy name ml path = |
257 fun deps_thy name ml path = |
305 try_ml_file name ml time); |
324 try_ml_file name ml time); |
306 |
325 |
307 |
326 |
308 (* interactive source of state transformers *) |
327 (* interactive source of state transformers *) |
309 |
328 |
310 val isar = |
329 fun isar term = |
311 Source.tty |
330 Source.tty |
312 |> Symbol.source true |
331 |> Symbol.source true |
313 |> OuterLex.source true get_lexicon (Position.line_name 1 "stdin") |
332 |> OuterLex.source true get_lexicon (Position.line_name 1 "stdin") |
314 |> source true get_parser; |
333 |> source term true get_parser; |
315 |
334 |
316 |
335 |
317 |
336 |
318 (** the read-eval-print loop **) |
337 (** the read-eval-print loop **) |
319 |
338 |
320 (* main loop *) |
339 (* main loop *) |
321 |
340 |
322 fun loop () = (Context.reset_context (); Toplevel.loop isar); |
341 fun gen_loop term = (Context.reset_context (); Toplevel.loop (isar term)); |
323 |
342 |
324 fun main () = |
343 fun gen_main term = |
325 (Toplevel.set_state Toplevel.toplevel; |
344 (Toplevel.set_state Toplevel.toplevel; |
326 ml_prompts "ML> " "ML# "; |
345 ml_prompts "ML> " "ML# "; |
327 writeln (Session.welcome ()); |
346 writeln (Session.welcome ()); |
328 loop ()); |
347 gen_loop term); |
|
348 |
|
349 fun main () = gen_main false; |
|
350 fun loop () = gen_loop false; |
|
351 fun sync_main () = gen_main true; |
|
352 fun sync_loop () = gen_loop true; |
329 |
353 |
330 |
354 |
331 (* help *) |
355 (* help *) |
332 |
356 |
333 fun help () = |
357 fun help () = |