* tags.h: Update tag system docs.
[bpt/guile.git] / libguile / modules.c
1 /* Copyright (C) 1998,2000,2001 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program 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
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
41
42
43 \f
44
45 #include <stdarg.h>
46
47 #include "libguile/_scm.h"
48
49 #include "libguile/eval.h"
50 #include "libguile/smob.h"
51 #include "libguile/procprop.h"
52 #include "libguile/vectors.h"
53 #include "libguile/hashtab.h"
54 #include "libguile/struct.h"
55 #include "libguile/variable.h"
56 #include "libguile/fluids.h"
57 #include "libguile/deprecation.h"
58
59 #include "libguile/modules.h"
60
61 int scm_module_system_booted_p = 0;
62
63 scm_t_bits scm_module_tag;
64
65 static SCM the_module;
66
67 SCM_DEFINE (scm_current_module, "current-module", 0, 0, 0,
68 (),
69 "Return the current module.")
70 #define FUNC_NAME s_scm_current_module
71 {
72 return scm_fluid_ref (the_module);
73 }
74 #undef FUNC_NAME
75
76 static void scm_post_boot_init_modules (void);
77
78 SCM_DEFINE (scm_set_current_module, "set-current-module", 1, 0, 0,
79 (SCM module),
80 "Set the current module to @var{module} and return"
81 "the previous current module.")
82 #define FUNC_NAME s_scm_set_current_module
83 {
84 SCM old;
85
86 if (!scm_module_system_booted_p)
87 scm_post_boot_init_modules ();
88
89 SCM_VALIDATE_MODULE (SCM_ARG1, module);
90
91 old = scm_current_module ();
92 scm_fluid_set_x (the_module, module);
93
94 #if SCM_DEBUG_DEPRECATED == 0
95 scm_fluid_set_x (SCM_VARIABLE_REF (scm_top_level_lookup_closure_var),
96 scm_current_module_lookup_closure ());
97 scm_fluid_set_x (SCM_VARIABLE_REF (scm_system_transformer),
98 scm_current_module_transformer ());
99 #endif
100
101 return old;
102 }
103 #undef FUNC_NAME
104
105 SCM_DEFINE (scm_interaction_environment, "interaction-environment", 0, 0, 0,
106 (),
107 "Return a specifier for the environment that contains\n"
108 "implementation--defined bindings, typically a superset of those\n"
109 "listed in the report. The intent is that this procedure will\n"
110 "return the environment in which the implementation would\n"
111 "evaluate expressions dynamically typed by the user.")
112 #define FUNC_NAME s_scm_interaction_environment
113 {
114 return scm_current_module ();
115 }
116 #undef FUNC_NAME
117
118 SCM
119 scm_c_call_with_current_module (SCM module,
120 SCM (*func)(void *), void *data)
121 {
122 return scm_c_with_fluid (the_module, module, func, data);
123 }
124
125 static SCM
126 convert_module_name (const char *name)
127 {
128 SCM list = SCM_EOL;
129 SCM *tail = &list;
130
131 const char *ptr;
132 while (*name)
133 {
134 while (*name == ' ')
135 name++;
136 ptr = name;
137 while (*ptr && *ptr != ' ')
138 ptr++;
139 if (ptr > name)
140 {
141 *tail = scm_cons (scm_mem2symbol (name, ptr-name), SCM_EOL);
142 tail = SCM_CDRLOC (*tail);
143 }
144 name = ptr;
145 }
146
147 return list;
148 }
149
150 static SCM process_define_module_var;
151 static SCM process_use_modules_var;
152 static SCM resolve_module_var;
153
154 SCM
155 scm_c_resolve_module (const char *name)
156 {
157 return scm_resolve_module (convert_module_name (name));
158 }
159
160 SCM
161 scm_resolve_module (SCM name)
162 {
163 return scm_call_1 (SCM_VARIABLE_REF (resolve_module_var), name);
164 }
165
166 SCM
167 scm_c_define_module (const char *name,
168 void (*init)(void *), void *data)
169 {
170 SCM module = scm_call_1 (SCM_VARIABLE_REF (process_define_module_var),
171 scm_list_1 (convert_module_name (name)));
172 if (init)
173 scm_c_call_with_current_module (module, (SCM (*)(void*))init, data);
174 return module;
175 }
176
177 void
178 scm_c_use_module (const char *name)
179 {
180 scm_call_1 (SCM_VARIABLE_REF (process_use_modules_var),
181 scm_list_1 (convert_module_name (name)));
182 }
183
184 static SCM module_export_x_var;
185
186 void
187 scm_c_export (const char *name, ...)
188 {
189 va_list ap;
190 SCM names = scm_cons (scm_str2symbol (name), SCM_EOL);
191 SCM *tail = SCM_CDRLOC (names);
192 va_start (ap, name);
193 while (1)
194 {
195 const char *n = va_arg (ap, const char *);
196 if (n == NULL)
197 break;
198 *tail = scm_cons (scm_str2symbol (n), SCM_EOL);
199 tail = SCM_CDRLOC (*tail);
200 }
201 scm_call_2 (SCM_VARIABLE_REF (module_export_x_var),
202 scm_current_module (), names);
203 }
204
205 /* Environments */
206
207 SCM
208 scm_top_level_env (SCM thunk)
209 {
210 if (SCM_IMP (thunk))
211 return SCM_EOL;
212 else
213 return scm_cons (thunk, SCM_EOL);
214 }
215
216 SCM
217 scm_env_top_level (SCM env)
218 {
219 while (SCM_NIMP (env))
220 {
221 if (!SCM_CONSP (SCM_CAR (env))
222 && SCM_NFALSEP (scm_procedure_p (SCM_CAR (env))))
223 return SCM_CAR (env);
224 env = SCM_CDR (env);
225 }
226 return SCM_BOOL_F;
227 }
228
229 SCM_SYMBOL (sym_module, "module");
230
231 static SCM the_root_module_var;
232
233 static SCM
234 the_root_module ()
235 {
236 if (scm_module_system_booted_p)
237 return SCM_VARIABLE_REF (the_root_module_var);
238 else
239 return SCM_BOOL_F;
240 }
241
242 SCM
243 scm_lookup_closure_module (SCM proc)
244 {
245 if (SCM_FALSEP (proc))
246 return the_root_module ();
247 else if (SCM_EVAL_CLOSURE_P (proc))
248 return SCM_PACK (SCM_SMOB_DATA (proc));
249 else
250 {
251 SCM mod = scm_procedure_property (proc, sym_module);
252 if (mod == SCM_BOOL_F)
253 mod = the_root_module ();
254 return mod;
255 }
256 }
257
258 SCM_DEFINE (scm_env_module, "env-module", 1, 0, 0,
259 (SCM env),
260 "Return the module of @var{ENV}, a lexical environment.")
261 #define FUNC_NAME s_scm_env_module
262 {
263 return scm_lookup_closure_module (scm_env_top_level (env));
264 }
265 #undef FUNC_NAME
266
267 /*
268 * C level implementation of the standard eval closure
269 *
270 * This increases loading speed substantially.
271 * The code will be replaced by the low-level environments in next release.
272 */
273
274 static SCM module_make_local_var_x_var;
275
276 static SCM
277 module_variable (SCM module, SCM sym)
278 {
279 /* 1. Check module obarray */
280 SCM b = scm_hashq_ref (SCM_MODULE_OBARRAY (module), sym, SCM_UNDEFINED);
281 if (SCM_VARIABLEP (b))
282 return b;
283 {
284 SCM binder = SCM_MODULE_BINDER (module);
285 if (SCM_NFALSEP (binder))
286 /* 2. Custom binder */
287 {
288 b = scm_call_3 (binder, module, sym, SCM_BOOL_F);
289 if (SCM_NFALSEP (b))
290 return b;
291 }
292 }
293 {
294 /* 3. Search the use list */
295 SCM uses = SCM_MODULE_USES (module);
296 while (SCM_CONSP (uses))
297 {
298 b = module_variable (SCM_CAR (uses), sym);
299 if (SCM_NFALSEP (b))
300 return b;
301 uses = SCM_CDR (uses);
302 }
303 return SCM_BOOL_F;
304 }
305 }
306
307 scm_t_bits scm_tc16_eval_closure;
308
309 #define SCM_F_EVAL_CLOSURE_INTERFACE (1<<16)
310 #define SCM_EVAL_CLOSURE_INTERFACE_P(e) \
311 (SCM_CELL_WORD_0 (e) & SCM_F_EVAL_CLOSURE_INTERFACE)
312
313 /* NOTE: This function may be called by a smob application
314 or from another C function directly. */
315 SCM
316 scm_eval_closure_lookup (SCM eclo, SCM sym, SCM definep)
317 {
318 SCM module = SCM_PACK (SCM_SMOB_DATA (eclo));
319 if (SCM_NFALSEP (definep))
320 {
321 if (SCM_EVAL_CLOSURE_INTERFACE_P (eclo))
322 return SCM_BOOL_F;
323 return scm_call_2 (SCM_VARIABLE_REF (module_make_local_var_x_var),
324 module, sym);
325 }
326 else
327 return module_variable (module, sym);
328 }
329
330 SCM_DEFINE (scm_standard_eval_closure, "standard-eval-closure", 1, 0, 0,
331 (SCM module),
332 "Return an eval closure for the module @var{module}.")
333 #define FUNC_NAME s_scm_standard_eval_closure
334 {
335 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure, SCM_UNPACK (module));
336 }
337 #undef FUNC_NAME
338
339 SCM_DEFINE (scm_standard_interface_eval_closure,
340 "standard-interface-eval-closure", 1, 0, 0,
341 (SCM module),
342 "Return a interface eval closure for the module @var{module}. "
343 "Such a closure does not allow new bindings to be added.")
344 #define FUNC_NAME s_scm_standard_interface_eval_closure
345 {
346 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure | SCM_F_EVAL_CLOSURE_INTERFACE,
347 SCM_UNPACK (module));
348 }
349 #undef FUNC_NAME
350
351 SCM
352 scm_module_lookup_closure (SCM module)
353 {
354 if (module == SCM_BOOL_F)
355 return SCM_BOOL_F;
356 else
357 return SCM_MODULE_EVAL_CLOSURE (module);
358 }
359
360 SCM
361 scm_current_module_lookup_closure ()
362 {
363 if (scm_module_system_booted_p)
364 return scm_module_lookup_closure (scm_current_module ());
365 else
366 return SCM_BOOL_F;
367 }
368
369 SCM
370 scm_module_transformer (SCM module)
371 {
372 if (module == SCM_BOOL_F)
373 return SCM_BOOL_F;
374 else
375 return SCM_MODULE_TRANSFORMER (module);
376 }
377
378 SCM
379 scm_current_module_transformer ()
380 {
381 if (scm_module_system_booted_p)
382 return scm_module_transformer (scm_current_module ());
383 else
384 return SCM_BOOL_F;
385 }
386
387 /* scm_sym2var
388 *
389 * looks up the variable bound to SYM according to PROC. PROC should be
390 * a `eval closure' of some module.
391 *
392 * When no binding exists, and DEFINEP is true, create a new binding
393 * with a initial value of SCM_UNDEFINED. Return `#f' when DEFINEP as
394 * false and no binding exists.
395 *
396 * When PROC is `#f', it is ignored and the binding is searched for in
397 * the scm_pre_modules_obarray (a `eq' hash table).
398 */
399
400 SCM scm_pre_modules_obarray;
401
402 SCM
403 scm_sym2var (SCM sym, SCM proc, SCM definep)
404 #define FUNC_NAME "scm_sym2var"
405 {
406 SCM var;
407
408 if (SCM_NIMP (proc))
409 {
410 if (SCM_EVAL_CLOSURE_P (proc))
411 {
412 /* Bypass evaluator in the standard case. */
413 var = scm_eval_closure_lookup (proc, sym, definep);
414 }
415 else
416 var = scm_call_2 (proc, sym, definep);
417 }
418 else
419 {
420 SCM handle;
421
422 if (definep == SCM_BOOL_F)
423 var = scm_hashq_ref (scm_pre_modules_obarray, sym, SCM_BOOL_F);
424 else
425 {
426 handle = scm_hashq_create_handle_x (scm_pre_modules_obarray,
427 sym, SCM_BOOL_F);
428 var = SCM_CDR (handle);
429 if (var == SCM_BOOL_F)
430 {
431 var = scm_make_variable (SCM_UNDEFINED);
432 #if SCM_ENABLE_VCELLS
433 scm_variable_set_name_hint (var, sym);
434 #endif
435 SCM_SETCDR (handle, var);
436 }
437 }
438 }
439
440 if (var != SCM_BOOL_F && !SCM_VARIABLEP (var))
441 SCM_MISC_ERROR ("~S is not bound to a variable", scm_list_1 (sym));
442
443 return var;
444 }
445 #undef FUNC_NAME
446
447 SCM
448 scm_c_module_lookup (SCM module, const char *name)
449 {
450 return scm_module_lookup (module, scm_str2symbol (name));
451 }
452
453 SCM
454 scm_module_lookup (SCM module, SCM sym)
455 #define FUNC_NAME "module-lookup"
456 {
457 SCM var;
458 SCM_VALIDATE_MODULE (1, module);
459
460 var = scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_F);
461 if (SCM_FALSEP (var))
462 SCM_MISC_ERROR ("unbound variable: ~S", scm_list_1 (sym));
463 return var;
464 }
465 #undef FUNC_NAME
466
467 SCM
468 scm_c_lookup (const char *name)
469 {
470 return scm_lookup (scm_str2symbol (name));
471 }
472
473 SCM
474 scm_lookup (SCM sym)
475 {
476 SCM var =
477 scm_sym2var (sym, scm_current_module_lookup_closure (), SCM_BOOL_F);
478 if (SCM_FALSEP (var))
479 scm_misc_error ("scm_lookup", "unbound variable: ~S", scm_list_1 (sym));
480 return var;
481 }
482
483 SCM
484 scm_c_module_define (SCM module, const char *name, SCM value)
485 {
486 return scm_module_define (module, scm_str2symbol (name), value);
487 }
488
489 SCM
490 scm_module_define (SCM module, SCM sym, SCM value)
491 #define FUNC_NAME "module-define"
492 {
493 SCM var;
494 SCM_VALIDATE_MODULE (1, module);
495
496 var = scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_T);
497 SCM_VARIABLE_SET (var, value);
498 return var;
499 }
500 #undef FUNC_NAME
501
502 SCM
503 scm_c_define (const char *name, SCM value)
504 {
505 return scm_define (scm_str2symbol (name), value);
506 }
507
508 SCM
509 scm_define (SCM sym, SCM value)
510 {
511 SCM var =
512 scm_sym2var (sym, scm_current_module_lookup_closure (), SCM_BOOL_T);
513 SCM_VARIABLE_SET (var, value);
514 return var;
515 }
516
517 SCM
518 scm_module_reverse_lookup (SCM module, SCM variable)
519 #define FUNC_NAME "module-reverse-lookup"
520 {
521 SCM obarray;
522 long i, n;
523
524 if (module == SCM_BOOL_F)
525 obarray = scm_pre_modules_obarray;
526 else
527 {
528 SCM_VALIDATE_MODULE (1, module);
529 obarray = SCM_MODULE_OBARRAY (module);
530 }
531
532 /* XXX - We do not use scm_hash_fold here to avoid searching the
533 whole obarray. We should have a scm_hash_find procedure. */
534
535 n = SCM_VECTOR_LENGTH (obarray);
536 for (i = 0; i < n; ++i)
537 {
538 SCM ls = SCM_VELTS (obarray)[i], handle;
539 while (!SCM_NULLP (ls))
540 {
541 handle = SCM_CAR (ls);
542 if (SCM_CDR (handle) == variable)
543 return SCM_CAR (handle);
544 ls = SCM_CDR (ls);
545 }
546 }
547
548 /* Try the `uses' list.
549 */
550 {
551 SCM uses = SCM_MODULE_USES (module);
552 while (SCM_CONSP (uses))
553 {
554 SCM sym = scm_module_reverse_lookup (SCM_CAR (uses), variable);
555 if (sym != SCM_BOOL_F)
556 return sym;
557 uses = SCM_CDR (uses);
558 }
559 }
560
561 return SCM_BOOL_F;
562 }
563 #undef FUNC_NAME
564
565 SCM_DEFINE (scm_get_pre_modules_obarray, "%get-pre-modules-obarray", 0, 0, 0,
566 (),
567 "Return the obarray that is used for all new bindings before "
568 "the module system is booted. The first call to "
569 "@code{set-current-module} will boot the module system.")
570 #define FUNC_NAME s_scm_get_pre_modules_obarray
571 {
572 return scm_pre_modules_obarray;
573 }
574 #undef FUNC_NAME
575
576 #if SCM_DEBUG_DEPRECATED == 0
577
578 static SCM root_module_lookup_closure;
579 SCM_SYMBOL (scm_sym_app, "app");
580 SCM_SYMBOL (scm_sym_modules, "modules");
581 static SCM module_prefix;
582 static SCM make_modules_in_var;
583 static SCM beautify_user_module_x_var;
584 static SCM try_module_autoload_var;
585
586 #endif
587
588 SCM_SYMBOL (scm_sym_system_module, "system-module");
589
590 SCM
591 scm_system_module_env_p (SCM env)
592 {
593 SCM proc = scm_env_top_level (env);
594 if (SCM_FALSEP (proc))
595 return SCM_BOOL_T;
596 return ((SCM_NFALSEP (scm_procedure_property (proc,
597 scm_sym_system_module)))
598 ? SCM_BOOL_T
599 : SCM_BOOL_F);
600 }
601
602 void
603 scm_modules_prehistory ()
604 {
605 scm_pre_modules_obarray
606 = scm_permanent_object (scm_c_make_hash_table (2001));
607 }
608
609 void
610 scm_init_modules ()
611 {
612 #ifndef SCM_MAGIC_SNARFER
613 #include "libguile/modules.x"
614 #endif
615 module_make_local_var_x_var = scm_c_define ("module-make-local-var!",
616 SCM_UNDEFINED);
617 scm_tc16_eval_closure = scm_make_smob_type ("eval-closure", 0);
618 scm_set_smob_mark (scm_tc16_eval_closure, scm_markcdr);
619 scm_set_smob_apply (scm_tc16_eval_closure, scm_eval_closure_lookup, 2, 0, 0);
620
621 the_module = scm_permanent_object (scm_make_fluid ());
622 }
623
624 static void
625 scm_post_boot_init_modules ()
626 {
627 #define PERM(x) scm_permanent_object(x)
628
629 SCM module_type = SCM_VARIABLE_REF (scm_c_lookup ("module-type"));
630 scm_module_tag = (SCM_CELL_WORD_1 (module_type) + scm_tc3_struct);
631
632 resolve_module_var = PERM (scm_c_lookup ("resolve-module"));
633 process_define_module_var = PERM (scm_c_lookup ("process-define-module"));
634 process_use_modules_var = PERM (scm_c_lookup ("process-use-modules"));
635 module_export_x_var = PERM (scm_c_lookup ("module-export!"));
636 the_root_module_var = PERM (scm_c_lookup ("the-root-module"));
637
638 #if SCM_DEBUG_DEPRECATED == 0
639
640 module_prefix = PERM (scm_list_2 (scm_sym_app, scm_sym_modules));
641 make_modules_in_var = PERM (scm_c_lookup ("make-modules-in"));
642 root_module_lookup_closure =
643 PERM (scm_module_lookup_closure (SCM_VARIABLE_REF (the_root_module_var)));
644 beautify_user_module_x_var = PERM (scm_c_lookup ("beautify-user-module!"));
645 try_module_autoload_var = PERM (scm_c_lookup ("try-module-autoload"));
646
647 #endif
648
649 scm_module_system_booted_p = 1;
650 }
651
652 #if SCM_DEBUG_DEPRECATED == 0
653
654 SCM
655 scm_the_root_module ()
656 {
657 scm_c_issue_deprecation_warning ("`scm_the_root_module' is deprecated. "
658 "Use `scm_c_resolve_module (\"guile\") "
659 "instead.");
660
661 return the_root_module ();
662 }
663
664 static SCM
665 scm_module_full_name (SCM name)
666 {
667 if (SCM_EQ_P (SCM_CAR (name), scm_sym_app))
668 return name;
669 else
670 return scm_append (scm_list_2 (module_prefix, name));
671 }
672
673 SCM
674 scm_make_module (SCM name)
675 {
676 scm_c_issue_deprecation_warning ("`scm_make_module' is deprecated. "
677 "Use `scm_c_define_module instead.");
678
679 return scm_call_2 (SCM_VARIABLE_REF (make_modules_in_var),
680 scm_the_root_module (),
681 scm_module_full_name (name));
682 }
683
684 SCM
685 scm_ensure_user_module (SCM module)
686 {
687 scm_c_issue_deprecation_warning ("`scm_ensure_user_module' is deprecated. "
688 "Use `scm_c_define_module instead.");
689
690 scm_call_1 (SCM_VARIABLE_REF (beautify_user_module_x_var), module);
691 return SCM_UNSPECIFIED;
692 }
693
694 SCM
695 scm_load_scheme_module (SCM name)
696 {
697 scm_c_issue_deprecation_warning ("`scm_load_scheme_module' is deprecated. "
698 "Use `scm_c_resolve_module instead.");
699
700 return scm_call_1 (SCM_VARIABLE_REF (try_module_autoload_var), name);
701 }
702
703 #endif
704
705 /*
706 Local Variables:
707 c-file-style: "gnu"
708 End:
709 */