1 /* Copyright (C) 1998,2000,2001 Free Software Foundation, Inc.
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)
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.
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
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
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.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
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.
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. */
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
49 #include "libguile/_scm.h"
51 #include "libguile/eval.h"
52 #include "libguile/smob.h"
53 #include "libguile/procprop.h"
54 #include "libguile/vectors.h"
55 #include "libguile/hashtab.h"
56 #include "libguile/struct.h"
57 #include "libguile/variable.h"
58 #include "libguile/fluids.h"
59 #include "libguile/deprecation.h"
61 #include "libguile/modules.h"
63 int scm_module_system_booted_p
= 0;
65 scm_t_bits scm_module_tag
;
67 static SCM the_module
;
69 SCM_DEFINE (scm_current_module
, "current-module", 0, 0, 0,
71 "Return the current module.")
72 #define FUNC_NAME s_scm_current_module
74 return scm_fluid_ref (the_module
);
78 static void scm_post_boot_init_modules (void);
80 SCM_DEFINE (scm_set_current_module
, "set-current-module", 1, 0, 0,
82 "Set the current module to @var{module} and return"
83 "the previous current module.")
84 #define FUNC_NAME s_scm_set_current_module
88 if (!scm_module_system_booted_p
)
89 scm_post_boot_init_modules ();
91 SCM_VALIDATE_MODULE (SCM_ARG1
, module
);
93 old
= scm_current_module ();
94 scm_fluid_set_x (the_module
, module
);
96 #if SCM_DEBUG_DEPRECATED == 0
97 scm_fluid_set_x (SCM_VARIABLE_REF (scm_top_level_lookup_closure_var
),
98 scm_current_module_lookup_closure ());
99 scm_fluid_set_x (SCM_VARIABLE_REF (scm_system_transformer
),
100 scm_current_module_transformer ());
107 SCM_DEFINE (scm_interaction_environment
, "interaction-environment", 0, 0, 0,
109 "Return a specifier for the environment that contains\n"
110 "implementation--defined bindings, typically a superset of those\n"
111 "listed in the report. The intent is that this procedure will\n"
112 "return the environment in which the implementation would\n"
113 "evaluate expressions dynamically typed by the user.")
114 #define FUNC_NAME s_scm_interaction_environment
116 return scm_current_module ();
121 scm_c_call_with_current_module (SCM module
,
122 SCM (*func
)(void *), void *data
)
124 return scm_c_with_fluid (the_module
, module
, func
, data
);
128 convert_module_name (const char *name
)
139 while (*ptr
&& *ptr
!= ' ')
143 *tail
= scm_cons (scm_mem2symbol (name
, ptr
-name
), SCM_EOL
);
144 tail
= SCM_CDRLOC (*tail
);
152 static SCM process_define_module_var
;
153 static SCM process_use_modules_var
;
154 static SCM resolve_module_var
;
157 scm_c_resolve_module (const char *name
)
159 return scm_resolve_module (convert_module_name (name
));
163 scm_resolve_module (SCM name
)
165 return scm_call_1 (SCM_VARIABLE_REF (resolve_module_var
), name
);
169 scm_c_define_module (const char *name
,
170 void (*init
)(void *), void *data
)
172 SCM module
= scm_call_1 (SCM_VARIABLE_REF (process_define_module_var
),
173 scm_list_1 (convert_module_name (name
)));
175 scm_c_call_with_current_module (module
, (SCM (*)(void*))init
, data
);
180 scm_c_use_module (const char *name
)
182 scm_call_1 (SCM_VARIABLE_REF (process_use_modules_var
),
183 scm_list_1 (convert_module_name (name
)));
186 static SCM module_export_x_var
;
189 scm_c_export (const char *name
, ...)
192 SCM names
= scm_cons (scm_str2symbol (name
), SCM_EOL
);
193 SCM
*tail
= SCM_CDRLOC (names
);
197 const char *n
= va_arg (ap
, const char *);
200 *tail
= scm_cons (scm_str2symbol (n
), SCM_EOL
);
201 tail
= SCM_CDRLOC (*tail
);
203 scm_call_2 (SCM_VARIABLE_REF (module_export_x_var
),
204 scm_current_module (), names
);
210 scm_top_level_env (SCM thunk
)
215 return scm_cons (thunk
, SCM_EOL
);
219 scm_env_top_level (SCM env
)
221 while (SCM_NIMP (env
))
223 if (!SCM_CONSP (SCM_CAR (env
))
224 && SCM_NFALSEP (scm_procedure_p (SCM_CAR (env
))))
225 return SCM_CAR (env
);
231 SCM_SYMBOL (sym_module
, "module");
233 static SCM the_root_module_var
;
238 if (scm_module_system_booted_p
)
239 return SCM_VARIABLE_REF (the_root_module_var
);
245 scm_lookup_closure_module (SCM proc
)
247 if (SCM_FALSEP (proc
))
248 return the_root_module ();
249 else if (SCM_EVAL_CLOSURE_P (proc
))
250 return SCM_PACK (SCM_SMOB_DATA (proc
));
253 SCM mod
= scm_procedure_property (proc
, sym_module
);
254 if (mod
== SCM_BOOL_F
)
255 mod
= the_root_module ();
260 SCM_DEFINE (scm_env_module
, "env-module", 1, 0, 0,
262 "Return the module of @var{ENV}, a lexical environment.")
263 #define FUNC_NAME s_scm_env_module
265 return scm_lookup_closure_module (scm_env_top_level (env
));
270 * C level implementation of the standard eval closure
272 * This increases loading speed substantially.
273 * The code will be replaced by the low-level environments in next release.
276 static SCM module_make_local_var_x_var
;
279 module_variable (SCM module
, SCM sym
)
281 /* 1. Check module obarray */
282 SCM b
= scm_hashq_ref (SCM_MODULE_OBARRAY (module
), sym
, SCM_UNDEFINED
);
283 if (SCM_VARIABLEP (b
))
286 SCM binder
= SCM_MODULE_BINDER (module
);
287 if (SCM_NFALSEP (binder
))
288 /* 2. Custom binder */
290 b
= scm_call_3 (binder
, module
, sym
, SCM_BOOL_F
);
296 /* 3. Search the use list */
297 SCM uses
= SCM_MODULE_USES (module
);
298 while (SCM_CONSP (uses
))
300 b
= module_variable (SCM_CAR (uses
), sym
);
303 uses
= SCM_CDR (uses
);
309 scm_t_bits scm_tc16_eval_closure
;
311 #define SCM_F_EVAL_CLOSURE_INTERFACE (1<<16)
312 #define SCM_EVAL_CLOSURE_INTERFACE_P(e) \
313 (SCM_CELL_WORD_0 (e) & SCM_F_EVAL_CLOSURE_INTERFACE)
315 /* NOTE: This function may be called by a smob application
316 or from another C function directly. */
318 scm_eval_closure_lookup (SCM eclo
, SCM sym
, SCM definep
)
320 SCM module
= SCM_PACK (SCM_SMOB_DATA (eclo
));
321 if (SCM_NFALSEP (definep
))
323 if (SCM_EVAL_CLOSURE_INTERFACE_P (eclo
))
325 return scm_call_2 (SCM_VARIABLE_REF (module_make_local_var_x_var
),
329 return module_variable (module
, sym
);
332 SCM_DEFINE (scm_standard_eval_closure
, "standard-eval-closure", 1, 0, 0,
334 "Return an eval closure for the module @var{module}.")
335 #define FUNC_NAME s_scm_standard_eval_closure
337 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure
, SCM_UNPACK (module
));
341 SCM_DEFINE (scm_standard_interface_eval_closure
,
342 "standard-interface-eval-closure", 1, 0, 0,
344 "Return a interface eval closure for the module @var{module}. "
345 "Such a closure does not allow new bindings to be added.")
346 #define FUNC_NAME s_scm_standard_interface_eval_closure
348 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure
| SCM_F_EVAL_CLOSURE_INTERFACE
,
349 SCM_UNPACK (module
));
354 scm_module_lookup_closure (SCM module
)
356 if (module
== SCM_BOOL_F
)
359 return SCM_MODULE_EVAL_CLOSURE (module
);
363 scm_current_module_lookup_closure ()
365 if (scm_module_system_booted_p
)
366 return scm_module_lookup_closure (scm_current_module ());
372 scm_module_transformer (SCM module
)
374 if (module
== SCM_BOOL_F
)
377 return SCM_MODULE_TRANSFORMER (module
);
381 scm_current_module_transformer ()
383 if (scm_module_system_booted_p
)
384 return scm_module_transformer (scm_current_module ());
391 * looks up the variable bound to SYM according to PROC. PROC should be
392 * a `eval closure' of some module.
394 * When no binding exists, and DEFINEP is true, create a new binding
395 * with a initial value of SCM_UNDEFINED. Return `#f' when DEFINEP as
396 * false and no binding exists.
398 * When PROC is `#f', it is ignored and the binding is searched for in
399 * the scm_pre_modules_obarray (a `eq' hash table).
402 SCM scm_pre_modules_obarray
;
405 scm_sym2var (SCM sym
, SCM proc
, SCM definep
)
406 #define FUNC_NAME "scm_sym2var"
412 if (SCM_EVAL_CLOSURE_P (proc
))
414 /* Bypass evaluator in the standard case. */
415 var
= scm_eval_closure_lookup (proc
, sym
, definep
);
418 var
= scm_call_2 (proc
, sym
, definep
);
424 if (definep
== SCM_BOOL_F
)
425 var
= scm_hashq_ref (scm_pre_modules_obarray
, sym
, SCM_BOOL_F
);
428 handle
= scm_hashq_create_handle_x (scm_pre_modules_obarray
,
430 var
= SCM_CDR (handle
);
431 if (var
== SCM_BOOL_F
)
433 var
= scm_make_variable (SCM_UNDEFINED
);
434 #if SCM_ENABLE_VCELLS
435 scm_variable_set_name_hint (var
, sym
);
437 SCM_SETCDR (handle
, var
);
442 if (var
!= SCM_BOOL_F
&& !SCM_VARIABLEP (var
))
443 SCM_MISC_ERROR ("~S is not bound to a variable", scm_list_1 (sym
));
450 scm_c_module_lookup (SCM module
, const char *name
)
452 return scm_module_lookup (module
, scm_str2symbol (name
));
456 scm_module_lookup (SCM module
, SCM sym
)
457 #define FUNC_NAME "module-lookup"
460 SCM_VALIDATE_MODULE (1, module
);
462 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_F
);
463 if (SCM_FALSEP (var
))
464 SCM_MISC_ERROR ("unbound variable: ~S", scm_list_1 (sym
));
470 scm_c_lookup (const char *name
)
472 return scm_lookup (scm_str2symbol (name
));
479 scm_sym2var (sym
, scm_current_module_lookup_closure (), SCM_BOOL_F
);
480 if (SCM_FALSEP (var
))
481 scm_misc_error ("scm_lookup", "unbound variable: ~S", scm_list_1 (sym
));
486 scm_c_module_define (SCM module
, const char *name
, SCM value
)
488 return scm_module_define (module
, scm_str2symbol (name
), value
);
492 scm_module_define (SCM module
, SCM sym
, SCM value
)
493 #define FUNC_NAME "module-define"
496 SCM_VALIDATE_MODULE (1, module
);
498 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_T
);
499 SCM_VARIABLE_SET (var
, value
);
505 scm_c_define (const char *name
, SCM value
)
507 return scm_define (scm_str2symbol (name
), value
);
511 scm_define (SCM sym
, SCM value
)
514 scm_sym2var (sym
, scm_current_module_lookup_closure (), SCM_BOOL_T
);
515 SCM_VARIABLE_SET (var
, value
);
520 scm_module_reverse_lookup (SCM module
, SCM variable
)
521 #define FUNC_NAME "module-reverse-lookup"
526 if (module
== SCM_BOOL_F
)
527 obarray
= scm_pre_modules_obarray
;
530 SCM_VALIDATE_MODULE (1, module
);
531 obarray
= SCM_MODULE_OBARRAY (module
);
534 /* XXX - We do not use scm_hash_fold here to avoid searching the
535 whole obarray. We should have a scm_hash_find procedure. */
537 n
= SCM_VECTOR_LENGTH (obarray
);
538 for (i
= 0; i
< n
; ++i
)
540 SCM ls
= SCM_VELTS (obarray
)[i
], handle
;
541 while (!SCM_NULLP (ls
))
543 handle
= SCM_CAR (ls
);
544 if (SCM_CDR (handle
) == variable
)
545 return SCM_CAR (handle
);
550 /* Try the `uses' list.
553 SCM uses
= SCM_MODULE_USES (module
);
554 while (SCM_CONSP (uses
))
556 SCM sym
= scm_module_reverse_lookup (SCM_CAR (uses
), variable
);
557 if (sym
!= SCM_BOOL_F
)
559 uses
= SCM_CDR (uses
);
567 SCM_DEFINE (scm_get_pre_modules_obarray
, "%get-pre-modules-obarray", 0, 0, 0,
569 "Return the obarray that is used for all new bindings before "
570 "the module system is booted. The first call to "
571 "@code{set-current-module} will boot the module system.")
572 #define FUNC_NAME s_scm_get_pre_modules_obarray
574 return scm_pre_modules_obarray
;
578 #if SCM_DEBUG_DEPRECATED == 0
580 static SCM root_module_lookup_closure
;
581 SCM_SYMBOL (scm_sym_app
, "app");
582 SCM_SYMBOL (scm_sym_modules
, "modules");
583 static SCM module_prefix
;
584 static SCM make_modules_in_var
;
585 static SCM beautify_user_module_x_var
;
586 static SCM try_module_autoload_var
;
590 SCM_SYMBOL (scm_sym_system_module
, "system-module");
593 scm_system_module_env_p (SCM env
)
595 SCM proc
= scm_env_top_level (env
);
596 if (SCM_FALSEP (proc
))
598 return ((SCM_NFALSEP (scm_procedure_property (proc
,
599 scm_sym_system_module
)))
605 scm_modules_prehistory ()
607 scm_pre_modules_obarray
608 = scm_permanent_object (scm_c_make_hash_table (2001));
614 #ifndef SCM_MAGIC_SNARFER
615 #include "libguile/modules.x"
617 module_make_local_var_x_var
= scm_c_define ("module-make-local-var!",
619 scm_tc16_eval_closure
= scm_make_smob_type ("eval-closure", 0);
620 scm_set_smob_mark (scm_tc16_eval_closure
, scm_markcdr
);
621 scm_set_smob_apply (scm_tc16_eval_closure
, scm_eval_closure_lookup
, 2, 0, 0);
623 the_module
= scm_permanent_object (scm_make_fluid ());
627 scm_post_boot_init_modules ()
629 #define PERM(x) scm_permanent_object(x)
631 SCM module_type
= SCM_VARIABLE_REF (scm_c_lookup ("module-type"));
632 scm_module_tag
= (SCM_CELL_WORD_1 (module_type
) + scm_tc3_cons_gloc
);
634 resolve_module_var
= PERM (scm_c_lookup ("resolve-module"));
635 process_define_module_var
= PERM (scm_c_lookup ("process-define-module"));
636 process_use_modules_var
= PERM (scm_c_lookup ("process-use-modules"));
637 module_export_x_var
= PERM (scm_c_lookup ("module-export!"));
638 the_root_module_var
= PERM (scm_c_lookup ("the-root-module"));
640 #if SCM_DEBUG_DEPRECATED == 0
642 module_prefix
= PERM (scm_list_2 (scm_sym_app
, scm_sym_modules
));
643 make_modules_in_var
= PERM (scm_c_lookup ("make-modules-in"));
644 root_module_lookup_closure
=
645 PERM (scm_module_lookup_closure (SCM_VARIABLE_REF (the_root_module_var
)));
646 beautify_user_module_x_var
= PERM (scm_c_lookup ("beautify-user-module!"));
647 try_module_autoload_var
= PERM (scm_c_lookup ("try-module-autoload"));
651 scm_module_system_booted_p
= 1;
654 #if SCM_DEBUG_DEPRECATED == 0
657 scm_the_root_module ()
659 scm_c_issue_deprecation_warning ("`scm_the_root_module' is deprecated. "
660 "Use `scm_c_resolve_module (\"guile\") "
663 return the_root_module ();
667 scm_module_full_name (SCM name
)
669 if (SCM_EQ_P (SCM_CAR (name
), scm_sym_app
))
672 return scm_append (scm_list_2 (module_prefix
, name
));
676 scm_make_module (SCM name
)
678 scm_c_issue_deprecation_warning ("`scm_make_module' is deprecated. "
679 "Use `scm_c_define_module instead.");
681 return scm_call_2 (SCM_VARIABLE_REF (make_modules_in_var
),
682 scm_the_root_module (),
683 scm_module_full_name (name
));
687 scm_ensure_user_module (SCM module
)
689 scm_c_issue_deprecation_warning ("`scm_ensure_user_module' is deprecated. "
690 "Use `scm_c_define_module instead.");
692 scm_call_1 (SCM_VARIABLE_REF (beautify_user_module_x_var
), module
);
693 return SCM_UNSPECIFIED
;
697 scm_load_scheme_module (SCM name
)
699 scm_c_issue_deprecation_warning ("`scm_load_scheme_module' is deprecated. "
700 "Use `scm_c_resolve_module instead.");
702 return scm_call_1 (SCM_VARIABLE_REF (try_module_autoload_var
), name
);