modules.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  1. /* Copyright (C) 1998,2000,2001,2002,2003,2004,2006,2007,2008 Free Software Foundation, Inc.
  2. *
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Lesser General Public License
  5. * as published by the Free Software Foundation; either version 3 of
  6. * the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Lesser General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Lesser General Public
  14. * License along with this library; if not, write to the Free Software
  15. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. * 02110-1301 USA
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. # include <config.h>
  20. #endif
  21. #include <stdarg.h>
  22. #include "libguile/_scm.h"
  23. #include "libguile/eval.h"
  24. #include "libguile/smob.h"
  25. #include "libguile/procprop.h"
  26. #include "libguile/vectors.h"
  27. #include "libguile/hashtab.h"
  28. #include "libguile/struct.h"
  29. #include "libguile/variable.h"
  30. #include "libguile/fluids.h"
  31. #include "libguile/deprecation.h"
  32. #include "libguile/modules.h"
  33. int scm_module_system_booted_p = 0;
  34. scm_t_bits scm_module_tag;
  35. static SCM the_module;
  36. static SCM the_root_module_var;
  37. static SCM
  38. the_root_module ()
  39. {
  40. if (scm_module_system_booted_p)
  41. return SCM_VARIABLE_REF (the_root_module_var);
  42. else
  43. return SCM_BOOL_F;
  44. }
  45. SCM_DEFINE (scm_current_module, "current-module", 0, 0, 0,
  46. (),
  47. "Return the current module.")
  48. #define FUNC_NAME s_scm_current_module
  49. {
  50. SCM curr = scm_fluid_ref (the_module);
  51. return scm_is_true (curr) ? curr : the_root_module ();
  52. }
  53. #undef FUNC_NAME
  54. static void scm_post_boot_init_modules (void);
  55. SCM_DEFINE (scm_set_current_module, "set-current-module", 1, 0, 0,
  56. (SCM module),
  57. "Set the current module to @var{module} and return\n"
  58. "the previous current module.")
  59. #define FUNC_NAME s_scm_set_current_module
  60. {
  61. SCM old;
  62. if (!scm_module_system_booted_p)
  63. scm_post_boot_init_modules ();
  64. SCM_VALIDATE_MODULE (SCM_ARG1, module);
  65. old = scm_current_module ();
  66. scm_fluid_set_x (the_module, module);
  67. return old;
  68. }
  69. #undef FUNC_NAME
  70. SCM_DEFINE (scm_interaction_environment, "interaction-environment", 0, 0, 0,
  71. (),
  72. "Return a specifier for the environment that contains\n"
  73. "implementation--defined bindings, typically a superset of those\n"
  74. "listed in the report. The intent is that this procedure will\n"
  75. "return the environment in which the implementation would\n"
  76. "evaluate expressions dynamically typed by the user.")
  77. #define FUNC_NAME s_scm_interaction_environment
  78. {
  79. return scm_current_module ();
  80. }
  81. #undef FUNC_NAME
  82. SCM
  83. scm_c_call_with_current_module (SCM module,
  84. SCM (*func)(void *), void *data)
  85. {
  86. return scm_c_with_fluid (the_module, module, func, data);
  87. }
  88. void
  89. scm_dynwind_current_module (SCM module)
  90. {
  91. scm_dynwind_fluid (the_module, module);
  92. }
  93. /*
  94. convert "A B C" to scheme list (A B C)
  95. */
  96. static SCM
  97. convert_module_name (const char *name)
  98. {
  99. SCM list = SCM_EOL;
  100. SCM *tail = &list;
  101. const char *ptr;
  102. while (*name)
  103. {
  104. while (*name == ' ')
  105. name++;
  106. ptr = name;
  107. while (*ptr && *ptr != ' ')
  108. ptr++;
  109. if (ptr > name)
  110. {
  111. SCM sym = scm_from_locale_symboln (name, ptr-name);
  112. *tail = scm_cons (sym, SCM_EOL);
  113. tail = SCM_CDRLOC (*tail);
  114. }
  115. name = ptr;
  116. }
  117. return list;
  118. }
  119. static SCM process_define_module_var;
  120. static SCM process_use_modules_var;
  121. static SCM resolve_module_var;
  122. SCM
  123. scm_c_resolve_module (const char *name)
  124. {
  125. return scm_resolve_module (convert_module_name (name));
  126. }
  127. SCM
  128. scm_resolve_module (SCM name)
  129. {
  130. return scm_call_1 (SCM_VARIABLE_REF (resolve_module_var), name);
  131. }
  132. SCM
  133. scm_c_define_module (const char *name,
  134. void (*init)(void *), void *data)
  135. {
  136. SCM module = scm_call_1 (SCM_VARIABLE_REF (process_define_module_var),
  137. scm_list_1 (convert_module_name (name)));
  138. if (init)
  139. scm_c_call_with_current_module (module, (SCM (*)(void*))init, data);
  140. return module;
  141. }
  142. void
  143. scm_c_use_module (const char *name)
  144. {
  145. scm_call_1 (SCM_VARIABLE_REF (process_use_modules_var),
  146. scm_list_1 (scm_list_1 (convert_module_name (name))));
  147. }
  148. static SCM module_export_x_var;
  149. SCM
  150. scm_module_export (SCM module, SCM namelist)
  151. {
  152. return scm_call_2 (SCM_VARIABLE_REF (module_export_x_var),
  153. module, namelist);
  154. }
  155. /*
  156. @code{scm_c_export}(@var{name-list})
  157. @code{scm_c_export} exports the named bindings from the current
  158. module, making them visible to users of the module. This function
  159. takes a list of string arguments, terminated by NULL, e.g.
  160. @example
  161. scm_c_export ("add-double-record", "bamboozle-money", NULL);
  162. @end example
  163. */
  164. void
  165. scm_c_export (const char *name, ...)
  166. {
  167. if (name)
  168. {
  169. va_list ap;
  170. SCM names = scm_cons (scm_from_locale_symbol (name), SCM_EOL);
  171. SCM *tail = SCM_CDRLOC (names);
  172. va_start (ap, name);
  173. while (1)
  174. {
  175. const char *n = va_arg (ap, const char *);
  176. if (n == NULL)
  177. break;
  178. *tail = scm_cons (scm_from_locale_symbol (n), SCM_EOL);
  179. tail = SCM_CDRLOC (*tail);
  180. }
  181. va_end (ap);
  182. scm_module_export (scm_current_module (), names);
  183. }
  184. }
  185. /* Environments */
  186. SCM
  187. scm_top_level_env (SCM thunk)
  188. {
  189. if (SCM_IMP (thunk))
  190. return SCM_EOL;
  191. else
  192. return scm_cons (thunk, SCM_EOL);
  193. }
  194. SCM
  195. scm_env_top_level (SCM env)
  196. {
  197. while (scm_is_pair (env))
  198. {
  199. SCM car_env = SCM_CAR (env);
  200. if (!scm_is_pair (car_env) && scm_is_true (scm_procedure_p (car_env)))
  201. return car_env;
  202. env = SCM_CDR (env);
  203. }
  204. return SCM_BOOL_F;
  205. }
  206. SCM_SYMBOL (sym_module, "module");
  207. SCM
  208. scm_lookup_closure_module (SCM proc)
  209. {
  210. if (scm_is_false (proc))
  211. return the_root_module ();
  212. else if (SCM_EVAL_CLOSURE_P (proc))
  213. return SCM_PACK (SCM_SMOB_DATA (proc));
  214. else
  215. {
  216. SCM mod = scm_procedure_property (proc, sym_module);
  217. if (scm_is_false (mod))
  218. mod = the_root_module ();
  219. return mod;
  220. }
  221. }
  222. SCM_DEFINE (scm_env_module, "env-module", 1, 0, 0,
  223. (SCM env),
  224. "Return the module of @var{ENV}, a lexical environment.")
  225. #define FUNC_NAME s_scm_env_module
  226. {
  227. return scm_lookup_closure_module (scm_env_top_level (env));
  228. }
  229. #undef FUNC_NAME
  230. /*
  231. * C level implementation of the standard eval closure
  232. *
  233. * This increases loading speed substantially. The code may be
  234. * replaced by something based on environments.[ch], in a future
  235. * release.
  236. */
  237. /* The `module-make-local-var!' variable. */
  238. static SCM module_make_local_var_x_var = SCM_UNSPECIFIED;
  239. /* The `default-duplicate-binding-procedures' variable. */
  240. static SCM default_duplicate_binding_procedures_var = SCM_UNSPECIFIED;
  241. /* Return the list of default duplicate binding handlers (procedures). */
  242. static inline SCM
  243. default_duplicate_binding_handlers (void)
  244. {
  245. SCM get_handlers;
  246. get_handlers = SCM_VARIABLE_REF (default_duplicate_binding_procedures_var);
  247. return (scm_call_0 (get_handlers));
  248. }
  249. /* Resolve the import of SYM in MODULE, where SYM is currently provided by
  250. both IFACE1 as VAR1 and IFACE2 as VAR2. Return the variable chosen by the
  251. duplicate binding handlers or `#f'. */
  252. static inline SCM
  253. resolve_duplicate_binding (SCM module, SCM sym,
  254. SCM iface1, SCM var1,
  255. SCM iface2, SCM var2)
  256. {
  257. SCM result = SCM_BOOL_F;
  258. if (!scm_is_eq (var1, var2))
  259. {
  260. SCM val1, val2;
  261. SCM handlers, h, handler_args;
  262. val1 = SCM_VARIABLE_REF (var1);
  263. val2 = SCM_VARIABLE_REF (var2);
  264. val1 = (val1 == SCM_UNSPECIFIED) ? SCM_BOOL_F : val1;
  265. val2 = (val2 == SCM_UNSPECIFIED) ? SCM_BOOL_F : val2;
  266. handlers = SCM_MODULE_DUPLICATE_HANDLERS (module);
  267. if (scm_is_false (handlers))
  268. handlers = default_duplicate_binding_handlers ();
  269. handler_args = scm_list_n (module, sym,
  270. iface1, val1, iface2, val2,
  271. var1, val1,
  272. SCM_UNDEFINED);
  273. for (h = handlers;
  274. scm_is_pair (h) && scm_is_false (result);
  275. h = SCM_CDR (h))
  276. {
  277. result = scm_apply (SCM_CAR (h), handler_args, SCM_EOL);
  278. }
  279. }
  280. else
  281. result = var1;
  282. return result;
  283. }
  284. SCM scm_pre_modules_obarray;
  285. /* Lookup SYM as an imported variable of MODULE. */
  286. static inline SCM
  287. module_imported_variable (SCM module, SCM sym)
  288. {
  289. #define SCM_BOUND_THING_P scm_is_true
  290. register SCM var, imports;
  291. /* Search cached imported bindings. */
  292. imports = SCM_MODULE_IMPORT_OBARRAY (module);
  293. var = scm_hashq_ref (imports, sym, SCM_UNDEFINED);
  294. if (SCM_BOUND_THING_P (var))
  295. return var;
  296. {
  297. /* Search the use list for yet uncached imported bindings, possibly
  298. resolving duplicates as needed and caching the result in the import
  299. obarray. */
  300. SCM uses;
  301. SCM found_var = SCM_BOOL_F, found_iface = SCM_BOOL_F;
  302. for (uses = SCM_MODULE_USES (module);
  303. scm_is_pair (uses);
  304. uses = SCM_CDR (uses))
  305. {
  306. SCM iface;
  307. iface = SCM_CAR (uses);
  308. var = scm_module_variable (iface, sym);
  309. if (SCM_BOUND_THING_P (var))
  310. {
  311. if (SCM_BOUND_THING_P (found_var))
  312. {
  313. /* SYM is a duplicate binding (imported more than once) so we
  314. need to resolve it. */
  315. found_var = resolve_duplicate_binding (module, sym,
  316. found_iface, found_var,
  317. iface, var);
  318. if (scm_is_eq (found_var, var))
  319. found_iface = iface;
  320. }
  321. else
  322. /* Keep track of the variable we found and check for other
  323. occurences of SYM in the use list. */
  324. found_var = var, found_iface = iface;
  325. }
  326. }
  327. if (SCM_BOUND_THING_P (found_var))
  328. {
  329. /* Save the lookup result for future reference. */
  330. (void) scm_hashq_set_x (imports, sym, found_var);
  331. return found_var;
  332. }
  333. }
  334. return SCM_BOOL_F;
  335. #undef SCM_BOUND_THING_P
  336. }
  337. SCM_DEFINE (scm_module_local_variable, "module-local-variable", 2, 0, 0,
  338. (SCM module, SCM sym),
  339. "Return the variable bound to @var{sym} in @var{module}. Return "
  340. "@code{#f} is @var{sym} is not bound locally in @var{module}.")
  341. #define FUNC_NAME s_scm_module_local_variable
  342. {
  343. #define SCM_BOUND_THING_P(b) \
  344. (scm_is_true (b))
  345. register SCM b;
  346. if (scm_module_system_booted_p)
  347. SCM_VALIDATE_MODULE (1, module);
  348. SCM_VALIDATE_SYMBOL (2, sym);
  349. if (scm_is_false (module))
  350. return scm_hashq_ref (scm_pre_modules_obarray, sym, SCM_UNDEFINED);
  351. /* 1. Check module obarray */
  352. b = scm_hashq_ref (SCM_MODULE_OBARRAY (module), sym, SCM_UNDEFINED);
  353. if (SCM_BOUND_THING_P (b))
  354. return b;
  355. /* 2. Search imported bindings. In order to be consistent with
  356. `module-variable', the binder gets called only when no imported binding
  357. matches SYM. */
  358. b = module_imported_variable (module, sym);
  359. if (SCM_BOUND_THING_P (b))
  360. return SCM_BOOL_F;
  361. {
  362. /* 3. Query the custom binder. */
  363. SCM binder = SCM_MODULE_BINDER (module);
  364. if (scm_is_true (binder))
  365. {
  366. b = scm_call_3 (binder, module, sym, SCM_BOOL_F);
  367. if (SCM_BOUND_THING_P (b))
  368. return b;
  369. }
  370. }
  371. return SCM_BOOL_F;
  372. #undef SCM_BOUND_THING_P
  373. }
  374. #undef FUNC_NAME
  375. SCM_DEFINE (scm_module_variable, "module-variable", 2, 0, 0,
  376. (SCM module, SCM sym),
  377. "Return the variable bound to @var{sym} in @var{module}. This "
  378. "may be both a local variable or an imported variable. Return "
  379. "@code{#f} is @var{sym} is not bound in @var{module}.")
  380. #define FUNC_NAME s_scm_module_variable
  381. {
  382. #define SCM_BOUND_THING_P(b) \
  383. (scm_is_true (b))
  384. register SCM var;
  385. if (scm_module_system_booted_p)
  386. SCM_VALIDATE_MODULE (1, module);
  387. SCM_VALIDATE_SYMBOL (2, sym);
  388. if (scm_is_false (module))
  389. return scm_hashq_ref (scm_pre_modules_obarray, sym, SCM_UNDEFINED);
  390. /* 1. Check module obarray */
  391. var = scm_hashq_ref (SCM_MODULE_OBARRAY (module), sym, SCM_UNDEFINED);
  392. if (SCM_BOUND_THING_P (var))
  393. return var;
  394. /* 2. Search among the imported variables. */
  395. var = module_imported_variable (module, sym);
  396. if (SCM_BOUND_THING_P (var))
  397. return var;
  398. {
  399. /* 3. Query the custom binder. */
  400. SCM binder;
  401. binder = SCM_MODULE_BINDER (module);
  402. if (scm_is_true (binder))
  403. {
  404. var = scm_call_3 (binder, module, sym, SCM_BOOL_F);
  405. if (SCM_BOUND_THING_P (var))
  406. return var;
  407. }
  408. }
  409. return SCM_BOOL_F;
  410. #undef SCM_BOUND_THING_P
  411. }
  412. #undef FUNC_NAME
  413. scm_t_bits scm_tc16_eval_closure;
  414. #define SCM_F_EVAL_CLOSURE_INTERFACE (1<<16)
  415. #define SCM_EVAL_CLOSURE_INTERFACE_P(e) \
  416. (SCM_CELL_WORD_0 (e) & SCM_F_EVAL_CLOSURE_INTERFACE)
  417. /* NOTE: This function may be called by a smob application
  418. or from another C function directly. */
  419. SCM
  420. scm_eval_closure_lookup (SCM eclo, SCM sym, SCM definep)
  421. {
  422. SCM module = SCM_PACK (SCM_SMOB_DATA (eclo));
  423. if (scm_is_true (definep))
  424. {
  425. if (SCM_EVAL_CLOSURE_INTERFACE_P (eclo))
  426. return SCM_BOOL_F;
  427. return scm_call_2 (SCM_VARIABLE_REF (module_make_local_var_x_var),
  428. module, sym);
  429. }
  430. else
  431. return scm_module_variable (module, sym);
  432. }
  433. SCM_DEFINE (scm_standard_eval_closure, "standard-eval-closure", 1, 0, 0,
  434. (SCM module),
  435. "Return an eval closure for the module @var{module}.")
  436. #define FUNC_NAME s_scm_standard_eval_closure
  437. {
  438. SCM_RETURN_NEWSMOB (scm_tc16_eval_closure, SCM_UNPACK (module));
  439. }
  440. #undef FUNC_NAME
  441. SCM_DEFINE (scm_standard_interface_eval_closure,
  442. "standard-interface-eval-closure", 1, 0, 0,
  443. (SCM module),
  444. "Return a interface eval closure for the module @var{module}. "
  445. "Such a closure does not allow new bindings to be added.")
  446. #define FUNC_NAME s_scm_standard_interface_eval_closure
  447. {
  448. SCM_RETURN_NEWSMOB (scm_tc16_eval_closure | SCM_F_EVAL_CLOSURE_INTERFACE,
  449. SCM_UNPACK (module));
  450. }
  451. #undef FUNC_NAME
  452. SCM_DEFINE (scm_eval_closure_module,
  453. "eval-closure-module", 1, 0, 0,
  454. (SCM eval_closure),
  455. "Return the module associated with this eval closure.")
  456. /* the idea is that eval closures are really not the way to do things, they're
  457. superfluous given our module system. this function lets mmacros migrate away
  458. from eval closures. */
  459. #define FUNC_NAME s_scm_eval_closure_module
  460. {
  461. SCM_MAKE_VALIDATE_MSG (SCM_ARG1, eval_closure, EVAL_CLOSURE_P,
  462. "eval-closure");
  463. return SCM_SMOB_OBJECT (eval_closure);
  464. }
  465. #undef FUNC_NAME
  466. SCM
  467. scm_module_lookup_closure (SCM module)
  468. {
  469. if (scm_is_false (module))
  470. return SCM_BOOL_F;
  471. else
  472. return SCM_MODULE_EVAL_CLOSURE (module);
  473. }
  474. SCM
  475. scm_current_module_lookup_closure ()
  476. {
  477. if (scm_module_system_booted_p)
  478. return scm_module_lookup_closure (scm_current_module ());
  479. else
  480. return SCM_BOOL_F;
  481. }
  482. SCM_SYMBOL (sym_sys_pre_modules_transformer, "%pre-modules-transformer");
  483. SCM
  484. scm_module_transformer (SCM module)
  485. {
  486. if (SCM_UNLIKELY (scm_is_false (module)))
  487. { SCM v = scm_hashq_ref (scm_pre_modules_obarray,
  488. sym_sys_pre_modules_transformer,
  489. SCM_BOOL_F);
  490. if (scm_is_false (v))
  491. return SCM_BOOL_F;
  492. else
  493. return SCM_VARIABLE_REF (v);
  494. }
  495. else
  496. return SCM_MODULE_TRANSFORMER (module);
  497. }
  498. SCM
  499. scm_current_module_transformer ()
  500. {
  501. return scm_module_transformer (scm_current_module ());
  502. }
  503. SCM_DEFINE (scm_module_import_interface, "module-import-interface", 2, 0, 0,
  504. (SCM module, SCM sym),
  505. "Return the module or interface from which @var{sym} is imported "
  506. "in @var{module}. If @var{sym} is not imported (i.e., it is not "
  507. "defined in @var{module} or it is a module-local binding instead "
  508. "of an imported one), then @code{#f} is returned.")
  509. #define FUNC_NAME s_scm_module_import_interface
  510. {
  511. SCM var, result = SCM_BOOL_F;
  512. SCM_VALIDATE_MODULE (1, module);
  513. SCM_VALIDATE_SYMBOL (2, sym);
  514. var = scm_module_variable (module, sym);
  515. if (scm_is_true (var))
  516. {
  517. /* Look for the module that provides VAR. */
  518. SCM local_var;
  519. local_var = scm_hashq_ref (SCM_MODULE_OBARRAY (module), sym,
  520. SCM_UNDEFINED);
  521. if (scm_is_eq (local_var, var))
  522. result = module;
  523. else
  524. {
  525. /* Look for VAR among the used modules. */
  526. SCM uses, imported_var;
  527. for (uses = SCM_MODULE_USES (module);
  528. scm_is_pair (uses) && scm_is_false (result);
  529. uses = SCM_CDR (uses))
  530. {
  531. imported_var = scm_module_variable (SCM_CAR (uses), sym);
  532. if (scm_is_eq (imported_var, var))
  533. result = SCM_CAR (uses);
  534. }
  535. }
  536. }
  537. return result;
  538. }
  539. #undef FUNC_NAME
  540. SCM_SYMBOL (sym_sys_module_public_interface, "%module-public-interface");
  541. SCM_DEFINE (scm_module_public_interface, "module-public-interface", 1, 0, 0,
  542. (SCM module),
  543. "Return the public interface of @var{module}.\n\n"
  544. "If @var{module} has no public interface, @code{#f} is returned.")
  545. #define FUNC_NAME s_scm_module_public_interface
  546. {
  547. SCM var;
  548. SCM_VALIDATE_MODULE (1, module);
  549. var = scm_module_local_variable (module, sym_sys_module_public_interface);
  550. if (scm_is_true (var))
  551. return SCM_VARIABLE_REF (var);
  552. else
  553. return SCM_BOOL_F;
  554. }
  555. #undef FUNC_NAME
  556. /* scm_sym2var
  557. *
  558. * looks up the variable bound to SYM according to PROC. PROC should be
  559. * a `eval closure' of some module.
  560. *
  561. * When no binding exists, and DEFINEP is true, create a new binding
  562. * with a initial value of SCM_UNDEFINED. Return `#f' when DEFINEP as
  563. * false and no binding exists.
  564. *
  565. * When PROC is `#f', it is ignored and the binding is searched for in
  566. * the scm_pre_modules_obarray (a `eq' hash table).
  567. */
  568. SCM
  569. scm_sym2var (SCM sym, SCM proc, SCM definep)
  570. #define FUNC_NAME "scm_sym2var"
  571. {
  572. SCM var;
  573. if (SCM_NIMP (proc))
  574. {
  575. if (SCM_EVAL_CLOSURE_P (proc))
  576. {
  577. /* Bypass evaluator in the standard case. */
  578. var = scm_eval_closure_lookup (proc, sym, definep);
  579. }
  580. else
  581. var = scm_call_2 (proc, sym, definep);
  582. }
  583. else
  584. {
  585. SCM handle;
  586. if (scm_is_false (definep))
  587. var = scm_hashq_ref (scm_pre_modules_obarray, sym, SCM_BOOL_F);
  588. else
  589. {
  590. handle = scm_hashq_create_handle_x (scm_pre_modules_obarray,
  591. sym, SCM_BOOL_F);
  592. var = SCM_CDR (handle);
  593. if (scm_is_false (var))
  594. {
  595. var = scm_make_variable (SCM_UNDEFINED);
  596. SCM_SETCDR (handle, var);
  597. }
  598. }
  599. }
  600. if (scm_is_true (var) && !SCM_VARIABLEP (var))
  601. SCM_MISC_ERROR ("~S is not bound to a variable", scm_list_1 (sym));
  602. return var;
  603. }
  604. #undef FUNC_NAME
  605. SCM
  606. scm_c_module_lookup (SCM module, const char *name)
  607. {
  608. return scm_module_lookup (module, scm_from_locale_symbol (name));
  609. }
  610. SCM
  611. scm_module_lookup (SCM module, SCM sym)
  612. #define FUNC_NAME "module-lookup"
  613. {
  614. SCM var;
  615. SCM_VALIDATE_MODULE (1, module);
  616. var = scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_F);
  617. if (scm_is_false (var))
  618. SCM_MISC_ERROR ("unbound variable: ~S", scm_list_1 (sym));
  619. return var;
  620. }
  621. #undef FUNC_NAME
  622. SCM
  623. scm_c_lookup (const char *name)
  624. {
  625. return scm_lookup (scm_from_locale_symbol (name));
  626. }
  627. SCM
  628. scm_lookup (SCM sym)
  629. {
  630. SCM var =
  631. scm_sym2var (sym, scm_current_module_lookup_closure (), SCM_BOOL_F);
  632. if (scm_is_false (var))
  633. scm_misc_error ("scm_lookup", "unbound variable: ~S", scm_list_1 (sym));
  634. return var;
  635. }
  636. SCM
  637. scm_c_module_define (SCM module, const char *name, SCM value)
  638. {
  639. return scm_module_define (module, scm_from_locale_symbol (name), value);
  640. }
  641. SCM
  642. scm_module_define (SCM module, SCM sym, SCM value)
  643. #define FUNC_NAME "module-define"
  644. {
  645. SCM var;
  646. SCM_VALIDATE_MODULE (1, module);
  647. var = scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_T);
  648. SCM_VARIABLE_SET (var, value);
  649. return var;
  650. }
  651. #undef FUNC_NAME
  652. SCM
  653. scm_c_define (const char *name, SCM value)
  654. {
  655. return scm_define (scm_from_locale_symbol (name), value);
  656. }
  657. SCM
  658. scm_define (SCM sym, SCM value)
  659. {
  660. SCM var =
  661. scm_sym2var (sym, scm_current_module_lookup_closure (), SCM_BOOL_T);
  662. SCM_VARIABLE_SET (var, value);
  663. return var;
  664. }
  665. SCM_DEFINE (scm_module_reverse_lookup, "module-reverse-lookup", 2, 0, 0,
  666. (SCM module, SCM variable),
  667. "Return the symbol under which @var{variable} is bound in "
  668. "@var{module} or @var{#f} if @var{variable} is not visible "
  669. "from @var{module}. If @var{module} is @code{#f}, then the "
  670. "pre-module obarray is used.")
  671. #define FUNC_NAME s_scm_module_reverse_lookup
  672. {
  673. SCM obarray;
  674. long i, n;
  675. if (scm_is_false (module))
  676. obarray = scm_pre_modules_obarray;
  677. else
  678. {
  679. SCM_VALIDATE_MODULE (1, module);
  680. obarray = SCM_MODULE_OBARRAY (module);
  681. }
  682. if (!SCM_HASHTABLE_P (obarray))
  683. return SCM_BOOL_F;
  684. /* XXX - We do not use scm_hash_fold here to avoid searching the
  685. whole obarray. We should have a scm_hash_find procedure. */
  686. n = SCM_HASHTABLE_N_BUCKETS (obarray);
  687. for (i = 0; i < n; ++i)
  688. {
  689. SCM ls = SCM_HASHTABLE_BUCKET (obarray, i), handle;
  690. while (!scm_is_null (ls))
  691. {
  692. handle = SCM_CAR (ls);
  693. if (SCM_CDR (handle) == variable)
  694. return SCM_CAR (handle);
  695. ls = SCM_CDR (ls);
  696. }
  697. }
  698. /* Try the `uses' list. */
  699. {
  700. SCM uses = SCM_MODULE_USES (module);
  701. while (scm_is_pair (uses))
  702. {
  703. SCM sym = scm_module_reverse_lookup (SCM_CAR (uses), variable);
  704. if (scm_is_true (sym))
  705. return sym;
  706. uses = SCM_CDR (uses);
  707. }
  708. }
  709. return SCM_BOOL_F;
  710. }
  711. #undef FUNC_NAME
  712. SCM_DEFINE (scm_get_pre_modules_obarray, "%get-pre-modules-obarray", 0, 0, 0,
  713. (),
  714. "Return the obarray that is used for all new bindings before "
  715. "the module system is booted. The first call to "
  716. "@code{set-current-module} will boot the module system.")
  717. #define FUNC_NAME s_scm_get_pre_modules_obarray
  718. {
  719. return scm_pre_modules_obarray;
  720. }
  721. #undef FUNC_NAME
  722. SCM_SYMBOL (scm_sym_system_module, "system-module");
  723. SCM
  724. scm_system_module_env_p (SCM env)
  725. {
  726. SCM proc = scm_env_top_level (env);
  727. if (scm_is_false (proc))
  728. return SCM_BOOL_T;
  729. return ((scm_is_true (scm_procedure_property (proc,
  730. scm_sym_system_module)))
  731. ? SCM_BOOL_T
  732. : SCM_BOOL_F);
  733. }
  734. void
  735. scm_modules_prehistory ()
  736. {
  737. scm_pre_modules_obarray
  738. = scm_permanent_object (scm_c_make_hash_table (1533));
  739. }
  740. void
  741. scm_init_modules ()
  742. {
  743. #include "libguile/modules.x"
  744. module_make_local_var_x_var = scm_c_define ("module-make-local-var!",
  745. SCM_UNDEFINED);
  746. scm_tc16_eval_closure = scm_make_smob_type ("eval-closure", 0);
  747. scm_set_smob_mark (scm_tc16_eval_closure, scm_markcdr);
  748. scm_set_smob_apply (scm_tc16_eval_closure, scm_eval_closure_lookup, 2, 0, 0);
  749. the_module = scm_permanent_object (scm_make_fluid ());
  750. }
  751. static void
  752. scm_post_boot_init_modules ()
  753. {
  754. #define PERM(x) scm_permanent_object(x)
  755. SCM module_type = SCM_VARIABLE_REF (scm_c_lookup ("module-type"));
  756. scm_module_tag = (SCM_CELL_WORD_1 (module_type) + scm_tc3_struct);
  757. resolve_module_var = PERM (scm_c_lookup ("resolve-module"));
  758. process_define_module_var = PERM (scm_c_lookup ("process-define-module"));
  759. process_use_modules_var = PERM (scm_c_lookup ("process-use-modules"));
  760. module_export_x_var = PERM (scm_c_lookup ("module-export!"));
  761. the_root_module_var = PERM (scm_c_lookup ("the-root-module"));
  762. default_duplicate_binding_procedures_var =
  763. PERM (scm_c_lookup ("default-duplicate-binding-procedures"));
  764. scm_module_system_booted_p = 1;
  765. }
  766. /*
  767. Local Variables:
  768. c-file-style: "gnu"
  769. End:
  770. */