modules.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* Copyright (C) 1998, 2000, 2002 Free Software Foundation, Inc.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2, or (at your option)
  6. * any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; see the file COPYING. If not, write to
  15. * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  16. * Boston, MA 02111-1307 USA
  17. *
  18. * As a special exception, the Free Software Foundation gives permission
  19. * for additional uses of the text contained in its release of GUILE.
  20. *
  21. * The exception is that, if you link the GUILE library with other files
  22. * to produce an executable, this does not by itself cause the
  23. * resulting executable to be covered by the GNU General Public License.
  24. * Your use of that executable is in no way restricted on account of
  25. * linking the GUILE library code into it.
  26. *
  27. * This exception does not however invalidate any other reasons why
  28. * the executable file might be covered by the GNU General Public License.
  29. *
  30. * This exception applies only to the code released by the
  31. * Free Software Foundation under the name GUILE. If you copy
  32. * code from other Free Software Foundation releases into a copy of
  33. * GUILE, as the General Public License permits, the exception does
  34. * not apply to the code that you add in this way. To avoid misleading
  35. * anyone as to the status of such modified files, you must delete
  36. * this exception notice from them.
  37. *
  38. * If you write modifications of your own for GUILE, it is your choice
  39. * whether to permit this exception to apply to your modifications.
  40. * If you do not wish that, delete this exception notice. */
  41. #include "libguile/_scm.h"
  42. #include "libguile/eval.h"
  43. #include "libguile/procprop.h"
  44. #include "libguile/vectors.h"
  45. #include "libguile/hashtab.h"
  46. #include "libguile/struct.h"
  47. #include "libguile/variable.h"
  48. #include "libguile/modules.h"
  49. static SCM the_root_module;
  50. static SCM root_module_lookup_closure;
  51. SCM
  52. scm_the_root_module ()
  53. {
  54. return SCM_CDR (the_root_module);
  55. }
  56. static SCM the_module;
  57. SCM
  58. scm_selected_module ()
  59. {
  60. return SCM_CDR (the_module);
  61. }
  62. static SCM set_current_module;
  63. SCM
  64. scm_select_module (SCM module)
  65. {
  66. SCM old = scm_selected_module ();
  67. scm_apply (SCM_CDR (set_current_module), SCM_LIST1 (module), SCM_EOL);
  68. return old;
  69. }
  70. SCM_SYMBOL (scm_sym_app, "app");
  71. SCM_SYMBOL (scm_sym_modules, "modules");
  72. static SCM module_prefix;
  73. static SCM
  74. scm_module_full_name (SCM name)
  75. {
  76. if (SCM_EQ_P (SCM_CAR (name), scm_sym_app))
  77. return name;
  78. else
  79. return scm_append (SCM_LIST2 (module_prefix, name));
  80. }
  81. static SCM make_modules_in;
  82. static SCM beautify_user_module_x;
  83. SCM
  84. scm_make_module (SCM name)
  85. {
  86. return scm_apply (SCM_CDR (make_modules_in),
  87. SCM_LIST2 (scm_the_root_module (),
  88. scm_module_full_name (name)),
  89. SCM_EOL);
  90. }
  91. SCM
  92. scm_ensure_user_module (SCM module)
  93. {
  94. scm_apply (SCM_CDR (beautify_user_module_x), SCM_LIST1 (module), SCM_EOL);
  95. return SCM_UNSPECIFIED;
  96. }
  97. static SCM module_eval_closure;
  98. SCM
  99. scm_module_lookup_closure (SCM module)
  100. {
  101. return scm_apply (SCM_CDR (module_eval_closure),
  102. SCM_LIST1 (module),
  103. SCM_EOL);
  104. }
  105. static SCM resolve_module;
  106. SCM
  107. scm_resolve_module (SCM name)
  108. {
  109. return scm_apply (SCM_CDR (resolve_module), SCM_LIST1 (name), SCM_EOL);
  110. }
  111. static SCM try_module_autoload;
  112. SCM
  113. scm_load_scheme_module (SCM name)
  114. {
  115. return scm_apply (SCM_CDR (try_module_autoload), SCM_LIST1 (name), SCM_EOL);
  116. }
  117. /* Environments
  118. */
  119. SCM
  120. scm_top_level_env (SCM thunk)
  121. {
  122. if (SCM_IMP (thunk))
  123. return SCM_EOL;
  124. else
  125. return scm_cons (thunk, SCM_EOL);
  126. }
  127. SCM
  128. scm_env_top_level (SCM env)
  129. {
  130. while (SCM_NIMP (env))
  131. {
  132. if (!SCM_CONSP (SCM_CAR (env))
  133. && SCM_NFALSEP (scm_procedure_p (SCM_CAR (env))))
  134. return SCM_CAR (env);
  135. env = SCM_CDR (env);
  136. }
  137. return SCM_BOOL_F;
  138. }
  139. SCM_SYMBOL (scm_sym_system_module, "system-module");
  140. SCM
  141. scm_system_module_env_p (SCM env)
  142. {
  143. SCM proc = scm_env_top_level (env);
  144. if (SCM_FALSEP (proc))
  145. proc = root_module_lookup_closure;
  146. return ((SCM_NFALSEP (scm_procedure_property (proc,
  147. scm_sym_system_module)))
  148. ? SCM_BOOL_T
  149. : SCM_BOOL_F);
  150. }
  151. /*
  152. * C level implementation of the standard eval closure
  153. *
  154. * This increases loading speed substantially.
  155. * The code will be replaced by the low-level environments in next release.
  156. */
  157. #define OBARRAY(module) (SCM_STRUCT_DATA (module) [0])
  158. #define USES(module) (SCM_STRUCT_DATA (module) [1])
  159. #define BINDER(module) (SCM_STRUCT_DATA (module) [2])
  160. static SCM module_make_local_var_x;
  161. static SCM
  162. module_variable (SCM module, SCM sym)
  163. {
  164. /* 1. Check module obarray */
  165. SCM b = scm_hashq_ref (OBARRAY (module), sym, SCM_UNDEFINED);
  166. if (SCM_VARIABLEP (b))
  167. return b;
  168. {
  169. SCM binder = BINDER (module);
  170. if (SCM_NFALSEP (binder))
  171. /* 2. Custom binder */
  172. {
  173. b = scm_apply (binder,
  174. SCM_LIST3 (module, sym, SCM_BOOL_F),
  175. SCM_EOL);
  176. if (SCM_NFALSEP (b))
  177. return b;
  178. }
  179. }
  180. {
  181. /* 3. Search the use list */
  182. SCM uses = USES (module);
  183. while (SCM_CONSP (uses))
  184. {
  185. b = module_variable (SCM_CAR (uses), sym);
  186. if (SCM_NFALSEP (b))
  187. return b;
  188. uses = SCM_CDR (uses);
  189. }
  190. return SCM_BOOL_F;
  191. }
  192. }
  193. static SCM f_eval_closure;
  194. static SCM
  195. eval_closure (SCM cclo, SCM sym, SCM definep)
  196. {
  197. SCM module = SCM_VELTS (cclo) [1];
  198. if (SCM_NFALSEP (definep))
  199. return scm_apply (SCM_CDR (module_make_local_var_x),
  200. SCM_LIST2 (module, sym),
  201. SCM_EOL);
  202. else
  203. return module_variable (module, sym);
  204. }
  205. SCM_DEFINE (scm_standard_eval_closure, "standard-eval-closure", 1, 0, 0,
  206. (SCM module),
  207. "")
  208. #define FUNC_NAME s_scm_standard_eval_closure
  209. {
  210. SCM cclo = scm_makcclo (f_eval_closure, SCM_MAKINUM (2));
  211. SCM_VELTS (cclo) [1] = module;
  212. return cclo;
  213. }
  214. #undef FUNC_NAME
  215. void
  216. scm_init_modules ()
  217. {
  218. #include "libguile/modules.x"
  219. module_make_local_var_x = scm_sysintern ("module-make-local-var!",
  220. SCM_UNDEFINED);
  221. f_eval_closure = scm_make_subr_opt ("eval-closure",
  222. scm_tc7_subr_3,
  223. eval_closure,
  224. 0);
  225. }
  226. void
  227. scm_post_boot_init_modules ()
  228. {
  229. the_root_module = scm_intern0 ("the-root-module");
  230. the_module = scm_intern0 ("the-module");
  231. set_current_module = scm_intern0 ("set-current-module");
  232. module_prefix = scm_permanent_object (SCM_LIST2 (scm_sym_app,
  233. scm_sym_modules));
  234. make_modules_in = scm_intern0 ("make-modules-in");
  235. beautify_user_module_x = scm_intern0 ("beautify-user-module!");
  236. module_eval_closure = scm_intern0 ("module-eval-closure");
  237. root_module_lookup_closure = scm_permanent_object
  238. (scm_module_lookup_closure (SCM_CDR (the_root_module)));
  239. resolve_module = scm_intern0 ("resolve-module");
  240. try_module_autoload = scm_intern0 ("try-module-autoload");
  241. }
  242. /*
  243. Local Variables:
  244. c-file-style: "gnu"
  245. End:
  246. */