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