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