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