src/Pure/Thy/thy_load.ML
changeset 54451 459cf6ee254e
parent 54450 7815563f50dc
child 54454 044faa8a8080
equal deleted inserted replaced
54450:7815563f50dc 54451:459cf6ee254e
     7 signature THY_LOAD =
     7 signature THY_LOAD =
     8 sig
     8 sig
     9   val master_directory: theory -> Path.T
     9   val master_directory: theory -> Path.T
    10   val imports_of: theory -> (string * Position.T) list
    10   val imports_of: theory -> (string * Position.T) list
    11   val thy_path: Path.T -> Path.T
    11   val thy_path: Path.T -> Path.T
       
    12   val read_files: Path.T -> string -> Path.T * Position.T -> Token.file list
    12   val parse_files: string -> (theory -> Token.file list) parser
    13   val parse_files: string -> (theory -> Token.file list) parser
    13   val check_thy: Path.T -> string ->
    14   val check_thy: Path.T -> string ->
    14    {master: Path.T * SHA1.digest, text: string, theory_pos: Position.T,
    15    {master: Path.T * SHA1.digest, text: string, theory_pos: Position.T,
    15     imports: (string * Position.T) list, keywords: Thy_Header.keywords}
    16     imports: (string * Position.T) list, keywords: Thy_Header.keywords}
    16   val provide: Path.T * SHA1.digest -> theory -> theory
    17   val provide: Path.T * SHA1.digest -> theory -> theory
    53 val imports_of = #imports o Files.get;
    54 val imports_of = #imports o Files.get;
    54 
    55 
    55 fun put_deps master_dir imports = map_files (fn _ => (master_dir, imports, []));
    56 fun put_deps master_dir imports = map_files (fn _ => (master_dir, imports, []));
    56 
    57 
    57 
    58 
    58 (* inlined files *)
    59 (* auxiliary files *)
    59 
    60 
    60 fun check_file dir file = File.check_file (File.full_path dir file);
    61 fun check_file dir file = File.check_file (File.full_path dir file);
    61 
    62 
    62 fun read_files cmd dir (path, pos) =
    63 fun read_files dir cmd (path, pos) =
    63   let
    64   let
    64     fun make_file file =
    65     fun make_file file =
    65       let
    66       let
    66         val _ = Position.report pos (Markup.path (Path.implode file));
    67         val _ = Position.report pos (Markup.path (Path.implode file));
    67         val full_path = check_file dir file;
    68         val full_path = check_file dir file;
    74 
    75 
    75 fun parse_files cmd =
    76 fun parse_files cmd =
    76   Scan.ahead Parse.not_eof -- Parse.path >> (fn (tok, name) => fn thy =>
    77   Scan.ahead Parse.not_eof -- Parse.path >> (fn (tok, name) => fn thy =>
    77     (case Token.get_files tok of
    78     (case Token.get_files tok of
    78       SOME files => files
    79       SOME files => files
    79     | NONE => read_files cmd (master_directory thy) (Path.explode name, Token.position_of tok)));
    80     | NONE => read_files (master_directory thy) cmd (Path.explode name, Token.position_of tok)));
    80 
    81 
    81 local
    82 
    82 
    83 (* theory files *)
    83 fun clean ((i1, t1) :: (i2, t2) :: toks) =
       
    84       if Token.keyword_with (fn s => s = "%" orelse s = "--") t1 then clean toks
       
    85       else (i1, t1) :: clean ((i2, t2) :: toks)
       
    86   | clean toks = toks;
       
    87 
       
    88 fun clean_tokens toks =
       
    89   ((0 upto length toks - 1) ~~ toks)
       
    90   |> filter (fn (_, tok) => Token.is_proper tok)
       
    91   |> clean;
       
    92 
       
    93 fun find_file toks =
       
    94   rev (clean_tokens toks) |> get_first (fn (i, tok) =>
       
    95     if Token.is_name tok then
       
    96       SOME (i, (Path.explode (Token.content_of tok), Token.position_of tok))
       
    97         handle ERROR msg => error (msg ^ Token.pos_of tok)
       
    98     else NONE);
       
    99 
       
   100 in
       
   101 
       
   102 fun resolve_files master_dir span =
       
   103   (case span of
       
   104     Thy_Syntax.Span (Thy_Syntax.Command (cmd, pos), toks) =>
       
   105       if Keyword.is_theory_load cmd then
       
   106         (case find_file toks of
       
   107           NONE => error ("Bad file argument of command " ^ quote cmd ^ Position.here pos)
       
   108         | SOME (i, path) =>
       
   109             let
       
   110               val toks' = toks |> map_index (fn (j, tok) =>
       
   111                 if i = j then Token.put_files (read_files cmd master_dir path) tok
       
   112                 else tok);
       
   113             in Thy_Syntax.Span (Thy_Syntax.Command (cmd, pos), toks') end)
       
   114       else span
       
   115   | span => span);
       
   116 
       
   117 end;
       
   118 
       
   119 
       
   120 (* check files *)
       
   121 
    84 
   122 val thy_path = Path.ext "thy";
    85 val thy_path = Path.ext "thy";
   123 
    86 
   124 fun check_thy dir thy_name =
    87 fun check_thy dir thy_name =
   125   let
    88   let
   211       |> Present.begin_theory update_time master_dir;
   174       |> Present.begin_theory update_time master_dir;
   212 
   175 
   213     val lexs = Keyword.get_lexicons ();
   176     val lexs = Keyword.get_lexicons ();
   214 
   177 
   215     val toks = Thy_Syntax.parse_tokens lexs text_pos text;
   178     val toks = Thy_Syntax.parse_tokens lexs text_pos text;
   216     val spans = map (resolve_files master_dir) (Thy_Syntax.parse_spans toks);
   179     val spans = map (Thy_Syntax.resolve_files (read_files master_dir)) (Thy_Syntax.parse_spans toks);
   217     val elements = Thy_Syntax.parse_elements spans;
   180     val elements = Thy_Syntax.parse_elements spans;
   218 
   181 
   219     val _ = Present.theory_source name
   182     val _ = Present.theory_source name
   220       (fn () => HTML.html_mode (implode o map Thy_Syntax.present_span) spans);
   183       (fn () => HTML.html_mode (implode o map Thy_Syntax.present_span) spans);
   221 
   184