Add br-if-logtest opcode
[bpt/guile.git] / libguile / eval.c
CommitLineData
747bd534 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,
dc7a33fa 2 * 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014
434f2f7a 3 * Free Software Foundation, Inc.
0f2d19dd 4 *
73be1d9e 5 * This library is free software; you can redistribute it and/or
53befeb7
NJ
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 3 of
8 * the License, or (at your option) any later version.
0f2d19dd 9 *
53befeb7
NJ
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
0f2d19dd 14 *
73be1d9e
MV
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
53befeb7
NJ
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA
73be1d9e 19 */
1bbd0b84 20
0f2d19dd
JB
21\f
22
dbb605f5 23#ifdef HAVE_CONFIG_H
3d05f2e0
RB
24# include <config.h>
25#endif
0f2d19dd 26
f7439099 27#include <alloca.h>
741b8a23 28#include <stdarg.h>
3d05f2e0 29
f7439099 30#include "libguile/__scm.h"
48b96f4b 31
a0599745 32#include "libguile/_scm.h"
21628685
DH
33#include "libguile/alist.h"
34#include "libguile/async.h"
35#include "libguile/continuations.h"
747022e4 36#include "libguile/control.h"
a0599745 37#include "libguile/debug.h"
328dc9a3 38#include "libguile/deprecation.h"
09074dbf 39#include "libguile/dynwind.h"
a0599745 40#include "libguile/eq.h"
a310a1d1 41#include "libguile/expand.h"
21628685 42#include "libguile/feature.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 155
cfc28c80
AW
156#define VECTOR_REF(v, i) (SCM_SIMPLE_VECTOR_REF (v, i))
157#define VECTOR_SET(v, i, x) (SCM_SIMPLE_VECTOR_SET (v, i, x))
158#define VECTOR_LENGTH(v) (SCM_SIMPLE_VECTOR_LENGTH (v))
159
160static SCM
161make_env (int n, SCM init, SCM next)
162{
163 SCM env = scm_c_make_vector (n + 1, init);
164 VECTOR_SET (env, 0, next);
165 return env;
166}
167
168static SCM
169next_rib (SCM env)
170{
171 return VECTOR_REF (env, 0);
172}
173
174static SCM
175env_tail (SCM env)
176{
177 while (SCM_I_IS_VECTOR (env))
178 env = next_rib (env);
179 return env;
180}
181
182static SCM
183env_ref (SCM env, int depth, int width)
184{
185 while (depth--)
186 env = next_rib (env);
187 return VECTOR_REF (env, width + 1);
188}
189
190static void
191env_set (SCM env, int depth, int width, SCM val)
192{
193 while (depth--)
194 env = next_rib (env);
195 VECTOR_SET (env, width + 1, val);
196}
197
e6729603 198
b7742c6b 199SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
e6729603 200
b7742c6b 201static void error_used_before_defined (void)
d0624e39 202{
b7742c6b
AW
203 scm_error (scm_unbound_variable_key, NULL,
204 "Variable used before given a value", SCM_EOL, SCM_BOOL_F);
d0624e39 205}
d0624e39 206
4af0d97e 207static void error_invalid_keyword (SCM proc, SCM obj)
d8a071fc 208{
4a655e50 209 scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
d8a071fc 210 scm_from_locale_string ("Invalid keyword"), SCM_EOL,
4af0d97e 211 scm_list_1 (obj));
d8a071fc
AW
212}
213
4af0d97e 214static void error_unrecognized_keyword (SCM proc, SCM kw)
d8a071fc 215{
4a655e50 216 scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
d8a071fc 217 scm_from_locale_string ("Unrecognized keyword"), SCM_EOL,
4af0d97e 218 scm_list_1 (kw));
d8a071fc
AW
219}
220
221
f3a9a51d
AW
222/* Multiple values truncation. */
223static SCM
224truncate_values (SCM x)
225{
226 if (SCM_LIKELY (!SCM_VALUESP (x)))
227 return x;
228 else
229 {
230 SCM l = scm_struct_ref (x, SCM_INUM0);
231 if (SCM_LIKELY (scm_is_pair (l)))
232 return scm_car (l);
233 else
234 {
235 scm_ithrow (scm_from_latin1_symbol ("vm-run"),
236 scm_list_3 (scm_from_latin1_symbol ("vm-run"),
237 scm_from_locale_string
238 ("Too few values returned to continuation"),
239 SCM_EOL),
240 1);
241 /* Not reached. */
242 return SCM_BOOL_F;
243 }
244 }
245}
246#define EVAL1(x, env) (truncate_values (eval ((x), (env))))
247
6f81708a 248static SCM
b7742c6b 249eval (SCM x, SCM env)
6f81708a 250{
b7742c6b
AW
251 SCM mx;
252 SCM proc = SCM_UNDEFINED, args = SCM_EOL;
b7ecadca 253 unsigned int argc;
6f81708a 254
b7742c6b
AW
255 loop:
256 SCM_TICK;
b7742c6b
AW
257
258 mx = SCM_MEMOIZED_ARGS (x);
0720f70e 259 switch (SCM_I_INUM (SCM_CAR (x)))
b7742c6b 260 {
6fc3eae4
AW
261 case SCM_M_SEQ:
262 eval (CAR (mx), env);
263 x = CDR (mx);
b7742c6b
AW
264 goto loop;
265
266 case SCM_M_IF:
f3a9a51d 267 if (scm_is_true (EVAL1 (CAR (mx), env)))
b7742c6b 268 x = CADR (mx);
6f81708a 269 else
b7742c6b
AW
270 x = CDDR (mx);
271 goto loop;
5fb64383 272
b7742c6b
AW
273 case SCM_M_LET:
274 {
275 SCM inits = CAR (mx);
cfc28c80
AW
276 SCM new_env;
277 int i;
278
ef47c422 279 new_env = make_env (VECTOR_LENGTH (inits), SCM_UNDEFINED, env);
cfc28c80
AW
280 for (i = 0; i < VECTOR_LENGTH (inits); i++)
281 env_set (new_env, 0, i, EVAL1 (VECTOR_REF (inits, i), env));
b7742c6b
AW
282 env = new_env;
283 x = CDR (mx);
284 goto loop;
285 }
286
287 case SCM_M_LAMBDA:
ef47c422 288 RETURN_BOOT_CLOSURE (mx, env);
5fb64383 289
b7742c6b
AW
290 case SCM_M_QUOTE:
291 return mx;
0f2d19dd 292
b7742c6b 293 case SCM_M_DEFINE:
f3a9a51d 294 scm_define (CAR (mx), EVAL1 (CDR (mx), env));
b7742c6b 295 return SCM_UNSPECIFIED;
212e58ed 296
ef47c422
AW
297 case SCM_M_CAPTURE_MODULE:
298 return eval (mx, scm_current_module ());
299
b7742c6b
AW
300 case SCM_M_APPLY:
301 /* Evaluate the procedure to be applied. */
f3a9a51d 302 proc = EVAL1 (CAR (mx), env);
b7742c6b 303 /* Evaluate the argument holding the list of arguments */
f3a9a51d 304 args = EVAL1 (CADR (mx), env);
b7742c6b
AW
305
306 apply_proc:
307 /* Go here to tail-apply a procedure. PROC is the procedure and
308 * ARGS is the list of arguments. */
314b8716 309 if (BOOT_CLOSURE_P (proc))
b7742c6b 310 {
7572ee52 311 prepare_boot_closure_env_for_apply (proc, args, &x, &env);
b7742c6b
AW
312 goto loop;
313 }
314 else
6b4ba76d 315 return scm_apply_0 (proc, args);
212e58ed 316
b7742c6b
AW
317 case SCM_M_CALL:
318 /* Evaluate the procedure to be applied. */
f3a9a51d 319 proc = EVAL1 (CAR (mx), env);
b7ecadca 320 argc = SCM_I_INUM (CADR (mx));
9331f91c 321 mx = CDDR (mx);
212e58ed 322
314b8716 323 if (BOOT_CLOSURE_P (proc))
5fa0939c 324 {
7572ee52 325 prepare_boot_closure_env_for_eval (proc, argc, mx, &x, &env);
b7742c6b 326 goto loop;
5fa0939c 327 }
b7742c6b
AW
328 else
329 {
e2cf8eb9 330 SCM *argv;
b7ecadca
LC
331 unsigned int i;
332
e2cf8eb9 333 argv = alloca (argc * sizeof (SCM));
b7ecadca 334 for (i = 0; i < argc; i++, mx = CDR (mx))
f3a9a51d 335 argv[i] = EVAL1 (CAR (mx), env);
b7ecadca 336
55ee3607 337 return scm_call_n (proc, argv, argc);
b7742c6b 338 }
b7ecadca 339
b7742c6b 340 case SCM_M_CONT:
f3a9a51d 341 return scm_i_call_with_current_continuation (EVAL1 (mx, env));
212e58ed 342
b7742c6b
AW
343 case SCM_M_CALL_WITH_VALUES:
344 {
345 SCM producer;
346 SCM v;
347
f3a9a51d
AW
348 producer = EVAL1 (CAR (mx), env);
349 /* `proc' is the consumer. */
350 proc = EVAL1 (CDR (mx), env);
6b4ba76d 351 v = scm_call_0 (producer);
b7742c6b
AW
352 if (SCM_VALUESP (v))
353 args = scm_struct_ref (v, SCM_INUM0);
354 else
355 args = scm_list_1 (v);
356 goto apply_proc;
357 }
26d5b9b4 358
b7742c6b
AW
359 case SCM_M_LEXICAL_REF:
360 {
cfc28c80
AW
361 SCM pos, ret;
362 int depth, width;
363
364 pos = mx;
365 depth = SCM_I_INUM (CAR (pos));
366 width = SCM_I_INUM (CDR (pos));
367
368 ret = env_ref (env, depth, width);
369
b7742c6b
AW
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 {
cfc28c80
AW
379 SCM pos;
380 int depth, width;
f3a9a51d 381 SCM val = EVAL1 (CDR (mx), env);
cfc28c80
AW
382
383 pos = CAR (mx);
384 depth = SCM_I_INUM (CAR (pos));
385 width = SCM_I_INUM (CDR (pos));
386
387 env_set (env, depth, width, val);
388
b7742c6b
AW
389 return SCM_UNSPECIFIED;
390 }
910b5125 391
b7742c6b
AW
392 case SCM_M_TOPLEVEL_REF:
393 if (SCM_VARIABLEP (mx))
394 return SCM_VARIABLE_REF (mx);
395 else
57d23e25 396 {
cfc28c80 397 env = env_tail (env);
ef47c422 398 return SCM_VARIABLE_REF (scm_memoize_variable_access_x (x, env));
57d23e25 399 }
57d23e25 400
b7742c6b
AW
401 case SCM_M_TOPLEVEL_SET:
402 {
403 SCM var = CAR (mx);
f3a9a51d 404 SCM val = EVAL1 (CDR (mx), env);
b7742c6b
AW
405 if (SCM_VARIABLEP (var))
406 {
407 SCM_VARIABLE_SET (var, val);
408 return SCM_UNSPECIFIED;
409 }
410 else
411 {
cfc28c80 412 env = env_tail (env);
ef47c422 413 SCM_VARIABLE_SET (scm_memoize_variable_access_x (x, env), 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
1773bc7d 439 case SCM_M_CALL_WITH_PROMPT:
747022e4 440 {
4fcbc1b0
AW
441 struct scm_vm *vp;
442 SCM k, res;
9d381ba4 443 scm_i_jmp_buf registers;
9ede013f
AW
444 /* We need the handler after nonlocal return to the setjmp, so
445 make sure it is volatile. */
446 volatile SCM handler;
447
448 k = EVAL1 (CAR (mx), env);
f3a9a51d 449 handler = EVAL1 (CDDR (mx), env);
e7f9abab 450 vp = scm_the_vm ();
9ede013f
AW
451
452 /* Push the prompt onto the dynamic stack. */
4fcbc1b0
AW
453 scm_dynstack_push_prompt (&SCM_I_CURRENT_THREAD->dynstack,
454 SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY
455 | SCM_F_DYNSTACK_PROMPT_PUSH_NARGS,
456 k,
457 vp->fp - vp->stack_base,
458 vp->sp - vp->stack_base,
459 vp->ip,
460 &registers);
9d381ba4
AW
461
462 if (SCM_I_SETJMP (registers))
747022e4 463 {
b8af64db 464 /* The prompt exited nonlocally. */
c2247b78 465 scm_gc_after_nonlocal_exit ();
747022e4 466 proc = handler;
e7f9abab 467 vp = scm_the_vm ();
4fcbc1b0 468 args = scm_i_prompt_pop_abort_args_x (vp);
747022e4
AW
469 goto apply_proc;
470 }
471
1773bc7d 472 res = scm_call_0 (eval (CADR (mx), env));
9ede013f 473 scm_dynstack_pop (&SCM_I_CURRENT_THREAD->dynstack);
747022e4
AW
474 return res;
475 }
476
b7742c6b
AW
477 default:
478 abort ();
479 }
910b5125
DH
480}
481
b7742c6b 482\f
2a6f7afe 483
b7742c6b
AW
484/* Simple procedure calls
485 */
2a6f7afe 486
b7742c6b
AW
487SCM
488scm_call_0 (SCM proc)
489{
55ee3607 490 return scm_call_n (proc, NULL, 0);
0f2d19dd
JB
491}
492
b7742c6b
AW
493SCM
494scm_call_1 (SCM proc, SCM arg1)
212e58ed 495{
55ee3607 496 return scm_call_n (proc, &arg1, 1);
b7742c6b 497}
212e58ed 498
b7742c6b
AW
499SCM
500scm_call_2 (SCM proc, SCM arg1, SCM arg2)
501{
bf5a05f2 502 SCM args[] = { arg1, arg2 };
55ee3607 503 return scm_call_n (proc, args, 2);
212e58ed
DH
504}
505
b7742c6b
AW
506SCM
507scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
0f2d19dd 508{
bf5a05f2 509 SCM args[] = { arg1, arg2, arg3 };
55ee3607 510 return scm_call_n (proc, args, 3);
0f2d19dd
JB
511}
512
b7742c6b
AW
513SCM
514scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
212e58ed 515{
bf5a05f2 516 SCM args[] = { arg1, arg2, arg3, arg4 };
55ee3607 517 return scm_call_n (proc, args, 4);
212e58ed
DH
518}
519
f32e67be
AW
520SCM
521scm_call_5 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5)
522{
523 SCM args[] = { arg1, arg2, arg3, arg4, arg5 };
55ee3607 524 return scm_call_n (proc, args, 5);
f32e67be
AW
525}
526
527SCM
528scm_call_6 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
529 SCM arg6)
530{
531 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6 };
55ee3607 532 return scm_call_n (proc, args, 6);
f32e67be
AW
533}
534
741b8a23
MW
535SCM
536scm_call_7 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
537 SCM arg6, SCM arg7)
538{
539 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
55ee3607 540 return scm_call_n (proc, args, 7);
741b8a23
MW
541}
542
543SCM
544scm_call_8 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
545 SCM arg6, SCM arg7, SCM arg8)
546{
547 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 };
55ee3607 548 return scm_call_n (proc, args, 8);
741b8a23
MW
549}
550
551SCM
552scm_call_9 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
553 SCM arg6, SCM arg7, SCM arg8, SCM arg9)
554{
555 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 };
55ee3607 556 return scm_call_n (proc, args, 9);
741b8a23
MW
557}
558
55ee3607 559/* scm_call_n defined in vm.c */
86fd6dff 560
741b8a23 561SCM
07c2ca0f 562scm_call (SCM proc, ...)
741b8a23
MW
563{
564 va_list argp;
565 SCM *argv = NULL;
566 size_t i, nargs = 0;
567
568 va_start (argp, proc);
569 while (!SCM_UNBNDP (va_arg (argp, SCM)))
570 nargs++;
571 va_end (argp);
572
573 argv = alloca (nargs * sizeof (SCM));
574 va_start (argp, proc);
575 for (i = 0; i < nargs; i++)
576 argv[i] = va_arg (argp, SCM);
577 va_end (argp);
578
55ee3607 579 return scm_call_n (proc, argv, nargs);
741b8a23
MW
580}
581
b7742c6b 582/* Simple procedure applies
9fbee57e 583 */
cc56ba80 584
b7742c6b
AW
585SCM
586scm_apply_0 (SCM proc, SCM args)
587{
6b4ba76d
AW
588 SCM *argv;
589 int i, nargs;
590
591 nargs = scm_ilength (args);
592 if (SCM_UNLIKELY (nargs < 0))
593 scm_wrong_type_arg_msg ("apply", 2, args, "list");
594
595 /* FIXME: Use vm_builtin_apply instead of alloca. */
596 argv = alloca (nargs * sizeof(SCM));
597 for (i = 0; i < nargs; i++)
598 {
599 argv[i] = SCM_CAR (args);
600 args = SCM_CDR (args);
601 }
602
55ee3607 603 return scm_call_n (proc, argv, nargs);
0f572ba7
DH
604}
605
b7742c6b
AW
606SCM
607scm_apply_1 (SCM proc, SCM arg1, SCM args)
0f572ba7 608{
6b4ba76d 609 return scm_apply_0 (proc, scm_cons (arg1, args));
8ae95199
DH
610}
611
b7742c6b
AW
612SCM
613scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
0f2d19dd 614{
6b4ba76d 615 return scm_apply_0 (proc, scm_cons2 (arg1, arg2, args));
0f2d19dd
JB
616}
617
b7742c6b
AW
618SCM
619scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
212e58ed 620{
6b4ba76d 621 return scm_apply_0 (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)));
212e58ed
DH
622}
623
60617d81
MW
624static SCM map_var, for_each_var;
625
626static void init_map_var (void)
627{
628 map_var = scm_private_variable (scm_the_root_module (),
629 scm_from_latin1_symbol ("map"));
630}
631
632static void init_for_each_var (void)
633{
634 for_each_var = scm_private_variable (scm_the_root_module (),
635 scm_from_latin1_symbol ("for-each"));
636}
b8229a3b 637
b7742c6b
AW
638SCM
639scm_map (SCM proc, SCM arg1, SCM args)
0f2d19dd 640{
60617d81
MW
641 static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
642 scm_i_pthread_once (&once, init_map_var);
0f2d19dd 643
dc7a33fa 644 return scm_apply_0 (scm_variable_ref (map_var),
6b4ba76d 645 scm_cons (proc, scm_cons (arg1, args)));
a2230b65 646}
d6754c23 647
b7742c6b
AW
648SCM
649scm_for_each (SCM proc, SCM arg1, SCM args)
0f2d19dd 650{
60617d81
MW
651 static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
652 scm_i_pthread_once (&once, init_for_each_var);
a2230b65 653
dc7a33fa 654 return scm_apply_0 (scm_variable_ref (for_each_var),
6b4ba76d 655 scm_cons (proc, scm_cons (arg1, args)));
b7742c6b 656}
71560395 657
71560395 658
5f161164
AW
659static SCM
660scm_c_primitive_eval (SCM exp)
b7742c6b 661{
a310a1d1 662 if (!SCM_EXPANDED_P (exp))
4f692ace 663 exp = scm_call_1 (scm_current_module_transformer (), exp);
ef47c422 664 return eval (scm_memoize_expression (exp), SCM_BOOL_F);
b7742c6b 665}
5f161164
AW
666
667static SCM var_primitive_eval;
668SCM
669scm_primitive_eval (SCM exp)
670{
55ee3607
AW
671 return scm_call_n (scm_variable_ref (var_primitive_eval),
672 &exp, 1);
5f161164 673}
71560395 674
b7742c6b
AW
675
676/* Eval does not take the second arg optionally. This is intentional
677 * in order to be R5RS compatible, and to prepare for the new module
678 * system, where we would like to make the choice of evaluation
679 * environment explicit. */
680
681SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
682 (SCM exp, SCM module_or_state),
683 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
684 "in the top-level environment specified by\n"
685 "@var{module_or_state}.\n"
686 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
687 "@var{module_or_state} is made the current module when\n"
688 "it is a module, or the current dynamic state when it is\n"
689 "a dynamic state."
690 "Example: (eval '(+ 1 2) (interaction-environment))")
691#define FUNC_NAME s_scm_eval
692{
693 SCM res;
694
695 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
696 if (scm_is_dynamic_state (module_or_state))
697 scm_dynwind_current_dynamic_state (module_or_state);
698 else if (scm_module_system_booted_p)
699 {
700 SCM_VALIDATE_MODULE (2, module_or_state);
701 scm_dynwind_current_module (module_or_state);
71560395 702 }
b7742c6b 703 /* otherwise if the module system isn't booted, ignore the module arg */
71560395 704
b7742c6b
AW
705 res = scm_primitive_eval (exp);
706
707 scm_dynwind_end ();
708 return res;
709}
710#undef FUNC_NAME
71560395
AW
711
712
b7742c6b 713static SCM f_apply;
71560395
AW
714
715/* Apply a function to a list of arguments.
716
6b4ba76d
AW
717 This function's interface is a bit wonly. It takes two required
718 arguments and a tail argument, as if it were:
719
71560395 720 (lambda (proc arg1 . args) ...)
6b4ba76d
AW
721
722 Usually you want to use scm_apply_0 or one of its cousins. */
71560395
AW
723
724SCM
725scm_apply (SCM proc, SCM arg1, SCM args)
726{
6b4ba76d
AW
727 return scm_apply_0 (proc,
728 scm_is_null (args) ? arg1 : scm_cons_star (arg1, args));
b7742c6b 729}
434f2f7a 730
7572ee52
AW
731static void
732prepare_boot_closure_env_for_apply (SCM proc, SCM args,
733 SCM *out_body, SCM *out_env)
314b8716 734{
8f9c5b58
AW
735 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
736 SCM env = BOOT_CLOSURE_ENV (proc);
cfc28c80
AW
737 int i;
738
8f9c5b58
AW
739 if (BOOT_CLOSURE_IS_FIXED (proc)
740 || (BOOT_CLOSURE_IS_REST (proc)
741 && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
742 {
743 if (SCM_UNLIKELY (scm_ilength (args) != nreq))
744 scm_wrong_num_args (proc);
cfc28c80
AW
745
746 env = make_env (nreq, SCM_UNDEFINED, env);
747 for (i = 0; i < nreq; args = CDR (args), i++)
748 env_set (env, 0, i, CAR (args));
7572ee52
AW
749 *out_body = BOOT_CLOSURE_BODY (proc);
750 *out_env = env;
8f9c5b58
AW
751 }
752 else if (BOOT_CLOSURE_IS_REST (proc))
314b8716
AW
753 {
754 if (SCM_UNLIKELY (scm_ilength (args) < nreq))
8f9c5b58 755 scm_wrong_num_args (proc);
cfc28c80
AW
756
757 env = make_env (nreq + 1, SCM_UNDEFINED, env);
758 for (i = 0; i < nreq; args = CDR (args), i++)
759 env_set (env, 0, i, CAR (args));
760 env_set (env, 0, i++, args);
761
7572ee52
AW
762 *out_body = BOOT_CLOSURE_BODY (proc);
763 *out_env = env;
314b8716
AW
764 }
765 else
d8a071fc 766 {
cfc28c80 767 int i, argc, nreq, nopt, nenv;
d8a071fc 768 SCM body, rest, kw, inits, alt;
dc3e203e 769 SCM mx = BOOT_CLOSURE_CODE (proc);
d8a071fc 770
7572ee52 771 loop:
dc3e203e 772 BOOT_CLOSURE_PARSE_FULL (mx, body, nargs, rest, nopt, kw, inits, alt);
d8a071fc
AW
773
774 argc = scm_ilength (args);
775 if (argc < nreq)
776 {
777 if (scm_is_true (alt))
7572ee52 778 {
dc3e203e 779 mx = alt;
7572ee52
AW
780 goto loop;
781 }
d8a071fc
AW
782 else
783 scm_wrong_num_args (proc);
784 }
785 if (scm_is_false (kw) && argc > nreq + nopt && scm_is_false (rest))
786 {
787 if (scm_is_true (alt))
7572ee52 788 {
dc3e203e 789 mx = alt;
7572ee52
AW
790 goto loop;
791 }
d8a071fc
AW
792 else
793 scm_wrong_num_args (proc);
794 }
cfc28c80
AW
795 if (scm_is_true (kw) && scm_is_false (rest))
796 {
797 int npos = 0;
798 SCM walk;
799 for (walk = args; scm_is_pair (walk); walk = CDR (walk), npos++)
800 if (npos >= nreq && scm_is_keyword (CAR (walk)))
801 break;
802
803 if (npos > nreq + nopt)
804 {
805 /* Too many positional args and no rest arg. */
806 if (scm_is_true (alt))
807 {
808 mx = alt;
809 goto loop;
810 }
811 else
812 scm_wrong_num_args (proc);
813 }
814 }
815
816 /* At this point we are committed to the chosen clause. */
817 nenv = nreq + (scm_is_true (rest) ? 1 : 0) + scm_ilength (inits);
818 env = make_env (nenv, SCM_UNDEFINED, env);
d8a071fc
AW
819
820 for (i = 0; i < nreq; i++, args = CDR (args))
cfc28c80 821 env_set (env, 0, i, CAR (args));
d8a071fc
AW
822
823 if (scm_is_false (kw))
824 {
825 /* Optional args (possibly), but no keyword args. */
826 for (; i < argc && i < nreq + nopt;
cfc28c80
AW
827 i++, args = CDR (args), inits = CDR (inits))
828 env_set (env, 0, i, CAR (args));
d8a071fc
AW
829
830 for (; i < nreq + nopt; i++, inits = CDR (inits))
cfc28c80 831 env_set (env, 0, i, EVAL1 (CAR (inits), env));
d8a071fc
AW
832
833 if (scm_is_true (rest))
cfc28c80 834 env_set (env, 0, i++, args);
d8a071fc
AW
835 }
836 else
837 {
838 SCM aok;
839
840 aok = CAR (kw);
841 kw = CDR (kw);
842
cfc28c80 843 /* Optional args. As before, but stop at the first keyword. */
d8a071fc
AW
844 for (; i < argc && i < nreq + nopt && !scm_is_keyword (CAR (args));
845 i++, args = CDR (args), inits = CDR (inits))
cfc28c80 846 env_set (env, 0, i, CAR (args));
d8a071fc
AW
847
848 for (; i < nreq + nopt; i++, inits = CDR (inits))
cfc28c80 849 env_set (env, 0, i, EVAL1 (CAR (inits), env));
d8a071fc
AW
850
851 if (scm_is_true (rest))
cfc28c80 852 env_set (env, 0, i++, args);
d8a071fc 853
cfc28c80 854 /* Parse keyword args. */
d8a071fc 855 {
d8a071fc 856 int kw_start_idx = i;
cfc28c80 857 SCM walk;
d8a071fc
AW
858
859 if (scm_is_pair (args) && scm_is_pair (CDR (args)))
860 for (; scm_is_pair (args) && scm_is_pair (CDR (args));
861 args = CDR (args))
862 {
cfc28c80 863 SCM k = CAR (args), v = CADR (args);
d8a071fc
AW
864 if (!scm_is_keyword (k))
865 {
866 if (scm_is_true (rest))
867 continue;
868 else
869 break;
870 }
871 for (walk = kw; scm_is_pair (walk); walk = CDR (walk))
872 if (scm_is_eq (k, CAAR (walk)))
873 {
cfc28c80 874 env_set (env, 0, SCM_I_INUM (CDAR (walk)), v);
d8a071fc
AW
875 args = CDR (args);
876 break;
877 }
878 if (scm_is_null (walk) && scm_is_false (aok))
4af0d97e 879 error_unrecognized_keyword (proc, k);
d8a071fc
AW
880 }
881 if (scm_is_pair (args) && scm_is_false (rest))
4af0d97e 882 error_invalid_keyword (proc, CAR (args));
d8a071fc
AW
883
884 /* Now fill in unbound values, evaluating init expressions in their
885 appropriate environment. */
cfc28c80
AW
886 for (i = kw_start_idx; scm_is_pair (inits); i++, inits = CDR (inits))
887 if (SCM_UNBNDP (env_ref (env, 0, i)))
888 env_set (env, 0, i, EVAL1 (CAR (inits), env));
d8a071fc
AW
889 }
890 }
8f9c5b58 891
cfc28c80
AW
892 if (!scm_is_null (inits))
893 abort ();
894 if (i != nenv)
895 abort ();
896
dc3e203e 897 *out_body = body;
7572ee52
AW
898 *out_env = env;
899 }
8f9c5b58
AW
900}
901
7572ee52 902static void
8f9c5b58 903prepare_boot_closure_env_for_eval (SCM proc, unsigned int argc,
7572ee52 904 SCM exps, SCM *out_body, SCM *inout_env)
8f9c5b58
AW
905{
906 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
907 SCM new_env = BOOT_CLOSURE_ENV (proc);
cfc28c80
AW
908 if ((BOOT_CLOSURE_IS_FIXED (proc)
909 || (BOOT_CLOSURE_IS_REST (proc)
910 && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
911 && nreq == argc)
314b8716 912 {
cfc28c80
AW
913 int i;
914
915 new_env = make_env (nreq, SCM_UNDEFINED, new_env);
916 for (i = 0; i < nreq; exps = CDR (exps), i++)
917 env_set (new_env, 0, i, EVAL1 (CAR (exps), *inout_env));
918
7572ee52
AW
919 *out_body = BOOT_CLOSURE_BODY (proc);
920 *inout_env = new_env;
314b8716 921 }
cfc28c80 922 else if (BOOT_CLOSURE_IS_REST (proc) && argc >= nreq)
8f9c5b58 923 {
cfc28c80
AW
924 SCM rest;
925 int i;
926
927 new_env = make_env (nreq + 1, SCM_UNDEFINED, new_env);
928 for (i = 0; i < nreq; exps = CDR (exps), i++)
929 env_set (new_env, 0, i, EVAL1 (CAR (exps), *inout_env));
930 for (rest = SCM_EOL; scm_is_pair (exps); exps = CDR (exps))
931 rest = scm_cons (EVAL1 (CAR (exps), *inout_env), rest);
932 env_set (new_env, 0, i++, scm_reverse_x (rest, SCM_UNDEFINED));
933
7572ee52
AW
934 *out_body = BOOT_CLOSURE_BODY (proc);
935 *inout_env = new_env;
8f9c5b58
AW
936 }
937 else
d8a071fc
AW
938 {
939 SCM args = SCM_EOL;
940 for (; scm_is_pair (exps); exps = CDR (exps))
f3a9a51d 941 args = scm_cons (EVAL1 (CAR (exps), *inout_env), args);
7572ee52
AW
942 args = scm_reverse_x (args, SCM_UNDEFINED);
943 prepare_boot_closure_env_for_apply (proc, args, out_body, inout_env);
d8a071fc 944 }
8f9c5b58
AW
945}
946
947static SCM
948boot_closure_apply (SCM closure, SCM args)
949{
7572ee52
AW
950 SCM body, env;
951 prepare_boot_closure_env_for_apply (closure, args, &body, &env);
952 return eval (body, env);
314b8716
AW
953}
954
955static int
956boot_closure_print (SCM closure, SCM port, scm_print_state *pstate)
957{
958 SCM args;
0607ebbf 959 scm_puts_unlocked ("#<boot-closure ", port);
fdecb44f 960 scm_uintprint (SCM_UNPACK (closure), 16, port);
0607ebbf 961 scm_putc_unlocked (' ', port);
314b8716 962 args = scm_make_list (scm_from_int (BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure)),
4a655e50 963 scm_from_latin1_symbol ("_"));
8f9c5b58 964 if (!BOOT_CLOSURE_IS_FIXED (closure) && BOOT_CLOSURE_HAS_REST_ARGS (closure))
4a655e50 965 args = scm_cons_star (scm_from_latin1_symbol ("_"), args);
7572ee52 966 /* FIXME: optionals and rests */
314b8716 967 scm_display (args, port);
0607ebbf 968 scm_putc_unlocked ('>', port);
314b8716
AW
969 return 1;
970}
971
0f2d19dd
JB
972void
973scm_init_eval ()
0f2d19dd 974{
5f161164
AW
975 SCM primitive_eval;
976
df9ca8d8 977 f_apply = scm_c_define_gsubr ("apply", 2, 0, 1, scm_apply);
86d31dfe 978
314b8716
AW
979 scm_tc16_boot_closure = scm_make_smob_type ("boot-closure", 0);
980 scm_set_smob_apply (scm_tc16_boot_closure, boot_closure_apply, 0, 0, 1);
981 scm_set_smob_print (scm_tc16_boot_closure, boot_closure_print);
982
5f161164
AW
983 primitive_eval = scm_c_make_gsubr ("primitive-eval", 1, 0, 0,
984 scm_c_primitive_eval);
985 var_primitive_eval = scm_define (SCM_SUBR_NAME (primitive_eval),
986 primitive_eval);
987
a0599745 988#include "libguile/eval.x"
0f2d19dd 989}
0f2d19dd 990
89e00824
ML
991/*
992 Local Variables:
993 c-file-style: "gnu"
994 End:
995*/
62560650 996