Remove obsolete compile-time option for freelist debugging.
[bpt/guile.git] / libguile / eval.c
CommitLineData
997659f8 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010
434f2f7a 2 * Free Software Foundation, Inc.
0f2d19dd 3 *
73be1d9e 4 * This library is free software; you can redistribute it and/or
53befeb7
NJ
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
0f2d19dd 8 *
53befeb7
NJ
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
0f2d19dd 13 *
73be1d9e
MV
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
53befeb7
NJ
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
73be1d9e 18 */
1bbd0b84 19
0f2d19dd
JB
20\f
21
dbb605f5 22#ifdef HAVE_CONFIG_H
3d05f2e0
RB
23# include <config.h>
24#endif
0f2d19dd 25
f7439099 26#include <alloca.h>
3d05f2e0 27
f7439099 28#include "libguile/__scm.h"
48b96f4b 29
a0599745 30#include "libguile/_scm.h"
21628685
DH
31#include "libguile/alist.h"
32#include "libguile/async.h"
33#include "libguile/continuations.h"
747022e4 34#include "libguile/control.h"
a0599745 35#include "libguile/debug.h"
328dc9a3 36#include "libguile/deprecation.h"
09074dbf 37#include "libguile/dynwind.h"
a0599745 38#include "libguile/eq.h"
21628685
DH
39#include "libguile/feature.h"
40#include "libguile/fluids.h"
21628685
DH
41#include "libguile/goops.h"
42#include "libguile/hash.h"
43#include "libguile/hashtab.h"
44#include "libguile/lang.h"
4610b011 45#include "libguile/list.h"
a0599745 46#include "libguile/macros.h"
b7742c6b 47#include "libguile/memoize.h"
a0599745
MD
48#include "libguile/modules.h"
49#include "libguile/ports.h"
7e6e6b37 50#include "libguile/print.h"
21628685 51#include "libguile/procprop.h"
4abef68f 52#include "libguile/programs.h"
a0599745 53#include "libguile/root.h"
21628685
DH
54#include "libguile/smob.h"
55#include "libguile/srcprop.h"
56#include "libguile/stackchk.h"
57#include "libguile/strings.h"
9de87eea 58#include "libguile/threads.h"
21628685
DH
59#include "libguile/throw.h"
60#include "libguile/validate.h"
a513ead3 61#include "libguile/values.h"
21628685 62#include "libguile/vectors.h"
4abef68f 63#include "libguile/vm.h"
a0599745 64
a0599745 65#include "libguile/eval.h"
0ee05b85 66#include "libguile/private-options.h"
89efbff4 67
0f2d19dd
JB
68\f
69
0ee05b85 70
b7742c6b 71/* We have three levels of EVAL here:
609a8b86 72
b7742c6b 73 - eval (exp, env)
89bff2fc 74
b7742c6b
AW
75 evaluates EXP in environment ENV. ENV is a lexical environment
76 structure as used by the actual tree code evaluator. When ENV is
77 a top-level environment, then changes to the current module are
78 tracked by updating ENV so that it continues to be in sync with
79 the current module.
e6729603 80
b7742c6b 81 - scm_primitive_eval (exp)
e6729603 82
b7742c6b
AW
83 evaluates EXP in the top-level environment as determined by the
84 current module. This is done by constructing a suitable
85 environment and calling eval. Thus, changes to the
86 top-level module are tracked normally.
e6729603 87
b7742c6b 88 - scm_eval (exp, mod)
e6729603 89
b7742c6b
AW
90 evaluates EXP while MOD is the current module. This is done
91 by setting the current module to MOD_OR_STATE, invoking
92 scm_primitive_eval on EXP, and then restoring the current module
93 to the value it had previously. That is, while EXP is evaluated,
94 changes to the current module (or dynamic state) are tracked,
95 but these changes do not persist when scm_eval returns.
e6729603 96
b7742c6b 97*/
e6729603 98
e6729603 99
314b8716
AW
100/* Boot closures. We only see these when compiling eval.scm, because once
101 eval.scm is in the house, closures are standard VM closures.
102 */
103
104static scm_t_bits scm_tc16_boot_closure;
105#define RETURN_BOOT_CLOSURE(code, env) SCM_RETURN_NEWSMOB2 (scm_tc16_boot_closure, (code), (env))
106#define BOOT_CLOSURE_P(obj) SCM_TYP16_PREDICATE (scm_tc16_boot_closure, (obj))
107#define BOOT_CLOSURE_CODE(x) SCM_SMOB_OBJECT (x)
108#define BOOT_CLOSURE_ENV(x) SCM_SMOB_OBJECT_2 (x)
109#define BOOT_CLOSURE_NUM_REQUIRED_ARGS(x) SCM_I_INUM (CAR (BOOT_CLOSURE_CODE (x)))
110#define BOOT_CLOSURE_HAS_REST_ARGS(x) scm_is_true (CADR (BOOT_CLOSURE_CODE (x)))
111#define BOOT_CLOSURE_BODY(x) CDDR (BOOT_CLOSURE_CODE (x))
112
113
114
b7742c6b
AW
115#if 0
116#define CAR(x) SCM_CAR(x)
117#define CDR(x) SCM_CDR(x)
118#define CAAR(x) SCM_CAAR(x)
119#define CADR(x) SCM_CADR(x)
120#define CDAR(x) SCM_CDAR(x)
121#define CDDR(x) SCM_CDDR(x)
122#define CADDR(x) SCM_CADDR(x)
123#define CDDDR(x) SCM_CDDDR(x)
124#else
125#define CAR(x) scm_car(x)
126#define CDR(x) scm_cdr(x)
127#define CAAR(x) scm_caar(x)
128#define CADR(x) scm_cadr(x)
129#define CDAR(x) scm_cdar(x)
130#define CDDR(x) scm_cddr(x)
131#define CADDR(x) scm_caddr(x)
132#define CDDDR(x) scm_cdddr(x)
133#endif
e6729603
DH
134
135
b7742c6b 136SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
e6729603 137
b7742c6b 138static void error_used_before_defined (void)
d0624e39 139{
b7742c6b
AW
140 scm_error (scm_unbound_variable_key, NULL,
141 "Variable used before given a value", SCM_EOL, SCM_BOOL_F);
d0624e39 142}
d0624e39 143
b7742c6b
AW
144int
145scm_badargsp (SCM formals, SCM args)
7e6e6b37 146{
b7742c6b
AW
147 while (!scm_is_null (formals))
148 {
149 if (!scm_is_pair (formals))
150 return 0;
151 if (scm_is_null (args))
152 return 1;
153 formals = CDR (formals);
154 args = CDR (args);
155 }
156 return !scm_is_null (args) ? 1 : 0;
7e6e6b37
DH
157}
158
b7742c6b 159/* the environment:
3149a5b6 160 (VAL ... . MOD)
b7742c6b
AW
161 If MOD is #f, it means the environment was captured before modules were
162 booted.
163 If MOD is the literal value '(), we are evaluating at the top level, and so
164 should track changes to the current module. You have to be careful in this
165 case, because further lexical contours should capture the current module.
166*/
167#define CAPTURE_ENV(env) \
168 ((env == SCM_EOL) ? scm_current_module () : \
169 ((env == SCM_BOOL_F) ? scm_the_root_module () : env))
6f81708a
DH
170
171static SCM
b7742c6b 172eval (SCM x, SCM env)
6f81708a 173{
b7742c6b
AW
174 SCM mx;
175 SCM proc = SCM_UNDEFINED, args = SCM_EOL;
6f81708a 176
b7742c6b
AW
177 loop:
178 SCM_TICK;
179 if (!SCM_MEMOIZED_P (x))
180 abort ();
181
182 mx = SCM_MEMOIZED_ARGS (x);
183 switch (SCM_MEMOIZED_TAG (x))
184 {
185 case SCM_M_BEGIN:
186 for (; !scm_is_null (CDR (mx)); mx = CDR (mx))
187 eval (CAR (mx), env);
188 x = CAR (mx);
189 goto loop;
190
191 case SCM_M_IF:
192 if (scm_is_true (eval (CAR (mx), env)))
193 x = CADR (mx);
6f81708a 194 else
b7742c6b
AW
195 x = CDDR (mx);
196 goto loop;
5fb64383 197
b7742c6b
AW
198 case SCM_M_LET:
199 {
200 SCM inits = CAR (mx);
201 SCM new_env = CAPTURE_ENV (env);
202 for (; scm_is_pair (inits); inits = CDR (inits))
203 new_env = scm_cons (eval (CAR (inits), env), new_env);
204 env = new_env;
205 x = CDR (mx);
206 goto loop;
207 }
208
209 case SCM_M_LAMBDA:
314b8716 210 RETURN_BOOT_CLOSURE (mx, CAPTURE_ENV (env));
5fb64383 211
b7742c6b
AW
212 case SCM_M_QUOTE:
213 return mx;
0f2d19dd 214
b7742c6b
AW
215 case SCM_M_DEFINE:
216 scm_define (CAR (mx), eval (CDR (mx), env));
217 return SCM_UNSPECIFIED;
212e58ed 218
d69531e2
AW
219 case SCM_M_DYNWIND:
220 {
221 SCM in, out, res, old_winds;
222 in = eval (CAR (mx), env);
223 out = eval (CDDR (mx), env);
224 scm_call_0 (in);
225 old_winds = scm_i_dynwinds ();
226 scm_i_set_dynwinds (scm_acons (in, out, old_winds));
227 res = eval (CADR (mx), env);
228 scm_i_set_dynwinds (old_winds);
229 scm_call_0 (out);
230 return res;
231 }
232
bb0229b5
AW
233 case SCM_M_WITH_FLUIDS:
234 {
235 long i, len;
236 SCM *fluidv, *valuesv, walk, wf, res;
237 len = scm_ilength (CAR (mx));
238 fluidv = alloca (sizeof (SCM)*len);
239 for (i = 0, walk = CAR (mx); i < len; i++, walk = CDR (walk))
240 fluidv[i] = eval (CAR (walk), env);
241 valuesv = alloca (sizeof (SCM)*len);
242 for (i = 0, walk = CADR (mx); i < len; i++, walk = CDR (walk))
243 valuesv[i] = eval (CAR (walk), env);
244
245 wf = scm_i_make_with_fluids (len, fluidv, valuesv);
246 scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state);
247 scm_i_set_dynwinds (scm_cons (wf, scm_i_dynwinds ()));
248 res = eval (CDDR (mx), env);
249 scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state);
250 scm_i_set_dynwinds (CDR (scm_i_dynwinds ()));
251
252 return res;
253 }
254
b7742c6b
AW
255 case SCM_M_APPLY:
256 /* Evaluate the procedure to be applied. */
257 proc = eval (CAR (mx), env);
258 /* Evaluate the argument holding the list of arguments */
259 args = eval (CADR (mx), env);
260
261 apply_proc:
262 /* Go here to tail-apply a procedure. PROC is the procedure and
263 * ARGS is the list of arguments. */
314b8716 264 if (BOOT_CLOSURE_P (proc))
b7742c6b 265 {
314b8716
AW
266 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
267 SCM new_env = BOOT_CLOSURE_ENV (proc);
268 if (BOOT_CLOSURE_HAS_REST_ARGS (proc))
b7742c6b
AW
269 {
270 if (SCM_UNLIKELY (scm_ilength (args) < nreq))
271 scm_wrong_num_args (proc);
272 for (; nreq; nreq--, args = CDR (args))
273 new_env = scm_cons (CAR (args), new_env);
274 new_env = scm_cons (args, new_env);
275 }
276 else
277 {
278 if (SCM_UNLIKELY (scm_ilength (args) != nreq))
279 scm_wrong_num_args (proc);
280 for (; scm_is_pair (args); args = CDR (args))
281 new_env = scm_cons (CAR (args), new_env);
282 }
314b8716 283 x = BOOT_CLOSURE_BODY (proc);
b7742c6b
AW
284 env = new_env;
285 goto loop;
286 }
287 else
67e2d80a 288 return scm_vm_apply (scm_the_vm (), proc, args);
212e58ed 289
b7742c6b
AW
290 case SCM_M_CALL:
291 /* Evaluate the procedure to be applied. */
292 proc = eval (CAR (mx), env);
9331f91c
AW
293 /* int nargs = CADR (mx); */
294 mx = CDDR (mx);
212e58ed 295
314b8716 296 if (BOOT_CLOSURE_P (proc))
5fa0939c 297 {
314b8716
AW
298 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
299 SCM new_env = BOOT_CLOSURE_ENV (proc);
300 if (BOOT_CLOSURE_HAS_REST_ARGS (proc))
b7742c6b
AW
301 {
302 if (SCM_UNLIKELY (scm_ilength (mx) < nreq))
303 scm_wrong_num_args (proc);
304 for (; nreq; nreq--, mx = CDR (mx))
305 new_env = scm_cons (eval (CAR (mx), env), new_env);
306 {
307 SCM rest = SCM_EOL;
308 for (; scm_is_pair (mx); mx = CDR (mx))
309 rest = scm_cons (eval (CAR (mx), env), rest);
310 new_env = scm_cons (scm_reverse (rest),
311 new_env);
312 }
313 }
314 else
315 {
316 for (; scm_is_pair (mx); mx = CDR (mx), nreq--)
317 new_env = scm_cons (eval (CAR (mx), env), new_env);
318 if (SCM_UNLIKELY (nreq != 0))
319 scm_wrong_num_args (proc);
320 }
314b8716 321 x = BOOT_CLOSURE_BODY (proc);
b7742c6b
AW
322 env = new_env;
323 goto loop;
5fa0939c 324 }
b7742c6b
AW
325 else
326 {
327 SCM rest = SCM_EOL;
9331f91c 328 /* FIXME: use alloca */
b7742c6b
AW
329 for (; scm_is_pair (mx); mx = CDR (mx))
330 rest = scm_cons (eval (CAR (mx), env), rest);
67e2d80a 331 return scm_vm_apply (scm_the_vm (), proc, scm_reverse (rest));
b7742c6b
AW
332 }
333
334 case SCM_M_CONT:
babfc7b2 335 return scm_i_call_with_current_continuation (eval (mx, env));
212e58ed 336
b7742c6b
AW
337 case SCM_M_CALL_WITH_VALUES:
338 {
339 SCM producer;
340 SCM v;
341
342 producer = eval (CAR (mx), env);
343 proc = eval (CDR (mx), env); /* proc is the consumer. */
67e2d80a 344 v = scm_vm_apply (scm_the_vm (), producer, SCM_EOL);
b7742c6b
AW
345 if (SCM_VALUESP (v))
346 args = scm_struct_ref (v, SCM_INUM0);
347 else
348 args = scm_list_1 (v);
349 goto apply_proc;
350 }
26d5b9b4 351
b7742c6b
AW
352 case SCM_M_LEXICAL_REF:
353 {
354 int n;
355 SCM ret;
356 for (n = SCM_I_INUM (mx); n; n--)
357 env = CDR (env);
358 ret = CAR (env);
359 if (SCM_UNLIKELY (SCM_UNBNDP (ret)))
360 /* we don't know what variable, though, because we don't have its
361 name */
362 error_used_before_defined ();
363 return ret;
364 }
1cc91f1b 365
b7742c6b
AW
366 case SCM_M_LEXICAL_SET:
367 {
368 int n;
369 SCM val = eval (CDR (mx), env);
370 for (n = SCM_I_INUM (CAR (mx)); n; n--)
371 env = CDR (env);
372 SCM_SETCAR (env, val);
373 return SCM_UNSPECIFIED;
374 }
910b5125 375
b7742c6b
AW
376 case SCM_M_TOPLEVEL_REF:
377 if (SCM_VARIABLEP (mx))
378 return SCM_VARIABLE_REF (mx);
379 else
57d23e25 380 {
b7742c6b 381 while (scm_is_pair (env))
f3a8d1b7 382 env = CDR (env);
3149a5b6
AW
383 return SCM_VARIABLE_REF
384 (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)));
57d23e25 385 }
57d23e25 386
b7742c6b
AW
387 case SCM_M_TOPLEVEL_SET:
388 {
389 SCM var = CAR (mx);
390 SCM val = eval (CDR (mx), env);
391 if (SCM_VARIABLEP (var))
392 {
393 SCM_VARIABLE_SET (var, val);
394 return SCM_UNSPECIFIED;
395 }
396 else
397 {
398 while (scm_is_pair (env))
f3a8d1b7 399 env = CDR (env);
3149a5b6
AW
400 SCM_VARIABLE_SET
401 (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)),
402 val);
b7742c6b
AW
403 return SCM_UNSPECIFIED;
404 }
405 }
910b5125 406
b7742c6b
AW
407 case SCM_M_MODULE_REF:
408 if (SCM_VARIABLEP (mx))
409 return SCM_VARIABLE_REF (mx);
910b5125 410 else
3149a5b6
AW
411 return SCM_VARIABLE_REF
412 (scm_memoize_variable_access_x (x, SCM_BOOL_F));
910b5125 413
b7742c6b
AW
414 case SCM_M_MODULE_SET:
415 if (SCM_VARIABLEP (CDR (mx)))
910b5125 416 {
b7742c6b
AW
417 SCM_VARIABLE_SET (CDR (mx), eval (CAR (mx), env));
418 return SCM_UNSPECIFIED;
419 }
420 else
421 {
3149a5b6
AW
422 SCM_VARIABLE_SET
423 (scm_memoize_variable_access_x (x, SCM_BOOL_F),
424 eval (CAR (mx), env));
b7742c6b 425 return SCM_UNSPECIFIED;
910b5125 426 }
910b5125 427
747022e4
AW
428 case SCM_M_PROMPT:
429 {
d2964315 430 SCM vm, prompt, handler, res;
747022e4 431
d2964315
AW
432 vm = scm_the_vm ();
433 prompt = scm_c_make_prompt (eval (CAR (mx), env), SCM_VM_DATA (vm)->fp,
434 SCM_VM_DATA (vm)->sp, SCM_VM_DATA (vm)->ip,
adbdfd6d 435 0, -1, scm_i_dynwinds ());
747022e4
AW
436 handler = eval (CDDR (mx), env);
437 scm_i_set_dynwinds (scm_cons (prompt, scm_i_dynwinds ()));
438
439 if (SCM_PROMPT_SETJMP (prompt))
440 {
b8af64db 441 /* The prompt exited nonlocally. */
747022e4 442 proc = handler;
b8af64db 443 args = scm_i_prompt_pop_abort_args_x (prompt);
747022e4
AW
444 goto apply_proc;
445 }
446
447 res = eval (CADR (mx), env);
448 scm_i_set_dynwinds (CDR (scm_i_dynwinds ()));
449 return res;
450 }
451
b7742c6b
AW
452 default:
453 abort ();
454 }
910b5125
DH
455}
456
b7742c6b
AW
457scm_t_option scm_eval_opts[] = {
458 { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." },
459 { 0 }
460};
e6729603 461
b7742c6b
AW
462scm_t_option scm_debug_opts[] = {
463 { SCM_OPTION_BOOLEAN, "cheap", 1,
464 "*This option is now obsolete. Setting it has no effect." },
465 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
466 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
467 { SCM_OPTION_BOOLEAN, "procnames", 1,
468 "Record procedure names at definition." },
469 { SCM_OPTION_BOOLEAN, "backwards", 0,
470 "Display backtrace in anti-chronological order." },
471 { SCM_OPTION_INTEGER, "width", 79, "Maximal width of backtrace." },
472 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
473 { SCM_OPTION_INTEGER, "frames", 3,
474 "Maximum number of tail-recursive frames in backtrace." },
475 { SCM_OPTION_INTEGER, "maxdepth", 1000,
476 "Maximal number of stored backtrace frames." },
477 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
478 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
479 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
480 /* This default stack limit will be overridden by debug.c:init_stack_limit(),
481 if we have getrlimit() and the stack limit is not INFINITY. But it is still
482 important, as some systems have both the soft and the hard limits set to
483 INFINITY; in that case we fall back to this value.
e6729603 484
b7742c6b
AW
485 The situation is aggravated by certain compilers, which can consume
486 "beaucoup de stack", as they say in France.
0f2d19dd 487
b7742c6b
AW
488 See http://thread.gmane.org/gmane.lisp.guile.devel/8599/focus=8662 for
489 more discussion. This setting is 640 KB on 32-bit arches (should be enough
490 for anyone!) or a whoppin' 1280 KB on 64-bit arches.
491 */
492 { SCM_OPTION_INTEGER, "stack", 160000, "Stack size limit (measured in words; 0 = no check)." },
493 { SCM_OPTION_SCM, "show-file-name", (unsigned long)SCM_BOOL_T,
494 "Show file names and line numbers "
495 "in backtraces when not `#f'. A value of `base' "
496 "displays only base names, while `#t' displays full names."},
497 { SCM_OPTION_BOOLEAN, "warn-deprecated", 0,
498 "Warn when deprecated features are used." },
499 { 0 },
500};
212e58ed 501
1cc91f1b 502
b7742c6b
AW
503/*
504 * this ordering is awkward and illogical, but we maintain it for
505 * compatibility. --hwn
506 */
507scm_t_option scm_evaluator_trap_table[] = {
508 { SCM_OPTION_BOOLEAN, "traps", 0, "Enable evaluator traps." },
509 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
510 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
511 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." },
512 { SCM_OPTION_SCM, "enter-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for enter-frame traps." },
513 { SCM_OPTION_SCM, "apply-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for apply-frame traps." },
514 { SCM_OPTION_SCM, "exit-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for exit-frame traps." },
515 { SCM_OPTION_BOOLEAN, "memoize-symbol", 0, "Trap when memoizing a symbol." },
516 { SCM_OPTION_SCM, "memoize-symbol-handler", (unsigned long)SCM_BOOL_F, "The handler for memoization." },
517 { 0 }
518};
8ea46249 519
0f2d19dd 520
b7742c6b
AW
521SCM_DEFINE (scm_eval_options_interface, "eval-options-interface", 0, 1, 0,
522 (SCM setting),
523 "Option interface for the evaluation options. Instead of using\n"
524 "this procedure directly, use the procedures @code{eval-enable},\n"
525 "@code{eval-disable}, @code{eval-set!} and @code{eval-options}.")
526#define FUNC_NAME s_scm_eval_options_interface
212e58ed 527{
b7742c6b
AW
528 SCM ans;
529
530 scm_dynwind_begin (0);
531 scm_dynwind_critical_section (SCM_BOOL_F);
532 ans = scm_options (setting,
533 scm_eval_opts,
534 FUNC_NAME);
535 scm_dynwind_end ();
212e58ed 536
b7742c6b
AW
537 return ans;
538}
539#undef FUNC_NAME
0f2d19dd 540
1cc91f1b 541
b7742c6b
AW
542SCM_DEFINE (scm_evaluator_traps, "evaluator-traps-interface", 0, 1, 0,
543 (SCM setting),
544 "Option interface for the evaluator trap options.")
545#define FUNC_NAME s_scm_evaluator_traps
0f2d19dd 546{
b7742c6b 547 SCM ans;
2a6f7afe 548
b7742c6b
AW
549
550 scm_options_try (setting,
551 scm_evaluator_trap_table,
552 FUNC_NAME, 1);
553 SCM_CRITICAL_SECTION_START;
554 ans = scm_options (setting,
555 scm_evaluator_trap_table,
556 FUNC_NAME);
2a6f7afe 557
b7742c6b
AW
558 /* njrev: same again. */
559 SCM_CRITICAL_SECTION_END;
560 return ans;
561}
562#undef FUNC_NAME
2a6f7afe 563
2a6f7afe 564
2a6f7afe 565
b7742c6b 566\f
2a6f7afe 567
b7742c6b
AW
568/* Simple procedure calls
569 */
2a6f7afe 570
b7742c6b
AW
571SCM
572scm_call_0 (SCM proc)
573{
bf5a05f2 574 return scm_c_vm_run (scm_the_vm (), proc, NULL, 0);
0f2d19dd
JB
575}
576
b7742c6b
AW
577SCM
578scm_call_1 (SCM proc, SCM arg1)
212e58ed 579{
bf5a05f2 580 return scm_c_vm_run (scm_the_vm (), proc, &arg1, 1);
b7742c6b 581}
212e58ed 582
b7742c6b
AW
583SCM
584scm_call_2 (SCM proc, SCM arg1, SCM arg2)
585{
bf5a05f2
AW
586 SCM args[] = { arg1, arg2 };
587 return scm_c_vm_run (scm_the_vm (), proc, args, 2);
212e58ed
DH
588}
589
b7742c6b
AW
590SCM
591scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
0f2d19dd 592{
bf5a05f2
AW
593 SCM args[] = { arg1, arg2, arg3 };
594 return scm_c_vm_run (scm_the_vm (), proc, args, 3);
0f2d19dd
JB
595}
596
b7742c6b
AW
597SCM
598scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
212e58ed 599{
bf5a05f2
AW
600 SCM args[] = { arg1, arg2, arg3, arg4 };
601 return scm_c_vm_run (scm_the_vm (), proc, args, 4);
212e58ed
DH
602}
603
86fd6dff
AW
604SCM
605scm_call_n (SCM proc, SCM *argv, size_t nargs)
606{
607 return scm_c_vm_run (scm_the_vm (), proc, argv, nargs);
608}
609
b7742c6b 610/* Simple procedure applies
9fbee57e 611 */
cc56ba80 612
b7742c6b
AW
613SCM
614scm_apply_0 (SCM proc, SCM args)
615{
616 return scm_apply (proc, args, SCM_EOL);
0f572ba7
DH
617}
618
b7742c6b
AW
619SCM
620scm_apply_1 (SCM proc, SCM arg1, SCM args)
0f572ba7 621{
b7742c6b 622 return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
8ae95199
DH
623}
624
b7742c6b
AW
625SCM
626scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
0f2d19dd 627{
b7742c6b 628 return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
0f2d19dd
JB
629}
630
b7742c6b
AW
631SCM
632scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
212e58ed 633{
b7742c6b
AW
634 return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
635 SCM_EOL);
212e58ed
DH
636}
637
b7742c6b 638/* This code processes the arguments to apply:
8ea46249 639
b7742c6b 640 (apply PROC ARG1 ... ARGS)
302c12b4 641
b7742c6b
AW
642 Given a list (ARG1 ... ARGS), this function conses the ARG1
643 ... arguments onto the front of ARGS, and returns the resulting
644 list. Note that ARGS is a list; thus, the argument to this
645 function is a list whose last element is a list.
302c12b4 646
b7742c6b
AW
647 Apply calls this function, and applies PROC to the elements of the
648 result. apply:nconc2last takes care of building the list of
649 arguments, given (ARG1 ... ARGS).
a954ce1d 650
b7742c6b
AW
651 Rather than do new consing, apply:nconc2last destroys its argument.
652 On that topic, this code came into my care with the following
653 beautifully cryptic comment on that topic: "This will only screw
654 you if you do (scm_apply scm_apply '( ... ))" If you know what
655 they're referring to, send me a patch to this comment. */
0f2d19dd 656
b7742c6b
AW
657SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
658 (SCM lst),
659 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
660 "conses the @var{arg1} @dots{} arguments onto the front of\n"
661 "@var{args}, and returns the resulting list. Note that\n"
662 "@var{args} is a list; thus, the argument to this function is\n"
663 "a list whose last element is a list.\n"
664 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
665 "destroys its argument, so use with care.")
666#define FUNC_NAME s_scm_nconc2last
212e58ed 667{
b7742c6b
AW
668 SCM *lloc;
669 SCM_VALIDATE_NONEMPTYLIST (1, lst);
670 lloc = &lst;
671 while (!scm_is_null (SCM_CDR (*lloc))) /* Perhaps should be
672 SCM_NULL_OR_NIL_P, but not
673 needed in 99.99% of cases,
674 and it could seriously hurt
675 performance. - Neil */
676 lloc = SCM_CDRLOC (*lloc);
677 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
678 *lloc = SCM_CAR (*lloc);
679 return lst;
212e58ed 680}
b7742c6b 681#undef FUNC_NAME
212e58ed 682
b8229a3b
MS
683
684
b7742c6b 685/* Typechecking for multi-argument MAP and FOR-EACH.
0f2d19dd 686
b7742c6b
AW
687 Verify that each element of the vector ARGV, except for the first,
688 is a proper list whose length is LEN. Attribute errors to WHO,
689 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
690static inline void
691check_map_args (SCM argv,
692 long len,
693 SCM gf,
694 SCM proc,
695 SCM args,
696 const char *who)
212e58ed 697{
b7742c6b 698 long i;
0f2d19dd 699
b7742c6b 700 for (i = SCM_SIMPLE_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
9fbee57e 701 {
b7742c6b
AW
702 SCM elt = SCM_SIMPLE_VECTOR_REF (argv, i);
703 long elt_len = scm_ilength (elt);
5cb22e96 704
b7742c6b
AW
705 if (elt_len < 0)
706 {
707 if (gf)
708 scm_apply_generic (gf, scm_cons (proc, args));
709 else
710 scm_wrong_type_arg (who, i + 2, elt);
711 }
1cc91f1b 712
b7742c6b
AW
713 if (elt_len != len)
714 scm_out_of_range_pos (who, elt, scm_from_long (i + 2));
0f2d19dd 715 }
0f2d19dd 716}
6dbd0af5 717
212e58ed 718
b7742c6b 719SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
212e58ed 720
b7742c6b
AW
721/* Note: Currently, scm_map applies PROC to the argument list(s)
722 sequentially, starting with the first element(s). This is used in
723 evalext.c where the Scheme procedure `map-in-order', which guarantees
724 sequential behaviour, is implemented using scm_map. If the
725 behaviour changes, we need to update `map-in-order'.
726*/
0f2d19dd 727
b7742c6b
AW
728SCM
729scm_map (SCM proc, SCM arg1, SCM args)
730#define FUNC_NAME s_map
0f2d19dd 731{
b7742c6b
AW
732 long i, len;
733 SCM res = SCM_EOL;
734 SCM *pres = &res;
0f2d19dd 735
b7742c6b
AW
736 len = scm_ilength (arg1);
737 SCM_GASSERTn (len >= 0,
738 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
739 SCM_VALIDATE_REST_ARGUMENT (args);
740 if (scm_is_null (args))
0f2d19dd 741 {
b7742c6b
AW
742 SCM_GASSERT2 (scm_is_true (scm_procedure_p (proc)), g_map, proc, arg1, SCM_ARG1, s_map);
743 while (SCM_NIMP (arg1))
744 {
745 *pres = scm_list_1 (scm_call_1 (proc, SCM_CAR (arg1)));
746 pres = SCM_CDRLOC (*pres);
747 arg1 = SCM_CDR (arg1);
748 }
749 return res;
0f2d19dd 750 }
b7742c6b
AW
751 if (scm_is_null (SCM_CDR (args)))
752 {
753 SCM arg2 = SCM_CAR (args);
754 int len2 = scm_ilength (arg2);
755 SCM_GASSERTn (scm_is_true (scm_procedure_p (proc)), g_map,
756 scm_cons2 (proc, arg1, args), SCM_ARG1, s_map);
757 SCM_GASSERTn (len2 >= 0,
758 g_map, scm_cons2 (proc, arg1, args), SCM_ARG3, s_map);
759 if (len2 != len)
760 SCM_OUT_OF_RANGE (3, arg2);
761 while (SCM_NIMP (arg1))
762 {
763 *pres = scm_list_1 (scm_call_2 (proc, SCM_CAR (arg1), SCM_CAR (arg2)));
764 pres = SCM_CDRLOC (*pres);
765 arg1 = SCM_CDR (arg1);
766 arg2 = SCM_CDR (arg2);
767 }
768 return res;
769 }
770 arg1 = scm_cons (arg1, args);
771 args = scm_vector (arg1);
772 check_map_args (args, len, g_map, proc, arg1, s_map);
773 while (1)
d6754c23 774 {
b7742c6b
AW
775 arg1 = SCM_EOL;
776 for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
777 {
778 SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
779 if (SCM_IMP (elt))
780 return res;
781 arg1 = scm_cons (SCM_CAR (elt), arg1);
782 SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
783 }
784 *pres = scm_list_1 (scm_apply (proc, arg1, SCM_EOL));
785 pres = SCM_CDRLOC (*pres);
d6754c23 786 }
0f2d19dd 787}
b7742c6b 788#undef FUNC_NAME
0f2d19dd 789
302c12b4 790
b7742c6b 791SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
d6754c23 792
b7742c6b
AW
793SCM
794scm_for_each (SCM proc, SCM arg1, SCM args)
795#define FUNC_NAME s_for_each
0f2d19dd 796{
b7742c6b
AW
797 long i, len;
798 len = scm_ilength (arg1);
799 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
800 SCM_ARG2, s_for_each);
801 SCM_VALIDATE_REST_ARGUMENT (args);
802 if (scm_is_null (args))
26d5b9b4 803 {
b7742c6b
AW
804 SCM_GASSERT2 (scm_is_true (scm_procedure_p (proc)), g_for_each,
805 proc, arg1, SCM_ARG1, s_for_each);
806 while (SCM_NIMP (arg1))
807 {
808 scm_call_1 (proc, SCM_CAR (arg1));
809 arg1 = SCM_CDR (arg1);
810 }
811 return SCM_UNSPECIFIED;
26d5b9b4 812 }
b7742c6b 813 if (scm_is_null (SCM_CDR (args)))
26d5b9b4 814 {
b7742c6b
AW
815 SCM arg2 = SCM_CAR (args);
816 int len2 = scm_ilength (arg2);
817 SCM_GASSERTn (scm_is_true (scm_procedure_p (proc)), g_for_each,
818 scm_cons2 (proc, arg1, args), SCM_ARG1, s_for_each);
819 SCM_GASSERTn (len2 >= 0, g_for_each,
820 scm_cons2 (proc, arg1, args), SCM_ARG3, s_for_each);
821 if (len2 != len)
822 SCM_OUT_OF_RANGE (3, arg2);
823 while (SCM_NIMP (arg1))
824 {
825 scm_call_2 (proc, SCM_CAR (arg1), SCM_CAR (arg2));
826 arg1 = SCM_CDR (arg1);
827 arg2 = SCM_CDR (arg2);
828 }
829 return SCM_UNSPECIFIED;
26d5b9b4 830 }
b7742c6b
AW
831 arg1 = scm_cons (arg1, args);
832 args = scm_vector (arg1);
833 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
834 while (1)
302c12b4 835 {
b7742c6b
AW
836 arg1 = SCM_EOL;
837 for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
71560395 838 {
b7742c6b
AW
839 SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
840 if (SCM_IMP (elt))
841 return SCM_UNSPECIFIED;
842 arg1 = scm_cons (SCM_CAR (elt), arg1);
843 SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
844 }
845 scm_apply (proc, arg1, SCM_EOL);
846 }
847}
848#undef FUNC_NAME
71560395 849
71560395 850
5f161164
AW
851static SCM
852scm_c_primitive_eval (SCM exp)
b7742c6b
AW
853{
854 SCM transformer = scm_current_module_transformer ();
855 if (scm_is_true (transformer))
856 exp = scm_call_1 (transformer, exp);
857 exp = scm_memoize_expression (exp);
858 return eval (exp, SCM_EOL);
859}
5f161164
AW
860
861static SCM var_primitive_eval;
862SCM
863scm_primitive_eval (SCM exp)
864{
865 return scm_c_vm_run (scm_the_vm (), scm_variable_ref (var_primitive_eval),
866 &exp, 1);
867}
71560395 868
b7742c6b
AW
869
870/* Eval does not take the second arg optionally. This is intentional
871 * in order to be R5RS compatible, and to prepare for the new module
872 * system, where we would like to make the choice of evaluation
873 * environment explicit. */
874
875SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
876 (SCM exp, SCM module_or_state),
877 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
878 "in the top-level environment specified by\n"
879 "@var{module_or_state}.\n"
880 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
881 "@var{module_or_state} is made the current module when\n"
882 "it is a module, or the current dynamic state when it is\n"
883 "a dynamic state."
884 "Example: (eval '(+ 1 2) (interaction-environment))")
885#define FUNC_NAME s_scm_eval
886{
887 SCM res;
888
889 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
890 if (scm_is_dynamic_state (module_or_state))
891 scm_dynwind_current_dynamic_state (module_or_state);
892 else if (scm_module_system_booted_p)
893 {
894 SCM_VALIDATE_MODULE (2, module_or_state);
895 scm_dynwind_current_module (module_or_state);
71560395 896 }
b7742c6b 897 /* otherwise if the module system isn't booted, ignore the module arg */
71560395 898
b7742c6b
AW
899 res = scm_primitive_eval (exp);
900
901 scm_dynwind_end ();
902 return res;
903}
904#undef FUNC_NAME
71560395
AW
905
906
b7742c6b 907static SCM f_apply;
71560395
AW
908
909/* Apply a function to a list of arguments.
910
911 This function is exported to the Scheme level as taking two
912 required arguments and a tail argument, as if it were:
913 (lambda (proc arg1 . args) ...)
914 Thus, if you just have a list of arguments to pass to a procedure,
915 pass the list as ARG1, and '() for ARGS. If you have some fixed
916 args, pass the first as ARG1, then cons any remaining fixed args
917 onto the front of your argument list, and pass that as ARGS. */
918
919SCM
920scm_apply (SCM proc, SCM arg1, SCM args)
921{
b7742c6b 922 /* Fix things up so that args contains all args. */
71560395 923 if (scm_is_null (args))
b7742c6b 924 args = arg1;
71560395 925 else
b7742c6b 926 args = scm_cons_star (arg1, args);
71560395 927
67e2d80a 928 return scm_vm_apply (scm_the_vm (), proc, args);
b7742c6b 929}
434f2f7a
DH
930
931
314b8716
AW
932static SCM
933boot_closure_apply (SCM closure, SCM args)
934{
935 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure);
936 SCM new_env = BOOT_CLOSURE_ENV (closure);
937 if (BOOT_CLOSURE_HAS_REST_ARGS (closure))
938 {
939 if (SCM_UNLIKELY (scm_ilength (args) < nreq))
940 scm_wrong_num_args (closure);
941 for (; nreq; nreq--, args = CDR (args))
942 new_env = scm_cons (CAR (args), new_env);
943 new_env = scm_cons (args, new_env);
944 }
945 else
946 {
947 if (SCM_UNLIKELY (scm_ilength (args) != nreq))
948 scm_wrong_num_args (closure);
949 for (; scm_is_pair (args); args = CDR (args))
950 new_env = scm_cons (CAR (args), new_env);
951 }
952 return eval (BOOT_CLOSURE_BODY (closure), new_env);
953}
954
955static int
956boot_closure_print (SCM closure, SCM port, scm_print_state *pstate)
957{
958 SCM args;
959 scm_puts ("#<boot-closure ", port);
960 scm_uintprint ((unsigned long)SCM2PTR (closure), 16, port);
961 scm_putc (' ', port);
962 args = scm_make_list (scm_from_int (BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure)),
963 scm_from_locale_symbol ("_"));
964 if (BOOT_CLOSURE_HAS_REST_ARGS (closure))
965 args = scm_cons_star (scm_from_locale_symbol ("_"), args);
966 scm_display (args, port);
967 scm_putc ('>', port);
968 return 1;
969}
970
0f2d19dd
JB
971void
972scm_init_eval ()
0f2d19dd 973{
5f161164
AW
974 SCM primitive_eval;
975
33b97402 976 scm_init_opts (scm_evaluator_traps,
62560650 977 scm_evaluator_trap_table);
33b97402 978 scm_init_opts (scm_eval_options_interface,
62560650 979 scm_eval_opts);
33b97402 980
df9ca8d8 981 f_apply = scm_c_define_gsubr ("apply", 2, 0, 1, scm_apply);
86d31dfe 982
314b8716
AW
983 scm_tc16_boot_closure = scm_make_smob_type ("boot-closure", 0);
984 scm_set_smob_apply (scm_tc16_boot_closure, boot_closure_apply, 0, 0, 1);
985 scm_set_smob_print (scm_tc16_boot_closure, boot_closure_print);
986
5f161164
AW
987 primitive_eval = scm_c_make_gsubr ("primitive-eval", 1, 0, 0,
988 scm_c_primitive_eval);
989 var_primitive_eval = scm_define (SCM_SUBR_NAME (primitive_eval),
990 primitive_eval);
991
a0599745 992#include "libguile/eval.x"
0f2d19dd 993}
0f2d19dd 994
89e00824
ML
995/*
996 Local Variables:
997 c-file-style: "gnu"
998 End:
999*/
62560650 1000