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