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