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