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