simplified;
authorwenzelm
Tue, 05 Oct 1999 21:18:54 +0200
changeset 7746 b52c1a632e6a
parent 7745 131005d3a62d
child 7747 ca4e3b75345a
simplified; header command;
src/Pure/Isar/outer_syntax.ML
--- a/src/Pure/Isar/outer_syntax.ML	Tue Oct 05 21:18:13 1999 +0200
+++ b/src/Pure/Isar/outer_syntax.ML	Tue Oct 05 21:18:54 1999 +0200
@@ -206,10 +206,14 @@
 
 (** read theory **)
 
-(* theory keyword *)
+(* special keywords *)
 
+val headerN = "header";
 val theoryN = "theory";
+
 val theory_keyword = OuterParse.$$$ theoryN;
+val header_keyword = OuterParse.$$$ headerN;
+val semicolon = P.$$$ ";";
 
 
 (* sources *)
@@ -217,7 +221,7 @@
 local
 
 val no_terminator =
-  Scan.unless (P.$$$ ";") (Scan.one (OuterLex.not_sync andf OuterLex.not_eof));
+  Scan.unless semicolon (Scan.one (OuterLex.not_sync andf OuterLex.not_eof));
 
 val recover = Scan.prompt "recover# " (Scan.repeat no_terminator);
 
@@ -242,7 +246,7 @@
   |> Source.filter OuterLex.is_proper;
 
 
-(* detect header *)
+(* scan header *)
 
 fun scan_header get_lex scan (src, pos) =
   src
@@ -252,46 +256,54 @@
   |> Source.source OuterLex.stopper (Scan.single scan) None
   |> (fst o the o Source.get_single);
 
-val check_header_lexicon = Scan.make_lexicon [Symbol.explode theoryN];
+
+(* detect new/old header *)
+
+local
 
-fun is_old_theory src =
-  is_none (scan_header (K check_header_lexicon) (Scan.option theory_keyword) src);
+val check_header_lexicon = Scan.make_lexicon [Symbol.explode headerN, Symbol.explode theoryN];
+val check_header = Scan.option (header_keyword || theory_keyword);
+
+in
+
+fun is_old_theory src = is_none (scan_header (K check_header_lexicon) check_header src);
+
+end;
 
 
 (* deps_thy --- inspect theory header *)
 
+local
+
 val header_lexicon =
-  Scan.make_lexicon (map Symbol.explode ["(", ")", "+", ":", "=", "files", theoryN]);
-
-local
+  Scan.make_lexicon (map Symbol.explode ["(", ")", "+", ":", ";", "=", "files", headerN, theoryN]);
 
 val file_name =
   (P.$$$ "(" |-- P.!!! (P.name --| P.$$$ ")")) >> rpair false || P.name >> rpair true;
 
-val theory_head =
+in
+
+val theory_header =
   (P.name -- (P.$$$ "=" |-- P.enum1 "+" P.name) --
-    Scan.optional (P.$$$ "files" |-- P.!!! (Scan.repeat1 file_name)) [])
+    Scan.optional (P.$$$ "files" |-- P.!!! (Scan.repeat1 file_name)) [] --|  P.$$$ ":")
   >> (fn ((A, Bs), files) => (A, Bs, files));
 
-in
-
-val theory_header = theory_head --| (Scan.ahead P.eof || P.$$$ ":");
-val only_header = theory_keyword |-- theory_head --| Scan.ahead P.eof;
-val new_header = theory_keyword |-- P.!!! theory_header;
+val new_header =
+  header_keyword |-- (P.!!! (P.text -- Scan.option semicolon -- theory_keyword |-- theory_header))
+    || theory_keyword |-- P.!!! theory_header;
 
 val old_header =
   P.name -- (P.$$$ "=" |-- P.name -- Scan.repeat (P.$$$ "+" |-- P.name))
   >> (fn (A, (B, Bs)) => (A, B :: Bs, []: (string * bool) list));
 
-end;
-
 fun deps_thy name path =
   let
     val src = Source.of_string (File.read path);
     val pos = Path.position path;
     val (name', parents, files) =
       (*Note: old style headers dynamically depend on the current lexicon :-( *)
-      if is_old_theory (src, pos) then scan_header ThySyn.get_lexicon (Scan.error old_header) (src, pos)
+      if is_old_theory (src, pos) then
+        scan_header ThySyn.get_lexicon (Scan.error old_header) (src, pos)
       else scan_header (K header_lexicon) (Scan.error new_header) (src, pos);
 
     val ml_path = ThyLoad.ml_path name;
@@ -302,9 +314,13 @@
     else (parents, map (Path.unpack o #1) files @ ml_file)
   end;
 
+end;
+
 
 (* load_thy --- read text (including header) *)
 
+local
+
 fun try_ml_file name ml time =
   let
     val path = ThyLoad.ml_path name;
@@ -316,22 +332,11 @@
   end;
 
 fun parse_thy src_pos =
-  let
-    val lex_src = filter_proper (token_source src_pos);
-    val only_head =
-      lex_src
-      |> Source.source OuterLex.stopper (Scan.single (Scan.option only_header)) None
-      |> (fst o the o Source.get_single);
-  in
-    (case only_head of
-      None =>
-        lex_src
-        |> source false false (K (get_parser ()))
-        |> Source.exhaust
-    | Some spec =>
-        [Toplevel.empty |> Toplevel.name theoryN |> IsarThy.theory spec,
-          Toplevel.empty |> Toplevel.name "end" |> Toplevel.exit])
-  end;
+  src_pos
+  |> token_source
+  |> filter_proper
+  |> source false false (K (get_parser ()))
+  |> Source.exhaust;
 
 fun run_thy name path =
   let
@@ -350,6 +355,8 @@
     Present.verbatim_source name present_text
   end;
 
+in
+
 fun load_thy name ml time path =
  (if time then
     timeit (fn () =>
@@ -360,6 +367,8 @@
   Context.context (ThyInfo.get_theory name);
   try_ml_file name ml time);
 
+end;
+
 
 (* interactive source of state transformers *)