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