modules.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. /* Copyright (C) 1998,2000,2001,2002, 2003, 2004, 2006, 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
  5. * License as published by the Free Software Foundation; either
  6. * version 2.1 of the License, or (at your option) any later version.
  7. *
  8. * This library 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 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 02110-1301 USA
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. # include <config.h>
  19. #endif
  20. #include <stdarg.h>
  21. #include "libguile/_scm.h"
  22. #include "libguile/eval.h"
  23. #include "libguile/smob.h"
  24. #include "libguile/procprop.h"
  25. #include "libguile/vectors.h"
  26. #include "libguile/hashtab.h"
  27. #include "libguile/struct.h"
  28. #include "libguile/variable.h"
  29. #include "libguile/fluids.h"
  30. #include "libguile/deprecation.h"
  31. #include "libguile/modules.h"
  32. int scm_module_system_booted_p = 0;
  33. scm_t_bits scm_module_tag;
  34. static SCM the_module;
  35. static SCM the_root_module_var;
  36. static SCM
  37. the_root_module ()
  38. {
  39. if (scm_module_system_booted_p)
  40. return SCM_VARIABLE_REF (the_root_module_var);
  41. else
  42. return SCM_BOOL_F;
  43. }
  44. SCM_DEFINE (scm_current_module, "current-module", 0, 0, 0,
  45. (),
  46. "Return the current module.")
  47. #define FUNC_NAME s_scm_current_module
  48. {
  49. SCM curr = scm_fluid_ref (the_module);
  50. return scm_is_true (curr) ? curr : the_root_module ();
  51. }
  52. #undef FUNC_NAME
  53. static void scm_post_boot_init_modules (void);
  54. SCM_DEFINE (scm_set_current_module, "set-current-module", 1, 0, 0,
  55. (SCM module),
  56. "Set the current module to @var{module} and return\n"
  57. "the previous current module.")
  58. #define FUNC_NAME s_scm_set_current_module
  59. {
  60. SCM old;
  61. if (!scm_module_system_booted_p)
  62. scm_post_boot_init_modules ();
  63. SCM_VALIDATE_MODULE (SCM_ARG1, module);
  64. old = scm_current_module ();
  65. scm_fluid_set_x (the_module, module);
  66. return old;
  67. }
  68. #undef FUNC_NAME
  69. SCM_DEFINE (scm_interaction_environment, "interaction-environment", 0, 0, 0,
  70. (),
  71. "Return a specifier for the environment that contains\n"
  72. "implementation--defined bindings, typically a superset of those\n"
  73. "listed in the report. The intent is that this procedure will\n"
  74. "return the environment in which the implementation would\n"
  75. "evaluate expressions dynamically typed by the user.")
  76. #define FUNC_NAME s_scm_interaction_environment
  77. {
  78. return scm_current_module ();
  79. }
  80. #undef FUNC_NAME
  81. SCM
  82. scm_c_call_with_current_module (SCM module,
  83. SCM (*func)(void *), void *data)
  84. {
  85. return scm_c_with_fluid (the_module, module, func, data);
  86. }
  87. void
  88. scm_dynwind_current_module (SCM module)
  89. {
  90. scm_dynwind_fluid (the_module, module);
  91. }
  92. /*
  93. convert "A B C" to scheme list (A B C)
  94. */
  95. static SCM
  96. convert_module_name (const char *name)
  97. {
  98. SCM list = SCM_EOL;
  99. SCM *tail = &list;
  100. const char *ptr;
  101. while (*name)
  102. {
  103. while (*name == ' ')
  104. name++;
  105. ptr = name;
  106. while (*ptr && *ptr != ' ')
  107. ptr++;
  108. if (ptr > name)
  109. {
  110. SCM sym = scm_from_locale_symboln (name, ptr-name);
  111. *tail = scm_cons (sym, SCM_EOL);
  112. tail = SCM_CDRLOC (*tail);
  113. }
  114. name = ptr;
  115. }
  116. return list;
  117. }
  118. static SCM process_define_module_var;
  119. static SCM process_use_modules_var;
  120. static SCM resolve_module_var;
  121. SCM
  122. scm_c_resolve_module (const char *name)
  123. {
  124. return scm_resolve_module (convert_module_name (name));
  125. }
  126. SCM
  127. scm_resolve_module (SCM name)
  128. {
  129. return scm_call_1 (SCM_VARIABLE_REF (resolve_module_var), name);
  130. }
  131. SCM
  132. scm_c_define_module (const char *name,
  133. void (*init)(void *), void *data)
  134. {
  135. SCM module = scm_call_1 (SCM_VARIABLE_REF (process_define_module_var),
  136. scm_list_1 (convert_module_name (name)));
  137. if (init)
  138. scm_c_call_with_current_module (module, (SCM (*)(void*))init, data);
  139. return module;
  140. }
  141. void
  142. scm_c_use_module (const char *name)
  143. {
  144. scm_call_1 (SCM_VARIABLE_REF (process_use_modules_var),
  145. scm_list_1 (scm_list_1 (convert_module_name (name))));
  146. }
  147. static SCM module_export_x_var;
  148. /*
  149. TODO: should export this function? --hwn.
  150. */
  151. static SCM
  152. scm_export (SCM module, SCM namelist)
  153. {
  154. return scm_call_2 (SCM_VARIABLE_REF (module_export_x_var),
  155. module, namelist);
  156. }
  157. /*
  158. @code{scm_c_export}(@var{name-list})
  159. @code{scm_c_export} exports the named bindings from the current
  160. module, making them visible to users of the module. This function
  161. takes a list of string arguments, terminated by NULL, e.g.
  162. @example
  163. scm_c_export ("add-double-record", "bamboozle-money", NULL);
  164. @end example
  165. */
  166. void
  167. scm_c_export (const char *name, ...)
  168. {
  169. if (name)
  170. {
  171. va_list ap;
  172. SCM names = scm_cons (scm_from_locale_symbol (name), SCM_EOL);
  173. SCM *tail = SCM_CDRLOC (names);
  174. va_start (ap, name);
  175. while (1)
  176. {
  177. const char *n = va_arg (ap, const char *);
  178. if (n == NULL)
  179. break;
  180. *tail = scm_cons (scm_from_locale_symbol (n), SCM_EOL);
  181. tail = SCM_CDRLOC (*tail);
  182. }
  183. va_end (ap);
  184. scm_export (scm_current_module(), names);
  185. }
  186. }
  187. /* Environments */
  188. SCM
  189. scm_top_level_env (SCM thunk)
  190. {
  191. if (SCM_IMP (thunk))
  192. return SCM_EOL;
  193. else
  194. return scm_cons (thunk, SCM_EOL);
  195. }
  196. SCM
  197. scm_env_top_level (SCM env)
  198. {
  199. while (scm_is_pair (env))
  200. {
  201. SCM car_env = SCM_CAR (env);
  202. if (!scm_is_pair (car_env) && scm_is_true (scm_procedure_p (car_env)))
  203. return car_env;
  204. env = SCM_CDR (env);
  205. }
  206. return SCM_BOOL_F;
  207. }
  208. SCM_SYMBOL (sym_module, "module");
  209. SCM
  210. scm_lookup_closure_module (SCM proc)
  211. {
  212. if (scm_is_false (proc))
  213. return the_root_module ();
  214. else if (SCM_EVAL_CLOSURE_P (proc))
  215. return SCM_PACK (SCM_SMOB_DATA (proc));
  216. else
  217. {
  218. SCM mod = scm_procedure_property (proc, sym_module);
  219. if (scm_is_false (mod))
  220. mod = the_root_module ();
  221. return mod;
  222. }
  223. }
  224. SCM_DEFINE (scm_env_module, "env-module", 1, 0, 0,
  225. (SCM env),
  226. "Return the module of @var{ENV}, a lexical environment.")
  227. #define FUNC_NAME s_scm_env_module
  228. {
  229. return scm_lookup_closure_module (scm_env_top_level (env));
  230. }
  231. #undef FUNC_NAME
  232. /*
  233. * C level implementation of the standard eval closure
  234. *
  235. * This increases loading speed substantially.
  236. * The code will be replaced by the low-level environments in next release.
  237. */
  238. static SCM module_make_local_var_x_var;
  239. static SCM
  240. module_variable (SCM module, SCM sym)
  241. {
  242. #define SCM_BOUND_THING_P(b) \
  243. (scm_is_true (b))
  244. /* 1. Check module obarray */
  245. SCM b = scm_hashq_ref (SCM_MODULE_OBARRAY (module), sym, SCM_UNDEFINED);
  246. if (SCM_BOUND_THING_P (b))
  247. return b;
  248. {
  249. SCM binder = SCM_MODULE_BINDER (module);
  250. if (scm_is_true (binder))
  251. /* 2. Custom binder */
  252. {
  253. b = scm_call_3 (binder, module, sym, SCM_BOOL_F);
  254. if (SCM_BOUND_THING_P (b))
  255. return b;
  256. }
  257. }
  258. {
  259. /* 3. Search the use list */
  260. SCM uses = SCM_MODULE_USES (module);
  261. while (scm_is_pair (uses))
  262. {
  263. b = module_variable (SCM_CAR (uses), sym);
  264. if (SCM_BOUND_THING_P (b))
  265. return b;
  266. uses = SCM_CDR (uses);
  267. }
  268. return SCM_BOOL_F;
  269. }
  270. #undef SCM_BOUND_THING_P
  271. }
  272. scm_t_bits scm_tc16_eval_closure;
  273. #define SCM_F_EVAL_CLOSURE_INTERFACE (1<<16)
  274. #define SCM_EVAL_CLOSURE_INTERFACE_P(e) \
  275. (SCM_CELL_WORD_0 (e) & SCM_F_EVAL_CLOSURE_INTERFACE)
  276. /* NOTE: This function may be called by a smob application
  277. or from another C function directly. */
  278. SCM
  279. scm_eval_closure_lookup (SCM eclo, SCM sym, SCM definep)
  280. {
  281. SCM module = SCM_PACK (SCM_SMOB_DATA (eclo));
  282. if (scm_is_true (definep))
  283. {
  284. if (SCM_EVAL_CLOSURE_INTERFACE_P (eclo))
  285. return SCM_BOOL_F;
  286. return scm_call_2 (SCM_VARIABLE_REF (module_make_local_var_x_var),
  287. module, sym);
  288. }
  289. else
  290. return module_variable (module, sym);
  291. }
  292. SCM_DEFINE (scm_standard_eval_closure, "standard-eval-closure", 1, 0, 0,
  293. (SCM module),
  294. "Return an eval closure for the module @var{module}.")
  295. #define FUNC_NAME s_scm_standard_eval_closure
  296. {
  297. SCM_RETURN_NEWSMOB (scm_tc16_eval_closure, SCM_UNPACK (module));
  298. }
  299. #undef FUNC_NAME
  300. SCM_DEFINE (scm_standard_interface_eval_closure,
  301. "standard-interface-eval-closure", 1, 0, 0,
  302. (SCM module),
  303. "Return a interface eval closure for the module @var{module}. "
  304. "Such a closure does not allow new bindings to be added.")
  305. #define FUNC_NAME s_scm_standard_interface_eval_closure
  306. {
  307. SCM_RETURN_NEWSMOB (scm_tc16_eval_closure | SCM_F_EVAL_CLOSURE_INTERFACE,
  308. SCM_UNPACK (module));
  309. }
  310. #undef FUNC_NAME
  311. SCM
  312. scm_module_lookup_closure (SCM module)
  313. {
  314. if (scm_is_false (module))
  315. return SCM_BOOL_F;
  316. else
  317. return SCM_MODULE_EVAL_CLOSURE (module);
  318. }
  319. SCM
  320. scm_current_module_lookup_closure ()
  321. {
  322. if (scm_module_system_booted_p)
  323. return scm_module_lookup_closure (scm_current_module ());
  324. else
  325. return SCM_BOOL_F;
  326. }
  327. SCM
  328. scm_module_transformer (SCM module)
  329. {
  330. if (scm_is_false (module))
  331. return SCM_BOOL_F;
  332. else
  333. return SCM_MODULE_TRANSFORMER (module);
  334. }
  335. SCM
  336. scm_current_module_transformer ()
  337. {
  338. if (scm_module_system_booted_p)
  339. return scm_module_transformer (scm_current_module ());
  340. else
  341. return SCM_BOOL_F;
  342. }
  343. SCM_DEFINE (scm_module_import_interface, "module-import-interface", 2, 0, 0,
  344. (SCM module, SCM sym),
  345. "")
  346. #define FUNC_NAME s_scm_module_import_interface
  347. {
  348. #define SCM_BOUND_THING_P(b) (scm_is_true (b))
  349. SCM uses;
  350. SCM_VALIDATE_MODULE (SCM_ARG1, module);
  351. /* Search the use list */
  352. uses = SCM_MODULE_USES (module);
  353. while (scm_is_pair (uses))
  354. {
  355. SCM _interface = SCM_CAR (uses);
  356. /* 1. Check module obarray */
  357. SCM b = scm_hashq_ref (SCM_MODULE_OBARRAY (_interface), sym, SCM_BOOL_F);
  358. if (SCM_BOUND_THING_P (b))
  359. return _interface;
  360. {
  361. SCM binder = SCM_MODULE_BINDER (_interface);
  362. if (scm_is_true (binder))
  363. /* 2. Custom binder */
  364. {
  365. b = scm_call_3 (binder, _interface, sym, SCM_BOOL_F);
  366. if (SCM_BOUND_THING_P (b))
  367. return _interface;
  368. }
  369. }
  370. /* 3. Search use list recursively. */
  371. _interface = scm_module_import_interface (_interface, sym);
  372. if (scm_is_true (_interface))
  373. return _interface;
  374. uses = SCM_CDR (uses);
  375. }
  376. return SCM_BOOL_F;
  377. }
  378. #undef FUNC_NAME
  379. /* scm_sym2var
  380. *
  381. * looks up the variable bound to SYM according to PROC. PROC should be
  382. * a `eval closure' of some module.
  383. *
  384. * When no binding exists, and DEFINEP is true, create a new binding
  385. * with a initial value of SCM_UNDEFINED. Return `#f' when DEFINEP as
  386. * false and no binding exists.
  387. *
  388. * When PROC is `#f', it is ignored and the binding is searched for in
  389. * the scm_pre_modules_obarray (a `eq' hash table).
  390. */
  391. SCM scm_pre_modules_obarray;
  392. SCM
  393. scm_sym2var (SCM sym, SCM proc, SCM definep)
  394. #define FUNC_NAME "scm_sym2var"
  395. {
  396. SCM var;
  397. if (SCM_NIMP (proc))
  398. {
  399. if (SCM_EVAL_CLOSURE_P (proc))
  400. {
  401. /* Bypass evaluator in the standard case. */
  402. var = scm_eval_closure_lookup (proc, sym, definep);
  403. }
  404. else
  405. var = scm_call_2 (proc, sym, definep);
  406. }
  407. else
  408. {
  409. SCM handle;
  410. if (scm_is_false (definep))
  411. var = scm_hashq_ref (scm_pre_modules_obarray, sym, SCM_BOOL_F);
  412. else
  413. {
  414. handle = scm_hashq_create_handle_x (scm_pre_modules_obarray,
  415. sym, SCM_BOOL_F);
  416. var = SCM_CDR (handle);
  417. if (scm_is_false (var))
  418. {
  419. var = scm_make_variable (SCM_UNDEFINED);
  420. SCM_SETCDR (handle, var);
  421. }
  422. }
  423. }
  424. if (scm_is_true (var) && !SCM_VARIABLEP (var))
  425. SCM_MISC_ERROR ("~S is not bound to a variable", scm_list_1 (sym));
  426. return var;
  427. }
  428. #undef FUNC_NAME
  429. SCM
  430. scm_c_module_lookup (SCM module, const char *name)
  431. {
  432. return scm_module_lookup (module, scm_from_locale_symbol (name));
  433. }
  434. SCM
  435. scm_module_lookup (SCM module, SCM sym)
  436. #define FUNC_NAME "module-lookup"
  437. {
  438. SCM var;
  439. SCM_VALIDATE_MODULE (1, module);
  440. var = scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_F);
  441. if (scm_is_false (var))
  442. SCM_MISC_ERROR ("unbound variable: ~S", scm_list_1 (sym));
  443. return var;
  444. }
  445. #undef FUNC_NAME
  446. SCM
  447. scm_c_lookup (const char *name)
  448. {
  449. return scm_lookup (scm_from_locale_symbol (name));
  450. }
  451. SCM
  452. scm_lookup (SCM sym)
  453. {
  454. SCM var =
  455. scm_sym2var (sym, scm_current_module_lookup_closure (), SCM_BOOL_F);
  456. if (scm_is_false (var))
  457. scm_misc_error ("scm_lookup", "unbound variable: ~S", scm_list_1 (sym));
  458. return var;
  459. }
  460. SCM
  461. scm_c_module_define (SCM module, const char *name, SCM value)
  462. {
  463. return scm_module_define (module, scm_from_locale_symbol (name), value);
  464. }
  465. SCM
  466. scm_module_define (SCM module, SCM sym, SCM value)
  467. #define FUNC_NAME "module-define"
  468. {
  469. SCM var;
  470. SCM_VALIDATE_MODULE (1, module);
  471. var = scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_T);
  472. SCM_VARIABLE_SET (var, value);
  473. return var;
  474. }
  475. #undef FUNC_NAME
  476. SCM
  477. scm_c_define (const char *name, SCM value)
  478. {
  479. return scm_define (scm_from_locale_symbol (name), value);
  480. }
  481. SCM
  482. scm_define (SCM sym, SCM value)
  483. {
  484. SCM var =
  485. scm_sym2var (sym, scm_current_module_lookup_closure (), SCM_BOOL_T);
  486. SCM_VARIABLE_SET (var, value);
  487. return var;
  488. }
  489. SCM
  490. scm_module_reverse_lookup (SCM module, SCM variable)
  491. #define FUNC_NAME "module-reverse-lookup"
  492. {
  493. SCM obarray;
  494. long i, n;
  495. if (scm_is_false (module))
  496. obarray = scm_pre_modules_obarray;
  497. else
  498. {
  499. SCM_VALIDATE_MODULE (1, module);
  500. obarray = SCM_MODULE_OBARRAY (module);
  501. }
  502. if (!SCM_HASHTABLE_P (obarray))
  503. return SCM_BOOL_F;
  504. /* XXX - We do not use scm_hash_fold here to avoid searching the
  505. whole obarray. We should have a scm_hash_find procedure. */
  506. n = SCM_HASHTABLE_N_BUCKETS (obarray);
  507. for (i = 0; i < n; ++i)
  508. {
  509. SCM ls = SCM_HASHTABLE_BUCKET (obarray, i), handle;
  510. while (!scm_is_null (ls))
  511. {
  512. handle = SCM_CAR (ls);
  513. if (SCM_CDR (handle) == variable)
  514. return SCM_CAR (handle);
  515. ls = SCM_CDR (ls);
  516. }
  517. }
  518. /* Try the `uses' list.
  519. */
  520. {
  521. SCM uses = SCM_MODULE_USES (module);
  522. while (scm_is_pair (uses))
  523. {
  524. SCM sym = scm_module_reverse_lookup (SCM_CAR (uses), variable);
  525. if (scm_is_true (sym))
  526. return sym;
  527. uses = SCM_CDR (uses);
  528. }
  529. }
  530. return SCM_BOOL_F;
  531. }
  532. #undef FUNC_NAME
  533. SCM_DEFINE (scm_get_pre_modules_obarray, "%get-pre-modules-obarray", 0, 0, 0,
  534. (),
  535. "Return the obarray that is used for all new bindings before "
  536. "the module system is booted. The first call to "
  537. "@code{set-current-module} will boot the module system.")
  538. #define FUNC_NAME s_scm_get_pre_modules_obarray
  539. {
  540. return scm_pre_modules_obarray;
  541. }
  542. #undef FUNC_NAME
  543. SCM_SYMBOL (scm_sym_system_module, "system-module");
  544. SCM
  545. scm_system_module_env_p (SCM env)
  546. {
  547. SCM proc = scm_env_top_level (env);
  548. if (scm_is_false (proc))
  549. return SCM_BOOL_T;
  550. return ((scm_is_true (scm_procedure_property (proc,
  551. scm_sym_system_module)))
  552. ? SCM_BOOL_T
  553. : SCM_BOOL_F);
  554. }
  555. void
  556. scm_modules_prehistory ()
  557. {
  558. scm_pre_modules_obarray
  559. = scm_permanent_object (scm_c_make_hash_table (1533));
  560. }
  561. void
  562. scm_init_modules ()
  563. {
  564. #include "libguile/modules.x"
  565. module_make_local_var_x_var = scm_c_define ("module-make-local-var!",
  566. SCM_UNDEFINED);
  567. scm_tc16_eval_closure = scm_make_smob_type ("eval-closure", 0);
  568. scm_set_smob_mark (scm_tc16_eval_closure, scm_markcdr);
  569. scm_set_smob_apply (scm_tc16_eval_closure, scm_eval_closure_lookup, 2, 0, 0);
  570. the_module = scm_permanent_object (scm_make_fluid ());
  571. }
  572. static void
  573. scm_post_boot_init_modules ()
  574. {
  575. #define PERM(x) scm_permanent_object(x)
  576. SCM module_type = SCM_VARIABLE_REF (scm_c_lookup ("module-type"));
  577. scm_module_tag = (SCM_CELL_WORD_1 (module_type) + scm_tc3_struct);
  578. resolve_module_var = PERM (scm_c_lookup ("resolve-module"));
  579. process_define_module_var = PERM (scm_c_lookup ("process-define-module"));
  580. process_use_modules_var = PERM (scm_c_lookup ("process-use-modules"));
  581. module_export_x_var = PERM (scm_c_lookup ("module-export!"));
  582. the_root_module_var = PERM (scm_c_lookup ("the-root-module"));
  583. scm_module_system_booted_p = 1;
  584. }
  585. /*
  586. Local Variables:
  587. c-file-style: "gnu"
  588. End:
  589. */