more ceval excision
[bpt/guile.git] / libguile / eval.i.c
1 /*
2 * eval.i.c - actual evaluator code for GUILE
3 *
4 * Copyright (C) 2002, 03, 04, 05, 06, 07, 09 Free Software Foundation, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 3 of
9 * the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 */
21
22 /*
23 This code is specific for the debugging support.
24 */
25
26 #define PREP_APPLY(p, l) \
27 { ++debug.info; debug.info->a.proc = p; debug.info->a.args = l; }
28
29 #define ENTER_APPLY \
30 do { \
31 SCM_SET_ARGSREADY (debug);\
32 if (scm_check_apply_p && SCM_TRAPS_P)\
33 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && SCM_PROCTRACEP (proc)))\
34 {\
35 SCM tmp, tail = scm_from_bool(SCM_TRACED_FRAME_P (debug)); \
36 SCM_SET_TRACED_FRAME (debug); \
37 SCM_TRAPS_P = 0;\
38 tmp = scm_make_debugobj (&debug);\
39 scm_call_3 (SCM_APPLY_FRAME_HDLR, scm_sym_apply_frame, tmp, tail);\
40 SCM_TRAPS_P = 1;\
41 }\
42 } while (0)
43
44 #define RETURN(e) do { proc = (e); goto exit; } while (0)
45
46 #ifdef STACK_CHECKING
47 # ifndef EVAL_STACK_CHECKING
48 # define EVAL_STACK_CHECKING
49 # endif /* EVAL_STACK_CHECKING */
50 #endif /* STACK_CHECKING */
51
52
53
54
55 static SCM
56 eval_args (SCM l, SCM env, SCM proc, SCM *lloc)
57 {
58 SCM *results = lloc;
59 while (scm_is_pair (l))
60 {
61 const SCM res = SCM_I_XEVALCAR (l, env);
62
63 *lloc = scm_list_1 (res);
64 lloc = SCM_CDRLOC (*lloc);
65 l = SCM_CDR (l);
66 }
67 if (!scm_is_null (l))
68 scm_wrong_num_args (proc);
69 return *results;
70 }
71
72
73
74
75 #define EVAL(x, env) SCM_I_XEVAL(x, env)
76 #define EVALCAR(x, env) SCM_I_XEVALCAR(x, env)
77
78
79
80 /* Update the toplevel environment frame ENV so that it refers to the
81 * current module. */
82 #define UPDATE_TOPLEVEL_ENV(env) \
83 do { \
84 SCM p = scm_current_module_lookup_closure (); \
85 if (p != SCM_CAR (env)) \
86 env = scm_top_level_env (p); \
87 } while (0)
88
89
90 #define SCM_VALIDATE_NON_EMPTY_COMBINATION(x) \
91 ASSERT_SYNTAX (!scm_is_eq ((x), SCM_EOL), s_empty_combination, x)
92
93
94 /* This is the evaluator.
95 *
96 * eval takes two input parameters, x and env: x is a single expression to be
97 * evalutated. env is the environment in which bindings are searched.
98 *
99 * x is known to be a pair. Since x is a single expression, it is necessarily
100 * in a tail position. If x is just a call to another function like in the
101 * expression (foo exp1 exp2 ...), the realization of that call therefore
102 * _must_not_ increase stack usage (the evaluation of exp1, exp2 etc.,
103 * however, may do so). This is realized by making extensive use of 'goto'
104 * statements within the evaluator: The gotos replace recursive calls to
105 * `eval', thus re-using the same stack frame that `eval' was already using.
106 * If, however, x represents some form that requires to evaluate a sequence of
107 * expressions like (begin exp1 exp2 ...), then recursive calls to `eval' are
108 * performed for all but the last expression of that sequence. */
109
110 static SCM
111 eval (SCM x, SCM env)
112 {
113 SCM proc, arg1;
114 scm_t_debug_frame debug;
115 scm_t_debug_info *debug_info_end;
116 debug.prev = scm_i_last_debug_frame ();
117 debug.status = 0;
118 /*
119 * The debug.vect contains twice as much scm_t_debug_info frames as the
120 * user has specified with (debug-set! frames <n>).
121 *
122 * Even frames are eval frames, odd frames are apply frames.
123 */
124 debug.vect = alloca (scm_debug_eframe_size * sizeof (scm_t_debug_info));
125 debug.info = debug.vect;
126 debug_info_end = debug.vect + scm_debug_eframe_size;
127 scm_i_set_last_debug_frame (&debug);
128 #ifdef EVAL_STACK_CHECKING
129 if (scm_stack_checking_enabled_p && SCM_STACK_OVERFLOW_P (&proc))
130 {
131 debug.info->e.exp = x;
132 debug.info->e.env = env;
133 scm_report_stack_overflow ();
134 }
135 #endif
136
137 goto start;
138
139 loop:
140 SCM_CLEAR_ARGSREADY (debug);
141 if (SCM_OVERFLOWP (debug))
142 --debug.info;
143 /*
144 * In theory, this should be the only place where it is necessary to
145 * check for space in debug.vect since both eval frames and
146 * available space are even.
147 *
148 * For this to be the case, however, it is necessary that primitive
149 * special forms which jump back to `loop', `begin' or some similar
150 * label call PREP_APPLY.
151 */
152 else if (++debug.info >= debug_info_end)
153 {
154 SCM_SET_OVERFLOW (debug);
155 debug.info -= 2;
156 }
157
158 start:
159 debug.info->e.exp = x;
160 debug.info->e.env = env;
161 if (scm_check_entry_p && SCM_TRAPS_P)
162 {
163 if (SCM_ENTER_FRAME_P
164 || (SCM_BREAKPOINTS_P && scm_c_source_property_breakpoint_p (x)))
165 {
166 SCM stackrep;
167 SCM tail = scm_from_bool (SCM_TAILRECP (debug));
168 SCM_SET_TAILREC (debug);
169 stackrep = scm_make_debugobj (&debug);
170 SCM_TRAPS_P = 0;
171 stackrep = scm_call_4 (SCM_ENTER_FRAME_HDLR,
172 scm_sym_enter_frame,
173 stackrep,
174 tail,
175 unmemoize_expression (x, env));
176 SCM_TRAPS_P = 1;
177 if (scm_is_pair (stackrep) &&
178 scm_is_eq (SCM_CAR (stackrep), sym_instead))
179 {
180 /* This gives the possibility for the debugger to modify
181 the source expression before evaluation. */
182 x = SCM_CDR (stackrep);
183 if (SCM_IMP (x))
184 RETURN (x);
185 }
186 }
187 }
188 dispatch:
189 SCM_TICK;
190 if (SCM_ISYMP (SCM_CAR (x)))
191 {
192 switch (ISYMNUM (SCM_CAR (x)))
193 {
194 case (ISYMNUM (SCM_IM_AND)):
195 x = SCM_CDR (x);
196 while (!scm_is_null (SCM_CDR (x)))
197 {
198 SCM test_result = EVALCAR (x, env);
199 if (scm_is_false_or_nil (test_result))
200 RETURN (SCM_BOOL_F);
201 else
202 x = SCM_CDR (x);
203 }
204 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
205 goto carloop;
206
207 case (ISYMNUM (SCM_IM_BEGIN)):
208 x = SCM_CDR (x);
209 if (scm_is_null (x))
210 RETURN (SCM_UNSPECIFIED);
211
212 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
213
214 begin:
215 /* If we are on toplevel with a lookup closure, we need to sync
216 with the current module. */
217 if (scm_is_pair (env) && !scm_is_pair (SCM_CAR (env)))
218 {
219 UPDATE_TOPLEVEL_ENV (env);
220 while (!scm_is_null (SCM_CDR (x)))
221 {
222 EVALCAR (x, env);
223 UPDATE_TOPLEVEL_ENV (env);
224 x = SCM_CDR (x);
225 }
226 goto carloop;
227 }
228 else
229 goto nontoplevel_begin;
230
231 nontoplevel_begin:
232 while (!scm_is_null (SCM_CDR (x)))
233 {
234 const SCM form = SCM_CAR (x);
235 if (SCM_IMP (form))
236 {
237 if (SCM_ISYMP (form))
238 {
239 scm_dynwind_begin (0);
240 scm_i_dynwind_pthread_mutex_lock (&source_mutex);
241 /* check for race condition */
242 if (SCM_ISYMP (SCM_CAR (x)))
243 m_expand_body (x, env);
244 scm_dynwind_end ();
245 goto nontoplevel_begin;
246 }
247 else
248 SCM_VALIDATE_NON_EMPTY_COMBINATION (form);
249 }
250 else
251 (void) EVAL (form, env);
252 x = SCM_CDR (x);
253 }
254
255 carloop:
256 {
257 /* scm_eval last form in list */
258 const SCM last_form = SCM_CAR (x);
259
260 if (scm_is_pair (last_form))
261 {
262 /* This is by far the most frequent case. */
263 x = last_form;
264 goto loop; /* tail recurse */
265 }
266 else if (SCM_IMP (last_form))
267 RETURN (SCM_I_EVALIM (last_form, env));
268 else if (SCM_VARIABLEP (last_form))
269 RETURN (SCM_VARIABLE_REF (last_form));
270 else if (scm_is_symbol (last_form))
271 RETURN (*scm_lookupcar (x, env, 1));
272 else
273 RETURN (last_form);
274 }
275
276
277 case (ISYMNUM (SCM_IM_CASE)):
278 x = SCM_CDR (x);
279 {
280 const SCM key = EVALCAR (x, env);
281 x = SCM_CDR (x);
282 while (!scm_is_null (x))
283 {
284 const SCM clause = SCM_CAR (x);
285 SCM labels = SCM_CAR (clause);
286 if (scm_is_eq (labels, SCM_IM_ELSE))
287 {
288 x = SCM_CDR (clause);
289 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
290 goto begin;
291 }
292 while (!scm_is_null (labels))
293 {
294 const SCM label = SCM_CAR (labels);
295 if (scm_is_eq (label, key)
296 || scm_is_true (scm_eqv_p (label, key)))
297 {
298 x = SCM_CDR (clause);
299 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
300 goto begin;
301 }
302 labels = SCM_CDR (labels);
303 }
304 x = SCM_CDR (x);
305 }
306 }
307 RETURN (SCM_UNSPECIFIED);
308
309
310 case (ISYMNUM (SCM_IM_COND)):
311 x = SCM_CDR (x);
312 while (!scm_is_null (x))
313 {
314 const SCM clause = SCM_CAR (x);
315 if (scm_is_eq (SCM_CAR (clause), SCM_IM_ELSE))
316 {
317 x = SCM_CDR (clause);
318 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
319 goto begin;
320 }
321 else
322 {
323 arg1 = EVALCAR (clause, env);
324 /* SRFI 61 extended cond */
325 if (!scm_is_null (SCM_CDR (clause))
326 && !scm_is_null (SCM_CDDR (clause))
327 && scm_is_eq (SCM_CADDR (clause), SCM_IM_ARROW))
328 {
329 SCM xx, guard_result;
330 if (SCM_VALUESP (arg1))
331 arg1 = scm_struct_ref (arg1, SCM_INUM0);
332 else
333 arg1 = scm_list_1 (arg1);
334 xx = SCM_CDR (clause);
335 proc = EVALCAR (xx, env);
336 guard_result = scm_apply (proc, arg1, SCM_EOL);
337 if (scm_is_true_and_not_nil (guard_result))
338 {
339 proc = SCM_CDDR (xx);
340 proc = EVALCAR (proc, env);
341 PREP_APPLY (proc, arg1);
342 goto apply_proc;
343 }
344 }
345 else if (scm_is_true_and_not_nil (arg1))
346 {
347 x = SCM_CDR (clause);
348 if (scm_is_null (x))
349 RETURN (arg1);
350 else if (!scm_is_eq (SCM_CAR (x), SCM_IM_ARROW))
351 {
352 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
353 goto begin;
354 }
355 else
356 {
357 proc = SCM_CDR (x);
358 proc = EVALCAR (proc, env);
359 PREP_APPLY (proc, scm_list_1 (arg1));
360 ENTER_APPLY;
361 goto evap1;
362 }
363 }
364 x = SCM_CDR (x);
365 }
366 }
367 RETURN (SCM_UNSPECIFIED);
368
369
370 case (ISYMNUM (SCM_IM_DO)):
371 x = SCM_CDR (x);
372 {
373 /* Compute the initialization values and the initial environment. */
374 SCM init_forms = SCM_CAR (x);
375 SCM init_values = SCM_EOL;
376 while (!scm_is_null (init_forms))
377 {
378 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
379 init_forms = SCM_CDR (init_forms);
380 }
381 x = SCM_CDR (x);
382 env = SCM_EXTEND_ENV (SCM_CAR (x), init_values, env);
383 }
384 x = SCM_CDR (x);
385 {
386 SCM test_form = SCM_CAR (x);
387 SCM body_forms = SCM_CADR (x);
388 SCM step_forms = SCM_CDDR (x);
389
390 SCM test_result = EVALCAR (test_form, env);
391
392 while (scm_is_false_or_nil (test_result))
393 {
394 {
395 /* Evaluate body forms. */
396 SCM temp_forms;
397 for (temp_forms = body_forms;
398 !scm_is_null (temp_forms);
399 temp_forms = SCM_CDR (temp_forms))
400 {
401 SCM form = SCM_CAR (temp_forms);
402 /* Dirk:FIXME: We only need to eval forms that may have
403 * a side effect here. This is only true for forms that
404 * start with a pair. All others are just constants.
405 * Since with the current memoizer 'form' may hold a
406 * constant, we call EVAL here to handle the constant
407 * cases. In the long run it would make sense to have
408 * the macro transformer of 'do' eliminate all forms
409 * that have no sideeffect. Then instead of EVAL we
410 * could call CEVAL directly here. */
411 (void) EVAL (form, env);
412 }
413 }
414
415 {
416 /* Evaluate the step expressions. */
417 SCM temp_forms;
418 SCM step_values = SCM_EOL;
419 for (temp_forms = step_forms;
420 !scm_is_null (temp_forms);
421 temp_forms = SCM_CDR (temp_forms))
422 {
423 const SCM value = EVALCAR (temp_forms, env);
424 step_values = scm_cons (value, step_values);
425 }
426 env = SCM_EXTEND_ENV (SCM_CAAR (env),
427 step_values,
428 SCM_CDR (env));
429 }
430
431 test_result = EVALCAR (test_form, env);
432 }
433 }
434 x = SCM_CDAR (x);
435 if (scm_is_null (x))
436 RETURN (SCM_UNSPECIFIED);
437 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
438 goto nontoplevel_begin;
439
440
441 case (ISYMNUM (SCM_IM_IF)):
442 x = SCM_CDR (x);
443 {
444 SCM test_result = EVALCAR (x, env);
445 x = SCM_CDR (x); /* then expression */
446 if (scm_is_false_or_nil (test_result))
447 {
448 x = SCM_CDR (x); /* else expression */
449 if (scm_is_null (x))
450 RETURN (SCM_UNSPECIFIED);
451 }
452 }
453 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
454 goto carloop;
455
456
457 case (ISYMNUM (SCM_IM_LET)):
458 x = SCM_CDR (x);
459 {
460 SCM init_forms = SCM_CADR (x);
461 SCM init_values = SCM_EOL;
462 do
463 {
464 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
465 init_forms = SCM_CDR (init_forms);
466 }
467 while (!scm_is_null (init_forms));
468 env = SCM_EXTEND_ENV (SCM_CAR (x), init_values, env);
469 }
470 x = SCM_CDDR (x);
471 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
472 goto nontoplevel_begin;
473
474
475 case (ISYMNUM (SCM_IM_LETREC)):
476 x = SCM_CDR (x);
477 env = SCM_EXTEND_ENV (SCM_CAR (x), undefineds, env);
478 x = SCM_CDR (x);
479 {
480 SCM init_forms = SCM_CAR (x);
481 SCM init_values = scm_list_1 (SCM_BOOL_T);
482 SCM *init_values_eol = SCM_CDRLOC (init_values);
483 ceval_letrec_inits (env, init_forms, &init_values_eol);
484 SCM_SETCDR (SCM_CAR (env), SCM_CDR (init_values));
485 }
486 x = SCM_CDR (x);
487 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
488 goto nontoplevel_begin;
489
490
491 case (ISYMNUM (SCM_IM_LETSTAR)):
492 x = SCM_CDR (x);
493 {
494 SCM bindings = SCM_CAR (x);
495 if (!scm_is_null (bindings))
496 {
497 do
498 {
499 SCM name = SCM_CAR (bindings);
500 SCM init = SCM_CDR (bindings);
501 env = SCM_EXTEND_ENV (name, EVALCAR (init, env), env);
502 bindings = SCM_CDR (init);
503 }
504 while (!scm_is_null (bindings));
505 }
506 }
507 x = SCM_CDR (x);
508 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
509 goto nontoplevel_begin;
510
511
512 case (ISYMNUM (SCM_IM_OR)):
513 x = SCM_CDR (x);
514 while (!scm_is_null (SCM_CDR (x)))
515 {
516 SCM val = EVALCAR (x, env);
517 if (scm_is_true_and_not_nil (val))
518 RETURN (val);
519 else
520 x = SCM_CDR (x);
521 }
522 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
523 goto carloop;
524
525
526 case (ISYMNUM (SCM_IM_LAMBDA)):
527 RETURN (scm_closure (SCM_CDR (x), env));
528
529
530 case (ISYMNUM (SCM_IM_QUOTE)):
531 RETURN (SCM_CDR (x));
532
533
534 case (ISYMNUM (SCM_IM_SET_X)):
535 x = SCM_CDR (x);
536 {
537 SCM *location;
538 SCM variable = SCM_CAR (x);
539 if (SCM_ILOCP (variable))
540 location = scm_ilookup (variable, env);
541 else if (SCM_VARIABLEP (variable))
542 location = SCM_VARIABLE_LOC (variable);
543 else
544 {
545 /* (scm_is_symbol (variable)) is known to be true */
546 variable = lazy_memoize_variable (variable, env);
547 SCM_SETCAR (x, variable);
548 location = SCM_VARIABLE_LOC (variable);
549 }
550 x = SCM_CDR (x);
551 *location = EVALCAR (x, env);
552 }
553 RETURN (SCM_UNSPECIFIED);
554
555
556 case (ISYMNUM (SCM_IM_APPLY)):
557 /* Evaluate the procedure to be applied. */
558 x = SCM_CDR (x);
559 proc = EVALCAR (x, env);
560 PREP_APPLY (proc, SCM_EOL);
561
562 /* Evaluate the argument holding the list of arguments */
563 x = SCM_CDR (x);
564 arg1 = EVALCAR (x, env);
565
566 apply_proc:
567 /* Go here to tail-apply a procedure. PROC is the procedure and
568 * ARG1 is the list of arguments. PREP_APPLY must have been called
569 * before jumping to apply_proc. */
570 if (SCM_CLOSUREP (proc))
571 {
572 SCM formals = SCM_CLOSURE_FORMALS (proc);
573 debug.info->a.args = arg1;
574 if (SCM_UNLIKELY (scm_badargsp (formals, arg1)))
575 scm_wrong_num_args (proc);
576 ENTER_APPLY;
577 /* Copy argument list */
578 if (SCM_NULL_OR_NIL_P (arg1))
579 env = SCM_EXTEND_ENV (formals, SCM_EOL, SCM_ENV (proc));
580 else
581 {
582 SCM args = scm_list_1 (SCM_CAR (arg1));
583 SCM tail = args;
584 arg1 = SCM_CDR (arg1);
585 while (!SCM_NULL_OR_NIL_P (arg1))
586 {
587 SCM new_tail = scm_list_1 (SCM_CAR (arg1));
588 SCM_SETCDR (tail, new_tail);
589 tail = new_tail;
590 arg1 = SCM_CDR (arg1);
591 }
592 env = SCM_EXTEND_ENV (formals, args, SCM_ENV (proc));
593 }
594
595 x = SCM_CLOSURE_BODY (proc);
596 goto nontoplevel_begin;
597 }
598 else
599 {
600 ENTER_APPLY;
601 RETURN (scm_apply (proc, arg1, SCM_EOL));
602 }
603
604
605 case (ISYMNUM (SCM_IM_CONT)):
606 {
607 int first;
608 SCM val = scm_make_continuation (&first);
609
610 if (!first)
611 RETURN (val);
612 else
613 {
614 arg1 = val;
615 proc = SCM_CDR (x);
616 proc = EVALCAR (proc, env);
617 PREP_APPLY (proc, scm_list_1 (arg1));
618 ENTER_APPLY;
619 goto evap1;
620 }
621 }
622
623
624 case (ISYMNUM (SCM_IM_DELAY)):
625 RETURN (scm_make_promise (scm_closure (SCM_CDR (x), env)));
626
627 case (ISYMNUM (SCM_IM_SLOT_REF)):
628 x = SCM_CDR (x);
629 {
630 SCM instance = EVALCAR (x, env);
631 unsigned long int slot = SCM_I_INUM (SCM_CDR (x));
632 RETURN (SCM_PACK (SCM_STRUCT_DATA (instance) [slot]));
633 }
634
635
636 case (ISYMNUM (SCM_IM_SLOT_SET_X)):
637 x = SCM_CDR (x);
638 {
639 SCM instance = EVALCAR (x, env);
640 unsigned long int slot = SCM_I_INUM (SCM_CADR (x));
641 SCM value = EVALCAR (SCM_CDDR (x), env);
642 SCM_STRUCT_DATA (instance) [slot] = SCM_UNPACK (value);
643 RETURN (SCM_UNSPECIFIED);
644 }
645
646
647 #if SCM_ENABLE_ELISP
648
649 case (ISYMNUM (SCM_IM_NIL_COND)):
650 {
651 SCM test_form = SCM_CDR (x);
652 x = SCM_CDR (test_form);
653 while (!SCM_NULL_OR_NIL_P (x))
654 {
655 SCM test_result = EVALCAR (test_form, env);
656 if (!(scm_is_false (test_result)
657 || SCM_NULL_OR_NIL_P (test_result)))
658 {
659 if (scm_is_eq (SCM_CAR (x), SCM_UNSPECIFIED))
660 RETURN (test_result);
661 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
662 goto carloop;
663 }
664 else
665 {
666 test_form = SCM_CDR (x);
667 x = SCM_CDR (test_form);
668 }
669 }
670 x = test_form;
671 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
672 goto carloop;
673 }
674
675 #endif /* SCM_ENABLE_ELISP */
676
677 case (ISYMNUM (SCM_IM_BIND)):
678 {
679 SCM vars, exps, vals;
680
681 x = SCM_CDR (x);
682 vars = SCM_CAAR (x);
683 exps = SCM_CDAR (x);
684 vals = SCM_EOL;
685 while (!scm_is_null (exps))
686 {
687 vals = scm_cons (EVALCAR (exps, env), vals);
688 exps = SCM_CDR (exps);
689 }
690
691 scm_swap_bindings (vars, vals);
692 scm_i_set_dynwinds (scm_acons (vars, vals, scm_i_dynwinds ()));
693
694 /* Ignore all but the last evaluation result. */
695 for (x = SCM_CDR (x); !scm_is_null (SCM_CDR (x)); x = SCM_CDR (x))
696 {
697 if (scm_is_pair (SCM_CAR (x)))
698 eval (SCM_CAR (x), env);
699 }
700 proc = EVALCAR (x, env);
701
702 scm_i_set_dynwinds (SCM_CDR (scm_i_dynwinds ()));
703 scm_swap_bindings (vars, vals);
704
705 RETURN (proc);
706 }
707
708
709 case (ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
710 {
711 SCM producer;
712
713 x = SCM_CDR (x);
714 producer = EVALCAR (x, env);
715 x = SCM_CDR (x);
716 proc = EVALCAR (x, env); /* proc is the consumer. */
717 arg1 = scm_apply (producer, SCM_EOL, SCM_EOL);
718 if (SCM_VALUESP (arg1))
719 {
720 /* The list of arguments is not copied. Rather, it is assumed
721 * that this has been done by the 'values' procedure. */
722 arg1 = scm_struct_ref (arg1, SCM_INUM0);
723 }
724 else
725 {
726 arg1 = scm_list_1 (arg1);
727 }
728 PREP_APPLY (proc, arg1);
729 goto apply_proc;
730 }
731
732
733 default:
734 break;
735 }
736 }
737 else
738 {
739 if (SCM_VARIABLEP (SCM_CAR (x)))
740 proc = SCM_VARIABLE_REF (SCM_CAR (x));
741 else if (SCM_ILOCP (SCM_CAR (x)))
742 proc = *scm_ilookup (SCM_CAR (x), env);
743 else if (scm_is_pair (SCM_CAR (x)))
744 proc = eval (SCM_CAR (x), env);
745 else if (scm_is_symbol (SCM_CAR (x)))
746 {
747 SCM orig_sym = SCM_CAR (x);
748 {
749 SCM *location = scm_lookupcar1 (x, env, 1);
750 if (location == NULL)
751 {
752 /* we have lost the race, start again. */
753 goto dispatch;
754 }
755 proc = *location;
756 if (scm_check_memoize_p && SCM_TRAPS_P)
757 {
758 SCM arg1, retval;
759
760 SCM_CLEAR_TRACED_FRAME (debug);
761 arg1 = scm_make_debugobj (&debug);
762 retval = SCM_BOOL_T;
763 SCM_TRAPS_P = 0;
764 retval = scm_call_4 (SCM_MEMOIZE_HDLR,
765 scm_sym_memoize_symbol,
766 arg1, x, env);
767
768 /*
769 do something with retval?
770 */
771 SCM_TRAPS_P = 1;
772 }
773 }
774
775 if (SCM_MACROP (proc))
776 {
777 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of
778 lookupcar */
779 handle_a_macro: /* inputs: x, env, proc */
780 /* Set a flag during macro expansion so that macro
781 application frames can be deleted from the backtrace. */
782 SCM_SET_MACROEXP (debug);
783 arg1 = scm_apply (SCM_MACRO_CODE (proc), x,
784 scm_cons (env, scm_listofnull));
785 SCM_CLEAR_MACROEXP (debug);
786 switch (SCM_MACRO_TYPE (proc))
787 {
788 case 3:
789 case 2:
790 if (!scm_is_pair (arg1))
791 arg1 = scm_list_2 (SCM_IM_BEGIN, arg1);
792
793 assert (!scm_is_eq (x, SCM_CAR (arg1))
794 && !scm_is_eq (x, SCM_CDR (arg1)));
795
796 if (!SCM_CLOSUREP (SCM_MACRO_CODE (proc)))
797 {
798 SCM_CRITICAL_SECTION_START;
799 SCM_SETCAR (x, SCM_CAR (arg1));
800 SCM_SETCDR (x, SCM_CDR (arg1));
801 SCM_CRITICAL_SECTION_END;
802 goto dispatch;
803 }
804 /* Prevent memoizing of debug info expression. */
805 debug.info->e.exp = scm_cons_source (debug.info->e.exp,
806 SCM_CAR (x),
807 SCM_CDR (x));
808 SCM_CRITICAL_SECTION_START;
809 SCM_SETCAR (x, SCM_CAR (arg1));
810 SCM_SETCDR (x, SCM_CDR (arg1));
811 SCM_CRITICAL_SECTION_END;
812 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
813 goto loop;
814 #if SCM_ENABLE_DEPRECATED == 1
815 case 1:
816 x = arg1;
817 if (SCM_NIMP (x))
818 {
819 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
820 goto loop;
821 }
822 else
823 RETURN (arg1);
824 #endif
825 case 0:
826 RETURN (arg1);
827 }
828 }
829 }
830 else
831 proc = SCM_CAR (x);
832
833 if (SCM_MACROP (proc))
834 goto handle_a_macro;
835 }
836
837
838 /* When reaching this part of the code, the following is granted: Variable x
839 * holds the first pair of an expression of the form (<function> arg ...).
840 * Variable proc holds the object that resulted from the evaluation of
841 * <function>. In the following, the arguments (if any) will be evaluated,
842 * and proc will be applied to them. If proc does not really hold a
843 * function object, this will be signalled as an error on the scheme
844 * level. If the number of arguments does not match the number of arguments
845 * that are allowed to be passed to proc, also an error on the scheme level
846 * will be signalled. */
847
848 PREP_APPLY (proc, SCM_EOL);
849 if (scm_is_null (SCM_CDR (x))) {
850 ENTER_APPLY;
851 evap0:
852 SCM_ASRTGO (!SCM_IMP (proc), badfun);
853 switch (SCM_TYP7 (proc))
854 { /* no arguments given */
855 case scm_tc7_subr_0:
856 RETURN (SCM_SUBRF (proc) ());
857 case scm_tc7_subr_1o:
858 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
859 case scm_tc7_lsubr:
860 RETURN (SCM_SUBRF (proc) (SCM_EOL));
861 case scm_tc7_rpsubr:
862 RETURN (SCM_BOOL_T);
863 case scm_tc7_asubr:
864 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
865 case scm_tc7_program:
866 RETURN (scm_c_vm_run (scm_the_vm (), proc, NULL, 0));
867 case scm_tc7_smob:
868 if (!SCM_SMOB_APPLICABLE_P (proc))
869 goto badfun;
870 RETURN (SCM_SMOB_APPLY_0 (proc));
871 case scm_tc7_gsubr:
872 debug.info->a.proc = proc;
873 debug.info->a.args = SCM_EOL;
874 RETURN (scm_i_gsubr_apply (proc, SCM_UNDEFINED));
875 case scm_tc7_pws:
876 proc = SCM_PROCEDURE (proc);
877 debug.info->a.proc = proc;
878 if (!SCM_CLOSUREP (proc))
879 goto evap0;
880 /* fallthrough */
881 case scm_tcs_closures:
882 {
883 const SCM formals = SCM_CLOSURE_FORMALS (proc);
884 if (SCM_UNLIKELY (scm_is_pair (formals)))
885 goto wrongnumargs;
886 x = SCM_CLOSURE_BODY (proc);
887 env = SCM_EXTEND_ENV (formals, SCM_EOL, SCM_ENV (proc));
888 goto nontoplevel_begin;
889 }
890 case scm_tcs_struct:
891 if (SCM_STRUCT_APPLICABLE_P (proc))
892 {
893 proc = SCM_STRUCT_PROCEDURE (proc);
894 debug.info->a.proc = proc;
895 goto evap0;
896 }
897 else
898 goto badfun;
899 case scm_tc7_subr_1:
900 case scm_tc7_subr_2:
901 case scm_tc7_subr_2o:
902 case scm_tc7_dsubr:
903 case scm_tc7_cxr:
904 case scm_tc7_subr_3:
905 case scm_tc7_lsubr_2:
906 wrongnumargs:
907 scm_wrong_num_args (proc);
908 default:
909 badfun:
910 scm_misc_error (NULL, "Wrong type to apply: ~S", scm_list_1 (proc));
911 }
912 }
913
914 /* must handle macros by here */
915 x = SCM_CDR (x);
916 if (SCM_LIKELY (scm_is_pair (x)))
917 arg1 = EVALCAR (x, env);
918 else
919 scm_wrong_num_args (proc);
920 debug.info->a.args = scm_list_1 (arg1);
921 x = SCM_CDR (x);
922 {
923 SCM arg2;
924 if (scm_is_null (x))
925 {
926 ENTER_APPLY;
927 evap1: /* inputs: proc, arg1 */
928 SCM_ASRTGO (!SCM_IMP (proc), badfun);
929 switch (SCM_TYP7 (proc))
930 { /* have one argument in arg1 */
931 case scm_tc7_subr_2o:
932 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
933 case scm_tc7_subr_1:
934 case scm_tc7_subr_1o:
935 RETURN (SCM_SUBRF (proc) (arg1));
936 case scm_tc7_dsubr:
937 if (SCM_I_INUMP (arg1))
938 {
939 RETURN (scm_from_double (SCM_DSUBRF (proc) ((double) SCM_I_INUM (arg1))));
940 }
941 else if (SCM_REALP (arg1))
942 {
943 RETURN (scm_from_double (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
944 }
945 else if (SCM_BIGP (arg1))
946 {
947 RETURN (scm_from_double (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
948 }
949 else if (SCM_FRACTIONP (arg1))
950 {
951 RETURN (scm_from_double (SCM_DSUBRF (proc) (scm_i_fraction2double (arg1))));
952 }
953 SCM_WTA_DISPATCH_1_SUBR (proc, arg1, SCM_ARG1);
954 case scm_tc7_cxr:
955 RETURN (scm_i_chase_pairs (arg1, (scm_t_bits) SCM_SUBRF (proc)));
956 case scm_tc7_rpsubr:
957 RETURN (SCM_BOOL_T);
958 case scm_tc7_program:
959 RETURN (scm_c_vm_run (scm_the_vm (), proc, &arg1, 1));
960 case scm_tc7_asubr:
961 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
962 case scm_tc7_lsubr:
963 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
964 case scm_tc7_smob:
965 if (!SCM_SMOB_APPLICABLE_P (proc))
966 goto badfun;
967 RETURN (SCM_SMOB_APPLY_1 (proc, arg1));
968 case scm_tc7_gsubr:
969 debug.info->a.args = debug.info->a.args;
970 debug.info->a.proc = proc;
971 RETURN (scm_i_gsubr_apply (proc, arg1, SCM_UNDEFINED));
972 case scm_tc7_pws:
973 proc = SCM_PROCEDURE (proc);
974 debug.info->a.proc = proc;
975 if (!SCM_CLOSUREP (proc))
976 goto evap1;
977 /* fallthrough */
978 case scm_tcs_closures:
979 {
980 /* clos1: */
981 const SCM formals = SCM_CLOSURE_FORMALS (proc);
982 if (scm_is_null (formals)
983 || (scm_is_pair (formals) && scm_is_pair (SCM_CDR (formals))))
984 goto wrongnumargs;
985 x = SCM_CLOSURE_BODY (proc);
986 env = SCM_EXTEND_ENV (formals,
987 debug.info->a.args,
988 SCM_ENV (proc));
989 goto nontoplevel_begin;
990 }
991 case scm_tcs_struct:
992 if (SCM_STRUCT_APPLICABLE_P (proc))
993 {
994 proc = SCM_STRUCT_PROCEDURE (proc);
995 debug.info->a.proc = proc;
996 goto evap1;
997 }
998 else
999 goto badfun;
1000 case scm_tc7_subr_2:
1001 case scm_tc7_subr_0:
1002 case scm_tc7_subr_3:
1003 case scm_tc7_lsubr_2:
1004 scm_wrong_num_args (proc);
1005 default:
1006 goto badfun;
1007 }
1008 }
1009 if (SCM_LIKELY (scm_is_pair (x)))
1010 arg2 = EVALCAR (x, env);
1011 else
1012 scm_wrong_num_args (proc);
1013
1014 { /* have two or more arguments */
1015 debug.info->a.args = scm_list_2 (arg1, arg2);
1016 x = SCM_CDR (x);
1017 if (scm_is_null (x)) {
1018 ENTER_APPLY;
1019 evap2:
1020 SCM_ASRTGO (!SCM_IMP (proc), badfun);
1021 switch (SCM_TYP7 (proc))
1022 { /* have two arguments */
1023 case scm_tc7_subr_2:
1024 case scm_tc7_subr_2o:
1025 RETURN (SCM_SUBRF (proc) (arg1, arg2));
1026 case scm_tc7_lsubr:
1027 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
1028 case scm_tc7_lsubr_2:
1029 RETURN (SCM_SUBRF (proc) (arg1, arg2, SCM_EOL));
1030 case scm_tc7_rpsubr:
1031 case scm_tc7_asubr:
1032 RETURN (SCM_SUBRF (proc) (arg1, arg2));
1033 case scm_tc7_program:
1034 { SCM args[2];
1035 args[0] = arg1;
1036 args[1] = arg2;
1037 RETURN (scm_c_vm_run (scm_the_vm (), proc, args, 2));
1038 }
1039 case scm_tc7_smob:
1040 if (!SCM_SMOB_APPLICABLE_P (proc))
1041 goto badfun;
1042 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, arg2));
1043 case scm_tc7_gsubr:
1044 RETURN (scm_i_gsubr_apply_list (proc, debug.info->a.args));
1045 case scm_tcs_struct:
1046 if (SCM_STRUCT_APPLICABLE_P (proc))
1047 {
1048 operatorn:
1049 RETURN (scm_apply (SCM_STRUCT_PROCEDURE (proc),
1050 debug.info->a.args,
1051 SCM_EOL));
1052 }
1053 else
1054 goto badfun;
1055 case scm_tc7_subr_0:
1056 case scm_tc7_dsubr:
1057 case scm_tc7_cxr:
1058 case scm_tc7_subr_1o:
1059 case scm_tc7_subr_1:
1060 case scm_tc7_subr_3:
1061 scm_wrong_num_args (proc);
1062 default:
1063 goto badfun;
1064 case scm_tc7_pws:
1065 proc = SCM_PROCEDURE (proc);
1066 debug.info->a.proc = proc;
1067 if (!SCM_CLOSUREP (proc))
1068 goto evap2;
1069 /* fallthrough */
1070 case scm_tcs_closures:
1071 {
1072 /* clos2: */
1073 const SCM formals = SCM_CLOSURE_FORMALS (proc);
1074 if (scm_is_null (formals)
1075 || (scm_is_pair (formals)
1076 && (scm_is_null (SCM_CDR (formals))
1077 || (scm_is_pair (SCM_CDR (formals))
1078 && scm_is_pair (SCM_CDDR (formals))))))
1079 goto wrongnumargs;
1080 env = SCM_EXTEND_ENV (formals,
1081 debug.info->a.args,
1082 SCM_ENV (proc));
1083 x = SCM_CLOSURE_BODY (proc);
1084 goto nontoplevel_begin;
1085 }
1086 }
1087 }
1088 if (SCM_UNLIKELY (!scm_is_pair (x)))
1089 scm_wrong_num_args (proc);
1090 debug.info->a.args = scm_cons2 (arg1, arg2,
1091 eval_args (x, env, proc,
1092 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
1093 ENTER_APPLY;
1094 evap3:
1095 SCM_ASRTGO (!SCM_IMP (proc), badfun);
1096 switch (SCM_TYP7 (proc))
1097 { /* have 3 or more arguments */
1098 case scm_tc7_subr_3:
1099 if (!scm_is_null (SCM_CDR (x)))
1100 scm_wrong_num_args (proc);
1101 else
1102 RETURN (SCM_SUBRF (proc) (arg1, arg2,
1103 SCM_CADDR (debug.info->a.args)));
1104 case scm_tc7_asubr:
1105 arg1 = SCM_SUBRF(proc)(arg1, arg2);
1106 arg2 = SCM_CDDR (debug.info->a.args);
1107 do
1108 {
1109 arg1 = SCM_SUBRF(proc)(arg1, SCM_CAR (arg2));
1110 arg2 = SCM_CDR (arg2);
1111 }
1112 while (SCM_NIMP (arg2));
1113 RETURN (arg1);
1114 case scm_tc7_rpsubr:
1115 if (scm_is_false (SCM_SUBRF (proc) (arg1, arg2)))
1116 RETURN (SCM_BOOL_F);
1117 arg1 = SCM_CDDR (debug.info->a.args);
1118 do
1119 {
1120 if (scm_is_false (SCM_SUBRF (proc) (arg2, SCM_CAR (arg1))))
1121 RETURN (SCM_BOOL_F);
1122 arg2 = SCM_CAR (arg1);
1123 arg1 = SCM_CDR (arg1);
1124 }
1125 while (SCM_NIMP (arg1));
1126 RETURN (SCM_BOOL_T);
1127 case scm_tc7_lsubr_2:
1128 RETURN (SCM_SUBRF (proc) (arg1, arg2,
1129 SCM_CDDR (debug.info->a.args)));
1130 case scm_tc7_lsubr:
1131 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
1132 case scm_tc7_smob:
1133 if (!SCM_SMOB_APPLICABLE_P (proc))
1134 goto badfun;
1135 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2,
1136 SCM_CDDR (debug.info->a.args)));
1137 case scm_tc7_gsubr:
1138 RETURN (scm_i_gsubr_apply_list (proc, debug.info->a.args));
1139 case scm_tc7_program:
1140 RETURN (scm_vm_apply (scm_the_vm (), proc, debug.info->a.args));
1141 case scm_tc7_pws:
1142 proc = SCM_PROCEDURE (proc);
1143 debug.info->a.proc = proc;
1144 if (!SCM_CLOSUREP (proc))
1145 goto evap3;
1146 /* fallthrough */
1147 case scm_tcs_closures:
1148 {
1149 const SCM formals = SCM_CLOSURE_FORMALS (proc);
1150 if (scm_is_null (formals)
1151 || (scm_is_pair (formals)
1152 && (scm_is_null (SCM_CDR (formals))
1153 || (scm_is_pair (SCM_CDR (formals))
1154 && scm_badargsp (SCM_CDDR (formals), x)))))
1155 goto wrongnumargs;
1156 SCM_SET_ARGSREADY (debug);
1157 env = SCM_EXTEND_ENV (formals,
1158 debug.info->a.args,
1159 SCM_ENV (proc));
1160 x = SCM_CLOSURE_BODY (proc);
1161 goto nontoplevel_begin;
1162 }
1163 case scm_tcs_struct:
1164 if (SCM_STRUCT_APPLICABLE_P (proc))
1165 goto operatorn;
1166 else
1167 goto badfun;
1168 case scm_tc7_subr_2:
1169 case scm_tc7_subr_1o:
1170 case scm_tc7_subr_2o:
1171 case scm_tc7_subr_0:
1172 case scm_tc7_dsubr:
1173 case scm_tc7_cxr:
1174 case scm_tc7_subr_1:
1175 scm_wrong_num_args (proc);
1176 default:
1177 goto badfun;
1178 }
1179 }
1180 }
1181 exit:
1182 if (scm_check_exit_p && SCM_TRAPS_P)
1183 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
1184 {
1185 SCM_CLEAR_TRACED_FRAME (debug);
1186 arg1 = scm_make_debugobj (&debug);
1187 SCM_TRAPS_P = 0;
1188 arg1 = scm_call_3 (SCM_EXIT_FRAME_HDLR, scm_sym_exit_frame, arg1, proc);
1189 SCM_TRAPS_P = 1;
1190 if (scm_is_pair (arg1) && scm_is_eq (SCM_CAR (arg1), sym_instead))
1191 proc = SCM_CDR (arg1);
1192 }
1193 scm_i_set_last_debug_frame (debug.prev);
1194 return proc;
1195 }
1196
1197
1198
1199
1200 /* Apply a function to a list of arguments.
1201
1202 This function is exported to the Scheme level as taking two
1203 required arguments and a tail argument, as if it were:
1204 (lambda (proc arg1 . args) ...)
1205 Thus, if you just have a list of arguments to pass to a procedure,
1206 pass the list as ARG1, and '() for ARGS. If you have some fixed
1207 args, pass the first as ARG1, then cons any remaining fixed args
1208 onto the front of your argument list, and pass that as ARGS. */
1209
1210 SCM
1211 scm_apply (SCM proc, SCM arg1, SCM args)
1212 {
1213 scm_t_debug_frame debug;
1214 scm_t_debug_info debug_vect_body;
1215 debug.prev = scm_i_last_debug_frame ();
1216 debug.status = SCM_APPLYFRAME;
1217 debug.vect = &debug_vect_body;
1218 debug.vect[0].a.proc = proc;
1219 debug.vect[0].a.args = SCM_EOL;
1220 scm_i_set_last_debug_frame (&debug);
1221
1222 SCM_ASRTGO (SCM_NIMP (proc), badproc);
1223
1224 /* If ARGS is the empty list, then we're calling apply with only two
1225 arguments --- ARG1 is the list of arguments for PROC. Whatever
1226 the case, futz with things so that ARG1 is the first argument to
1227 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
1228 rest.
1229
1230 Setting the debug apply frame args this way is pretty messy.
1231 Perhaps we should store arg1 and args directly in the frame as
1232 received, and let scm_frame_arguments unpack them, because that's
1233 a relatively rare operation. This works for now; if the Guile
1234 developer archives are still around, see Mikael's post of
1235 11-Apr-97. */
1236 if (scm_is_null (args))
1237 {
1238 if (scm_is_null (arg1))
1239 {
1240 arg1 = SCM_UNDEFINED;
1241 debug.vect[0].a.args = SCM_EOL;
1242 }
1243 else
1244 {
1245 debug.vect[0].a.args = arg1;
1246 args = SCM_CDR (arg1);
1247 arg1 = SCM_CAR (arg1);
1248 }
1249 }
1250 else
1251 {
1252 args = scm_nconc2last (args);
1253 debug.vect[0].a.args = scm_cons (arg1, args);
1254 }
1255 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
1256 {
1257 SCM tmp = scm_make_debugobj (&debug);
1258 SCM_TRAPS_P = 0;
1259 scm_call_2 (SCM_ENTER_FRAME_HDLR, scm_sym_enter_frame, tmp);
1260 SCM_TRAPS_P = 1;
1261 }
1262 ENTER_APPLY;
1263 tail:
1264 switch (SCM_TYP7 (proc))
1265 {
1266 case scm_tc7_subr_2o:
1267 if (SCM_UNLIKELY (SCM_UNBNDP (arg1)))
1268 scm_wrong_num_args (proc);
1269 if (scm_is_null (args))
1270 args = SCM_UNDEFINED;
1271 else
1272 {
1273 if (SCM_UNLIKELY (! scm_is_null (SCM_CDR (args))))
1274 scm_wrong_num_args (proc);
1275 args = SCM_CAR (args);
1276 }
1277 RETURN (SCM_SUBRF (proc) (arg1, args));
1278 case scm_tc7_subr_2:
1279 if (SCM_UNLIKELY (scm_is_null (args) ||
1280 !scm_is_null (SCM_CDR (args))))
1281 scm_wrong_num_args (proc);
1282 args = SCM_CAR (args);
1283 RETURN (SCM_SUBRF (proc) (arg1, args));
1284 case scm_tc7_subr_0:
1285 if (SCM_UNLIKELY (!SCM_UNBNDP (arg1)))
1286 scm_wrong_num_args (proc);
1287 else
1288 RETURN (SCM_SUBRF (proc) ());
1289 case scm_tc7_subr_1:
1290 if (SCM_UNLIKELY (SCM_UNBNDP (arg1)))
1291 scm_wrong_num_args (proc);
1292 case scm_tc7_subr_1o:
1293 if (SCM_UNLIKELY (!scm_is_null (args)))
1294 scm_wrong_num_args (proc);
1295 else
1296 RETURN (SCM_SUBRF (proc) (arg1));
1297 case scm_tc7_dsubr:
1298 if (SCM_UNLIKELY (SCM_UNBNDP (arg1) || !scm_is_null (args)))
1299 scm_wrong_num_args (proc);
1300 if (SCM_I_INUMP (arg1))
1301 {
1302 RETURN (scm_from_double (SCM_DSUBRF (proc) ((double) SCM_I_INUM (arg1))));
1303 }
1304 else if (SCM_REALP (arg1))
1305 {
1306 RETURN (scm_from_double (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
1307 }
1308 else if (SCM_BIGP (arg1))
1309 {
1310 RETURN (scm_from_double (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
1311 }
1312 else if (SCM_FRACTIONP (arg1))
1313 {
1314 RETURN (scm_from_double (SCM_DSUBRF (proc) (scm_i_fraction2double (arg1))));
1315 }
1316 SCM_WTA_DISPATCH_1_SUBR (proc, arg1, SCM_ARG1);
1317 case scm_tc7_cxr:
1318 if (SCM_UNLIKELY (SCM_UNBNDP (arg1) || !scm_is_null (args)))
1319 scm_wrong_num_args (proc);
1320 RETURN (scm_i_chase_pairs (arg1, (scm_t_bits) SCM_SUBRF (proc)));
1321 case scm_tc7_subr_3:
1322 if (SCM_UNLIKELY (scm_is_null (args)
1323 || scm_is_null (SCM_CDR (args))
1324 || !scm_is_null (SCM_CDDR (args))))
1325 scm_wrong_num_args (proc);
1326 else
1327 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CADR (args)));
1328 case scm_tc7_lsubr:
1329 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args));
1330 case scm_tc7_lsubr_2:
1331 if (SCM_UNLIKELY (!scm_is_pair (args)))
1332 scm_wrong_num_args (proc);
1333 else
1334 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)));
1335 case scm_tc7_asubr:
1336 if (scm_is_null (args))
1337 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
1338 while (SCM_NIMP (args))
1339 {
1340 SCM_ASSERT (scm_is_pair (args), args, SCM_ARG2, "apply");
1341 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
1342 args = SCM_CDR (args);
1343 }
1344 RETURN (arg1);
1345 case scm_tc7_program:
1346 if (SCM_UNBNDP (arg1))
1347 RETURN (scm_c_vm_run (scm_the_vm (), proc, NULL, 0));
1348 else
1349 RETURN (scm_vm_apply (scm_the_vm (), proc, scm_cons (arg1, args)));
1350 case scm_tc7_rpsubr:
1351 if (scm_is_null (args))
1352 RETURN (SCM_BOOL_T);
1353 while (SCM_NIMP (args))
1354 {
1355 SCM_ASSERT (scm_is_pair (args), args, SCM_ARG2, "apply");
1356 if (scm_is_false (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
1357 RETURN (SCM_BOOL_F);
1358 arg1 = SCM_CAR (args);
1359 args = SCM_CDR (args);
1360 }
1361 RETURN (SCM_BOOL_T);
1362 case scm_tcs_closures:
1363 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
1364 if (SCM_UNLIKELY (scm_badargsp (SCM_CLOSURE_FORMALS (proc), arg1)))
1365 scm_wrong_num_args (proc);
1366
1367 /* Copy argument list */
1368 if (SCM_IMP (arg1))
1369 args = arg1;
1370 else
1371 {
1372 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
1373 for (arg1 = SCM_CDR (arg1); scm_is_pair (arg1); arg1 = SCM_CDR (arg1))
1374 {
1375 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED));
1376 tl = SCM_CDR (tl);
1377 }
1378 SCM_SETCDR (tl, arg1);
1379 }
1380
1381 args = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
1382 args,
1383 SCM_ENV (proc));
1384 proc = SCM_CLOSURE_BODY (proc);
1385 again:
1386 arg1 = SCM_CDR (proc);
1387 while (!scm_is_null (arg1))
1388 {
1389 if (SCM_IMP (SCM_CAR (proc)))
1390 {
1391 if (SCM_ISYMP (SCM_CAR (proc)))
1392 {
1393 scm_dynwind_begin (0);
1394 scm_i_dynwind_pthread_mutex_lock (&source_mutex);
1395 /* check for race condition */
1396 if (SCM_ISYMP (SCM_CAR (proc)))
1397 m_expand_body (proc, args);
1398 scm_dynwind_end ();
1399 goto again;
1400 }
1401 else
1402 SCM_VALIDATE_NON_EMPTY_COMBINATION (SCM_CAR (proc));
1403 }
1404 else
1405 (void) EVAL (SCM_CAR (proc), args);
1406 proc = arg1;
1407 arg1 = SCM_CDR (proc);
1408 }
1409 RETURN (EVALCAR (proc, args));
1410 case scm_tc7_smob:
1411 if (!SCM_SMOB_APPLICABLE_P (proc))
1412 goto badproc;
1413 if (SCM_UNBNDP (arg1))
1414 RETURN (SCM_SMOB_APPLY_0 (proc));
1415 else if (scm_is_null (args))
1416 RETURN (SCM_SMOB_APPLY_1 (proc, arg1));
1417 else if (scm_is_null (SCM_CDR (args)))
1418 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, SCM_CAR (args)));
1419 else
1420 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, SCM_CAR (args), SCM_CDR (args)));
1421 case scm_tc7_gsubr:
1422 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
1423 debug.vect[0].a.proc = proc;
1424 debug.vect[0].a.args = args;
1425 RETURN (scm_i_gsubr_apply_list (proc, args));
1426 case scm_tc7_pws:
1427 proc = SCM_PROCEDURE (proc);
1428 debug.vect[0].a.proc = proc;
1429 goto tail;
1430 case scm_tcs_struct:
1431 if (SCM_STRUCT_APPLICABLE_P (proc))
1432 {
1433 proc = SCM_STRUCT_PROCEDURE (proc);
1434 debug.vect[0].a.proc = proc;
1435 if (SCM_NIMP (proc))
1436 goto tail;
1437 else
1438 goto badproc;
1439 }
1440 else if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
1441 {
1442 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
1443 RETURN (scm_apply_generic (proc, args));
1444 }
1445 else
1446 goto badproc;
1447 default:
1448 badproc:
1449 scm_wrong_type_arg ("apply", SCM_ARG1, proc);
1450 }
1451 exit:
1452 if (scm_check_exit_p && SCM_TRAPS_P)
1453 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
1454 {
1455 SCM_CLEAR_TRACED_FRAME (debug);
1456 arg1 = scm_make_debugobj (&debug);
1457 SCM_TRAPS_P = 0;
1458 arg1 = scm_call_3 (SCM_EXIT_FRAME_HDLR, scm_sym_exit_frame, arg1, proc);
1459 SCM_TRAPS_P = 1;
1460 if (scm_is_pair (arg1) && scm_is_eq (SCM_CAR (arg1), sym_instead))
1461 proc = SCM_CDR (arg1);
1462 }
1463 scm_i_set_last_debug_frame (debug.prev);
1464 return proc;
1465 }
1466
1467 #undef RETURN
1468 #undef ENTER_APPLY
1469 #undef PREP_APPLY