1 /* Copyright (C) 1998,2000,2001,2002, 2003 Free Software Foundation, Inc.
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.
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.
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
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "libguile/_scm.h"
25 #include "libguile/eval.h"
26 #include "libguile/smob.h"
27 #include "libguile/procprop.h"
28 #include "libguile/vectors.h"
29 #include "libguile/hashtab.h"
30 #include "libguile/struct.h"
31 #include "libguile/variable.h"
32 #include "libguile/fluids.h"
33 #include "libguile/deprecation.h"
35 #include "libguile/modules.h"
37 int scm_module_system_booted_p
= 0;
39 scm_t_bits scm_module_tag
;
41 static SCM the_module
;
43 SCM_DEFINE (scm_current_module
, "current-module", 0, 0, 0,
45 "Return the current module.")
46 #define FUNC_NAME s_scm_current_module
48 return scm_fluid_ref (the_module
);
52 static void scm_post_boot_init_modules (void);
54 SCM_DEFINE (scm_set_current_module
, "set-current-module", 1, 0, 0,
56 "Set the current module to @var{module} and return\n"
57 "the previous current module.")
58 #define FUNC_NAME s_scm_set_current_module
62 if (!scm_module_system_booted_p
)
63 scm_post_boot_init_modules ();
65 SCM_VALIDATE_MODULE (SCM_ARG1
, module
);
67 old
= scm_current_module ();
68 scm_fluid_set_x (the_module
, module
);
74 SCM_DEFINE (scm_interaction_environment
, "interaction-environment", 0, 0, 0,
76 "Return a specifier for the environment that contains\n"
77 "implementation--defined bindings, typically a superset of those\n"
78 "listed in the report. The intent is that this procedure will\n"
79 "return the environment in which the implementation would\n"
80 "evaluate expressions dynamically typed by the user.")
81 #define FUNC_NAME s_scm_interaction_environment
83 return scm_current_module ();
88 scm_c_call_with_current_module (SCM module
,
89 SCM (*func
)(void *), void *data
)
91 return scm_c_with_fluid (the_module
, module
, func
, data
);
96 convert "A B C" to scheme list (A B C)
99 convert_module_name (const char *name
)
110 while (*ptr
&& *ptr
!= ' ')
114 *tail
= scm_cons (scm_mem2symbol (name
, ptr
-name
), SCM_EOL
);
115 tail
= SCM_CDRLOC (*tail
);
123 static SCM process_define_module_var
;
124 static SCM process_use_modules_var
;
125 static SCM resolve_module_var
;
128 scm_c_resolve_module (const char *name
)
130 return scm_resolve_module (convert_module_name (name
));
134 scm_resolve_module (SCM name
)
136 return scm_call_1 (SCM_VARIABLE_REF (resolve_module_var
), name
);
140 scm_c_define_module (const char *name
,
141 void (*init
)(void *), void *data
)
143 SCM module
= scm_call_1 (SCM_VARIABLE_REF (process_define_module_var
),
144 scm_list_1 (convert_module_name (name
)));
146 scm_c_call_with_current_module (module
, (SCM (*)(void*))init
, data
);
151 scm_c_use_module (const char *name
)
153 scm_call_1 (SCM_VARIABLE_REF (process_use_modules_var
),
154 scm_list_1 (scm_list_1 (convert_module_name (name
))));
157 static SCM module_export_x_var
;
161 TODO: should export this function? --hwn.
164 scm_export (SCM module
, SCM namelist
)
166 return scm_call_2 (SCM_VARIABLE_REF (module_export_x_var
),
172 @code{scm_c_export}(@var{name-list})
174 @code{scm_c_export} exports the named bindings from the current
175 module, making them visible to users of the module. This function
176 takes a list of string arguments, terminated by NULL, e.g.
179 scm_c_export ("add-double-record", "bamboozle-money", NULL);
183 scm_c_export (const char *name
, ...)
188 SCM names
= scm_cons (scm_str2symbol (name
), SCM_EOL
);
189 SCM
*tail
= SCM_CDRLOC (names
);
193 const char *n
= va_arg (ap
, const char *);
196 *tail
= scm_cons (scm_str2symbol (n
), SCM_EOL
);
197 tail
= SCM_CDRLOC (*tail
);
200 scm_export (scm_current_module(), names
);
208 scm_top_level_env (SCM thunk
)
213 return scm_cons (thunk
, SCM_EOL
);
217 scm_env_top_level (SCM env
)
219 while (SCM_CONSP (env
))
221 SCM car_env
= SCM_CAR (env
);
222 if (!SCM_CONSP (car_env
) && !SCM_FALSEP (scm_procedure_p (car_env
)))
229 SCM_SYMBOL (sym_module
, "module");
231 static SCM the_root_module_var
;
236 if (scm_module_system_booted_p
)
237 return SCM_VARIABLE_REF (the_root_module_var
);
243 scm_lookup_closure_module (SCM proc
)
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
));
251 SCM mod
= scm_procedure_property (proc
, sym_module
);
252 if (SCM_FALSEP (mod
))
253 mod
= the_root_module ();
258 SCM_DEFINE (scm_env_module
, "env-module", 1, 0, 0,
260 "Return the module of @var{ENV}, a lexical environment.")
261 #define FUNC_NAME s_scm_env_module
263 return scm_lookup_closure_module (scm_env_top_level (env
));
268 * C level implementation of the standard eval closure
270 * This increases loading speed substantially.
271 * The code will be replaced by the low-level environments in next release.
274 static SCM module_make_local_var_x_var
;
277 module_variable (SCM module
, SCM sym
)
279 #define SCM_BOUND_THING_P(b) \
281 (!SCM_VARIABLEP(b) || !SCM_UNBNDP (SCM_VARIABLE_REF (b))))
283 /* 1. Check module obarray */
284 SCM b
= scm_hashq_ref (SCM_MODULE_OBARRAY (module
), sym
, SCM_UNDEFINED
);
285 if (SCM_BOUND_THING_P (b
))
288 SCM binder
= SCM_MODULE_BINDER (module
);
289 if (!SCM_FALSEP (binder
))
290 /* 2. Custom binder */
292 b
= scm_call_3 (binder
, module
, sym
, SCM_BOOL_F
);
293 if (SCM_BOUND_THING_P (b
))
298 /* 3. Search the use list */
299 SCM uses
= SCM_MODULE_USES (module
);
300 while (SCM_CONSP (uses
))
302 b
= module_variable (SCM_CAR (uses
), sym
);
303 if (SCM_BOUND_THING_P (b
))
305 uses
= SCM_CDR (uses
);
309 #undef SCM_BOUND_THING_P
312 scm_t_bits scm_tc16_eval_closure
;
314 #define SCM_F_EVAL_CLOSURE_INTERFACE (1<<16)
315 #define SCM_EVAL_CLOSURE_INTERFACE_P(e) \
316 (SCM_CELL_WORD_0 (e) & SCM_F_EVAL_CLOSURE_INTERFACE)
318 /* NOTE: This function may be called by a smob application
319 or from another C function directly. */
321 scm_eval_closure_lookup (SCM eclo
, SCM sym
, SCM definep
)
323 SCM module
= SCM_PACK (SCM_SMOB_DATA (eclo
));
324 if (!SCM_FALSEP (definep
))
326 if (SCM_EVAL_CLOSURE_INTERFACE_P (eclo
))
328 return scm_call_2 (SCM_VARIABLE_REF (module_make_local_var_x_var
),
332 return module_variable (module
, sym
);
335 SCM_DEFINE (scm_standard_eval_closure
, "standard-eval-closure", 1, 0, 0,
337 "Return an eval closure for the module @var{module}.")
338 #define FUNC_NAME s_scm_standard_eval_closure
340 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure
, SCM_UNPACK (module
));
344 SCM_DEFINE (scm_standard_interface_eval_closure
,
345 "standard-interface-eval-closure", 1, 0, 0,
347 "Return a interface eval closure for the module @var{module}. "
348 "Such a closure does not allow new bindings to be added.")
349 #define FUNC_NAME s_scm_standard_interface_eval_closure
351 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure
| SCM_F_EVAL_CLOSURE_INTERFACE
,
352 SCM_UNPACK (module
));
357 scm_module_lookup_closure (SCM module
)
359 if (SCM_FALSEP (module
))
362 return SCM_MODULE_EVAL_CLOSURE (module
);
366 scm_current_module_lookup_closure ()
368 if (scm_module_system_booted_p
)
369 return scm_module_lookup_closure (scm_current_module ());
375 scm_module_transformer (SCM module
)
377 if (SCM_FALSEP (module
))
380 return SCM_MODULE_TRANSFORMER (module
);
384 scm_current_module_transformer ()
386 if (scm_module_system_booted_p
)
387 return scm_module_transformer (scm_current_module ());
392 SCM_DEFINE (scm_module_import_interface
, "module-import-interface", 2, 0, 0,
393 (SCM module
, SCM sym
),
395 #define FUNC_NAME s_scm_module_import_interface
397 #define SCM_BOUND_THING_P(b) (!SCM_FALSEP (b))
399 SCM_VALIDATE_MODULE (SCM_ARG1
, module
);
400 /* Search the use list */
401 uses
= SCM_MODULE_USES (module
);
402 while (SCM_CONSP (uses
))
404 SCM _interface
= SCM_CAR (uses
);
405 /* 1. Check module obarray */
406 SCM b
= scm_hashq_ref (SCM_MODULE_OBARRAY (_interface
), sym
, SCM_BOOL_F
);
407 if (SCM_BOUND_THING_P (b
))
410 SCM binder
= SCM_MODULE_BINDER (_interface
);
411 if (!SCM_FALSEP (binder
))
412 /* 2. Custom binder */
414 b
= scm_call_3 (binder
, _interface
, sym
, SCM_BOOL_F
);
415 if (SCM_BOUND_THING_P (b
))
419 /* 3. Search use list recursively. */
420 _interface
= scm_module_import_interface (_interface
, sym
);
421 if (!SCM_FALSEP (_interface
))
423 uses
= SCM_CDR (uses
);
431 * looks up the variable bound to SYM according to PROC. PROC should be
432 * a `eval closure' of some module.
434 * When no binding exists, and DEFINEP is true, create a new binding
435 * with a initial value of SCM_UNDEFINED. Return `#f' when DEFINEP as
436 * false and no binding exists.
438 * When PROC is `#f', it is ignored and the binding is searched for in
439 * the scm_pre_modules_obarray (a `eq' hash table).
442 SCM scm_pre_modules_obarray
;
445 scm_sym2var (SCM sym
, SCM proc
, SCM definep
)
446 #define FUNC_NAME "scm_sym2var"
452 if (SCM_EVAL_CLOSURE_P (proc
))
454 /* Bypass evaluator in the standard case. */
455 var
= scm_eval_closure_lookup (proc
, sym
, definep
);
458 var
= scm_call_2 (proc
, sym
, definep
);
464 if (SCM_FALSEP (definep
))
465 var
= scm_hashq_ref (scm_pre_modules_obarray
, sym
, SCM_BOOL_F
);
468 handle
= scm_hashq_create_handle_x (scm_pre_modules_obarray
,
470 var
= SCM_CDR (handle
);
471 if (SCM_FALSEP (var
))
473 var
= scm_make_variable (SCM_UNDEFINED
);
474 SCM_SETCDR (handle
, var
);
479 if (!SCM_FALSEP (var
) && !SCM_VARIABLEP (var
))
480 SCM_MISC_ERROR ("~S is not bound to a variable", scm_list_1 (sym
));
487 scm_c_module_lookup (SCM module
, const char *name
)
489 return scm_module_lookup (module
, scm_str2symbol (name
));
493 scm_module_lookup (SCM module
, SCM sym
)
494 #define FUNC_NAME "module-lookup"
497 SCM_VALIDATE_MODULE (1, module
);
499 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_F
);
500 if (SCM_FALSEP (var
))
501 SCM_MISC_ERROR ("unbound variable: ~S", scm_list_1 (sym
));
507 scm_c_lookup (const char *name
)
509 return scm_lookup (scm_str2symbol (name
));
516 scm_sym2var (sym
, scm_current_module_lookup_closure (), SCM_BOOL_F
);
517 if (SCM_FALSEP (var
))
518 scm_misc_error ("scm_lookup", "unbound variable: ~S", scm_list_1 (sym
));
523 scm_c_module_define (SCM module
, const char *name
, SCM value
)
525 return scm_module_define (module
, scm_str2symbol (name
), value
);
529 scm_module_define (SCM module
, SCM sym
, SCM value
)
530 #define FUNC_NAME "module-define"
533 SCM_VALIDATE_MODULE (1, module
);
535 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_T
);
536 SCM_VARIABLE_SET (var
, value
);
542 scm_c_define (const char *name
, SCM value
)
544 return scm_define (scm_str2symbol (name
), value
);
548 scm_define (SCM sym
, SCM value
)
551 scm_sym2var (sym
, scm_current_module_lookup_closure (), SCM_BOOL_T
);
552 SCM_VARIABLE_SET (var
, value
);
557 scm_module_reverse_lookup (SCM module
, SCM variable
)
558 #define FUNC_NAME "module-reverse-lookup"
563 if (SCM_FALSEP (module
))
564 obarray
= scm_pre_modules_obarray
;
567 SCM_VALIDATE_MODULE (1, module
);
568 obarray
= SCM_MODULE_OBARRAY (module
);
571 /* XXX - We do not use scm_hash_fold here to avoid searching the
572 whole obarray. We should have a scm_hash_find procedure. */
574 n
= SCM_HASHTABLE_N_BUCKETS (obarray
);
575 for (i
= 0; i
< n
; ++i
)
577 SCM ls
= SCM_HASHTABLE_BUCKETS (obarray
)[i
], handle
;
578 while (!SCM_NULLP (ls
))
580 handle
= SCM_CAR (ls
);
581 if (SCM_CDR (handle
) == variable
)
582 return SCM_CAR (handle
);
587 /* Try the `uses' list.
590 SCM uses
= SCM_MODULE_USES (module
);
591 while (SCM_CONSP (uses
))
593 SCM sym
= scm_module_reverse_lookup (SCM_CAR (uses
), variable
);
594 if (!SCM_FALSEP (sym
))
596 uses
= SCM_CDR (uses
);
604 SCM_DEFINE (scm_get_pre_modules_obarray
, "%get-pre-modules-obarray", 0, 0, 0,
606 "Return the obarray that is used for all new bindings before "
607 "the module system is booted. The first call to "
608 "@code{set-current-module} will boot the module system.")
609 #define FUNC_NAME s_scm_get_pre_modules_obarray
611 return scm_pre_modules_obarray
;
615 SCM_SYMBOL (scm_sym_system_module
, "system-module");
618 scm_system_module_env_p (SCM env
)
620 SCM proc
= scm_env_top_level (env
);
621 if (SCM_FALSEP (proc
))
623 return ((!SCM_FALSEP (scm_procedure_property (proc
,
624 scm_sym_system_module
)))
630 scm_modules_prehistory ()
632 scm_pre_modules_obarray
633 = scm_permanent_object (scm_c_make_hash_table (1533));
639 #include "libguile/modules.x"
640 module_make_local_var_x_var
= scm_c_define ("module-make-local-var!",
642 scm_tc16_eval_closure
= scm_make_smob_type ("eval-closure", 0);
643 scm_set_smob_mark (scm_tc16_eval_closure
, scm_markcdr
);
644 scm_set_smob_apply (scm_tc16_eval_closure
, scm_eval_closure_lookup
, 2, 0, 0);
646 the_module
= scm_permanent_object (scm_make_fluid ());
650 scm_post_boot_init_modules ()
652 #define PERM(x) scm_permanent_object(x)
654 SCM module_type
= SCM_VARIABLE_REF (scm_c_lookup ("module-type"));
655 scm_module_tag
= (SCM_CELL_WORD_1 (module_type
) + scm_tc3_struct
);
657 resolve_module_var
= PERM (scm_c_lookup ("resolve-module"));
658 process_define_module_var
= PERM (scm_c_lookup ("process-define-module"));
659 process_use_modules_var
= PERM (scm_c_lookup ("process-use-modules"));
660 module_export_x_var
= PERM (scm_c_lookup ("module-export!"));
661 the_root_module_var
= PERM (scm_c_lookup ("the-root-module"));
663 scm_module_system_booted_p
= 1;