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