simplify handling of nonlocal prompt returns from c
[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 {
430 SCM prompt, handler, res;
431
2d026f04 432 prompt = scm_c_make_prompt (scm_the_vm (), eval (CAR (mx), env), 0, -1);
747022e4
AW
433 handler = eval (CDDR (mx), env);
434 scm_i_set_dynwinds (scm_cons (prompt, scm_i_dynwinds ()));
435
436 if (SCM_PROMPT_SETJMP (prompt))
437 {
b8af64db 438 /* The prompt exited nonlocally. */
747022e4 439 proc = handler;
b8af64db 440 args = scm_i_prompt_pop_abort_args_x (prompt);
747022e4
AW
441 goto apply_proc;
442 }
443
444 res = eval (CADR (mx), env);
445 scm_i_set_dynwinds (CDR (scm_i_dynwinds ()));
446 return res;
447 }
448
b7742c6b
AW
449 default:
450 abort ();
451 }
910b5125
DH
452}
453
b7742c6b
AW
454scm_t_option scm_eval_opts[] = {
455 { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." },
456 { 0 }
457};
e6729603 458
b7742c6b
AW
459scm_t_option scm_debug_opts[] = {
460 { SCM_OPTION_BOOLEAN, "cheap", 1,
461 "*This option is now obsolete. Setting it has no effect." },
462 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
463 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
464 { SCM_OPTION_BOOLEAN, "procnames", 1,
465 "Record procedure names at definition." },
466 { SCM_OPTION_BOOLEAN, "backwards", 0,
467 "Display backtrace in anti-chronological order." },
468 { SCM_OPTION_INTEGER, "width", 79, "Maximal width of backtrace." },
469 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
470 { SCM_OPTION_INTEGER, "frames", 3,
471 "Maximum number of tail-recursive frames in backtrace." },
472 { SCM_OPTION_INTEGER, "maxdepth", 1000,
473 "Maximal number of stored backtrace frames." },
474 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
475 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
476 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
477 /* This default stack limit will be overridden by debug.c:init_stack_limit(),
478 if we have getrlimit() and the stack limit is not INFINITY. But it is still
479 important, as some systems have both the soft and the hard limits set to
480 INFINITY; in that case we fall back to this value.
e6729603 481
b7742c6b
AW
482 The situation is aggravated by certain compilers, which can consume
483 "beaucoup de stack", as they say in France.
0f2d19dd 484
b7742c6b
AW
485 See http://thread.gmane.org/gmane.lisp.guile.devel/8599/focus=8662 for
486 more discussion. This setting is 640 KB on 32-bit arches (should be enough
487 for anyone!) or a whoppin' 1280 KB on 64-bit arches.
488 */
489 { SCM_OPTION_INTEGER, "stack", 160000, "Stack size limit (measured in words; 0 = no check)." },
490 { SCM_OPTION_SCM, "show-file-name", (unsigned long)SCM_BOOL_T,
491 "Show file names and line numbers "
492 "in backtraces when not `#f'. A value of `base' "
493 "displays only base names, while `#t' displays full names."},
494 { SCM_OPTION_BOOLEAN, "warn-deprecated", 0,
495 "Warn when deprecated features are used." },
496 { 0 },
497};
212e58ed 498
1cc91f1b 499
b7742c6b
AW
500/*
501 * this ordering is awkward and illogical, but we maintain it for
502 * compatibility. --hwn
503 */
504scm_t_option scm_evaluator_trap_table[] = {
505 { SCM_OPTION_BOOLEAN, "traps", 0, "Enable evaluator traps." },
506 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
507 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
508 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." },
509 { SCM_OPTION_SCM, "enter-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for enter-frame traps." },
510 { SCM_OPTION_SCM, "apply-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for apply-frame traps." },
511 { SCM_OPTION_SCM, "exit-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for exit-frame traps." },
512 { SCM_OPTION_BOOLEAN, "memoize-symbol", 0, "Trap when memoizing a symbol." },
513 { SCM_OPTION_SCM, "memoize-symbol-handler", (unsigned long)SCM_BOOL_F, "The handler for memoization." },
514 { 0 }
515};
8ea46249 516
0f2d19dd 517
b7742c6b
AW
518SCM_DEFINE (scm_eval_options_interface, "eval-options-interface", 0, 1, 0,
519 (SCM setting),
520 "Option interface for the evaluation options. Instead of using\n"
521 "this procedure directly, use the procedures @code{eval-enable},\n"
522 "@code{eval-disable}, @code{eval-set!} and @code{eval-options}.")
523#define FUNC_NAME s_scm_eval_options_interface
212e58ed 524{
b7742c6b
AW
525 SCM ans;
526
527 scm_dynwind_begin (0);
528 scm_dynwind_critical_section (SCM_BOOL_F);
529 ans = scm_options (setting,
530 scm_eval_opts,
531 FUNC_NAME);
532 scm_dynwind_end ();
212e58ed 533
b7742c6b
AW
534 return ans;
535}
536#undef FUNC_NAME
0f2d19dd 537
1cc91f1b 538
b7742c6b
AW
539SCM_DEFINE (scm_evaluator_traps, "evaluator-traps-interface", 0, 1, 0,
540 (SCM setting),
541 "Option interface for the evaluator trap options.")
542#define FUNC_NAME s_scm_evaluator_traps
0f2d19dd 543{
b7742c6b 544 SCM ans;
2a6f7afe 545
b7742c6b
AW
546
547 scm_options_try (setting,
548 scm_evaluator_trap_table,
549 FUNC_NAME, 1);
550 SCM_CRITICAL_SECTION_START;
551 ans = scm_options (setting,
552 scm_evaluator_trap_table,
553 FUNC_NAME);
2a6f7afe 554
b7742c6b
AW
555 /* njrev: same again. */
556 SCM_CRITICAL_SECTION_END;
557 return ans;
558}
559#undef FUNC_NAME
2a6f7afe 560
2a6f7afe 561
2a6f7afe 562
b7742c6b 563\f
2a6f7afe 564
b7742c6b
AW
565/* Simple procedure calls
566 */
2a6f7afe 567
b7742c6b
AW
568SCM
569scm_call_0 (SCM proc)
570{
bf5a05f2 571 return scm_c_vm_run (scm_the_vm (), proc, NULL, 0);
0f2d19dd
JB
572}
573
b7742c6b
AW
574SCM
575scm_call_1 (SCM proc, SCM arg1)
212e58ed 576{
bf5a05f2 577 return scm_c_vm_run (scm_the_vm (), proc, &arg1, 1);
b7742c6b 578}
212e58ed 579
b7742c6b
AW
580SCM
581scm_call_2 (SCM proc, SCM arg1, SCM arg2)
582{
bf5a05f2
AW
583 SCM args[] = { arg1, arg2 };
584 return scm_c_vm_run (scm_the_vm (), proc, args, 2);
212e58ed
DH
585}
586
b7742c6b
AW
587SCM
588scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
0f2d19dd 589{
bf5a05f2
AW
590 SCM args[] = { arg1, arg2, arg3 };
591 return scm_c_vm_run (scm_the_vm (), proc, args, 3);
0f2d19dd
JB
592}
593
b7742c6b
AW
594SCM
595scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
212e58ed 596{
bf5a05f2
AW
597 SCM args[] = { arg1, arg2, arg3, arg4 };
598 return scm_c_vm_run (scm_the_vm (), proc, args, 4);
212e58ed
DH
599}
600
86fd6dff
AW
601SCM
602scm_call_n (SCM proc, SCM *argv, size_t nargs)
603{
604 return scm_c_vm_run (scm_the_vm (), proc, argv, nargs);
605}
606
b7742c6b 607/* Simple procedure applies
9fbee57e 608 */
cc56ba80 609
b7742c6b
AW
610SCM
611scm_apply_0 (SCM proc, SCM args)
612{
613 return scm_apply (proc, args, SCM_EOL);
0f572ba7
DH
614}
615
b7742c6b
AW
616SCM
617scm_apply_1 (SCM proc, SCM arg1, SCM args)
0f572ba7 618{
b7742c6b 619 return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
8ae95199
DH
620}
621
b7742c6b
AW
622SCM
623scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
0f2d19dd 624{
b7742c6b 625 return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
0f2d19dd
JB
626}
627
b7742c6b
AW
628SCM
629scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
212e58ed 630{
b7742c6b
AW
631 return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
632 SCM_EOL);
212e58ed
DH
633}
634
b7742c6b 635/* This code processes the arguments to apply:
8ea46249 636
b7742c6b 637 (apply PROC ARG1 ... ARGS)
302c12b4 638
b7742c6b
AW
639 Given a list (ARG1 ... ARGS), this function conses the ARG1
640 ... arguments onto the front of ARGS, and returns the resulting
641 list. Note that ARGS is a list; thus, the argument to this
642 function is a list whose last element is a list.
302c12b4 643
b7742c6b
AW
644 Apply calls this function, and applies PROC to the elements of the
645 result. apply:nconc2last takes care of building the list of
646 arguments, given (ARG1 ... ARGS).
a954ce1d 647
b7742c6b
AW
648 Rather than do new consing, apply:nconc2last destroys its argument.
649 On that topic, this code came into my care with the following
650 beautifully cryptic comment on that topic: "This will only screw
651 you if you do (scm_apply scm_apply '( ... ))" If you know what
652 they're referring to, send me a patch to this comment. */
0f2d19dd 653
b7742c6b
AW
654SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
655 (SCM lst),
656 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
657 "conses the @var{arg1} @dots{} arguments onto the front of\n"
658 "@var{args}, and returns the resulting list. Note that\n"
659 "@var{args} is a list; thus, the argument to this function is\n"
660 "a list whose last element is a list.\n"
661 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
662 "destroys its argument, so use with care.")
663#define FUNC_NAME s_scm_nconc2last
212e58ed 664{
b7742c6b
AW
665 SCM *lloc;
666 SCM_VALIDATE_NONEMPTYLIST (1, lst);
667 lloc = &lst;
668 while (!scm_is_null (SCM_CDR (*lloc))) /* Perhaps should be
669 SCM_NULL_OR_NIL_P, but not
670 needed in 99.99% of cases,
671 and it could seriously hurt
672 performance. - Neil */
673 lloc = SCM_CDRLOC (*lloc);
674 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
675 *lloc = SCM_CAR (*lloc);
676 return lst;
212e58ed 677}
b7742c6b 678#undef FUNC_NAME
212e58ed 679
b8229a3b
MS
680
681
b7742c6b 682/* Typechecking for multi-argument MAP and FOR-EACH.
0f2d19dd 683
b7742c6b
AW
684 Verify that each element of the vector ARGV, except for the first,
685 is a proper list whose length is LEN. Attribute errors to WHO,
686 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
687static inline void
688check_map_args (SCM argv,
689 long len,
690 SCM gf,
691 SCM proc,
692 SCM args,
693 const char *who)
212e58ed 694{
b7742c6b 695 long i;
0f2d19dd 696
b7742c6b 697 for (i = SCM_SIMPLE_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
9fbee57e 698 {
b7742c6b
AW
699 SCM elt = SCM_SIMPLE_VECTOR_REF (argv, i);
700 long elt_len = scm_ilength (elt);
5cb22e96 701
b7742c6b
AW
702 if (elt_len < 0)
703 {
704 if (gf)
705 scm_apply_generic (gf, scm_cons (proc, args));
706 else
707 scm_wrong_type_arg (who, i + 2, elt);
708 }
1cc91f1b 709
b7742c6b
AW
710 if (elt_len != len)
711 scm_out_of_range_pos (who, elt, scm_from_long (i + 2));
0f2d19dd 712 }
0f2d19dd 713}
6dbd0af5 714
212e58ed 715
b7742c6b 716SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
212e58ed 717
b7742c6b
AW
718/* Note: Currently, scm_map applies PROC to the argument list(s)
719 sequentially, starting with the first element(s). This is used in
720 evalext.c where the Scheme procedure `map-in-order', which guarantees
721 sequential behaviour, is implemented using scm_map. If the
722 behaviour changes, we need to update `map-in-order'.
723*/
0f2d19dd 724
b7742c6b
AW
725SCM
726scm_map (SCM proc, SCM arg1, SCM args)
727#define FUNC_NAME s_map
0f2d19dd 728{
b7742c6b
AW
729 long i, len;
730 SCM res = SCM_EOL;
731 SCM *pres = &res;
0f2d19dd 732
b7742c6b
AW
733 len = scm_ilength (arg1);
734 SCM_GASSERTn (len >= 0,
735 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
736 SCM_VALIDATE_REST_ARGUMENT (args);
737 if (scm_is_null (args))
0f2d19dd 738 {
b7742c6b
AW
739 SCM_GASSERT2 (scm_is_true (scm_procedure_p (proc)), g_map, proc, arg1, SCM_ARG1, s_map);
740 while (SCM_NIMP (arg1))
741 {
742 *pres = scm_list_1 (scm_call_1 (proc, SCM_CAR (arg1)));
743 pres = SCM_CDRLOC (*pres);
744 arg1 = SCM_CDR (arg1);
745 }
746 return res;
0f2d19dd 747 }
b7742c6b
AW
748 if (scm_is_null (SCM_CDR (args)))
749 {
750 SCM arg2 = SCM_CAR (args);
751 int len2 = scm_ilength (arg2);
752 SCM_GASSERTn (scm_is_true (scm_procedure_p (proc)), g_map,
753 scm_cons2 (proc, arg1, args), SCM_ARG1, s_map);
754 SCM_GASSERTn (len2 >= 0,
755 g_map, scm_cons2 (proc, arg1, args), SCM_ARG3, s_map);
756 if (len2 != len)
757 SCM_OUT_OF_RANGE (3, arg2);
758 while (SCM_NIMP (arg1))
759 {
760 *pres = scm_list_1 (scm_call_2 (proc, SCM_CAR (arg1), SCM_CAR (arg2)));
761 pres = SCM_CDRLOC (*pres);
762 arg1 = SCM_CDR (arg1);
763 arg2 = SCM_CDR (arg2);
764 }
765 return res;
766 }
767 arg1 = scm_cons (arg1, args);
768 args = scm_vector (arg1);
769 check_map_args (args, len, g_map, proc, arg1, s_map);
770 while (1)
d6754c23 771 {
b7742c6b
AW
772 arg1 = SCM_EOL;
773 for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
774 {
775 SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
776 if (SCM_IMP (elt))
777 return res;
778 arg1 = scm_cons (SCM_CAR (elt), arg1);
779 SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
780 }
781 *pres = scm_list_1 (scm_apply (proc, arg1, SCM_EOL));
782 pres = SCM_CDRLOC (*pres);
d6754c23 783 }
0f2d19dd 784}
b7742c6b 785#undef FUNC_NAME
0f2d19dd 786
302c12b4 787
b7742c6b 788SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
d6754c23 789
b7742c6b
AW
790SCM
791scm_for_each (SCM proc, SCM arg1, SCM args)
792#define FUNC_NAME s_for_each
0f2d19dd 793{
b7742c6b
AW
794 long i, len;
795 len = scm_ilength (arg1);
796 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
797 SCM_ARG2, s_for_each);
798 SCM_VALIDATE_REST_ARGUMENT (args);
799 if (scm_is_null (args))
26d5b9b4 800 {
b7742c6b
AW
801 SCM_GASSERT2 (scm_is_true (scm_procedure_p (proc)), g_for_each,
802 proc, arg1, SCM_ARG1, s_for_each);
803 while (SCM_NIMP (arg1))
804 {
805 scm_call_1 (proc, SCM_CAR (arg1));
806 arg1 = SCM_CDR (arg1);
807 }
808 return SCM_UNSPECIFIED;
26d5b9b4 809 }
b7742c6b 810 if (scm_is_null (SCM_CDR (args)))
26d5b9b4 811 {
b7742c6b
AW
812 SCM arg2 = SCM_CAR (args);
813 int len2 = scm_ilength (arg2);
814 SCM_GASSERTn (scm_is_true (scm_procedure_p (proc)), g_for_each,
815 scm_cons2 (proc, arg1, args), SCM_ARG1, s_for_each);
816 SCM_GASSERTn (len2 >= 0, g_for_each,
817 scm_cons2 (proc, arg1, args), SCM_ARG3, s_for_each);
818 if (len2 != len)
819 SCM_OUT_OF_RANGE (3, arg2);
820 while (SCM_NIMP (arg1))
821 {
822 scm_call_2 (proc, SCM_CAR (arg1), SCM_CAR (arg2));
823 arg1 = SCM_CDR (arg1);
824 arg2 = SCM_CDR (arg2);
825 }
826 return SCM_UNSPECIFIED;
26d5b9b4 827 }
b7742c6b
AW
828 arg1 = scm_cons (arg1, args);
829 args = scm_vector (arg1);
830 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
831 while (1)
302c12b4 832 {
b7742c6b
AW
833 arg1 = SCM_EOL;
834 for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
71560395 835 {
b7742c6b
AW
836 SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
837 if (SCM_IMP (elt))
838 return SCM_UNSPECIFIED;
839 arg1 = scm_cons (SCM_CAR (elt), arg1);
840 SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
841 }
842 scm_apply (proc, arg1, SCM_EOL);
843 }
844}
845#undef FUNC_NAME
71560395 846
71560395 847
5f161164
AW
848static SCM
849scm_c_primitive_eval (SCM exp)
b7742c6b
AW
850{
851 SCM transformer = scm_current_module_transformer ();
852 if (scm_is_true (transformer))
853 exp = scm_call_1 (transformer, exp);
854 exp = scm_memoize_expression (exp);
855 return eval (exp, SCM_EOL);
856}
5f161164
AW
857
858static SCM var_primitive_eval;
859SCM
860scm_primitive_eval (SCM exp)
861{
862 return scm_c_vm_run (scm_the_vm (), scm_variable_ref (var_primitive_eval),
863 &exp, 1);
864}
71560395 865
b7742c6b
AW
866
867/* Eval does not take the second arg optionally. This is intentional
868 * in order to be R5RS compatible, and to prepare for the new module
869 * system, where we would like to make the choice of evaluation
870 * environment explicit. */
871
872SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
873 (SCM exp, SCM module_or_state),
874 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
875 "in the top-level environment specified by\n"
876 "@var{module_or_state}.\n"
877 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
878 "@var{module_or_state} is made the current module when\n"
879 "it is a module, or the current dynamic state when it is\n"
880 "a dynamic state."
881 "Example: (eval '(+ 1 2) (interaction-environment))")
882#define FUNC_NAME s_scm_eval
883{
884 SCM res;
885
886 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
887 if (scm_is_dynamic_state (module_or_state))
888 scm_dynwind_current_dynamic_state (module_or_state);
889 else if (scm_module_system_booted_p)
890 {
891 SCM_VALIDATE_MODULE (2, module_or_state);
892 scm_dynwind_current_module (module_or_state);
71560395 893 }
b7742c6b 894 /* otherwise if the module system isn't booted, ignore the module arg */
71560395 895
b7742c6b
AW
896 res = scm_primitive_eval (exp);
897
898 scm_dynwind_end ();
899 return res;
900}
901#undef FUNC_NAME
71560395
AW
902
903
b7742c6b 904static SCM f_apply;
71560395
AW
905
906/* Apply a function to a list of arguments.
907
908 This function is exported to the Scheme level as taking two
909 required arguments and a tail argument, as if it were:
910 (lambda (proc arg1 . args) ...)
911 Thus, if you just have a list of arguments to pass to a procedure,
912 pass the list as ARG1, and '() for ARGS. If you have some fixed
913 args, pass the first as ARG1, then cons any remaining fixed args
914 onto the front of your argument list, and pass that as ARGS. */
915
916SCM
917scm_apply (SCM proc, SCM arg1, SCM args)
918{
b7742c6b 919 /* Fix things up so that args contains all args. */
71560395 920 if (scm_is_null (args))
b7742c6b 921 args = arg1;
71560395 922 else
b7742c6b 923 args = scm_cons_star (arg1, args);
71560395 924
67e2d80a 925 return scm_vm_apply (scm_the_vm (), proc, args);
b7742c6b 926}
434f2f7a
DH
927
928
314b8716
AW
929static SCM
930boot_closure_apply (SCM closure, SCM args)
931{
932 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure);
933 SCM new_env = BOOT_CLOSURE_ENV (closure);
934 if (BOOT_CLOSURE_HAS_REST_ARGS (closure))
935 {
936 if (SCM_UNLIKELY (scm_ilength (args) < nreq))
937 scm_wrong_num_args (closure);
938 for (; nreq; nreq--, args = CDR (args))
939 new_env = scm_cons (CAR (args), new_env);
940 new_env = scm_cons (args, new_env);
941 }
942 else
943 {
944 if (SCM_UNLIKELY (scm_ilength (args) != nreq))
945 scm_wrong_num_args (closure);
946 for (; scm_is_pair (args); args = CDR (args))
947 new_env = scm_cons (CAR (args), new_env);
948 }
949 return eval (BOOT_CLOSURE_BODY (closure), new_env);
950}
951
952static int
953boot_closure_print (SCM closure, SCM port, scm_print_state *pstate)
954{
955 SCM args;
956 scm_puts ("#<boot-closure ", port);
957 scm_uintprint ((unsigned long)SCM2PTR (closure), 16, port);
958 scm_putc (' ', port);
959 args = scm_make_list (scm_from_int (BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure)),
960 scm_from_locale_symbol ("_"));
961 if (BOOT_CLOSURE_HAS_REST_ARGS (closure))
962 args = scm_cons_star (scm_from_locale_symbol ("_"), args);
963 scm_display (args, port);
964 scm_putc ('>', port);
965 return 1;
966}
967
0f2d19dd
JB
968void
969scm_init_eval ()
0f2d19dd 970{
5f161164
AW
971 SCM primitive_eval;
972
33b97402 973 scm_init_opts (scm_evaluator_traps,
62560650 974 scm_evaluator_trap_table);
33b97402 975 scm_init_opts (scm_eval_options_interface,
62560650 976 scm_eval_opts);
33b97402 977
df9ca8d8 978 f_apply = scm_c_define_gsubr ("apply", 2, 0, 1, scm_apply);
86d31dfe 979
314b8716
AW
980 scm_tc16_boot_closure = scm_make_smob_type ("boot-closure", 0);
981 scm_set_smob_apply (scm_tc16_boot_closure, boot_closure_apply, 0, 0, 1);
982 scm_set_smob_print (scm_tc16_boot_closure, boot_closure_print);
983
5f161164
AW
984 primitive_eval = scm_c_make_gsubr ("primitive-eval", 1, 0, 0,
985 scm_c_primitive_eval);
986 var_primitive_eval = scm_define (SCM_SUBR_NAME (primitive_eval),
987 primitive_eval);
988
a0599745 989#include "libguile/eval.x"
0f2d19dd 990}
0f2d19dd 991
89e00824
ML
992/*
993 Local Variables:
994 c-file-style: "gnu"
995 End:
996*/
62560650 997