1 /* Copyright (C) 1998, 2000 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;
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_apply (SCM_VARIABLE_REF (resolve_module_var
),
166 SCM_LIST1 (name
), SCM_EOL
);
170 scm_c_define_module (const char *name
,
171 void (*init
)(void *), void *data
)
173 SCM module
= scm_apply (SCM_VARIABLE_REF (process_define_module_var
),
174 SCM_LIST1 (SCM_LIST1 (convert_module_name (name
))),
177 scm_c_call_with_current_module (module
, (SCM (*)(void*))init
, data
);
182 scm_c_use_module (const char *name
)
184 scm_apply (SCM_VARIABLE_REF (process_use_modules_var
),
185 SCM_LIST1 (SCM_LIST1 (convert_module_name (name
))),
189 static SCM module_export_x_var
;
192 scm_c_export (const char *name
, ...)
195 SCM names
= scm_cons (scm_str2symbol (name
), SCM_EOL
);
196 SCM
*tail
= SCM_CDRLOC (names
);
200 const char *n
= va_arg (ap
, const char *);
203 *tail
= scm_cons (scm_str2symbol (n
), SCM_EOL
);
204 tail
= SCM_CDRLOC (*tail
);
206 scm_apply (SCM_VARIABLE_REF (module_export_x_var
),
207 SCM_LIST2 (scm_current_module (),
215 scm_top_level_env (SCM thunk
)
220 return scm_cons (thunk
, SCM_EOL
);
224 scm_env_top_level (SCM env
)
226 while (SCM_NIMP (env
))
228 if (!SCM_CONSP (SCM_CAR (env
))
229 && SCM_NFALSEP (scm_procedure_p (SCM_CAR (env
))))
230 return SCM_CAR (env
);
236 SCM_SYMBOL (sym_module
, "module");
238 static SCM the_root_module_var
;
243 if (scm_module_system_booted_p
)
244 return SCM_VARIABLE_REF (the_root_module_var
);
250 scm_lookup_closure_module (SCM proc
)
252 if (SCM_FALSEP (proc
))
253 return the_root_module ();
254 else if (SCM_EVAL_CLOSURE_P (proc
))
255 return SCM_PACK (SCM_SMOB_DATA (proc
));
258 SCM mod
= scm_procedure_property (proc
, sym_module
);
259 if (mod
== SCM_BOOL_F
)
260 mod
= the_root_module ();
265 SCM_DEFINE (scm_env_module
, "env-module", 1, 0, 0,
267 "Return the module of @var{ENV}, a lexical environment.")
268 #define FUNC_NAME s_scm_env_module
270 return scm_lookup_closure_module (scm_env_top_level (env
));
275 * C level implementation of the standard eval closure
277 * This increases loading speed substantially.
278 * The code will be replaced by the low-level environments in next release.
281 static SCM module_make_local_var_x_var
;
284 module_variable (SCM module
, SCM sym
)
286 /* 1. Check module obarray */
287 SCM b
= scm_hashq_ref (SCM_MODULE_OBARRAY (module
), sym
, SCM_UNDEFINED
);
288 if (SCM_VARIABLEP (b
))
291 SCM binder
= SCM_MODULE_BINDER (module
);
292 if (SCM_NFALSEP (binder
))
293 /* 2. Custom binder */
295 b
= scm_apply (binder
,
296 SCM_LIST3 (module
, sym
, SCM_BOOL_F
),
303 /* 3. Search the use list */
304 SCM uses
= SCM_MODULE_USES (module
);
305 while (SCM_CONSP (uses
))
307 b
= module_variable (SCM_CAR (uses
), sym
);
310 uses
= SCM_CDR (uses
);
316 scm_bits_t scm_tc16_eval_closure
;
318 #define SCM_F_EVAL_CLOSURE_INTERFACE (1<<16)
319 #define SCM_EVAL_CLOSURE_INTERFACE_P(e) \
320 (SCM_CELL_WORD_0 (e) & SCM_F_EVAL_CLOSURE_INTERFACE)
322 /* NOTE: This function may be called by a smob application
323 or from another C function directly. */
325 scm_eval_closure_lookup (SCM eclo
, SCM sym
, SCM definep
)
327 SCM module
= SCM_PACK (SCM_SMOB_DATA (eclo
));
328 if (SCM_NFALSEP (definep
))
330 if (SCM_EVAL_CLOSURE_INTERFACE_P (eclo
))
332 return scm_apply (SCM_VARIABLE_REF (module_make_local_var_x_var
),
333 SCM_LIST2 (module
, sym
),
337 return module_variable (module
, sym
);
340 SCM_DEFINE (scm_standard_eval_closure
, "standard-eval-closure", 1, 0, 0,
342 "Return an eval closure for the module @var{module}.")
343 #define FUNC_NAME s_scm_standard_eval_closure
345 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure
, SCM_UNPACK (module
));
349 SCM_DEFINE (scm_standard_interface_eval_closure
,
350 "standard-interface-eval-closure", 1, 0, 0,
352 "Return a interface eval closure for the module @var{module}. "
353 "Such a closure does not allow new bindings to be added.")
354 #define FUNC_NAME s_scm_standard_interface_eval_closure
356 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure
| SCM_F_EVAL_CLOSURE_INTERFACE
,
357 SCM_UNPACK (module
));
362 scm_module_lookup_closure (SCM module
)
364 if (module
== SCM_BOOL_F
)
367 return SCM_MODULE_EVAL_CLOSURE (module
);
371 scm_current_module_lookup_closure ()
373 if (scm_module_system_booted_p
)
374 return scm_module_lookup_closure (scm_current_module ());
380 scm_module_transformer (SCM module
)
382 if (module
== SCM_BOOL_F
)
385 return SCM_MODULE_TRANSFORMER (module
);
389 scm_current_module_transformer ()
391 if (scm_module_system_booted_p
)
392 return scm_module_transformer (scm_current_module ());
399 * looks up the variable bound to SYM according to PROC. PROC should be
400 * a `eval closure' of some module.
402 * When no binding exists, and DEFINEP is true, create a new binding
403 * with a initial value of SCM_UNDEFINED. Return `#f' when DEFINEP as
404 * false and no binding exists.
406 * When PROC is `#f', it is ignored and the binding is searched for in
407 * the scm_pre_modules_obarray (a `eq' hash table).
410 SCM scm_pre_modules_obarray
;
413 scm_sym2var (SCM sym
, SCM proc
, SCM definep
)
414 #define FUNC_NAME "scm_sym2var"
420 if (SCM_EVAL_CLOSURE_P (proc
))
422 /* Bypass evaluator in the standard case. */
423 var
= scm_eval_closure_lookup (proc
, sym
, definep
);
426 var
= scm_apply (proc
, sym
, scm_cons (definep
, scm_listofnull
));
432 if (definep
== SCM_BOOL_F
)
433 var
= scm_hashq_ref (scm_pre_modules_obarray
, sym
, SCM_BOOL_F
);
436 handle
= scm_hashq_create_handle_x (scm_pre_modules_obarray
,
438 var
= SCM_CDR (handle
);
439 if (var
== SCM_BOOL_F
)
441 var
= scm_make_variable (SCM_UNDEFINED
);
442 #if SCM_ENABLE_VCELLS
443 scm_variable_set_name_hint (var
, sym
);
445 SCM_SETCDR (handle
, var
);
450 if (var
!= SCM_BOOL_F
&& !SCM_VARIABLEP (var
))
451 SCM_MISC_ERROR ("~S is not bound to a variable", SCM_LIST1 (sym
));
458 scm_c_module_lookup (SCM module
, const char *name
)
460 return scm_module_lookup (module
, scm_str2symbol (name
));
464 scm_module_lookup (SCM module
, SCM sym
)
465 #define FUNC_NAME "module-lookup"
468 SCM_VALIDATE_MODULE (1, module
);
470 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_F
);
471 if (SCM_FALSEP (var
))
472 SCM_MISC_ERROR ("unbound variable: ~S", SCM_LIST1 (sym
));
478 scm_c_lookup (const char *name
)
480 return scm_lookup (scm_str2symbol (name
));
487 scm_sym2var (sym
, scm_current_module_lookup_closure (), SCM_BOOL_F
);
488 if (SCM_FALSEP (var
))
489 scm_misc_error ("scm_lookup", "unbound variable: ~S", SCM_LIST1 (sym
));
494 scm_c_module_define (SCM module
, const char *name
, SCM value
)
496 return scm_module_define (module
, scm_str2symbol (name
), value
);
500 scm_module_define (SCM module
, SCM sym
, SCM value
)
501 #define FUNC_NAME "module-define"
504 SCM_VALIDATE_MODULE (1, module
);
506 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_T
);
507 SCM_VARIABLE_SET (var
, value
);
513 scm_c_define (const char *name
, SCM value
)
515 return scm_define (scm_str2symbol (name
), value
);
519 scm_define (SCM sym
, SCM value
)
522 scm_sym2var (sym
, scm_current_module_lookup_closure (), SCM_BOOL_T
);
523 SCM_VARIABLE_SET (var
, value
);
528 scm_module_reverse_lookup (SCM module
, SCM variable
)
529 #define FUNC_NAME "module-reverse-lookup"
534 if (module
== SCM_BOOL_F
)
535 obarray
= scm_pre_modules_obarray
;
538 SCM_VALIDATE_MODULE (1, module
);
539 obarray
= SCM_MODULE_OBARRAY (module
);
542 /* XXX - We do not use scm_hash_fold here to avoid searching the
543 whole obarray. We should have a scm_hash_find procedure. */
545 n
= SCM_VECTOR_LENGTH (obarray
);
546 for (i
= 0; i
< n
; ++i
)
548 SCM ls
= SCM_VELTS (obarray
)[i
], handle
;
549 while (!SCM_NULLP (ls
))
551 handle
= SCM_CAR (ls
);
552 if (SCM_CDR (handle
) == variable
)
553 return SCM_CAR (handle
);
558 /* Try the `uses' list.
561 SCM uses
= SCM_MODULE_USES (module
);
562 while (SCM_CONSP (uses
))
564 SCM sym
= scm_module_reverse_lookup (SCM_CAR (uses
), variable
);
565 if (sym
!= SCM_BOOL_F
)
567 uses
= SCM_CDR (uses
);
575 SCM_DEFINE (scm_get_pre_modules_obarray
, "%get-pre-modules-obarray", 0, 0, 0,
577 "Return the obarray that is used for all new bindings before "
578 "the module system is booted. The first call to "
579 "@code{set-current-module} will boot the module system.")
580 #define FUNC_NAME s_scm_get_pre_modules_obarray
582 return scm_pre_modules_obarray
;
586 #if SCM_DEBUG_DEPRECATED == 0
588 static SCM root_module_lookup_closure
;
589 SCM_SYMBOL (scm_sym_app
, "app");
590 SCM_SYMBOL (scm_sym_modules
, "modules");
591 static SCM module_prefix
;
592 static SCM make_modules_in_var
;
593 static SCM beautify_user_module_x_var
;
594 static SCM try_module_autoload_var
;
598 SCM_SYMBOL (scm_sym_system_module
, "system-module");
601 scm_system_module_env_p (SCM env
)
603 SCM proc
= scm_env_top_level (env
);
604 if (SCM_FALSEP (proc
))
606 return ((SCM_NFALSEP (scm_procedure_property (proc
,
607 scm_sym_system_module
)))
613 scm_modules_prehistory ()
615 scm_pre_modules_obarray
616 = scm_permanent_object (scm_c_make_hash_table (2001));
622 #ifndef SCM_MAGIC_SNARFER
623 #include "libguile/modules.x"
625 module_make_local_var_x_var
= scm_c_define ("module-make-local-var!",
627 scm_tc16_eval_closure
= scm_make_smob_type ("eval-closure", 0);
628 scm_set_smob_mark (scm_tc16_eval_closure
, scm_markcdr
);
629 scm_set_smob_apply (scm_tc16_eval_closure
, scm_eval_closure_lookup
, 2, 0, 0);
631 the_module
= scm_permanent_object (scm_make_fluid ());
635 scm_post_boot_init_modules ()
637 #define PERM(x) scm_permanent_object(x)
639 SCM module_type
= SCM_VARIABLE_REF (scm_c_lookup ("module-type"));
640 scm_module_tag
= (SCM_CELL_WORD_1 (module_type
) + scm_tc3_cons_gloc
);
642 resolve_module_var
= PERM (scm_c_lookup ("resolve-module"));
643 process_define_module_var
= PERM (scm_c_lookup ("process-define-module"));
644 process_use_modules_var
= PERM (scm_c_lookup ("process-use-modules"));
645 module_export_x_var
= PERM (scm_c_lookup ("module-export!"));
646 the_root_module_var
= PERM (scm_c_lookup ("the-root-module"));
648 #if SCM_DEBUG_DEPRECATED == 0
650 module_prefix
= PERM (SCM_LIST2 (scm_sym_app
, scm_sym_modules
));
651 make_modules_in_var
= PERM (scm_c_lookup ("make-modules-in"));
652 root_module_lookup_closure
=
653 PERM (scm_module_lookup_closure (SCM_VARIABLE_REF (the_root_module_var
)));
654 beautify_user_module_x_var
= PERM (scm_c_lookup ("beautify-user-module!"));
655 try_module_autoload_var
= PERM (scm_c_lookup ("try-module-autoload"));
659 scm_module_system_booted_p
= 1;
662 #if SCM_DEBUG_DEPRECATED == 0
665 scm_the_root_module ()
667 scm_c_issue_deprecation_warning ("`scm_the_root_module' is deprecated. "
668 "Use `scm_c_resolve_module (\"guile\") "
671 return the_root_module ();
675 scm_module_full_name (SCM name
)
677 if (SCM_EQ_P (SCM_CAR (name
), scm_sym_app
))
680 return scm_append (SCM_LIST2 (module_prefix
, name
));
684 scm_make_module (SCM name
)
686 scm_c_issue_deprecation_warning ("`scm_make_module' is deprecated. "
687 "Use `scm_c_define_module instead.");
689 return scm_apply (SCM_VARIABLE_REF (make_modules_in_var
),
690 SCM_LIST2 (scm_the_root_module (),
691 scm_module_full_name (name
)),
696 scm_ensure_user_module (SCM module
)
698 scm_c_issue_deprecation_warning ("`scm_ensure_user_module' is deprecated. "
699 "Use `scm_c_define_module instead.");
701 scm_apply (SCM_VARIABLE_REF (beautify_user_module_x_var
),
702 SCM_LIST1 (module
), SCM_EOL
);
703 return SCM_UNSPECIFIED
;
707 scm_load_scheme_module (SCM name
)
709 scm_c_issue_deprecation_warning ("`scm_load_scheme_module' is deprecated. "
710 "Use `scm_c_resolve_module instead.");
712 return scm_apply (SCM_VARIABLE_REF (try_module_autoload_var
),
713 SCM_LIST1 (name
), SCM_EOL
);