* Make SCM_DEBUG_CELL_ACCESSES=1 work with GUILE_DEBUG_FREELIST.
[bpt/guile.git] / libguile / modules.c
CommitLineData
152abe96 1/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
1ffa265b
MD
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. */
6e8d25a6
GB
41
42/* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
44
1ffa265b
MD
45\f
46
a0599745 47#include "libguile/_scm.h"
1ffa265b 48
a0599745 49#include "libguile/eval.h"
fb43bf74 50#include "libguile/smob.h"
a0599745 51#include "libguile/procprop.h"
152abe96
MD
52#include "libguile/vectors.h"
53#include "libguile/hashtab.h"
54#include "libguile/struct.h"
55#include "libguile/variable.h"
7f763132 56#include "libguile/fluids.h"
1ffa265b 57
a0599745 58#include "libguile/modules.h"
1ffa265b 59
e3365c07
MD
60SCM scm_module_system_booted_p = 0;
61
62SCM scm_module_tag;
55000e5f 63SCM scm_module_type;
e3365c07 64
281004cc 65static SCM the_root_module;
c15c33ee 66static SCM root_module_lookup_closure;
281004cc
MD
67
68SCM
69scm_the_root_module ()
70{
71 return SCM_CDR (the_root_module);
72}
73
1ffa265b
MD
74static SCM the_module;
75
55000e5f
MV
76SCM_DEFINE (scm_current_module, "current-module", 0, 0, 0,
77 (),
78 "Return the current module.")
79#define FUNC_NAME s_scm_current_module
1ffa265b 80{
55000e5f 81 return scm_fluid_ref (the_module);
1ffa265b 82}
55000e5f 83#undef FUNC_NAME
1ffa265b 84
55000e5f
MV
85#define SCM_VALIDATE_STRUCT_TYPE(pos, v, type) \
86 do { \
87 SCM_ASSERT (SCM_NIMP (v) && SCM_NFALSEP (SCM_STRUCTP (v)) \
88 && SCM_STRUCT_VTABLE (v) == (type), \
89 v, pos, FUNC_NAME); \
90 } while (0)
1ffa265b 91
55000e5f
MV
92SCM_DEFINE (scm_set_current_module, "set-current-module", 1, 0, 0,
93 (SCM module),
94 "Set the current module to @var{module} and return"
95 "the previous current module.")
96#define FUNC_NAME s_scm_set_current_module
1ffa265b 97{
55000e5f
MV
98 SCM old;
99
100 /* XXX - we can not validate our argument when the module system
101 hasn't been booted yet since we don't know the type. This
102 should be fixed when we have a cleaner way of booting
103 Guile.
104 */
105 if (scm_module_system_booted_p)
106 SCM_VALIDATE_STRUCT_TYPE (SCM_ARG1, module, scm_module_type);
107
108 old = scm_current_module ();
109 scm_fluid_set_x (the_module, module);
110
111#if SCM_DEBUG_DEPRECATED == 0
112 scm_fluid_set_x (SCM_CDR (scm_top_level_lookup_closure_var),
113 scm_current_module_lookup_closure ());
114 scm_fluid_set_x (SCM_CDR (scm_system_transformer),
115 scm_current_module_transformer ());
116#endif
117
1ffa265b
MD
118 return old;
119}
55000e5f 120#undef FUNC_NAME
1ffa265b 121
e3365c07
MD
122SCM_DEFINE (scm_interaction_environment, "interaction-environment", 0, 0, 0,
123 (),
1e6808ea
MG
124 "Return a specifier for the environment that contains\n"
125 "implementation--defined bindings, typically a superset of those\n"
126 "listed in the report. The intent is that this procedure will\n"
127 "return the environment in which the implementation would\n"
128 "evaluate expressions dynamically typed by the user.")
e3365c07
MD
129#define FUNC_NAME s_scm_interaction_environment
130{
aa767bc5 131 return scm_current_module ();
e3365c07
MD
132}
133#undef FUNC_NAME
134
1ffa265b
MD
135SCM_SYMBOL (scm_sym_app, "app");
136SCM_SYMBOL (scm_sym_modules, "modules");
137static SCM module_prefix;
138
139static SCM
140scm_module_full_name (SCM name)
141{
54778cd3 142 if (SCM_EQ_P (SCM_CAR (name), scm_sym_app))
1ffa265b
MD
143 return name;
144 else
145 return scm_append (SCM_LIST2 (module_prefix, name));
146}
147
148static SCM make_modules_in;
281004cc 149static SCM beautify_user_module_x;
1ffa265b
MD
150
151SCM
152scm_make_module (SCM name)
153{
154 return scm_apply (SCM_CDR (make_modules_in),
281004cc 155 SCM_LIST2 (scm_the_root_module (),
1ffa265b
MD
156 scm_module_full_name (name)),
157 SCM_EOL);
158}
159
281004cc
MD
160SCM
161scm_ensure_user_module (SCM module)
162{
163 scm_apply (SCM_CDR (beautify_user_module_x), SCM_LIST1 (module), SCM_EOL);
164 return SCM_UNSPECIFIED;
165}
166
1ffa265b
MD
167SCM
168scm_module_lookup_closure (SCM module)
169{
e3365c07 170 return SCM_MODULE_EVAL_CLOSURE (module);
1ffa265b
MD
171}
172
9e57344b
MV
173SCM
174scm_current_module_lookup_closure ()
175{
176 if (scm_module_system_booted_p)
177 return scm_module_lookup_closure (scm_current_module ());
178 else
179 return SCM_BOOL_F;
180}
181
55000e5f
MV
182SCM
183scm_module_transformer (SCM module)
184{
185 return SCM_MODULE_TRANSFORMER (module);
186}
187
188SCM
189scm_current_module_transformer ()
190{
191 if (scm_module_system_booted_p)
192 return scm_module_transformer (scm_current_module ());
193 else
194 return SCM_BOOL_F;
195}
196
90184345
MD
197static SCM resolve_module;
198
199SCM
200scm_resolve_module (SCM name)
201{
202 return scm_apply (SCM_CDR (resolve_module), SCM_LIST1 (name), SCM_EOL);
203}
204
281004cc
MD
205static SCM try_module_autoload;
206
207SCM
208scm_load_scheme_module (SCM name)
209{
210 return scm_apply (SCM_CDR (try_module_autoload), SCM_LIST1 (name), SCM_EOL);
211}
212
e3365c07 213/* Environments */
d164a5af
MD
214
215SCM
6e8d25a6 216scm_top_level_env (SCM thunk)
d164a5af
MD
217{
218 if (SCM_IMP (thunk))
219 return SCM_EOL;
220 else
221 return scm_cons (thunk, SCM_EOL);
222}
223
224SCM
225scm_env_top_level (SCM env)
226{
227 while (SCM_NIMP (env))
228 {
229 if (!SCM_CONSP (SCM_CAR (env))
230 && SCM_NFALSEP (scm_procedure_p (SCM_CAR (env))))
c15c33ee 231 return SCM_CAR (env);
d164a5af
MD
232 env = SCM_CDR (env);
233 }
234 return SCM_BOOL_F;
235}
236
237
238SCM_SYMBOL (scm_sym_system_module, "system-module");
239
240SCM
241scm_system_module_env_p (SCM env)
242{
243 SCM proc = scm_env_top_level (env);
244 if (SCM_FALSEP (proc))
c15c33ee 245 proc = root_module_lookup_closure;
d164a5af
MD
246 return ((SCM_NFALSEP (scm_procedure_property (proc,
247 scm_sym_system_module)))
248 ? SCM_BOOL_T
249 : SCM_BOOL_F);
250}
251
152abe96
MD
252/*
253 * C level implementation of the standard eval closure
254 *
255 * This increases loading speed substantially.
256 * The code will be replaced by the low-level environments in next release.
257 */
258
152abe96
MD
259static SCM module_make_local_var_x;
260
261static SCM
262module_variable (SCM module, SCM sym)
263{
264 /* 1. Check module obarray */
e3365c07 265 SCM b = scm_hashq_ref (SCM_MODULE_OBARRAY (module), sym, SCM_UNDEFINED);
152abe96
MD
266 if (SCM_VARIABLEP (b))
267 return b;
268 {
e3365c07 269 SCM binder = SCM_MODULE_BINDER (module);
152abe96
MD
270 if (SCM_NFALSEP (binder))
271 /* 2. Custom binder */
272 {
273 b = scm_apply (binder,
274 SCM_LIST3 (module, sym, SCM_BOOL_F),
275 SCM_EOL);
276 if (SCM_NFALSEP (b))
277 return b;
278 }
279 }
280 {
281 /* 3. Search the use list */
e3365c07 282 SCM uses = SCM_MODULE_USES (module);
152abe96
MD
283 while (SCM_CONSP (uses))
284 {
285 b = module_variable (SCM_CAR (uses), sym);
286 if (SCM_NFALSEP (b))
287 return b;
288 uses = SCM_CDR (uses);
289 }
290 return SCM_BOOL_F;
291 }
292}
293
e841c3e0 294scm_bits_t scm_tc16_eval_closure;
152abe96 295
fb43bf74
KN
296/* NOTE: This function may be called by a smob application
297 or from another C function directly. */
298SCM
299scm_eval_closure_lookup (SCM eclo, SCM sym, SCM definep)
152abe96 300{
fb43bf74 301 SCM module = SCM_PACK (SCM_SMOB_DATA (eclo));
152abe96
MD
302 if (SCM_NFALSEP (definep))
303 return scm_apply (SCM_CDR (module_make_local_var_x),
304 SCM_LIST2 (module, sym),
305 SCM_EOL);
306 else
307 return module_variable (module, sym);
308}
309
310SCM_DEFINE (scm_standard_eval_closure, "standard-eval-closure", 1, 0, 0,
311 (SCM module),
84526793 312 "Return an eval closure for the module @var{module}.")
152abe96
MD
313#define FUNC_NAME s_scm_standard_eval_closure
314{
e841c3e0 315 SCM_RETURN_NEWSMOB (scm_tc16_eval_closure, SCM_UNPACK (module));
152abe96
MD
316}
317#undef FUNC_NAME
318
1ffa265b
MD
319void
320scm_init_modules ()
321{
8dc9439f 322#ifndef SCM_MAGIC_SNARFER
a0599745 323#include "libguile/modules.x"
8dc9439f 324#endif
152abe96
MD
325 module_make_local_var_x = scm_sysintern ("module-make-local-var!",
326 SCM_UNDEFINED);
e841c3e0
KN
327 scm_tc16_eval_closure = scm_make_smob_type ("eval-closure", 0);
328 scm_set_smob_mark (scm_tc16_eval_closure, scm_markcdr);
329 scm_set_smob_apply (scm_tc16_eval_closure, scm_eval_closure_lookup, 2, 0, 0);
55000e5f
MV
330
331 the_module = scm_permanent_object (scm_make_fluid ());
1ffa265b
MD
332}
333
334void
335scm_post_boot_init_modules ()
336{
55000e5f
MV
337 scm_module_type =
338 scm_permanent_object (SCM_CDR (scm_intern0 ("module-type")));
339 scm_module_tag = (SCM_CELL_WORD_1 (scm_module_type) + scm_tc3_cons_gloc);
1ffa265b
MD
340 module_prefix = scm_permanent_object (SCM_LIST2 (scm_sym_app,
341 scm_sym_modules));
342 make_modules_in = scm_intern0 ("make-modules-in");
281004cc 343 beautify_user_module_x = scm_intern0 ("beautify-user-module!");
55000e5f 344 the_root_module = scm_intern0 ("the-root-module");
c15c33ee
MD
345 root_module_lookup_closure = scm_permanent_object
346 (scm_module_lookup_closure (SCM_CDR (the_root_module)));
90184345 347 resolve_module = scm_intern0 ("resolve-module");
281004cc 348 try_module_autoload = scm_intern0 ("try-module-autoload");
e3365c07 349 scm_module_system_booted_p = 1;
1ffa265b 350}
89e00824
ML
351
352/*
353 Local Variables:
354 c-file-style: "gnu"
355 End:
356*/