| author | haftmann | 
| Sat, 19 May 2007 11:33:32 +0200 | |
| changeset 23026 | db38b8046294 | 
| parent 22145 | fedad292f738 | 
| child 23872 | f449381e2caa | 
| permissions | -rw-r--r-- | 
| 6168 | 1 | (* Title: Pure/Thy/thy_load.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Markus Wenzel, TU Muenchen | |
| 4 | ||
| 15801 | 5 | Theory loader primitives, including load path. | 
| 6168 | 6 | *) | 
| 7 | ||
| 8 | signature BASIC_THY_LOAD = | |
| 9 | sig | |
| 10 | val show_path: unit -> string list | |
| 11 | val add_path: string -> unit | |
| 10252 | 12 | val path_add: string -> unit | 
| 6168 | 13 | val del_path: string -> unit | 
| 7438 | 14 |   val with_path: string -> ('a -> 'b) -> 'a -> 'b
 | 
| 9103 | 15 |   val with_paths: string list -> ('a -> 'b) -> 'a -> 'b
 | 
| 6205 | 16 | val reset_path: unit -> unit | 
| 6168 | 17 | end; | 
| 18 | ||
| 19 | signature THY_LOAD = | |
| 20 | sig | |
| 21 | include BASIC_THY_LOAD | |
| 17366 | 22 | val ml_exts: string list | 
| 6205 | 23 | val ml_path: string -> Path.T | 
| 7901 | 24 | val thy_path: string -> Path.T | 
| 15157 
faeb23489b73
Function check_file now takes optional path (current directory) as an argument.
 berghofe parents: 
14981diff
changeset | 25 | val check_file: Path.T option -> Path.T -> (Path.T * File.info) option | 
| 
faeb23489b73
Function check_file now takes optional path (current directory) as an argument.
 berghofe parents: 
14981diff
changeset | 26 | val load_file: Path.T option -> Path.T -> (Path.T * File.info) | 
| 7190 | 27 | eqtype master | 
| 28 | val get_thy: master -> Path.T * File.info | |
| 7940 | 29 | val check_thy: Path.T -> string -> bool -> master | 
| 30 | val deps_thy: Path.T -> string -> bool -> master * (string list * Path.T list) | |
| 7190 | 31 | val load_thy: Path.T -> string -> bool -> bool -> master | 
| 6168 | 32 | end; | 
| 33 | ||
| 7940 | 34 | (*this backdoor sealed later*) | 
| 6168 | 35 | signature PRIVATE_THY_LOAD = | 
| 36 | sig | |
| 37 | include THY_LOAD | |
| 7940 | 38 | val deps_thy_fn: (string -> bool -> Path.T -> string list * Path.T list) ref | 
| 6205 | 39 | val load_thy_fn: (string -> bool -> bool -> Path.T -> unit) ref | 
| 6168 | 40 | end; | 
| 41 | ||
| 42 | structure ThyLoad: PRIVATE_THY_LOAD = | |
| 43 | struct | |
| 44 | ||
| 45 | ||
| 6232 | 46 | (* maintain load path *) | 
| 6168 | 47 | |
| 48 | val load_path = ref [Path.current]; | |
| 49 | fun change_path f = load_path := f (! load_path); | |
| 50 | ||
| 21858 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
17366diff
changeset | 51 | fun show_path () = map Path.implode (! load_path); | 
| 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
17366diff
changeset | 52 | fun del_path s = change_path (filter_out (equal (Path.explode s))); | 
| 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
17366diff
changeset | 53 | fun add_path s = (del_path s; change_path (cons (Path.explode s))); | 
| 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
17366diff
changeset | 54 | fun path_add s = (del_path s; change_path (fn path => path @ [Path.explode s])); | 
| 6205 | 55 | fun reset_path () = load_path := [Path.current]; | 
| 21858 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
17366diff
changeset | 56 | fun with_paths ss f x = 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 | 57 | fun with_path s f x = with_paths [s] f x; | 
| 6168 | 58 | |
| 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 | ||
| 15157 
faeb23489b73
Function check_file now takes optional path (current directory) as an argument.
 berghofe parents: 
14981diff
changeset | 69 | fun check_file current src_path = | 
| 6232 | 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) | 
| 15570 | 75 | in Option.map (fn info => (File.full_path ext_path, info)) (File.info ext_path) end; | 
| 6232 | 76 | |
| 77 | fun find_dir dir = | |
| 78 | get_first (find_ext (Path.append dir path)) ml_exts; | |
| 13533 | 79 | |
| 15531 | 80 | fun add_current ps = (case current of NONE => ps | 
| 81 | | (SOME p) => if Path.is_current p then ps else p :: ps); | |
| 15157 
faeb23489b73
Function check_file now takes optional path (current directory) as an argument.
 berghofe parents: 
14981diff
changeset | 82 | |
| 13533 | 83 | val paths = | 
| 84 | if Path.is_current path then error "Bad file specification" | |
| 15157 
faeb23489b73
Function check_file now takes optional path (current directory) as an argument.
 berghofe parents: 
14981diff
changeset | 85 | else if Path.is_basic path then add_current (! load_path) | 
| 
faeb23489b73
Function check_file now takes optional path (current directory) as an argument.
 berghofe parents: 
14981diff
changeset | 86 | else add_current [Path.current]; | 
| 13533 | 87 | in get_first find_dir paths end; | 
| 6232 | 88 | |
| 89 | ||
| 7940 | 90 | (* load_file *) | 
| 6168 | 91 | |
| 15157 
faeb23489b73
Function check_file now takes optional path (current directory) as an argument.
 berghofe parents: 
14981diff
changeset | 92 | fun load_file current raw_path = | 
| 
faeb23489b73
Function check_file now takes optional path (current directory) as an argument.
 berghofe parents: 
14981diff
changeset | 93 | (case check_file current raw_path of | 
| 21858 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
17366diff
changeset | 94 |     NONE => error ("Could not find ML file " ^ quote (Path.implode raw_path))
 | 
| 22145 | 95 | | SOME (path, info) => (ML_Context.use path; (path, info))); | 
| 7190 | 96 | |
| 97 | ||
| 98 | (* datatype master *) | |
| 99 | ||
| 100 | datatype master = Master of (Path.T * File.info) * (Path.T * File.info) option; | |
| 101 | ||
| 102 | fun get_thy (Master (thy, _)) = thy; | |
| 6232 | 103 | |
| 104 | ||
| 7940 | 105 | (* check / process theory files *) | 
| 6168 | 106 | |
| 7940 | 107 | local | 
| 108 | ||
| 109 | fun check_thy_aux (name, ml) = | |
| 16269 | 110 | let val thy_file = thy_path name in | 
| 111 | case check_file NONE thy_file of | |
| 21858 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
17366diff
changeset | 112 |       NONE => error ("Could not find theory file " ^ quote (Path.implode thy_file) ^
 | 
| 16269 | 113 | " in dir(s) " ^ commas_quote (show_path ())) | 
| 114 | | SOME thy_info => (thy_info, if ml then check_file NONE (ml_path name) else NONE) | |
| 115 | end; | |
| 7940 | 116 | |
| 21950 | 117 | fun cond_add_path path f x = | 
| 118 | if Path.is_current path then f x else Library.setmp load_path (path :: ! load_path) f x; | |
| 119 | ||
| 7940 | 120 | in | 
| 121 | ||
| 9655 
a4d2da014ec3
renamed cond_with_path to cond_add_path (add to front);
 wenzelm parents: 
9103diff
changeset | 122 | fun check_thy dir name ml = Master (cond_add_path dir check_thy_aux (name, ml)); | 
| 6205 | 123 | |
| 7940 | 124 | fun process_thy dir f name ml = | 
| 125 | let val master as Master ((path, _), _) = check_thy dir name ml | |
| 9655 
a4d2da014ec3
renamed cond_with_path to cond_add_path (add to front);
 wenzelm parents: 
9103diff
changeset | 126 | in (master, cond_add_path dir f path) end; | 
| 7940 | 127 | |
| 128 | end; | |
| 6484 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6363diff
changeset | 129 | |
| 6168 | 130 | |
| 7940 | 131 | (* deps_thy and load_thy *) | 
| 6168 | 132 | |
| 133 | (*hooks for theory syntax dependent operations*) | |
| 134 | fun undefined _ = raise Match; | |
| 7940 | 135 | val deps_thy_fn = ref (undefined: string -> bool -> Path.T -> string list * Path.T list); | 
| 6205 | 136 | val load_thy_fn = ref (undefined: string -> bool -> bool -> Path.T -> unit); | 
| 6168 | 137 | |
| 7940 | 138 | fun deps_thy dir name ml = process_thy dir (! deps_thy_fn name ml) name ml; | 
| 139 | fun load_thy dir name ml time = #1 (process_thy dir (! load_thy_fn name ml time) name ml); | |
| 6168 | 140 | |
| 141 | ||
| 142 | end; | |
| 143 | ||
| 144 | structure BasicThyLoad: BASIC_THY_LOAD = ThyLoad; | |
| 145 | open BasicThyLoad; |