| author | bulwahn | 
| Sat, 24 Oct 2009 16:55:43 +0200 | |
| changeset 33145 | 1a22f7ca1dfc | 
| parent 32811 | a692298ecbe0 | 
| child 32966 | 5b21661fe618 | 
| permissions | -rw-r--r-- | 
| 6168 | 1 | (* Title: Pure/Thy/thy_load.ML | 
| 2 | Author: Markus Wenzel, TU Muenchen | |
| 3 | ||
| 15801 | 4 | Theory loader primitives, including load path. | 
| 6168 | 5 | *) | 
| 6 | ||
| 7 | signature BASIC_THY_LOAD = | |
| 8 | sig | |
| 9 | val show_path: unit -> string list | |
| 10 | val add_path: string -> unit | |
| 10252 | 11 | val path_add: string -> unit | 
| 6168 | 12 | val del_path: string -> unit | 
| 7438 | 13 |   val with_path: string -> ('a -> 'b) -> 'a -> 'b
 | 
| 9103 | 14 |   val with_paths: string list -> ('a -> 'b) -> 'a -> 'b
 | 
| 6205 | 15 | val reset_path: unit -> unit | 
| 6168 | 16 | end; | 
| 17 | ||
| 18 | signature THY_LOAD = | |
| 19 | sig | |
| 20 | include BASIC_THY_LOAD | |
| 17366 | 21 | val ml_exts: string list | 
| 6205 | 22 | val ml_path: string -> Path.T | 
| 7901 | 23 | val thy_path: string -> Path.T | 
| 29418 | 24 | val split_thy_path: Path.T -> Path.T * string | 
| 23885 
09254a1622e3
simplified ThyLoad interfaces: only one additional directory;
 wenzelm parents: 
23876diff
changeset | 25 | val check_file: Path.T -> Path.T -> (Path.T * File.ident) option | 
| 
09254a1622e3
simplified ThyLoad interfaces: only one additional directory;
 wenzelm parents: 
23876diff
changeset | 26 | val check_ml: Path.T -> Path.T -> (Path.T * File.ident) option | 
| 24189 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 wenzelm parents: 
24065diff
changeset | 27 | val check_thy: Path.T -> string -> Path.T * File.ident | 
| 29515 | 28 | val check_name: string -> string -> unit | 
| 24189 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 wenzelm parents: 
24065diff
changeset | 29 | val deps_thy: Path.T -> string -> | 
| 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 wenzelm parents: 
24065diff
changeset | 30 |    {master: Path.T * File.ident, text: string list, imports: string list, uses: Path.T list}
 | 
| 23885 
09254a1622e3
simplified ThyLoad interfaces: only one additional directory;
 wenzelm parents: 
23876diff
changeset | 31 | val load_ml: Path.T -> Path.T -> Path.T * File.ident | 
| 6168 | 32 | end; | 
| 33 | ||
| 26616 | 34 | structure ThyLoad: THY_LOAD = | 
| 6168 | 35 | struct | 
| 36 | ||
| 37 | ||
| 6232 | 38 | (* maintain load path *) | 
| 6168 | 39 | |
| 32738 | 40 | local val load_path = Unsynchronized.ref [Path.current] in | 
| 6168 | 41 | |
| 21858 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
17366diff
changeset | 42 | fun show_path () = map Path.implode (! load_path); | 
| 23944 | 43 | |
| 32738 | 44 | fun del_path s = CRITICAL (fn () => | 
| 45 | Unsynchronized.change load_path (remove (op =) (Path.explode s))); | |
| 46 | fun add_path s = CRITICAL (fn () => | |
| 47 | (del_path s; Unsynchronized.change load_path (cons (Path.explode s)))); | |
| 48 | fun path_add s = CRITICAL (fn () => | |
| 49 | (del_path s; Unsynchronized.change load_path (fn path => path @ [Path.explode s]))); | |
| 6205 | 50 | fun reset_path () = load_path := [Path.current]; | 
| 23944 | 51 | |
| 52 | fun with_paths ss f x = | |
| 53 | CRITICAL (fn () => Library.setmp load_path (! load_path @ map Path.explode ss) f x); | |
| 9655 
a4d2da014ec3
renamed cond_with_path to cond_add_path (add to front);
 wenzelm parents: 
9103diff
changeset | 54 | fun with_path s f x = with_paths [s] f x; | 
| 6168 | 55 | |
| 23944 | 56 | fun search_path dir path = | 
| 57 | distinct (op =) (dir :: (if Path.is_basic path then (! load_path) else [Path.current])); | |
| 58 | ||
| 59 | end; | |
| 60 | ||
| 6168 | 61 | |
| 6232 | 62 | (* file formats *) | 
| 6168 | 63 | |
| 23872 | 64 | val ml_exts = ["ML", "sml"]; | 
| 6232 | 65 | val ml_path = Path.ext "ML" o Path.basic; | 
| 66 | val thy_path = Path.ext "thy" o Path.basic; | |
| 6168 | 67 | |
| 29418 | 68 | fun split_thy_path path = | 
| 69 | (case Path.split_ext path of | |
| 70 | (path', "thy") => (Path.dir path', Path.implode (Path.base path')) | |
| 71 |   | _ => error ("Bad theory file specification " ^ Path.implode path));
 | |
| 72 | ||
| 6168 | 73 | |
| 23872 | 74 | (* check files *) | 
| 6232 | 75 | |
| 32811 | 76 | fun check_ext exts paths src_path = | 
| 6232 | 77 | let | 
| 78 | val path = Path.expand src_path; | |
| 23872 | 79 | val _ = Path.is_current path andalso error "Bad file specification"; | 
| 6168 | 80 | |
| 23885 
09254a1622e3
simplified ThyLoad interfaces: only one additional directory;
 wenzelm parents: 
23876diff
changeset | 81 | fun try_ext rel_path ext = | 
| 8750 | 82 | let val ext_path = Path.expand (Path.ext ext rel_path) | 
| 23872 | 83 | in Option.map (fn id => (File.full_path ext_path, id)) (File.ident ext_path) end; | 
| 23885 
09254a1622e3
simplified ThyLoad interfaces: only one additional directory;
 wenzelm parents: 
23876diff
changeset | 84 |     fun try_prfx prfx = get_first (try_ext (Path.append prfx path)) ("" :: exts);
 | 
| 23944 | 85 | in get_first try_prfx paths end; | 
| 6232 | 86 | |
| 32811 | 87 | fun check_file dir path = check_ext [] (search_path dir path) path; | 
| 88 | fun check_ml dir path = check_ext ml_exts (search_path dir path) path; | |
| 6168 | 89 | |
| 24189 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 wenzelm parents: 
24065diff
changeset | 90 | fun check_thy dir name = | 
| 23944 | 91 | let | 
| 92 | val thy_file = thy_path name; | |
| 93 | val paths = search_path dir thy_file; | |
| 94 | in | |
| 32811 | 95 | (case check_ext [] paths thy_file of | 
| 23872 | 96 |       NONE => error ("Could not find theory file " ^ quote (Path.implode thy_file) ^
 | 
| 23944 | 97 | " in " ^ commas_quote (map Path.implode paths)) | 
| 24189 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 wenzelm parents: 
24065diff
changeset | 98 | | SOME thy_id => thy_id) | 
| 23872 | 99 | end; | 
| 6232 | 100 | |
| 29515 | 101 | fun check_name name name' = | 
| 102 | if name = name' then () | |
| 103 |   else error ("Filename " ^ quote (Path.implode (thy_path name)) ^
 | |
| 104 | " does not agree with theory name " ^ quote name'); | |
| 105 | ||
| 6232 | 106 | |
| 23872 | 107 | (* theory deps *) | 
| 7940 | 108 | |
| 24189 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 wenzelm parents: 
24065diff
changeset | 109 | fun deps_thy dir name = | 
| 23872 | 110 | let | 
| 24189 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 wenzelm parents: 
24065diff
changeset | 111 | val master as (path, _) = check_thy dir name; | 
| 24065 | 112 | val text = explode (File.read path); | 
| 23872 | 113 | val (name', imports, uses) = | 
| 32466 | 114 | Thy_Header.read (Path.position path) (Source.of_list_limited 8000 text); | 
| 29515 | 115 | val _ = check_name name name'; | 
| 24189 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 wenzelm parents: 
24065diff
changeset | 116 | val uses = map (Path.explode o #1) uses; | 
| 24065 | 117 |   in {master = master, text = text, imports = imports, uses = uses} end;
 | 
| 6484 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6363diff
changeset | 118 | |
| 6168 | 119 | |
| 23872 | 120 | (* load files *) | 
| 6168 | 121 | |
| 23885 
09254a1622e3
simplified ThyLoad interfaces: only one additional directory;
 wenzelm parents: 
23876diff
changeset | 122 | fun load_ml dir raw_path = | 
| 
09254a1622e3
simplified ThyLoad interfaces: only one additional directory;
 wenzelm parents: 
23876diff
changeset | 123 | (case check_ml dir raw_path of | 
| 23872 | 124 |     NONE => error ("Could not find ML file " ^ quote (Path.implode raw_path))
 | 
| 26455 | 125 | | SOME (path, id) => (ML_Context.eval_file path; (path, id))); | 
| 6168 | 126 | |
| 127 | end; | |
| 128 | ||
| 32738 | 129 | structure Basic_Thy_Load: BASIC_THY_LOAD = ThyLoad; | 
| 130 | open Basic_Thy_Load; |