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