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