src/Pure/Isar/outer_syntax.ML
changeset 6860 8dc6a1e6fa13
parent 6733 429bbd7ef26d
child 6868 27ba88d57399
equal deleted inserted replaced
6859:2b3db2b6c129 6860:8dc6a1e6fa13
    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 =
   277       |> (fst o the o Source.get_single);
   296       |> (fst o the o Source.get_single);
   278   in
   297   in
   279     (case only_head of
   298     (case only_head of
   280       None =>
   299       None =>
   281         lex_src
   300         lex_src
   282         |> source false (K (get_parser ()))
   301         |> source false false (K (get_parser ()))
   283         |> Source.exhaust
   302         |> Source.exhaust
   284     | Some spec =>
   303     | Some spec =>
   285         [Toplevel.empty |> Toplevel.name theoryN |> IsarThy.theory spec,
   304         [Toplevel.empty |> Toplevel.name theoryN |> IsarThy.theory spec,
   286           Toplevel.empty |> Toplevel.name "end" |> Toplevel.exit])
   305           Toplevel.empty |> Toplevel.name "end" |> Toplevel.exit])
   287   end;
   306   end;
   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 () =