Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / libguile / eval.c
CommitLineData
9ede013f 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012
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>
741b8a23 27#include <stdarg.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"
a310a1d1 40#include "libguile/expand.h"
21628685
DH
41#include "libguile/feature.h"
42#include "libguile/fluids.h"
21628685
DH
43#include "libguile/goops.h"
44#include "libguile/hash.h"
45#include "libguile/hashtab.h"
4610b011 46#include "libguile/list.h"
a0599745 47#include "libguile/macros.h"
b7742c6b 48#include "libguile/memoize.h"
a0599745
MD
49#include "libguile/modules.h"
50#include "libguile/ports.h"
7e6e6b37 51#include "libguile/print.h"
21628685 52#include "libguile/procprop.h"
4abef68f 53#include "libguile/programs.h"
a0599745 54#include "libguile/root.h"
21628685
DH
55#include "libguile/smob.h"
56#include "libguile/srcprop.h"
57#include "libguile/stackchk.h"
58#include "libguile/strings.h"
9de87eea 59#include "libguile/threads.h"
21628685
DH
60#include "libguile/throw.h"
61#include "libguile/validate.h"
a513ead3 62#include "libguile/values.h"
21628685 63#include "libguile/vectors.h"
4abef68f 64#include "libguile/vm.h"
a0599745 65
a0599745 66#include "libguile/eval.h"
0ee05b85 67#include "libguile/private-options.h"
89efbff4 68
0f2d19dd
JB
69\f
70
0ee05b85 71
b7742c6b 72/* We have three levels of EVAL here:
609a8b86 73
b7742c6b 74 - eval (exp, env)
89bff2fc 75
b7742c6b
AW
76 evaluates EXP in environment ENV. ENV is a lexical environment
77 structure as used by the actual tree code evaluator. When ENV is
78 a top-level environment, then changes to the current module are
79 tracked by updating ENV so that it continues to be in sync with
80 the current module.
e6729603 81
b7742c6b 82 - scm_primitive_eval (exp)
e6729603 83
b7742c6b
AW
84 evaluates EXP in the top-level environment as determined by the
85 current module. This is done by constructing a suitable
86 environment and calling eval. Thus, changes to the
87 top-level module are tracked normally.
e6729603 88
b7742c6b 89 - scm_eval (exp, mod)
e6729603 90
b7742c6b
AW
91 evaluates EXP while MOD is the current module. This is done
92 by setting the current module to MOD_OR_STATE, invoking
93 scm_primitive_eval on EXP, and then restoring the current module
94 to the value it had previously. That is, while EXP is evaluated,
95 changes to the current module (or dynamic state) are tracked,
96 but these changes do not persist when scm_eval returns.
e6729603 97
b7742c6b 98*/
e6729603 99
e6729603 100
314b8716
AW
101/* Boot closures. We only see these when compiling eval.scm, because once
102 eval.scm is in the house, closures are standard VM closures.
103 */
104
105static scm_t_bits scm_tc16_boot_closure;
b2b33168
AW
106#define RETURN_BOOT_CLOSURE(code, env) \
107 SCM_RETURN_NEWSMOB2 (scm_tc16_boot_closure, SCM_UNPACK (code), SCM_UNPACK (env))
314b8716
AW
108#define BOOT_CLOSURE_P(obj) SCM_TYP16_PREDICATE (scm_tc16_boot_closure, (obj))
109#define BOOT_CLOSURE_CODE(x) SCM_SMOB_OBJECT (x)
110#define BOOT_CLOSURE_ENV(x) SCM_SMOB_OBJECT_2 (x)
8f9c5b58 111#define BOOT_CLOSURE_BODY(x) CAR (BOOT_CLOSURE_CODE (x))
c438cd71
LC
112#define BOOT_CLOSURE_NUM_REQUIRED_ARGS(x) (SCM_I_INUM (CADDR (BOOT_CLOSURE_CODE (x))))
113#define BOOT_CLOSURE_IS_FIXED(x) (scm_is_null (CDDDR (BOOT_CLOSURE_CODE (x))))
8f9c5b58 114/* NB: One may only call the following accessors if the closure is not FIXED. */
c438cd71
LC
115#define BOOT_CLOSURE_HAS_REST_ARGS(x) scm_is_true (CADDR (SCM_CDR (BOOT_CLOSURE_CODE (x))))
116#define BOOT_CLOSURE_IS_REST(x) scm_is_null (SCM_CDR (CDDDR (BOOT_CLOSURE_CODE (x))))
8f9c5b58
AW
117/* NB: One may only call the following accessors if the closure is not REST. */
118#define BOOT_CLOSURE_IS_FULL(x) (1)
dc3e203e
AW
119#define BOOT_CLOSURE_PARSE_FULL(fu_,body,nargs,rest,nopt,kw,inits,alt) \
120 do { SCM fu = fu_; \
c438cd71 121 body = CAR (fu); fu = CDDR (fu); \
dc3e203e
AW
122 \
123 rest = kw = alt = SCM_BOOL_F; \
124 inits = SCM_EOL; \
125 nopt = 0; \
126 \
127 nreq = SCM_I_INUM (CAR (fu)); fu = CDR (fu); \
128 if (scm_is_pair (fu)) \
129 { \
130 rest = CAR (fu); fu = CDR (fu); \
131 if (scm_is_pair (fu)) \
132 { \
133 nopt = SCM_I_INUM (CAR (fu)); fu = CDR (fu); \
134 kw = CAR (fu); fu = CDR (fu); \
135 inits = CAR (fu); fu = CDR (fu); \
136 alt = CAR (fu); \
137 } \
138 } \
d8a071fc 139 } while (0)
7572ee52
AW
140static void prepare_boot_closure_env_for_apply (SCM proc, SCM args,
141 SCM *out_body, SCM *out_env);
142static void prepare_boot_closure_env_for_eval (SCM proc, unsigned int argc,
143 SCM exps, SCM *out_body,
144 SCM *inout_env);
314b8716
AW
145
146
b7742c6b
AW
147#define CAR(x) SCM_CAR(x)
148#define CDR(x) SCM_CDR(x)
149#define CAAR(x) SCM_CAAR(x)
150#define CADR(x) SCM_CADR(x)
151#define CDAR(x) SCM_CDAR(x)
152#define CDDR(x) SCM_CDDR(x)
153#define CADDR(x) SCM_CADDR(x)
154#define CDDDR(x) SCM_CDDDR(x)
e6729603
DH
155
156
b7742c6b 157SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
e6729603 158
b7742c6b 159static void error_used_before_defined (void)
d0624e39 160{
b7742c6b
AW
161 scm_error (scm_unbound_variable_key, NULL,
162 "Variable used before given a value", SCM_EOL, SCM_BOOL_F);
d0624e39 163}
d0624e39 164
d8a071fc
AW
165static void error_invalid_keyword (SCM proc)
166{
4a655e50 167 scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
d8a071fc
AW
168 scm_from_locale_string ("Invalid keyword"), SCM_EOL,
169 SCM_BOOL_F);
170}
171
172static void error_unrecognized_keyword (SCM proc)
173{
4a655e50 174 scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
d8a071fc
AW
175 scm_from_locale_string ("Unrecognized keyword"), SCM_EOL,
176 SCM_BOOL_F);
177}
178
179
f3a9a51d
AW
180/* Multiple values truncation. */
181static SCM
182truncate_values (SCM x)
183{
184 if (SCM_LIKELY (!SCM_VALUESP (x)))
185 return x;
186 else
187 {
188 SCM l = scm_struct_ref (x, SCM_INUM0);
189 if (SCM_LIKELY (scm_is_pair (l)))
190 return scm_car (l);
191 else
192 {
193 scm_ithrow (scm_from_latin1_symbol ("vm-run"),
194 scm_list_3 (scm_from_latin1_symbol ("vm-run"),
195 scm_from_locale_string
196 ("Too few values returned to continuation"),
197 SCM_EOL),
198 1);
199 /* Not reached. */
200 return SCM_BOOL_F;
201 }
202 }
203}
204#define EVAL1(x, env) (truncate_values (eval ((x), (env))))
205
b7742c6b 206/* the environment:
3149a5b6 207 (VAL ... . MOD)
b7742c6b
AW
208 If MOD is #f, it means the environment was captured before modules were
209 booted.
210 If MOD is the literal value '(), we are evaluating at the top level, and so
211 should track changes to the current module. You have to be careful in this
212 case, because further lexical contours should capture the current module.
213*/
214#define CAPTURE_ENV(env) \
393baa8a
AW
215 (scm_is_null (env) ? scm_current_module () : \
216 (scm_is_false (env) ? scm_the_root_module () : env))
6f81708a
DH
217
218static SCM
b7742c6b 219eval (SCM x, SCM env)
6f81708a 220{
b7742c6b
AW
221 SCM mx;
222 SCM proc = SCM_UNDEFINED, args = SCM_EOL;
b7ecadca 223 unsigned int argc;
6f81708a 224
b7742c6b
AW
225 loop:
226 SCM_TICK;
227 if (!SCM_MEMOIZED_P (x))
228 abort ();
229
230 mx = SCM_MEMOIZED_ARGS (x);
231 switch (SCM_MEMOIZED_TAG (x))
232 {
6fc3eae4
AW
233 case SCM_M_SEQ:
234 eval (CAR (mx), env);
235 x = CDR (mx);
b7742c6b
AW
236 goto loop;
237
238 case SCM_M_IF:
f3a9a51d 239 if (scm_is_true (EVAL1 (CAR (mx), env)))
b7742c6b 240 x = CADR (mx);
6f81708a 241 else
b7742c6b
AW
242 x = CDDR (mx);
243 goto loop;
5fb64383 244
b7742c6b
AW
245 case SCM_M_LET:
246 {
247 SCM inits = CAR (mx);
248 SCM new_env = CAPTURE_ENV (env);
249 for (; scm_is_pair (inits); inits = CDR (inits))
f3a9a51d
AW
250 new_env = scm_cons (EVAL1 (CAR (inits), env),
251 new_env);
b7742c6b
AW
252 env = new_env;
253 x = CDR (mx);
254 goto loop;
255 }
256
257 case SCM_M_LAMBDA:
314b8716 258 RETURN_BOOT_CLOSURE (mx, CAPTURE_ENV (env));
5fb64383 259
b7742c6b
AW
260 case SCM_M_QUOTE:
261 return mx;
0f2d19dd 262
b7742c6b 263 case SCM_M_DEFINE:
f3a9a51d 264 scm_define (CAR (mx), EVAL1 (CDR (mx), env));
b7742c6b 265 return SCM_UNSPECIFIED;
212e58ed 266
d69531e2
AW
267 case SCM_M_DYNWIND:
268 {
9ede013f
AW
269 SCM in, out, res;
270 scm_i_thread *t = SCM_I_CURRENT_THREAD;
f3a9a51d
AW
271 in = EVAL1 (CAR (mx), env);
272 out = EVAL1 (CDDR (mx), env);
d69531e2 273 scm_call_0 (in);
9ede013f 274 scm_dynstack_push_dynwind (&t->dynstack, in, out);
d69531e2 275 res = eval (CADR (mx), env);
9ede013f 276 scm_dynstack_pop (&t->dynstack);
d69531e2
AW
277 scm_call_0 (out);
278 return res;
279 }
280
bb0229b5
AW
281 case SCM_M_WITH_FLUIDS:
282 {
283 long i, len;
9ede013f
AW
284 SCM *fluidv, *valuesv, walk, res;
285 scm_i_thread *thread = SCM_I_CURRENT_THREAD;
286
bb0229b5
AW
287 len = scm_ilength (CAR (mx));
288 fluidv = alloca (sizeof (SCM)*len);
289 for (i = 0, walk = CAR (mx); i < len; i++, walk = CDR (walk))
f3a9a51d 290 fluidv[i] = EVAL1 (CAR (walk), env);
bb0229b5
AW
291 valuesv = alloca (sizeof (SCM)*len);
292 for (i = 0, walk = CADR (mx); i < len; i++, walk = CDR (walk))
f3a9a51d 293 valuesv[i] = EVAL1 (CAR (walk), env);
bb0229b5 294
9ede013f
AW
295 scm_dynstack_push_fluids (&thread->dynstack, len, fluidv, valuesv,
296 thread->dynamic_state);
bb0229b5 297 res = eval (CDDR (mx), env);
9ede013f 298 scm_dynstack_unwind_fluids (&thread->dynstack, thread->dynamic_state);
bb0229b5
AW
299
300 return res;
301 }
302
b7742c6b
AW
303 case SCM_M_APPLY:
304 /* Evaluate the procedure to be applied. */
f3a9a51d 305 proc = EVAL1 (CAR (mx), env);
b7742c6b 306 /* Evaluate the argument holding the list of arguments */
f3a9a51d 307 args = EVAL1 (CADR (mx), env);
b7742c6b
AW
308
309 apply_proc:
310 /* Go here to tail-apply a procedure. PROC is the procedure and
311 * ARGS is the list of arguments. */
314b8716 312 if (BOOT_CLOSURE_P (proc))
b7742c6b 313 {
7572ee52 314 prepare_boot_closure_env_for_apply (proc, args, &x, &env);
b7742c6b
AW
315 goto loop;
316 }
317 else
ea9f4f4b 318 return scm_call_with_vm (scm_the_vm (), proc, args);
212e58ed 319
b7742c6b
AW
320 case SCM_M_CALL:
321 /* Evaluate the procedure to be applied. */
f3a9a51d 322 proc = EVAL1 (CAR (mx), env);
b7ecadca 323 argc = SCM_I_INUM (CADR (mx));
9331f91c 324 mx = CDDR (mx);
212e58ed 325
314b8716 326 if (BOOT_CLOSURE_P (proc))
5fa0939c 327 {
7572ee52 328 prepare_boot_closure_env_for_eval (proc, argc, mx, &x, &env);
b7742c6b 329 goto loop;
5fa0939c 330 }
b7742c6b
AW
331 else
332 {
e2cf8eb9 333 SCM *argv;
b7ecadca
LC
334 unsigned int i;
335
e2cf8eb9 336 argv = alloca (argc * sizeof (SCM));
b7ecadca 337 for (i = 0; i < argc; i++, mx = CDR (mx))
f3a9a51d 338 argv[i] = EVAL1 (CAR (mx), env);
b7ecadca
LC
339
340 return scm_c_vm_run (scm_the_vm (), proc, argv, argc);
b7742c6b 341 }
b7ecadca 342
b7742c6b 343 case SCM_M_CONT:
f3a9a51d 344 return scm_i_call_with_current_continuation (EVAL1 (mx, env));
212e58ed 345
b7742c6b
AW
346 case SCM_M_CALL_WITH_VALUES:
347 {
348 SCM producer;
349 SCM v;
350
f3a9a51d
AW
351 producer = EVAL1 (CAR (mx), env);
352 /* `proc' is the consumer. */
353 proc = EVAL1 (CDR (mx), env);
ea9f4f4b 354 v = scm_call_with_vm (scm_the_vm (), producer, SCM_EOL);
b7742c6b
AW
355 if (SCM_VALUESP (v))
356 args = scm_struct_ref (v, SCM_INUM0);
357 else
358 args = scm_list_1 (v);
359 goto apply_proc;
360 }
26d5b9b4 361
b7742c6b
AW
362 case SCM_M_LEXICAL_REF:
363 {
364 int n;
365 SCM ret;
366 for (n = SCM_I_INUM (mx); n; n--)
367 env = CDR (env);
368 ret = CAR (env);
369 if (SCM_UNLIKELY (SCM_UNBNDP (ret)))
370 /* we don't know what variable, though, because we don't have its
371 name */
372 error_used_before_defined ();
373 return ret;
374 }
1cc91f1b 375
b7742c6b
AW
376 case SCM_M_LEXICAL_SET:
377 {
378 int n;
f3a9a51d 379 SCM val = EVAL1 (CDR (mx), env);
b7742c6b
AW
380 for (n = SCM_I_INUM (CAR (mx)); n; n--)
381 env = CDR (env);
382 SCM_SETCAR (env, val);
383 return SCM_UNSPECIFIED;
384 }
910b5125 385
b7742c6b
AW
386 case SCM_M_TOPLEVEL_REF:
387 if (SCM_VARIABLEP (mx))
388 return SCM_VARIABLE_REF (mx);
389 else
57d23e25 390 {
b7742c6b 391 while (scm_is_pair (env))
f3a8d1b7 392 env = CDR (env);
3149a5b6
AW
393 return SCM_VARIABLE_REF
394 (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)));
57d23e25 395 }
57d23e25 396
b7742c6b
AW
397 case SCM_M_TOPLEVEL_SET:
398 {
399 SCM var = CAR (mx);
f3a9a51d 400 SCM val = EVAL1 (CDR (mx), env);
b7742c6b
AW
401 if (SCM_VARIABLEP (var))
402 {
403 SCM_VARIABLE_SET (var, val);
404 return SCM_UNSPECIFIED;
405 }
406 else
407 {
408 while (scm_is_pair (env))
f3a8d1b7 409 env = CDR (env);
3149a5b6
AW
410 SCM_VARIABLE_SET
411 (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)),
412 val);
b7742c6b
AW
413 return SCM_UNSPECIFIED;
414 }
415 }
910b5125 416
b7742c6b
AW
417 case SCM_M_MODULE_REF:
418 if (SCM_VARIABLEP (mx))
419 return SCM_VARIABLE_REF (mx);
910b5125 420 else
3149a5b6
AW
421 return SCM_VARIABLE_REF
422 (scm_memoize_variable_access_x (x, SCM_BOOL_F));
910b5125 423
b7742c6b
AW
424 case SCM_M_MODULE_SET:
425 if (SCM_VARIABLEP (CDR (mx)))
910b5125 426 {
f3a9a51d 427 SCM_VARIABLE_SET (CDR (mx), EVAL1 (CAR (mx), env));
b7742c6b
AW
428 return SCM_UNSPECIFIED;
429 }
430 else
431 {
3149a5b6
AW
432 SCM_VARIABLE_SET
433 (scm_memoize_variable_access_x (x, SCM_BOOL_F),
f3a9a51d 434 EVAL1 (CAR (mx), env));
b7742c6b 435 return SCM_UNSPECIFIED;
910b5125 436 }
910b5125 437
747022e4
AW
438 case SCM_M_PROMPT:
439 {
9ede013f 440 SCM vm, k, res;
9d381ba4 441 scm_i_jmp_buf registers;
9ede013f
AW
442 /* We need the handler after nonlocal return to the setjmp, so
443 make sure it is volatile. */
444 volatile SCM handler;
445
446 k = EVAL1 (CAR (mx), env);
f3a9a51d 447 handler = EVAL1 (CDDR (mx), env);
9ede013f
AW
448 vm = scm_the_vm ();
449
450 /* Push the prompt onto the dynamic stack. */
9ede013f 451 scm_dynstack_push_prompt (&SCM_I_CURRENT_THREAD->dynstack,
9d381ba4
AW
452 SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY,
453 k,
454 SCM_VM_DATA (vm)->fp,
455 SCM_VM_DATA (vm)->sp,
456 SCM_VM_DATA (vm)->ip,
457 &registers);
458
459 if (SCM_I_SETJMP (registers))
747022e4 460 {
b8af64db 461 /* The prompt exited nonlocally. */
747022e4 462 proc = handler;
572eef50 463 args = scm_i_prompt_pop_abort_args_x (scm_the_vm ());
747022e4
AW
464 goto apply_proc;
465 }
466
467 res = eval (CADR (mx), env);
9ede013f 468 scm_dynstack_pop (&SCM_I_CURRENT_THREAD->dynstack);
747022e4
AW
469 return res;
470 }
471
b7742c6b
AW
472 default:
473 abort ();
474 }
910b5125
DH
475}
476
b7742c6b 477\f
2a6f7afe 478
b7742c6b
AW
479/* Simple procedure calls
480 */
2a6f7afe 481
b7742c6b
AW
482SCM
483scm_call_0 (SCM proc)
484{
bf5a05f2 485 return scm_c_vm_run (scm_the_vm (), proc, NULL, 0);
0f2d19dd
JB
486}
487
b7742c6b
AW
488SCM
489scm_call_1 (SCM proc, SCM arg1)
212e58ed 490{
bf5a05f2 491 return scm_c_vm_run (scm_the_vm (), proc, &arg1, 1);
b7742c6b 492}
212e58ed 493
b7742c6b
AW
494SCM
495scm_call_2 (SCM proc, SCM arg1, SCM arg2)
496{
bf5a05f2
AW
497 SCM args[] = { arg1, arg2 };
498 return scm_c_vm_run (scm_the_vm (), proc, args, 2);
212e58ed
DH
499}
500
b7742c6b
AW
501SCM
502scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
0f2d19dd 503{
bf5a05f2
AW
504 SCM args[] = { arg1, arg2, arg3 };
505 return scm_c_vm_run (scm_the_vm (), proc, args, 3);
0f2d19dd
JB
506}
507
b7742c6b
AW
508SCM
509scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
212e58ed 510{
bf5a05f2
AW
511 SCM args[] = { arg1, arg2, arg3, arg4 };
512 return scm_c_vm_run (scm_the_vm (), proc, args, 4);
212e58ed
DH
513}
514
f32e67be
AW
515SCM
516scm_call_5 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5)
517{
518 SCM args[] = { arg1, arg2, arg3, arg4, arg5 };
519 return scm_c_vm_run (scm_the_vm (), proc, args, 5);
520}
521
522SCM
523scm_call_6 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
524 SCM arg6)
525{
526 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6 };
527 return scm_c_vm_run (scm_the_vm (), proc, args, 6);
528}
529
741b8a23
MW
530SCM
531scm_call_7 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
532 SCM arg6, SCM arg7)
533{
534 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
535 return scm_c_vm_run (scm_the_vm (), proc, args, 7);
536}
537
538SCM
539scm_call_8 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
540 SCM arg6, SCM arg7, SCM arg8)
541{
542 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 };
543 return scm_c_vm_run (scm_the_vm (), proc, args, 8);
544}
545
546SCM
547scm_call_9 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
548 SCM arg6, SCM arg7, SCM arg8, SCM arg9)
549{
550 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 };
551 return scm_c_vm_run (scm_the_vm (), proc, args, 9);
552}
553
86fd6dff
AW
554SCM
555scm_call_n (SCM proc, SCM *argv, size_t nargs)
556{
557 return scm_c_vm_run (scm_the_vm (), proc, argv, nargs);
558}
559
741b8a23 560SCM
07c2ca0f 561scm_call (SCM proc, ...)
741b8a23
MW
562{
563 va_list argp;
564 SCM *argv = NULL;
565 size_t i, nargs = 0;
566
567 va_start (argp, proc);
568 while (!SCM_UNBNDP (va_arg (argp, SCM)))
569 nargs++;
570 va_end (argp);
571
572 argv = alloca (nargs * sizeof (SCM));
573 va_start (argp, proc);
574 for (i = 0; i < nargs; i++)
575 argv[i] = va_arg (argp, SCM);
576 va_end (argp);
577
578 return scm_c_vm_run (scm_the_vm (), proc, argv, nargs);
579}
580
b7742c6b 581/* Simple procedure applies
9fbee57e 582 */
cc56ba80 583
b7742c6b
AW
584SCM
585scm_apply_0 (SCM proc, SCM args)
586{
587 return scm_apply (proc, args, SCM_EOL);
0f572ba7
DH
588}
589
b7742c6b
AW
590SCM
591scm_apply_1 (SCM proc, SCM arg1, SCM args)
0f572ba7 592{
b7742c6b 593 return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
8ae95199
DH
594}
595
b7742c6b
AW
596SCM
597scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
0f2d19dd 598{
b7742c6b 599 return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
0f2d19dd
JB
600}
601
b7742c6b
AW
602SCM
603scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
212e58ed 604{
b7742c6b
AW
605 return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
606 SCM_EOL);
212e58ed
DH
607}
608
b7742c6b 609/* This code processes the arguments to apply:
8ea46249 610
b7742c6b 611 (apply PROC ARG1 ... ARGS)
302c12b4 612
b7742c6b
AW
613 Given a list (ARG1 ... ARGS), this function conses the ARG1
614 ... arguments onto the front of ARGS, and returns the resulting
615 list. Note that ARGS is a list; thus, the argument to this
616 function is a list whose last element is a list.
302c12b4 617
b7742c6b
AW
618 Apply calls this function, and applies PROC to the elements of the
619 result. apply:nconc2last takes care of building the list of
620 arguments, given (ARG1 ... ARGS).
a954ce1d 621
b7742c6b
AW
622 Rather than do new consing, apply:nconc2last destroys its argument.
623 On that topic, this code came into my care with the following
624 beautifully cryptic comment on that topic: "This will only screw
625 you if you do (scm_apply scm_apply '( ... ))" If you know what
626 they're referring to, send me a patch to this comment. */
0f2d19dd 627
b7742c6b
AW
628SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
629 (SCM lst),
630 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
631 "conses the @var{arg1} @dots{} arguments onto the front of\n"
632 "@var{args}, and returns the resulting list. Note that\n"
633 "@var{args} is a list; thus, the argument to this function is\n"
634 "a list whose last element is a list.\n"
635 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
636 "destroys its argument, so use with care.")
637#define FUNC_NAME s_scm_nconc2last
212e58ed 638{
b7742c6b
AW
639 SCM *lloc;
640 SCM_VALIDATE_NONEMPTYLIST (1, lst);
641 lloc = &lst;
b6b84131 642 while (!scm_is_null (SCM_CDR (*lloc)))
b7742c6b
AW
643 lloc = SCM_CDRLOC (*lloc);
644 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
645 *lloc = SCM_CAR (*lloc);
646 return lst;
212e58ed 647}
b7742c6b 648#undef FUNC_NAME
212e58ed 649
b8229a3b 650
b7742c6b
AW
651SCM
652scm_map (SCM proc, SCM arg1, SCM args)
0f2d19dd 653{
a2230b65 654 static SCM var = SCM_BOOL_F;
0f2d19dd 655
a2230b65
AW
656 if (scm_is_false (var))
657 var = scm_private_variable (scm_the_root_module (),
658 scm_from_latin1_symbol ("map"));
302c12b4 659
a2230b65
AW
660 return scm_apply (scm_variable_ref (var),
661 scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
662}
d6754c23 663
b7742c6b
AW
664SCM
665scm_for_each (SCM proc, SCM arg1, SCM args)
0f2d19dd 666{
a2230b65
AW
667 static SCM var = SCM_BOOL_F;
668
669 if (scm_is_false (var))
670 var = scm_private_variable (scm_the_root_module (),
671 scm_from_latin1_symbol ("for-each"));
672
673 return scm_apply (scm_variable_ref (var),
674 scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
b7742c6b 675}
71560395 676
71560395 677
5f161164
AW
678static SCM
679scm_c_primitive_eval (SCM exp)
b7742c6b 680{
a310a1d1 681 if (!SCM_EXPANDED_P (exp))
4f692ace 682 exp = scm_call_1 (scm_current_module_transformer (), exp);
a310a1d1 683 return eval (scm_memoize_expression (exp), SCM_EOL);
b7742c6b 684}
5f161164
AW
685
686static SCM var_primitive_eval;
687SCM
688scm_primitive_eval (SCM exp)
689{
690 return scm_c_vm_run (scm_the_vm (), scm_variable_ref (var_primitive_eval),
691 &exp, 1);
692}
71560395 693
b7742c6b
AW
694
695/* Eval does not take the second arg optionally. This is intentional
696 * in order to be R5RS compatible, and to prepare for the new module
697 * system, where we would like to make the choice of evaluation
698 * environment explicit. */
699
700SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
701 (SCM exp, SCM module_or_state),
702 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
703 "in the top-level environment specified by\n"
704 "@var{module_or_state}.\n"
705 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
706 "@var{module_or_state} is made the current module when\n"
707 "it is a module, or the current dynamic state when it is\n"
708 "a dynamic state."
709 "Example: (eval '(+ 1 2) (interaction-environment))")
710#define FUNC_NAME s_scm_eval
711{
712 SCM res;
713
714 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
715 if (scm_is_dynamic_state (module_or_state))
716 scm_dynwind_current_dynamic_state (module_or_state);
717 else if (scm_module_system_booted_p)
718 {
719 SCM_VALIDATE_MODULE (2, module_or_state);
720 scm_dynwind_current_module (module_or_state);
71560395 721 }
b7742c6b 722 /* otherwise if the module system isn't booted, ignore the module arg */
71560395 723
b7742c6b
AW
724 res = scm_primitive_eval (exp);
725
726 scm_dynwind_end ();
727 return res;
728}
729#undef FUNC_NAME
71560395
AW
730
731
b7742c6b 732static SCM f_apply;
71560395
AW
733
734/* Apply a function to a list of arguments.
735
736 This function is exported to the Scheme level as taking two
737 required arguments and a tail argument, as if it were:
738 (lambda (proc arg1 . args) ...)
739 Thus, if you just have a list of arguments to pass to a procedure,
740 pass the list as ARG1, and '() for ARGS. If you have some fixed
741 args, pass the first as ARG1, then cons any remaining fixed args
742 onto the front of your argument list, and pass that as ARGS. */
743
744SCM
745scm_apply (SCM proc, SCM arg1, SCM args)
746{
b7742c6b 747 /* Fix things up so that args contains all args. */
71560395 748 if (scm_is_null (args))
b7742c6b 749 args = arg1;
71560395 750 else
b7742c6b 751 args = scm_cons_star (arg1, args);
71560395 752
ea9f4f4b 753 return scm_call_with_vm (scm_the_vm (), proc, args);
b7742c6b 754}
434f2f7a 755
7572ee52
AW
756static void
757prepare_boot_closure_env_for_apply (SCM proc, SCM args,
758 SCM *out_body, SCM *out_env)
314b8716 759{
8f9c5b58
AW
760 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
761 SCM env = BOOT_CLOSURE_ENV (proc);
dc3e203e 762
8f9c5b58
AW
763 if (BOOT_CLOSURE_IS_FIXED (proc)
764 || (BOOT_CLOSURE_IS_REST (proc)
765 && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
766 {
767 if (SCM_UNLIKELY (scm_ilength (args) != nreq))
768 scm_wrong_num_args (proc);
769 for (; scm_is_pair (args); args = CDR (args))
770 env = scm_cons (CAR (args), env);
7572ee52
AW
771 *out_body = BOOT_CLOSURE_BODY (proc);
772 *out_env = env;
8f9c5b58
AW
773 }
774 else if (BOOT_CLOSURE_IS_REST (proc))
314b8716
AW
775 {
776 if (SCM_UNLIKELY (scm_ilength (args) < nreq))
8f9c5b58 777 scm_wrong_num_args (proc);
314b8716 778 for (; nreq; nreq--, args = CDR (args))
8f9c5b58
AW
779 env = scm_cons (CAR (args), env);
780 env = scm_cons (args, env);
7572ee52
AW
781 *out_body = BOOT_CLOSURE_BODY (proc);
782 *out_env = env;
314b8716
AW
783 }
784 else
d8a071fc
AW
785 {
786 int i, argc, nreq, nopt;
787 SCM body, rest, kw, inits, alt;
dc3e203e 788 SCM mx = BOOT_CLOSURE_CODE (proc);
d8a071fc 789
7572ee52 790 loop:
dc3e203e 791 BOOT_CLOSURE_PARSE_FULL (mx, body, nargs, rest, nopt, kw, inits, alt);
d8a071fc
AW
792
793 argc = scm_ilength (args);
794 if (argc < nreq)
795 {
796 if (scm_is_true (alt))
7572ee52 797 {
dc3e203e 798 mx = alt;
7572ee52
AW
799 goto loop;
800 }
d8a071fc
AW
801 else
802 scm_wrong_num_args (proc);
803 }
804 if (scm_is_false (kw) && argc > nreq + nopt && scm_is_false (rest))
805 {
806 if (scm_is_true (alt))
7572ee52 807 {
dc3e203e 808 mx = alt;
7572ee52
AW
809 goto loop;
810 }
d8a071fc
AW
811 else
812 scm_wrong_num_args (proc);
813 }
814
815 for (i = 0; i < nreq; i++, args = CDR (args))
816 env = scm_cons (CAR (args), env);
817
818 if (scm_is_false (kw))
819 {
820 /* Optional args (possibly), but no keyword args. */
821 for (; i < argc && i < nreq + nopt;
822 i++, args = CDR (args))
823 {
824 env = scm_cons (CAR (args), env);
825 inits = CDR (inits);
826 }
827
828 for (; i < nreq + nopt; i++, inits = CDR (inits))
f3a9a51d 829 env = scm_cons (EVAL1 (CAR (inits), env), env);
d8a071fc
AW
830
831 if (scm_is_true (rest))
832 env = scm_cons (args, env);
833 }
834 else
835 {
836 SCM aok;
837
838 aok = CAR (kw);
839 kw = CDR (kw);
840
841 /* Keyword args. As before, but stop at the first keyword. */
842 for (; i < argc && i < nreq + nopt && !scm_is_keyword (CAR (args));
843 i++, args = CDR (args), inits = CDR (inits))
844 env = scm_cons (CAR (args), env);
845
846 for (; i < nreq + nopt; i++, inits = CDR (inits))
f3a9a51d 847 env = scm_cons (EVAL1 (CAR (inits), env), env);
d8a071fc
AW
848
849 if (scm_is_true (rest))
850 {
851 env = scm_cons (args, env);
852 i++;
853 }
854
855 /* Now fill in env with unbound values, limn the rest of the args for
856 keywords, and fill in unbound values with their inits. */
857 {
858 int imax = i - 1;
859 int kw_start_idx = i;
860 SCM walk, k, v;
861 for (walk = kw; scm_is_pair (walk); walk = CDR (walk))
862 if (SCM_I_INUM (CDAR (walk)) > imax)
863 imax = SCM_I_INUM (CDAR (walk));
864 for (; i <= imax; i++)
865 env = scm_cons (SCM_UNDEFINED, env);
866
867 if (scm_is_pair (args) && scm_is_pair (CDR (args)))
868 for (; scm_is_pair (args) && scm_is_pair (CDR (args));
869 args = CDR (args))
870 {
871 k = CAR (args); v = CADR (args);
872 if (!scm_is_keyword (k))
873 {
874 if (scm_is_true (rest))
875 continue;
876 else
877 break;
878 }
879 for (walk = kw; scm_is_pair (walk); walk = CDR (walk))
880 if (scm_is_eq (k, CAAR (walk)))
881 {
882 /* Well... ok, list-set! isn't the nicest interface, but
883 hey. */
884 int iset = imax - SCM_I_INUM (CDAR (walk));
885 scm_list_set_x (env, SCM_I_MAKINUM (iset), v);
886 args = CDR (args);
887 break;
888 }
889 if (scm_is_null (walk) && scm_is_false (aok))
890 error_unrecognized_keyword (proc);
891 }
892 if (scm_is_pair (args) && scm_is_false (rest))
893 error_invalid_keyword (proc);
894
895 /* Now fill in unbound values, evaluating init expressions in their
896 appropriate environment. */
897 for (i = imax - kw_start_idx; scm_is_pair (inits); i--, inits = CDR (inits))
898 {
899 SCM tail = scm_list_tail (env, SCM_I_MAKINUM (i));
900 if (SCM_UNBNDP (CAR (tail)))
f3a9a51d 901 SCM_SETCAR (tail, EVAL1 (CAR (inits), CDR (tail)));
d8a071fc
AW
902 }
903 }
904 }
8f9c5b58 905
dc3e203e 906 *out_body = body;
7572ee52
AW
907 *out_env = env;
908 }
8f9c5b58
AW
909}
910
7572ee52 911static void
8f9c5b58 912prepare_boot_closure_env_for_eval (SCM proc, unsigned int argc,
7572ee52 913 SCM exps, SCM *out_body, SCM *inout_env)
8f9c5b58
AW
914{
915 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
916 SCM new_env = BOOT_CLOSURE_ENV (proc);
917 if (BOOT_CLOSURE_IS_FIXED (proc)
918 || (BOOT_CLOSURE_IS_REST (proc)
919 && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
314b8716 920 {
8f9c5b58 921 for (; scm_is_pair (exps); exps = CDR (exps), nreq--)
f3a9a51d
AW
922 new_env = scm_cons (EVAL1 (CAR (exps), *inout_env),
923 new_env);
8f9c5b58
AW
924 if (SCM_UNLIKELY (nreq != 0))
925 scm_wrong_num_args (proc);
7572ee52
AW
926 *out_body = BOOT_CLOSURE_BODY (proc);
927 *inout_env = new_env;
314b8716 928 }
8f9c5b58
AW
929 else if (BOOT_CLOSURE_IS_REST (proc))
930 {
931 if (SCM_UNLIKELY (argc < nreq))
932 scm_wrong_num_args (proc);
933 for (; nreq; nreq--, exps = CDR (exps))
f3a9a51d
AW
934 new_env = scm_cons (EVAL1 (CAR (exps), *inout_env),
935 new_env);
8f9c5b58
AW
936 {
937 SCM rest = SCM_EOL;
938 for (; scm_is_pair (exps); exps = CDR (exps))
f3a9a51d 939 rest = scm_cons (EVAL1 (CAR (exps), *inout_env), rest);
8f9c5b58
AW
940 new_env = scm_cons (scm_reverse (rest),
941 new_env);
942 }
7572ee52
AW
943 *out_body = BOOT_CLOSURE_BODY (proc);
944 *inout_env = new_env;
8f9c5b58
AW
945 }
946 else
d8a071fc
AW
947 {
948 SCM args = SCM_EOL;
949 for (; scm_is_pair (exps); exps = CDR (exps))
f3a9a51d 950 args = scm_cons (EVAL1 (CAR (exps), *inout_env), args);
7572ee52
AW
951 args = scm_reverse_x (args, SCM_UNDEFINED);
952 prepare_boot_closure_env_for_apply (proc, args, out_body, inout_env);
d8a071fc 953 }
8f9c5b58
AW
954}
955
956static SCM
957boot_closure_apply (SCM closure, SCM args)
958{
7572ee52
AW
959 SCM body, env;
960 prepare_boot_closure_env_for_apply (closure, args, &body, &env);
961 return eval (body, env);
314b8716
AW
962}
963
964static int
965boot_closure_print (SCM closure, SCM port, scm_print_state *pstate)
966{
967 SCM args;
0607ebbf 968 scm_puts_unlocked ("#<boot-closure ", port);
fdecb44f 969 scm_uintprint (SCM_UNPACK (closure), 16, port);
0607ebbf 970 scm_putc_unlocked (' ', port);
314b8716 971 args = scm_make_list (scm_from_int (BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure)),
4a655e50 972 scm_from_latin1_symbol ("_"));
8f9c5b58 973 if (!BOOT_CLOSURE_IS_FIXED (closure) && BOOT_CLOSURE_HAS_REST_ARGS (closure))
4a655e50 974 args = scm_cons_star (scm_from_latin1_symbol ("_"), args);
7572ee52 975 /* FIXME: optionals and rests */
314b8716 976 scm_display (args, port);
0607ebbf 977 scm_putc_unlocked ('>', port);
314b8716
AW
978 return 1;
979}
980
0f2d19dd
JB
981void
982scm_init_eval ()
0f2d19dd 983{
5f161164
AW
984 SCM primitive_eval;
985
df9ca8d8 986 f_apply = scm_c_define_gsubr ("apply", 2, 0, 1, scm_apply);
86d31dfe 987
314b8716
AW
988 scm_tc16_boot_closure = scm_make_smob_type ("boot-closure", 0);
989 scm_set_smob_apply (scm_tc16_boot_closure, boot_closure_apply, 0, 0, 1);
990 scm_set_smob_print (scm_tc16_boot_closure, boot_closure_print);
991
5f161164
AW
992 primitive_eval = scm_c_make_gsubr ("primitive-eval", 1, 0, 0,
993 scm_c_primitive_eval);
994 var_primitive_eval = scm_define (SCM_SUBR_NAME (primitive_eval),
995 primitive_eval);
996
a0599745 997#include "libguile/eval.x"
0f2d19dd 998}
0f2d19dd 999
89e00824
ML
1000/*
1001 Local Variables:
1002 c-file-style: "gnu"
1003 End:
1004*/
62560650 1005