REPL Server: Don't establish a SIGINT handler.
[bpt/guile.git] / libguile / eval.c
CommitLineData
581f410f 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2013
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
4af0d97e 165static void error_invalid_keyword (SCM proc, SCM obj)
d8a071fc 166{
4a655e50 167 scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
d8a071fc 168 scm_from_locale_string ("Invalid keyword"), SCM_EOL,
4af0d97e 169 scm_list_1 (obj));
d8a071fc
AW
170}
171
4af0d97e 172static void error_unrecognized_keyword (SCM proc, SCM kw)
d8a071fc 173{
4a655e50 174 scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
d8a071fc 175 scm_from_locale_string ("Unrecognized keyword"), SCM_EOL,
4af0d97e 176 scm_list_1 (kw));
d8a071fc
AW
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 {
233 case SCM_M_BEGIN:
234 for (; !scm_is_null (CDR (mx)); mx = CDR (mx))
235 eval (CAR (mx), env);
236 x = CAR (mx);
237 goto loop;
238
239 case SCM_M_IF:
f3a9a51d 240 if (scm_is_true (EVAL1 (CAR (mx), env)))
b7742c6b 241 x = CADR (mx);
6f81708a 242 else
b7742c6b
AW
243 x = CDDR (mx);
244 goto loop;
5fb64383 245
b7742c6b
AW
246 case SCM_M_LET:
247 {
248 SCM inits = CAR (mx);
249 SCM new_env = CAPTURE_ENV (env);
250 for (; scm_is_pair (inits); inits = CDR (inits))
f3a9a51d
AW
251 new_env = scm_cons (EVAL1 (CAR (inits), env),
252 new_env);
b7742c6b
AW
253 env = new_env;
254 x = CDR (mx);
255 goto loop;
256 }
257
258 case SCM_M_LAMBDA:
314b8716 259 RETURN_BOOT_CLOSURE (mx, CAPTURE_ENV (env));
5fb64383 260
b7742c6b
AW
261 case SCM_M_QUOTE:
262 return mx;
0f2d19dd 263
b7742c6b 264 case SCM_M_DEFINE:
f3a9a51d 265 scm_define (CAR (mx), EVAL1 (CDR (mx), env));
b7742c6b 266 return SCM_UNSPECIFIED;
212e58ed 267
d69531e2
AW
268 case SCM_M_DYNWIND:
269 {
270 SCM in, out, res, old_winds;
f3a9a51d
AW
271 in = EVAL1 (CAR (mx), env);
272 out = EVAL1 (CDDR (mx), env);
d69531e2
AW
273 scm_call_0 (in);
274 old_winds = scm_i_dynwinds ();
275 scm_i_set_dynwinds (scm_acons (in, out, old_winds));
276 res = eval (CADR (mx), env);
277 scm_i_set_dynwinds (old_winds);
278 scm_call_0 (out);
279 return res;
280 }
281
bb0229b5
AW
282 case SCM_M_WITH_FLUIDS:
283 {
284 long i, len;
285 SCM *fluidv, *valuesv, walk, wf, res;
286 len = scm_ilength (CAR (mx));
287 fluidv = alloca (sizeof (SCM)*len);
288 for (i = 0, walk = CAR (mx); i < len; i++, walk = CDR (walk))
f3a9a51d 289 fluidv[i] = EVAL1 (CAR (walk), env);
bb0229b5
AW
290 valuesv = alloca (sizeof (SCM)*len);
291 for (i = 0, walk = CADR (mx); i < len; i++, walk = CDR (walk))
f3a9a51d 292 valuesv[i] = EVAL1 (CAR (walk), env);
bb0229b5
AW
293
294 wf = scm_i_make_with_fluids (len, fluidv, valuesv);
295 scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state);
296 scm_i_set_dynwinds (scm_cons (wf, scm_i_dynwinds ()));
297 res = eval (CDDR (mx), env);
298 scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state);
299 scm_i_set_dynwinds (CDR (scm_i_dynwinds ()));
300
301 return res;
302 }
303
b7742c6b
AW
304 case SCM_M_APPLY:
305 /* Evaluate the procedure to be applied. */
f3a9a51d 306 proc = EVAL1 (CAR (mx), env);
b7742c6b 307 /* Evaluate the argument holding the list of arguments */
f3a9a51d 308 args = EVAL1 (CADR (mx), env);
b7742c6b
AW
309
310 apply_proc:
311 /* Go here to tail-apply a procedure. PROC is the procedure and
312 * ARGS is the list of arguments. */
314b8716 313 if (BOOT_CLOSURE_P (proc))
b7742c6b 314 {
7572ee52 315 prepare_boot_closure_env_for_apply (proc, args, &x, &env);
b7742c6b
AW
316 goto loop;
317 }
318 else
ea9f4f4b 319 return scm_call_with_vm (scm_the_vm (), proc, args);
212e58ed 320
b7742c6b
AW
321 case SCM_M_CALL:
322 /* Evaluate the procedure to be applied. */
f3a9a51d 323 proc = EVAL1 (CAR (mx), env);
b7ecadca 324 argc = SCM_I_INUM (CADR (mx));
9331f91c 325 mx = CDDR (mx);
212e58ed 326
314b8716 327 if (BOOT_CLOSURE_P (proc))
5fa0939c 328 {
7572ee52 329 prepare_boot_closure_env_for_eval (proc, argc, mx, &x, &env);
b7742c6b 330 goto loop;
5fa0939c 331 }
b7742c6b
AW
332 else
333 {
e2cf8eb9 334 SCM *argv;
b7ecadca
LC
335 unsigned int i;
336
e2cf8eb9 337 argv = alloca (argc * sizeof (SCM));
b7ecadca 338 for (i = 0; i < argc; i++, mx = CDR (mx))
f3a9a51d 339 argv[i] = EVAL1 (CAR (mx), env);
b7ecadca
LC
340
341 return scm_c_vm_run (scm_the_vm (), proc, argv, argc);
b7742c6b 342 }
b7ecadca 343
b7742c6b 344 case SCM_M_CONT:
f3a9a51d 345 return scm_i_call_with_current_continuation (EVAL1 (mx, env));
212e58ed 346
b7742c6b
AW
347 case SCM_M_CALL_WITH_VALUES:
348 {
349 SCM producer;
350 SCM v;
351
f3a9a51d
AW
352 producer = EVAL1 (CAR (mx), env);
353 /* `proc' is the consumer. */
354 proc = EVAL1 (CDR (mx), env);
ea9f4f4b 355 v = scm_call_with_vm (scm_the_vm (), producer, SCM_EOL);
b7742c6b
AW
356 if (SCM_VALUESP (v))
357 args = scm_struct_ref (v, SCM_INUM0);
358 else
359 args = scm_list_1 (v);
360 goto apply_proc;
361 }
26d5b9b4 362
b7742c6b
AW
363 case SCM_M_LEXICAL_REF:
364 {
365 int n;
366 SCM ret;
367 for (n = SCM_I_INUM (mx); n; n--)
368 env = CDR (env);
369 ret = CAR (env);
370 if (SCM_UNLIKELY (SCM_UNBNDP (ret)))
371 /* we don't know what variable, though, because we don't have its
372 name */
373 error_used_before_defined ();
374 return ret;
375 }
1cc91f1b 376
b7742c6b
AW
377 case SCM_M_LEXICAL_SET:
378 {
379 int n;
f3a9a51d 380 SCM val = EVAL1 (CDR (mx), env);
b7742c6b
AW
381 for (n = SCM_I_INUM (CAR (mx)); n; n--)
382 env = CDR (env);
383 SCM_SETCAR (env, val);
384 return SCM_UNSPECIFIED;
385 }
910b5125 386
b7742c6b
AW
387 case SCM_M_TOPLEVEL_REF:
388 if (SCM_VARIABLEP (mx))
389 return SCM_VARIABLE_REF (mx);
390 else
57d23e25 391 {
b7742c6b 392 while (scm_is_pair (env))
f3a8d1b7 393 env = CDR (env);
3149a5b6
AW
394 return SCM_VARIABLE_REF
395 (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)));
57d23e25 396 }
57d23e25 397
b7742c6b
AW
398 case SCM_M_TOPLEVEL_SET:
399 {
400 SCM var = CAR (mx);
f3a9a51d 401 SCM val = EVAL1 (CDR (mx), env);
b7742c6b
AW
402 if (SCM_VARIABLEP (var))
403 {
404 SCM_VARIABLE_SET (var, val);
405 return SCM_UNSPECIFIED;
406 }
407 else
408 {
409 while (scm_is_pair (env))
f3a8d1b7 410 env = CDR (env);
3149a5b6
AW
411 SCM_VARIABLE_SET
412 (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)),
413 val);
b7742c6b
AW
414 return SCM_UNSPECIFIED;
415 }
416 }
910b5125 417
b7742c6b
AW
418 case SCM_M_MODULE_REF:
419 if (SCM_VARIABLEP (mx))
420 return SCM_VARIABLE_REF (mx);
910b5125 421 else
3149a5b6
AW
422 return SCM_VARIABLE_REF
423 (scm_memoize_variable_access_x (x, SCM_BOOL_F));
910b5125 424
b7742c6b
AW
425 case SCM_M_MODULE_SET:
426 if (SCM_VARIABLEP (CDR (mx)))
910b5125 427 {
f3a9a51d 428 SCM_VARIABLE_SET (CDR (mx), EVAL1 (CAR (mx), env));
b7742c6b
AW
429 return SCM_UNSPECIFIED;
430 }
431 else
432 {
3149a5b6
AW
433 SCM_VARIABLE_SET
434 (scm_memoize_variable_access_x (x, SCM_BOOL_F),
f3a9a51d 435 EVAL1 (CAR (mx), env));
b7742c6b 436 return SCM_UNSPECIFIED;
910b5125 437 }
910b5125 438
747022e4
AW
439 case SCM_M_PROMPT:
440 {
7112a34d
AW
441 SCM vm, res;
442 /* We need the prompt and handler values after a longjmp case,
443 so make sure they are volatile. */
444 volatile SCM handler, prompt;
747022e4 445
d2964315 446 vm = scm_the_vm ();
f3a9a51d
AW
447 prompt = scm_c_make_prompt (EVAL1 (CAR (mx), env),
448 SCM_VM_DATA (vm)->fp,
d2964315 449 SCM_VM_DATA (vm)->sp, SCM_VM_DATA (vm)->ip,
adbdfd6d 450 0, -1, scm_i_dynwinds ());
f3a9a51d 451 handler = EVAL1 (CDDR (mx), env);
747022e4
AW
452 scm_i_set_dynwinds (scm_cons (prompt, scm_i_dynwinds ()));
453
454 if (SCM_PROMPT_SETJMP (prompt))
455 {
b8af64db 456 /* The prompt exited nonlocally. */
747022e4 457 proc = handler;
572eef50 458 args = scm_i_prompt_pop_abort_args_x (scm_the_vm ());
747022e4
AW
459 goto apply_proc;
460 }
461
462 res = eval (CADR (mx), env);
463 scm_i_set_dynwinds (CDR (scm_i_dynwinds ()));
464 return res;
465 }
466
b7742c6b
AW
467 default:
468 abort ();
469 }
910b5125
DH
470}
471
b7742c6b 472\f
2a6f7afe 473
b7742c6b
AW
474/* Simple procedure calls
475 */
2a6f7afe 476
b7742c6b
AW
477SCM
478scm_call_0 (SCM proc)
479{
bf5a05f2 480 return scm_c_vm_run (scm_the_vm (), proc, NULL, 0);
0f2d19dd
JB
481}
482
b7742c6b
AW
483SCM
484scm_call_1 (SCM proc, SCM arg1)
212e58ed 485{
bf5a05f2 486 return scm_c_vm_run (scm_the_vm (), proc, &arg1, 1);
b7742c6b 487}
212e58ed 488
b7742c6b
AW
489SCM
490scm_call_2 (SCM proc, SCM arg1, SCM arg2)
491{
bf5a05f2
AW
492 SCM args[] = { arg1, arg2 };
493 return scm_c_vm_run (scm_the_vm (), proc, args, 2);
212e58ed
DH
494}
495
b7742c6b
AW
496SCM
497scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
0f2d19dd 498{
bf5a05f2
AW
499 SCM args[] = { arg1, arg2, arg3 };
500 return scm_c_vm_run (scm_the_vm (), proc, args, 3);
0f2d19dd
JB
501}
502
b7742c6b
AW
503SCM
504scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
212e58ed 505{
bf5a05f2
AW
506 SCM args[] = { arg1, arg2, arg3, arg4 };
507 return scm_c_vm_run (scm_the_vm (), proc, args, 4);
212e58ed
DH
508}
509
f32e67be
AW
510SCM
511scm_call_5 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5)
512{
513 SCM args[] = { arg1, arg2, arg3, arg4, arg5 };
514 return scm_c_vm_run (scm_the_vm (), proc, args, 5);
515}
516
517SCM
518scm_call_6 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
519 SCM arg6)
520{
521 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6 };
522 return scm_c_vm_run (scm_the_vm (), proc, args, 6);
523}
524
741b8a23
MW
525SCM
526scm_call_7 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
527 SCM arg6, SCM arg7)
528{
529 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
530 return scm_c_vm_run (scm_the_vm (), proc, args, 7);
531}
532
533SCM
534scm_call_8 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
535 SCM arg6, SCM arg7, SCM arg8)
536{
537 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 };
538 return scm_c_vm_run (scm_the_vm (), proc, args, 8);
539}
540
541SCM
542scm_call_9 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
543 SCM arg6, SCM arg7, SCM arg8, SCM arg9)
544{
545 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 };
546 return scm_c_vm_run (scm_the_vm (), proc, args, 9);
547}
548
86fd6dff
AW
549SCM
550scm_call_n (SCM proc, SCM *argv, size_t nargs)
551{
552 return scm_c_vm_run (scm_the_vm (), proc, argv, nargs);
553}
554
741b8a23 555SCM
07c2ca0f 556scm_call (SCM proc, ...)
741b8a23
MW
557{
558 va_list argp;
559 SCM *argv = NULL;
560 size_t i, nargs = 0;
561
562 va_start (argp, proc);
563 while (!SCM_UNBNDP (va_arg (argp, SCM)))
564 nargs++;
565 va_end (argp);
566
567 argv = alloca (nargs * sizeof (SCM));
568 va_start (argp, proc);
569 for (i = 0; i < nargs; i++)
570 argv[i] = va_arg (argp, SCM);
571 va_end (argp);
572
573 return scm_c_vm_run (scm_the_vm (), proc, argv, nargs);
574}
575
b7742c6b 576/* Simple procedure applies
9fbee57e 577 */
cc56ba80 578
b7742c6b
AW
579SCM
580scm_apply_0 (SCM proc, SCM args)
581{
582 return scm_apply (proc, args, SCM_EOL);
0f572ba7
DH
583}
584
b7742c6b
AW
585SCM
586scm_apply_1 (SCM proc, SCM arg1, SCM args)
0f572ba7 587{
b7742c6b 588 return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
8ae95199
DH
589}
590
b7742c6b
AW
591SCM
592scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
0f2d19dd 593{
b7742c6b 594 return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
0f2d19dd
JB
595}
596
b7742c6b
AW
597SCM
598scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
212e58ed 599{
b7742c6b
AW
600 return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
601 SCM_EOL);
212e58ed
DH
602}
603
b7742c6b 604/* This code processes the arguments to apply:
8ea46249 605
b7742c6b 606 (apply PROC ARG1 ... ARGS)
302c12b4 607
b7742c6b
AW
608 Given a list (ARG1 ... ARGS), this function conses the ARG1
609 ... arguments onto the front of ARGS, and returns the resulting
610 list. Note that ARGS is a list; thus, the argument to this
611 function is a list whose last element is a list.
302c12b4 612
b7742c6b
AW
613 Apply calls this function, and applies PROC to the elements of the
614 result. apply:nconc2last takes care of building the list of
615 arguments, given (ARG1 ... ARGS).
a954ce1d 616
b7742c6b
AW
617 Rather than do new consing, apply:nconc2last destroys its argument.
618 On that topic, this code came into my care with the following
619 beautifully cryptic comment on that topic: "This will only screw
620 you if you do (scm_apply scm_apply '( ... ))" If you know what
621 they're referring to, send me a patch to this comment. */
0f2d19dd 622
b7742c6b
AW
623SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
624 (SCM lst),
625 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
626 "conses the @var{arg1} @dots{} arguments onto the front of\n"
627 "@var{args}, and returns the resulting list. Note that\n"
628 "@var{args} is a list; thus, the argument to this function is\n"
629 "a list whose last element is a list.\n"
630 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
631 "destroys its argument, so use with care.")
632#define FUNC_NAME s_scm_nconc2last
212e58ed 633{
b7742c6b
AW
634 SCM *lloc;
635 SCM_VALIDATE_NONEMPTYLIST (1, lst);
636 lloc = &lst;
b6b84131 637 while (!scm_is_null (SCM_CDR (*lloc)))
b7742c6b
AW
638 lloc = SCM_CDRLOC (*lloc);
639 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
640 *lloc = SCM_CAR (*lloc);
641 return lst;
212e58ed 642}
b7742c6b 643#undef FUNC_NAME
212e58ed 644
b8229a3b 645
b7742c6b
AW
646SCM
647scm_map (SCM proc, SCM arg1, SCM args)
0f2d19dd 648{
a2230b65 649 static SCM var = SCM_BOOL_F;
0f2d19dd 650
a2230b65
AW
651 if (scm_is_false (var))
652 var = scm_private_variable (scm_the_root_module (),
653 scm_from_latin1_symbol ("map"));
302c12b4 654
a2230b65
AW
655 return scm_apply (scm_variable_ref (var),
656 scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
657}
d6754c23 658
b7742c6b
AW
659SCM
660scm_for_each (SCM proc, SCM arg1, SCM args)
0f2d19dd 661{
a2230b65
AW
662 static SCM var = SCM_BOOL_F;
663
664 if (scm_is_false (var))
665 var = scm_private_variable (scm_the_root_module (),
666 scm_from_latin1_symbol ("for-each"));
667
668 return scm_apply (scm_variable_ref (var),
669 scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
b7742c6b 670}
71560395 671
71560395 672
5f161164
AW
673static SCM
674scm_c_primitive_eval (SCM exp)
b7742c6b 675{
a310a1d1 676 if (!SCM_EXPANDED_P (exp))
4f692ace 677 exp = scm_call_1 (scm_current_module_transformer (), exp);
a310a1d1 678 return eval (scm_memoize_expression (exp), SCM_EOL);
b7742c6b 679}
5f161164
AW
680
681static SCM var_primitive_eval;
682SCM
683scm_primitive_eval (SCM exp)
684{
685 return scm_c_vm_run (scm_the_vm (), scm_variable_ref (var_primitive_eval),
686 &exp, 1);
687}
71560395 688
b7742c6b
AW
689
690/* Eval does not take the second arg optionally. This is intentional
691 * in order to be R5RS compatible, and to prepare for the new module
692 * system, where we would like to make the choice of evaluation
693 * environment explicit. */
694
695SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
696 (SCM exp, SCM module_or_state),
697 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
698 "in the top-level environment specified by\n"
699 "@var{module_or_state}.\n"
700 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
701 "@var{module_or_state} is made the current module when\n"
702 "it is a module, or the current dynamic state when it is\n"
703 "a dynamic state."
704 "Example: (eval '(+ 1 2) (interaction-environment))")
705#define FUNC_NAME s_scm_eval
706{
707 SCM res;
708
709 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
710 if (scm_is_dynamic_state (module_or_state))
711 scm_dynwind_current_dynamic_state (module_or_state);
712 else if (scm_module_system_booted_p)
713 {
714 SCM_VALIDATE_MODULE (2, module_or_state);
715 scm_dynwind_current_module (module_or_state);
71560395 716 }
b7742c6b 717 /* otherwise if the module system isn't booted, ignore the module arg */
71560395 718
b7742c6b
AW
719 res = scm_primitive_eval (exp);
720
721 scm_dynwind_end ();
722 return res;
723}
724#undef FUNC_NAME
71560395
AW
725
726
b7742c6b 727static SCM f_apply;
71560395
AW
728
729/* Apply a function to a list of arguments.
730
731 This function is exported to the Scheme level as taking two
732 required arguments and a tail argument, as if it were:
733 (lambda (proc arg1 . args) ...)
734 Thus, if you just have a list of arguments to pass to a procedure,
735 pass the list as ARG1, and '() for ARGS. If you have some fixed
736 args, pass the first as ARG1, then cons any remaining fixed args
737 onto the front of your argument list, and pass that as ARGS. */
738
739SCM
740scm_apply (SCM proc, SCM arg1, SCM args)
741{
b7742c6b 742 /* Fix things up so that args contains all args. */
71560395 743 if (scm_is_null (args))
b7742c6b 744 args = arg1;
71560395 745 else
b7742c6b 746 args = scm_cons_star (arg1, args);
71560395 747
ea9f4f4b 748 return scm_call_with_vm (scm_the_vm (), proc, args);
b7742c6b 749}
434f2f7a 750
7572ee52
AW
751static void
752prepare_boot_closure_env_for_apply (SCM proc, SCM args,
753 SCM *out_body, SCM *out_env)
314b8716 754{
8f9c5b58
AW
755 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
756 SCM env = BOOT_CLOSURE_ENV (proc);
dc3e203e 757
8f9c5b58
AW
758 if (BOOT_CLOSURE_IS_FIXED (proc)
759 || (BOOT_CLOSURE_IS_REST (proc)
760 && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
761 {
762 if (SCM_UNLIKELY (scm_ilength (args) != nreq))
763 scm_wrong_num_args (proc);
764 for (; scm_is_pair (args); args = CDR (args))
765 env = scm_cons (CAR (args), env);
7572ee52
AW
766 *out_body = BOOT_CLOSURE_BODY (proc);
767 *out_env = env;
8f9c5b58
AW
768 }
769 else if (BOOT_CLOSURE_IS_REST (proc))
314b8716
AW
770 {
771 if (SCM_UNLIKELY (scm_ilength (args) < nreq))
8f9c5b58 772 scm_wrong_num_args (proc);
314b8716 773 for (; nreq; nreq--, args = CDR (args))
8f9c5b58
AW
774 env = scm_cons (CAR (args), env);
775 env = scm_cons (args, env);
7572ee52
AW
776 *out_body = BOOT_CLOSURE_BODY (proc);
777 *out_env = env;
314b8716
AW
778 }
779 else
d8a071fc
AW
780 {
781 int i, argc, nreq, nopt;
782 SCM body, rest, kw, inits, alt;
dc3e203e 783 SCM mx = BOOT_CLOSURE_CODE (proc);
d8a071fc 784
7572ee52 785 loop:
dc3e203e 786 BOOT_CLOSURE_PARSE_FULL (mx, body, nargs, rest, nopt, kw, inits, alt);
d8a071fc
AW
787
788 argc = scm_ilength (args);
789 if (argc < nreq)
790 {
791 if (scm_is_true (alt))
7572ee52 792 {
dc3e203e 793 mx = alt;
7572ee52
AW
794 goto loop;
795 }
d8a071fc
AW
796 else
797 scm_wrong_num_args (proc);
798 }
799 if (scm_is_false (kw) && argc > nreq + nopt && scm_is_false (rest))
800 {
801 if (scm_is_true (alt))
7572ee52 802 {
dc3e203e 803 mx = alt;
7572ee52
AW
804 goto loop;
805 }
d8a071fc
AW
806 else
807 scm_wrong_num_args (proc);
808 }
809
810 for (i = 0; i < nreq; i++, args = CDR (args))
811 env = scm_cons (CAR (args), env);
812
813 if (scm_is_false (kw))
814 {
815 /* Optional args (possibly), but no keyword args. */
816 for (; i < argc && i < nreq + nopt;
817 i++, args = CDR (args))
818 {
819 env = scm_cons (CAR (args), env);
820 inits = CDR (inits);
821 }
822
823 for (; i < nreq + nopt; i++, inits = CDR (inits))
f3a9a51d 824 env = scm_cons (EVAL1 (CAR (inits), env), env);
d8a071fc
AW
825
826 if (scm_is_true (rest))
827 env = scm_cons (args, env);
828 }
829 else
830 {
831 SCM aok;
832
833 aok = CAR (kw);
834 kw = CDR (kw);
835
836 /* Keyword args. As before, but stop at the first keyword. */
837 for (; i < argc && i < nreq + nopt && !scm_is_keyword (CAR (args));
838 i++, args = CDR (args), inits = CDR (inits))
839 env = scm_cons (CAR (args), env);
840
841 for (; i < nreq + nopt; i++, inits = CDR (inits))
f3a9a51d 842 env = scm_cons (EVAL1 (CAR (inits), env), env);
d8a071fc
AW
843
844 if (scm_is_true (rest))
845 {
846 env = scm_cons (args, env);
847 i++;
848 }
581f410f
AW
849 else if (scm_is_true (alt)
850 && scm_is_pair (args) && !scm_is_keyword (CAR (args)))
851 {
852 /* Too many positional args, no rest arg, and we have an
853 alternate clause. */
854 mx = alt;
855 goto loop;
856 }
d8a071fc
AW
857
858 /* Now fill in env with unbound values, limn the rest of the args for
859 keywords, and fill in unbound values with their inits. */
860 {
861 int imax = i - 1;
862 int kw_start_idx = i;
863 SCM walk, k, v;
864 for (walk = kw; scm_is_pair (walk); walk = CDR (walk))
865 if (SCM_I_INUM (CDAR (walk)) > imax)
866 imax = SCM_I_INUM (CDAR (walk));
867 for (; i <= imax; i++)
868 env = scm_cons (SCM_UNDEFINED, env);
869
870 if (scm_is_pair (args) && scm_is_pair (CDR (args)))
871 for (; scm_is_pair (args) && scm_is_pair (CDR (args));
872 args = CDR (args))
873 {
874 k = CAR (args); v = CADR (args);
875 if (!scm_is_keyword (k))
876 {
877 if (scm_is_true (rest))
878 continue;
879 else
880 break;
881 }
882 for (walk = kw; scm_is_pair (walk); walk = CDR (walk))
883 if (scm_is_eq (k, CAAR (walk)))
884 {
885 /* Well... ok, list-set! isn't the nicest interface, but
886 hey. */
887 int iset = imax - SCM_I_INUM (CDAR (walk));
888 scm_list_set_x (env, SCM_I_MAKINUM (iset), v);
889 args = CDR (args);
890 break;
891 }
892 if (scm_is_null (walk) && scm_is_false (aok))
4af0d97e 893 error_unrecognized_keyword (proc, k);
d8a071fc
AW
894 }
895 if (scm_is_pair (args) && scm_is_false (rest))
4af0d97e 896 error_invalid_keyword (proc, CAR (args));
d8a071fc
AW
897
898 /* Now fill in unbound values, evaluating init expressions in their
899 appropriate environment. */
900 for (i = imax - kw_start_idx; scm_is_pair (inits); i--, inits = CDR (inits))
901 {
902 SCM tail = scm_list_tail (env, SCM_I_MAKINUM (i));
903 if (SCM_UNBNDP (CAR (tail)))
f3a9a51d 904 SCM_SETCAR (tail, EVAL1 (CAR (inits), CDR (tail)));
d8a071fc
AW
905 }
906 }
907 }
8f9c5b58 908
dc3e203e 909 *out_body = body;
7572ee52
AW
910 *out_env = env;
911 }
8f9c5b58
AW
912}
913
7572ee52 914static void
8f9c5b58 915prepare_boot_closure_env_for_eval (SCM proc, unsigned int argc,
7572ee52 916 SCM exps, SCM *out_body, SCM *inout_env)
8f9c5b58
AW
917{
918 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
919 SCM new_env = BOOT_CLOSURE_ENV (proc);
920 if (BOOT_CLOSURE_IS_FIXED (proc)
921 || (BOOT_CLOSURE_IS_REST (proc)
922 && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
314b8716 923 {
8f9c5b58 924 for (; scm_is_pair (exps); exps = CDR (exps), nreq--)
f3a9a51d
AW
925 new_env = scm_cons (EVAL1 (CAR (exps), *inout_env),
926 new_env);
8f9c5b58
AW
927 if (SCM_UNLIKELY (nreq != 0))
928 scm_wrong_num_args (proc);
7572ee52
AW
929 *out_body = BOOT_CLOSURE_BODY (proc);
930 *inout_env = new_env;
314b8716 931 }
8f9c5b58
AW
932 else if (BOOT_CLOSURE_IS_REST (proc))
933 {
934 if (SCM_UNLIKELY (argc < nreq))
935 scm_wrong_num_args (proc);
936 for (; nreq; nreq--, exps = CDR (exps))
f3a9a51d
AW
937 new_env = scm_cons (EVAL1 (CAR (exps), *inout_env),
938 new_env);
8f9c5b58
AW
939 {
940 SCM rest = SCM_EOL;
941 for (; scm_is_pair (exps); exps = CDR (exps))
f3a9a51d 942 rest = scm_cons (EVAL1 (CAR (exps), *inout_env), rest);
8f9c5b58
AW
943 new_env = scm_cons (scm_reverse (rest),
944 new_env);
945 }
7572ee52
AW
946 *out_body = BOOT_CLOSURE_BODY (proc);
947 *inout_env = new_env;
8f9c5b58
AW
948 }
949 else
d8a071fc
AW
950 {
951 SCM args = SCM_EOL;
952 for (; scm_is_pair (exps); exps = CDR (exps))
f3a9a51d 953 args = scm_cons (EVAL1 (CAR (exps), *inout_env), args);
7572ee52
AW
954 args = scm_reverse_x (args, SCM_UNDEFINED);
955 prepare_boot_closure_env_for_apply (proc, args, out_body, inout_env);
d8a071fc 956 }
8f9c5b58
AW
957}
958
959static SCM
960boot_closure_apply (SCM closure, SCM args)
961{
7572ee52
AW
962 SCM body, env;
963 prepare_boot_closure_env_for_apply (closure, args, &body, &env);
964 return eval (body, env);
314b8716
AW
965}
966
967static int
968boot_closure_print (SCM closure, SCM port, scm_print_state *pstate)
969{
970 SCM args;
971 scm_puts ("#<boot-closure ", port);
3d27ef4b 972 scm_uintprint ((scm_t_bits)SCM2PTR (closure), 16, port);
314b8716
AW
973 scm_putc (' ', port);
974 args = scm_make_list (scm_from_int (BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure)),
4a655e50 975 scm_from_latin1_symbol ("_"));
8f9c5b58 976 if (!BOOT_CLOSURE_IS_FIXED (closure) && BOOT_CLOSURE_HAS_REST_ARGS (closure))
4a655e50 977 args = scm_cons_star (scm_from_latin1_symbol ("_"), args);
7572ee52 978 /* FIXME: optionals and rests */
314b8716
AW
979 scm_display (args, port);
980 scm_putc ('>', port);
981 return 1;
982}
983
0f2d19dd
JB
984void
985scm_init_eval ()
0f2d19dd 986{
5f161164
AW
987 SCM primitive_eval;
988
df9ca8d8 989 f_apply = scm_c_define_gsubr ("apply", 2, 0, 1, scm_apply);
86d31dfe 990
314b8716
AW
991 scm_tc16_boot_closure = scm_make_smob_type ("boot-closure", 0);
992 scm_set_smob_apply (scm_tc16_boot_closure, boot_closure_apply, 0, 0, 1);
993 scm_set_smob_print (scm_tc16_boot_closure, boot_closure_print);
994
5f161164
AW
995 primitive_eval = scm_c_make_gsubr ("primitive-eval", 1, 0, 0,
996 scm_c_primitive_eval);
997 var_primitive_eval = scm_define (SCM_SUBR_NAME (primitive_eval),
998 primitive_eval);
999
a0599745 1000#include "libguile/eval.x"
0f2d19dd 1001}
0f2d19dd 1002
89e00824
ML
1003/*
1004 Local Variables:
1005 c-file-style: "gnu"
1006 End:
1007*/
62560650 1008