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. */
47 #include "libguile/_scm.h"
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"
59 #include "libguile/modules.h"
61 int scm_module_system_booted_p
= 0;
63 scm_t_bits scm_module_tag
;
65 static SCM the_module
;
67 SCM_DEFINE (scm_current_module
, "current-module", 0, 0, 0,
69 "Return the current module.")
70 #define FUNC_NAME s_scm_current_module
72 return scm_fluid_ref (the_module
);
76 static void scm_post_boot_init_modules (void);
78 SCM_DEFINE (scm_set_current_module
, "set-current-module", 1, 0, 0,
80 "Set the current module to @var{module} and return"
81 "the previous current module.")
82 #define FUNC_NAME s_scm_set_current_module
86 if (!scm_module_system_booted_p
)
87 scm_post_boot_init_modules ();
89 SCM_VALIDATE_MODULE (SCM_ARG1
, module
);
91 old
= scm_current_module ();
92 scm_fluid_set_x (the_module
, module
);
98 SCM_DEFINE (scm_interaction_environment
, "interaction-environment", 0, 0, 0,
100 "Return a specifier for the environment that contains\n"
101 "implementation--defined bindings, typically a superset of those\n"
102 "listed in the report. The intent is that this procedure will\n"
103 "return the environment in which the implementation would\n"
104 "evaluate expressions dynamically typed by the user.")
105 #define FUNC_NAME s_scm_interaction_environment
107 return scm_current_module ();
112 scm_c_call_with_current_module (SCM module
,
113 SCM (*func
)(void *), void *data
)
115 return scm_c_with_fluid (the_module
, module
, func
, data
);
119 convert_module_name (const char *name
)
130 while (*ptr
&& *ptr
!= ' ')
134 *tail
= scm_cons (scm_mem2symbol (name
, ptr
-name
), SCM_EOL
);
135 tail
= SCM_CDRLOC (*tail
);
143 static SCM process_define_module_var
;
144 static SCM process_use_modules_var
;
145 static SCM resolve_module_var
;
148 scm_c_resolve_module (const char *name
)
150 return scm_resolve_module (convert_module_name (name
));
154 scm_resolve_module (SCM name
)
156 return scm_call_1 (SCM_VARIABLE_REF (resolve_module_var
), name
);
160 scm_c_define_module (const char *name
,
161 void (*init
)(void *), void *data
)
163 SCM module
= scm_call_1 (SCM_VARIABLE_REF (process_define_module_var
),
164 scm_list_1 (convert_module_name (name
)));
166 scm_c_call_with_current_module (module
, (SCM (*)(void*))init
, data
);
171 scm_c_use_module (const char *name
)
173 scm_call_1 (SCM_VARIABLE_REF (process_use_modules_var
),
174 scm_list_1 (convert_module_name (name
)));
177 static SCM module_export_x_var
;
180 scm_c_export (const char *name
, ...)
183 SCM names
= scm_cons (scm_str2symbol (name
), SCM_EOL
);
184 SCM
*tail
= SCM_CDRLOC (names
);
188 const char *n
= va_arg (ap
, const char *);
191 *tail
= scm_cons (scm_str2symbol (n
), SCM_EOL
);
192 tail
= SCM_CDRLOC (*tail
);
194 scm_call_2 (SCM_VARIABLE_REF (module_export_x_var
),
195 scm_current_module (), names
);
201 scm_top_level_env (SCM thunk
)
206 return scm_cons (thunk
, SCM_EOL
);
210 scm_env_top_level (SCM env
)
212 while (SCM_NIMP (env
))
214 if (!SCM_CONSP (SCM_CAR (env
))
215 && SCM_NFALSEP (scm_procedure_p (SCM_CAR (env
))))
216 return SCM_CAR (env
);
222 SCM_SYMBOL (sym_module
, "module");
224 static SCM the_root_module_var
;
229 if (scm_module_system_booted_p
)
230 return SCM_VARIABLE_REF (the_root_module_var
);
236 scm_lookup_closure_module (SCM proc
)
238 if (SCM_FALSEP (proc
))
239 return the_root_module ();
240 else if (SCM_EVAL_CLOSURE_P (proc
))
241 return SCM_PACK (SCM_SMOB_DATA (proc
));
244 SCM mod
= scm_procedure_property (proc
, sym_module
);
245 if (mod
== SCM_BOOL_F
)
246 mod
= the_root_module ();
251 SCM_DEFINE (scm_env_module
, "env-module", 1, 0, 0,
253 "Return the module of @var{ENV}, a lexical environment.")
254 #define FUNC_NAME s_scm_env_module
256 return scm_lookup_closure_module (scm_env_top_level (env
));
261 * C level implementation of the standard eval closure
263 * This increases loading speed substantially.
264 * The code will be replaced by the low-level environments in next release.
267 static SCM module_make_local_var_x_var
;
270 module_variable (SCM module
, SCM sym
)
272 #define SCM_BOUND_THING_P(b) \
274 (!SCM_VARIABLEP(b) || !SCM_UNBNDP (SCM_VARIABLE_REF (b))))
276 /* 1. Check module obarray */
277 SCM b
= scm_hashq_ref (SCM_MODULE_OBARRAY (module
), sym
, SCM_UNDEFINED
);
278 if (SCM_BOUND_THING_P (b
))
281 SCM binder
= SCM_MODULE_BINDER (module
);
282 if (SCM_NFALSEP (binder
))
283 /* 2. Custom binder */
285 b
= scm_call_3 (binder
, module
, sym
, SCM_BOOL_F
);
286 if (SCM_BOUND_THING_P (b
))
291 /* 3. Search the use list */
292 SCM uses
= SCM_MODULE_USES (module
);
293 while (SCM_CONSP (uses
))
295 b
= module_variable (SCM_CAR (uses
), sym
);
296 if (SCM_BOUND_THING_P (b
))
298 uses
= SCM_CDR (uses
);
302 #undef SCM_BOUND_THING_P
305 scm_t_bits scm_tc16_eval_closure
;
307 #define SCM_F_EVAL_CLOSURE_INTERFACE (1<<16)
308 #define SCM_EVAL_CLOSURE_INTERFACE_P(e) \
309 (SCM_CELL_WORD_0 (e) & SCM_F_EVAL_CLOSURE_INTERFACE)
311 /* NOTE: This function may be called by a smob application
312 or from another C function directly. */
314 scm_eval_closure_lookup (SCM eclo
, SCM sym
, SCM definep
)
316 SCM module
= SCM_PACK (SCM_SMOB_DATA (eclo
));
317 if (SCM_NFALSEP (definep
))
319 if (SCM_EVAL_CLOSURE_INTERFACE_P (eclo
))
321 return scm_call_2 (SCM_VARIABLE_REF (module_make_local_var_x_var
),
325 return module_variable (module
, sym
);
328 SCM_DEFINE (scm_standard_eval_closure
, "standard-eval-closure", 1, 0, 0,
330 "Return an eval closure for the module @var{module}.")
331 #define FUNC_NAME s_scm_standard_eval_closure
333 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure
, SCM_UNPACK (module
));
337 SCM_DEFINE (scm_standard_interface_eval_closure
,
338 "standard-interface-eval-closure", 1, 0, 0,
340 "Return a interface eval closure for the module @var{module}. "
341 "Such a closure does not allow new bindings to be added.")
342 #define FUNC_NAME s_scm_standard_interface_eval_closure
344 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure
| SCM_F_EVAL_CLOSURE_INTERFACE
,
345 SCM_UNPACK (module
));
350 scm_module_lookup_closure (SCM module
)
352 if (module
== SCM_BOOL_F
)
355 return SCM_MODULE_EVAL_CLOSURE (module
);
359 scm_current_module_lookup_closure ()
361 if (scm_module_system_booted_p
)
362 return scm_module_lookup_closure (scm_current_module ());
368 scm_module_transformer (SCM module
)
370 if (module
== SCM_BOOL_F
)
373 return SCM_MODULE_TRANSFORMER (module
);
377 scm_current_module_transformer ()
379 if (scm_module_system_booted_p
)
380 return scm_module_transformer (scm_current_module ());
387 * looks up the variable bound to SYM according to PROC. PROC should be
388 * a `eval closure' of some module.
390 * When no binding exists, and DEFINEP is true, create a new binding
391 * with a initial value of SCM_UNDEFINED. Return `#f' when DEFINEP as
392 * false and no binding exists.
394 * When PROC is `#f', it is ignored and the binding is searched for in
395 * the scm_pre_modules_obarray (a `eq' hash table).
398 SCM scm_pre_modules_obarray
;
401 scm_sym2var (SCM sym
, SCM proc
, SCM definep
)
402 #define FUNC_NAME "scm_sym2var"
408 if (SCM_EVAL_CLOSURE_P (proc
))
410 /* Bypass evaluator in the standard case. */
411 var
= scm_eval_closure_lookup (proc
, sym
, definep
);
414 var
= scm_call_2 (proc
, sym
, definep
);
420 if (definep
== SCM_BOOL_F
)
421 var
= scm_hashq_ref (scm_pre_modules_obarray
, sym
, SCM_BOOL_F
);
424 handle
= scm_hashq_create_handle_x (scm_pre_modules_obarray
,
426 var
= SCM_CDR (handle
);
427 if (var
== SCM_BOOL_F
)
429 var
= scm_make_variable (SCM_UNDEFINED
);
430 SCM_SETCDR (handle
, var
);
435 if (var
!= SCM_BOOL_F
&& !SCM_VARIABLEP (var
))
436 SCM_MISC_ERROR ("~S is not bound to a variable", scm_list_1 (sym
));
443 scm_c_module_lookup (SCM module
, const char *name
)
445 return scm_module_lookup (module
, scm_str2symbol (name
));
449 scm_module_lookup (SCM module
, SCM sym
)
450 #define FUNC_NAME "module-lookup"
453 SCM_VALIDATE_MODULE (1, module
);
455 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_F
);
456 if (SCM_FALSEP (var
))
457 SCM_MISC_ERROR ("unbound variable: ~S", scm_list_1 (sym
));
463 scm_c_lookup (const char *name
)
465 return scm_lookup (scm_str2symbol (name
));
472 scm_sym2var (sym
, scm_current_module_lookup_closure (), SCM_BOOL_F
);
473 if (SCM_FALSEP (var
))
474 scm_misc_error ("scm_lookup", "unbound variable: ~S", scm_list_1 (sym
));
479 scm_c_module_define (SCM module
, const char *name
, SCM value
)
481 return scm_module_define (module
, scm_str2symbol (name
), value
);
485 scm_module_define (SCM module
, SCM sym
, SCM value
)
486 #define FUNC_NAME "module-define"
489 SCM_VALIDATE_MODULE (1, module
);
491 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_T
);
492 SCM_VARIABLE_SET (var
, value
);
498 scm_c_define (const char *name
, SCM value
)
500 return scm_define (scm_str2symbol (name
), value
);
504 scm_define (SCM sym
, SCM value
)
507 scm_sym2var (sym
, scm_current_module_lookup_closure (), SCM_BOOL_T
);
508 SCM_VARIABLE_SET (var
, value
);
513 scm_module_reverse_lookup (SCM module
, SCM variable
)
514 #define FUNC_NAME "module-reverse-lookup"
519 if (module
== SCM_BOOL_F
)
520 obarray
= scm_pre_modules_obarray
;
523 SCM_VALIDATE_MODULE (1, module
);
524 obarray
= SCM_MODULE_OBARRAY (module
);
527 /* XXX - We do not use scm_hash_fold here to avoid searching the
528 whole obarray. We should have a scm_hash_find procedure. */
530 n
= SCM_VECTOR_LENGTH (obarray
);
531 for (i
= 0; i
< n
; ++i
)
533 SCM ls
= SCM_VELTS (obarray
)[i
], handle
;
534 while (!SCM_NULLP (ls
))
536 handle
= SCM_CAR (ls
);
537 if (SCM_CDR (handle
) == variable
)
538 return SCM_CAR (handle
);
543 /* Try the `uses' list.
546 SCM uses
= SCM_MODULE_USES (module
);
547 while (SCM_CONSP (uses
))
549 SCM sym
= scm_module_reverse_lookup (SCM_CAR (uses
), variable
);
550 if (sym
!= SCM_BOOL_F
)
552 uses
= SCM_CDR (uses
);
560 SCM_DEFINE (scm_get_pre_modules_obarray
, "%get-pre-modules-obarray", 0, 0, 0,
562 "Return the obarray that is used for all new bindings before "
563 "the module system is booted. The first call to "
564 "@code{set-current-module} will boot the module system.")
565 #define FUNC_NAME s_scm_get_pre_modules_obarray
567 return scm_pre_modules_obarray
;
571 SCM_SYMBOL (scm_sym_system_module
, "system-module");
574 scm_system_module_env_p (SCM env
)
576 SCM proc
= scm_env_top_level (env
);
577 if (SCM_FALSEP (proc
))
579 return ((SCM_NFALSEP (scm_procedure_property (proc
,
580 scm_sym_system_module
)))
586 scm_modules_prehistory ()
588 scm_pre_modules_obarray
589 = scm_permanent_object (scm_c_make_hash_table (2001));
595 #ifndef SCM_MAGIC_SNARFER
596 #include "libguile/modules.x"
598 module_make_local_var_x_var
= scm_c_define ("module-make-local-var!",
600 scm_tc16_eval_closure
= scm_make_smob_type ("eval-closure", 0);
601 scm_set_smob_mark (scm_tc16_eval_closure
, scm_markcdr
);
602 scm_set_smob_apply (scm_tc16_eval_closure
, scm_eval_closure_lookup
, 2, 0, 0);
604 the_module
= scm_permanent_object (scm_make_fluid ());
608 scm_post_boot_init_modules ()
610 #define PERM(x) scm_permanent_object(x)
612 SCM module_type
= SCM_VARIABLE_REF (scm_c_lookup ("module-type"));
613 scm_module_tag
= (SCM_CELL_WORD_1 (module_type
) + scm_tc3_struct
);
615 resolve_module_var
= PERM (scm_c_lookup ("resolve-module"));
616 process_define_module_var
= PERM (scm_c_lookup ("process-define-module"));
617 process_use_modules_var
= PERM (scm_c_lookup ("process-use-modules"));
618 module_export_x_var
= PERM (scm_c_lookup ("module-export!"));
619 the_root_module_var
= PERM (scm_c_lookup ("the-root-module"));
621 scm_module_system_booted_p
= 1;