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