| author | wenzelm | 
| Sun, 21 May 2000 14:33:46 +0200 | |
| changeset 8896 | c80aba8c1d5e | 
| parent 8808 | 204f4ebbba64 | 
| child 9103 | ef56f093259d | 
| permissions | -rw-r--r-- | 
| 6168 | 1 | (* Title: Pure/Thy/thy_load.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Markus Wenzel, TU Muenchen | |
| 8808 | 4 | License: GPL (GNU GENERAL PUBLIC LICENSE) | 
| 6168 | 5 | |
| 6 | Theory loader primitives. | |
| 7 | *) | |
| 8 | ||
| 9 | signature BASIC_THY_LOAD = | |
| 10 | sig | |
| 11 | val show_path: unit -> string list | |
| 12 | val add_path: string -> unit | |
| 13 | val del_path: string -> unit | |
| 7438 | 14 |   val with_path: string -> ('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 | |
| 7950 | 21 |   val cond_with_path: Path.T -> ('a -> 'b) -> 'a -> 'b
 | 
| 6205 | 22 | val ml_path: string -> Path.T | 
| 7901 | 23 | val thy_path: string -> Path.T | 
| 6232 | 24 | val check_file: Path.T -> (Path.T * File.info) option | 
| 7940 | 25 | val load_file: Path.T -> (Path.T * File.info) | 
| 7190 | 26 | eqtype master | 
| 27 | val get_thy: master -> Path.T * File.info | |
| 7940 | 28 | val check_thy: Path.T -> string -> bool -> master | 
| 29 | val deps_thy: Path.T -> string -> bool -> master * (string list * Path.T list) | |
| 7190 | 30 | val load_thy: Path.T -> string -> bool -> bool -> master | 
| 6168 | 31 | end; | 
| 32 | ||
| 7940 | 33 | (*this backdoor sealed later*) | 
| 6168 | 34 | signature PRIVATE_THY_LOAD = | 
| 35 | sig | |
| 36 | include THY_LOAD | |
| 7940 | 37 | val deps_thy_fn: (string -> bool -> Path.T -> string list * Path.T list) ref | 
| 6205 | 38 | val load_thy_fn: (string -> bool -> bool -> Path.T -> unit) ref | 
| 6168 | 39 | end; | 
| 40 | ||
| 41 | structure ThyLoad: PRIVATE_THY_LOAD = | |
| 42 | struct | |
| 43 | ||
| 44 | ||
| 6232 | 45 | (* maintain load path *) | 
| 6168 | 46 | |
| 47 | val load_path = ref [Path.current]; | |
| 48 | fun change_path f = load_path := f (! load_path); | |
| 49 | ||
| 50 | fun show_path () = map Path.pack (! load_path); | |
| 6484 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6363diff
changeset | 51 | fun add_path s = change_path (cons (Path.unpack s)); | 
| 6168 | 52 | fun del_path s = change_path (filter_out (equal (Path.unpack s))); | 
| 6205 | 53 | fun reset_path () = load_path := [Path.current]; | 
| 7438 | 54 | fun with_path s f x = Library.setmp load_path (Path.unpack s :: ! load_path) f x; | 
| 6168 | 55 | |
| 7438 | 56 | fun cond_with_path path f x = | 
| 7190 | 57 | if Path.is_current path then f x else Library.setmp load_path (path :: ! load_path) f x; | 
| 58 | ||
| 6168 | 59 | |
| 6232 | 60 | (* file formats *) | 
| 6168 | 61 | |
| 6232 | 62 | val ml_exts = ["", "ML", "sml"]; | 
| 63 | val ml_path = Path.ext "ML" o Path.basic; | |
| 64 | val thy_path = Path.ext "thy" o Path.basic; | |
| 6168 | 65 | |
| 66 | ||
| 6232 | 67 | (* check_file *) | 
| 68 | ||
| 69 | fun check_file src_path = | |
| 70 | let | |
| 71 | val path = Path.expand src_path; | |
| 6168 | 72 | |
| 6232 | 73 | fun find_ext rel_path ext = | 
| 8750 | 74 | let val ext_path = Path.expand (Path.ext ext rel_path) | 
| 6232 | 75 | in apsome (fn info => (File.full_path ext_path, info)) (File.info ext_path) end; | 
| 76 | ||
| 77 | fun find_dir dir = | |
| 78 | get_first (find_ext (Path.append dir path)) ml_exts; | |
| 79 | in get_first find_dir (if Path.is_basic path then ! load_path else [Path.current]) end; | |
| 80 | ||
| 81 | ||
| 7940 | 82 | (* load_file *) | 
| 6168 | 83 | |
| 7940 | 84 | fun load_file raw_path = | 
| 6232 | 85 | (case check_file raw_path of | 
| 86 |     None => error ("Could not find ML file " ^ quote (Path.pack raw_path))
 | |
| 7940 | 87 | | Some (path, info) => (File.symbol_use path; (path, info))); | 
| 7190 | 88 | |
| 89 | ||
| 90 | (* datatype master *) | |
| 91 | ||
| 92 | datatype master = Master of (Path.T * File.info) * (Path.T * File.info) option; | |
| 93 | ||
| 94 | fun get_thy (Master (thy, _)) = thy; | |
| 6232 | 95 | |
| 96 | ||
| 7940 | 97 | (* check / process theory files *) | 
| 6168 | 98 | |
| 7940 | 99 | local | 
| 100 | ||
| 101 | fun check_thy_aux (name, ml) = | |
| 6232 | 102 | (case check_file (thy_path name) of | 
| 6484 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6363diff
changeset | 103 |     None => error ("Could not find theory file for " ^ quote name ^ " in dir(s) " ^
 | 
| 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6363diff
changeset | 104 | commas_quote (show_path ())) | 
| 7940 | 105 | | Some thy_info => (thy_info, if ml then check_file (ml_path name) else None)); | 
| 106 | ||
| 107 | in | |
| 108 | ||
| 109 | fun check_thy dir name ml = Master (cond_with_path dir check_thy_aux (name, ml)); | |
| 6205 | 110 | |
| 7940 | 111 | fun process_thy dir f name ml = | 
| 112 | let val master as Master ((path, _), _) = check_thy dir name ml | |
| 113 | in (master, cond_with_path dir f path) end; | |
| 114 | ||
| 115 | end; | |
| 6484 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6363diff
changeset | 116 | |
| 6168 | 117 | |
| 7940 | 118 | (* deps_thy and load_thy *) | 
| 6168 | 119 | |
| 120 | (*hooks for theory syntax dependent operations*) | |
| 121 | fun undefined _ = raise Match; | |
| 7940 | 122 | val deps_thy_fn = ref (undefined: string -> bool -> Path.T -> string list * Path.T list); | 
| 6205 | 123 | val load_thy_fn = ref (undefined: string -> bool -> bool -> Path.T -> unit); | 
| 6168 | 124 | |
| 7940 | 125 | fun deps_thy dir name ml = process_thy dir (! deps_thy_fn name ml) name ml; | 
| 126 | fun load_thy dir name ml time = #1 (process_thy dir (! load_thy_fn name ml time) name ml); | |
| 6168 | 127 | |
| 128 | ||
| 129 | end; | |
| 130 | ||
| 131 | structure BasicThyLoad: BASIC_THY_LOAD = ThyLoad; | |
| 132 | open BasicThyLoad; |