Replace "scm_*_t" with "scm_t_*", except "scm_lisp_t".
[bpt/guile.git] / libguile / eval.c
1 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
41
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
44
45 \f
46
47 /* This file is read twice in order to produce debugging versions of
48 * scm_ceval and scm_apply. These functions, scm_deval and
49 * scm_dapply, are produced when we define the preprocessor macro
50 * DEVAL. The file is divided into sections which are treated
51 * differently with respect to DEVAL. The heads of these sections are
52 * marked with the string "SECTION:".
53 */
54
55 /* SECTION: This code is compiled once.
56 */
57
58 #ifndef DEVAL
59
60 /* We need this to get the definitions for HAVE_ALLOCA_H, etc. */
61 #include "libguile/scmconfig.h"
62
63 /* AIX requires this to be the first thing in the file. The #pragma
64 directive is indented so pre-ANSI compilers will ignore it, rather
65 than choke on it. */
66 #ifndef __GNUC__
67 # if HAVE_ALLOCA_H
68 # include <alloca.h>
69 # else
70 # ifdef _AIX
71 #pragma alloca
72 # else
73 # ifndef alloca /* predefined by HP cc +Olibcalls */
74 char *alloca ();
75 # endif
76 # endif
77 # endif
78 #endif
79
80 #include "libguile/_scm.h"
81 #include "libguile/debug.h"
82 #include "libguile/dynwind.h"
83 #include "libguile/alist.h"
84 #include "libguile/eq.h"
85 #include "libguile/continuations.h"
86 #include "libguile/throw.h"
87 #include "libguile/smob.h"
88 #include "libguile/macros.h"
89 #include "libguile/procprop.h"
90 #include "libguile/hashtab.h"
91 #include "libguile/hash.h"
92 #include "libguile/srcprop.h"
93 #include "libguile/stackchk.h"
94 #include "libguile/objects.h"
95 #include "libguile/async.h"
96 #include "libguile/feature.h"
97 #include "libguile/modules.h"
98 #include "libguile/ports.h"
99 #include "libguile/root.h"
100 #include "libguile/vectors.h"
101 #include "libguile/fluids.h"
102 #include "libguile/values.h"
103
104 #include "libguile/validate.h"
105 #include "libguile/eval.h"
106
107 \f
108
109 #define SCM_VALIDATE_NON_EMPTY_COMBINATION(x) \
110 do { \
111 if (SCM_EQ_P ((x), SCM_EOL)) \
112 scm_misc_error (NULL, scm_s_expression, SCM_EOL); \
113 } while (0)
114
115 \f
116
117 /* The evaluator contains a plethora of EVAL symbols.
118 * This is an attempt at explanation.
119 *
120 * The following macros should be used in code which is read twice
121 * (where the choice of evaluator is hard soldered):
122 *
123 * SCM_CEVAL is the symbol used within one evaluator to call itself.
124 * Originally, it is defined to scm_ceval, but is redefined to
125 * scm_deval during the second pass.
126 *
127 * SIDEVAL corresponds to SCM_CEVAL, but is used in situations where
128 * only side effects of expressions matter. All immediates are
129 * ignored.
130 *
131 * SCM_EVALIM is used when it is known that the expression is an
132 * immediate. (This macro never calls an evaluator.)
133 *
134 * EVALCAR evaluates the car of an expression.
135 *
136 * EVALCELLCAR is like EVALCAR, but is used when it is known that the
137 * car is a lisp cell.
138 *
139 * The following macros should be used in code which is read once
140 * (where the choice of evaluator is dynamic):
141 *
142 * SCM_XEVAL takes care of immediates without calling an evaluator. It
143 * then calls scm_ceval *or* scm_deval, depending on the debugging
144 * mode.
145 *
146 * SCM_XEVALCAR corresponds to EVALCAR, but uses scm_ceval *or* scm_deval
147 * depending on the debugging mode.
148 *
149 * The main motivation for keeping this plethora is efficiency
150 * together with maintainability (=> locality of code).
151 */
152
153 #define SCM_CEVAL scm_ceval
154 #define SIDEVAL(x, env) if (SCM_NIMP (x)) SCM_CEVAL((x), (env))
155
156 #define EVALCELLCAR(x, env) (SCM_SYMBOLP (SCM_CAR (x)) \
157 ? *scm_lookupcar (x, env, 1) \
158 : SCM_CEVAL (SCM_CAR (x), env))
159
160 #define EVALCAR(x, env) (!SCM_CELLP (SCM_CAR (x)) \
161 ? (SCM_IMP (SCM_CAR (x)) \
162 ? SCM_EVALIM (SCM_CAR (x), env) \
163 : SCM_GLOC_VAL (SCM_CAR (x))) \
164 : EVALCELLCAR (x, env))
165
166 #define EXTEND_ENV SCM_EXTEND_ENV
167
168 #ifdef MEMOIZE_LOCALS
169
170 SCM *
171 scm_ilookup (SCM iloc, SCM env)
172 {
173 register long ir = SCM_IFRAME (iloc);
174 register SCM er = env;
175 for (; 0 != ir; --ir)
176 er = SCM_CDR (er);
177 er = SCM_CAR (er);
178 for (ir = SCM_IDIST (iloc); 0 != ir; --ir)
179 er = SCM_CDR (er);
180 if (SCM_ICDRP (iloc))
181 return SCM_CDRLOC (er);
182 return SCM_CARLOC (SCM_CDR (er));
183 }
184 #endif
185
186 #ifdef USE_THREADS
187
188 /* The Lookup Car Race
189 - by Eva Luator
190
191 Memoization of variables and special forms is done while executing
192 the code for the first time. As long as there is only one thread
193 everything is fine, but as soon as two threads execute the same
194 code concurrently `for the first time' they can come into conflict.
195
196 This memoization includes rewriting variable references into more
197 efficient forms and expanding macros. Furthermore, macro expansion
198 includes `compiling' special forms like `let', `cond', etc. into
199 tree-code instructions.
200
201 There shouldn't normally be a problem with memoizing local and
202 global variable references (into ilocs and glocs), because all
203 threads will mutate the code in *exactly* the same way and (if I
204 read the C code correctly) it is not possible to observe a half-way
205 mutated cons cell. The lookup procedure can handle this
206 transparently without any critical sections.
207
208 It is different with macro expansion, because macro expansion
209 happens outside of the lookup procedure and can't be
210 undone. Therefore it can't cope with it. It has to indicate
211 failure when it detects a lost race and hope that the caller can
212 handle it. Luckily, it turns out that this is the case.
213
214 An example to illustrate this: Suppose that the follwing form will
215 be memoized concurrently by two threads
216
217 (let ((x 12)) x)
218
219 Let's first examine the lookup of X in the body. The first thread
220 decides that it has to find the symbol "x" in the environment and
221 starts to scan it. Then the other thread takes over and actually
222 overtakes the first. It looks up "x" and substitutes an
223 appropriate iloc for it. Now the first thread continues and
224 completes its lookup. It comes to exactly the same conclusions as
225 the second one and could - without much ado - just overwrite the
226 iloc with the same iloc.
227
228 But let's see what will happen when the race occurs while looking
229 up the symbol "let" at the start of the form. It could happen that
230 the second thread interrupts the lookup of the first thread and not
231 only substitutes a gloc for it but goes right ahead and replaces it
232 with the compiled form (#@let* (x 12) x). Now, when the first
233 thread completes its lookup, it would replace the #@let* with a
234 gloc pointing to the "let" binding, effectively reverting the form
235 to (let (x 12) x). This is wrong. It has to detect that it has
236 lost the race and the evaluator has to reconsider the changed form
237 completely.
238
239 This race condition could be resolved with some kind of traffic
240 light (like mutexes) around scm_lookupcar, but I think that it is
241 best to avoid them in this case. They would serialize memoization
242 completely and because lookup involves calling arbitrary Scheme
243 code (via the lookup-thunk), threads could be blocked for an
244 arbitrary amount of time or even deadlock. But with the current
245 solution a lot of unnecessary work is potentially done. */
246
247 /* SCM_LOOKUPCAR1 is was SCM_LOOKUPCAR used to be but is allowed to
248 return NULL to indicate a failed lookup due to some race conditions
249 between threads. This only happens when VLOC is the first cell of
250 a special form that will eventually be memoized (like `let', etc.)
251 In that case the whole lookup is bogus and the caller has to
252 reconsider the complete special form.
253
254 SCM_LOOKUPCAR is still there, of course. It just calls
255 SCM_LOOKUPCAR1 and aborts on recieving NULL. So SCM_LOOKUPCAR
256 should only be called when it is known that VLOC is not the first
257 pair of a special form. Otherwise, use SCM_LOOKUPCAR1 and check
258 for NULL. I think I've found the only places where this
259 applies. */
260
261 #endif /* USE_THREADS */
262
263 SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
264
265 #ifdef USE_THREADS
266 static SCM *
267 scm_lookupcar1 (SCM vloc, SCM genv, int check)
268 #else
269 SCM *
270 scm_lookupcar (SCM vloc, SCM genv, int check)
271 #endif
272 {
273 SCM env = genv;
274 register SCM *al, fl, var = SCM_CAR (vloc);
275 #ifdef MEMOIZE_LOCALS
276 register SCM iloc = SCM_ILOC00;
277 #endif
278 for (; SCM_NIMP (env); env = SCM_CDR (env))
279 {
280 if (!SCM_CONSP (SCM_CAR (env)))
281 break;
282 al = SCM_CARLOC (env);
283 for (fl = SCM_CAR (*al); SCM_NIMP (fl); fl = SCM_CDR (fl))
284 {
285 if (SCM_NCONSP (fl))
286 {
287 if (SCM_EQ_P (fl, var))
288 {
289 #ifdef MEMOIZE_LOCALS
290 #ifdef USE_THREADS
291 if (! SCM_EQ_P (SCM_CAR (vloc), var))
292 goto race;
293 #endif
294 SCM_SET_CELL_WORD_0 (vloc, SCM_UNPACK (iloc) + SCM_ICDR);
295 #endif
296 return SCM_CDRLOC (*al);
297 }
298 else
299 break;
300 }
301 al = SCM_CDRLOC (*al);
302 if (SCM_EQ_P (SCM_CAR (fl), var))
303 {
304 #ifdef MEMOIZE_LOCALS
305 #ifndef SCM_RECKLESS /* letrec inits to SCM_UNDEFINED */
306 if (SCM_UNBNDP (SCM_CAR (*al)))
307 {
308 env = SCM_EOL;
309 goto errout;
310 }
311 #endif
312 #ifdef USE_THREADS
313 if (!SCM_EQ_P (SCM_CAR (vloc), var))
314 goto race;
315 #endif
316 SCM_SETCAR (vloc, iloc);
317 #endif
318 return SCM_CARLOC (*al);
319 }
320 #ifdef MEMOIZE_LOCALS
321 iloc = SCM_PACK (SCM_UNPACK (iloc) + SCM_IDINC);
322 #endif
323 }
324 #ifdef MEMOIZE_LOCALS
325 iloc = SCM_PACK ((~SCM_IDSTMSK) & (SCM_UNPACK(iloc) + SCM_IFRINC));
326 #endif
327 }
328 {
329 SCM top_thunk, real_var;
330 if (SCM_NIMP (env))
331 {
332 top_thunk = SCM_CAR (env); /* env now refers to a
333 top level env thunk */
334 env = SCM_CDR (env);
335 }
336 else
337 top_thunk = SCM_BOOL_F;
338 real_var = scm_sym2var (var, top_thunk, SCM_BOOL_F);
339 if (SCM_FALSEP (real_var))
340 goto errout;
341
342 #ifndef SCM_RECKLESS
343 if (SCM_NNULLP (env) || SCM_UNBNDP (SCM_VARIABLE_REF (real_var)))
344 {
345 errout:
346 /* scm_everr (vloc, genv,...) */
347 if (check)
348 {
349 if (SCM_NULLP (env))
350 scm_error (scm_unbound_variable_key, NULL,
351 "Unbound variable: ~S",
352 scm_cons (var, SCM_EOL), SCM_BOOL_F);
353 else
354 scm_misc_error (NULL, "Damaged environment: ~S",
355 scm_cons (var, SCM_EOL));
356 }
357 else
358 {
359 /* A variable could not be found, but we shall
360 not throw an error. */
361 static SCM undef_object = SCM_UNDEFINED;
362 return &undef_object;
363 }
364 }
365 #endif
366
367 #ifdef USE_THREADS
368 if (!SCM_EQ_P (SCM_CAR (vloc), var))
369 {
370 /* Some other thread has changed the very cell we are working
371 on. In effect, it must have done our job or messed it up
372 completely. */
373 race:
374 var = SCM_CAR (vloc);
375 if (SCM_ITAG3 (var) == scm_tc3_cons_gloc)
376 return SCM_GLOC_VAL_LOC (var);
377 #ifdef MEMOIZE_LOCALS
378 if (SCM_ITAG7 (var) == SCM_ITAG7 (SCM_ILOC00))
379 return scm_ilookup (var, genv);
380 #endif
381 /* We can't cope with anything else than glocs and ilocs. When
382 a special form has been memoized (i.e. `let' into `#@let') we
383 return NULL and expect the calling function to do the right
384 thing. For the evaluator, this means going back and redoing
385 the dispatch on the car of the form. */
386 return NULL;
387 }
388 #endif /* USE_THREADS */
389
390 SCM_SET_CELL_WORD_0 (vloc, SCM_UNPACK (real_var) + scm_tc3_cons_gloc);
391 return SCM_VARIABLE_LOC (real_var);
392 }
393 }
394
395 #ifdef USE_THREADS
396 SCM *
397 scm_lookupcar (SCM vloc, SCM genv, int check)
398 {
399 SCM *loc = scm_lookupcar1 (vloc, genv, check);
400 if (loc == NULL)
401 abort ();
402 return loc;
403 }
404 #endif
405
406 #define unmemocar scm_unmemocar
407
408 SCM_SYMBOL (sym_three_question_marks, "???");
409
410 SCM
411 scm_unmemocar (SCM form, SCM env)
412 {
413 SCM c;
414
415 if (SCM_IMP (form))
416 return form;
417 c = SCM_CAR (form);
418 if (SCM_ITAG3 (c) == scm_tc3_cons_gloc)
419 {
420 SCM sym =
421 scm_module_reverse_lookup (scm_env_module (env), SCM_GLOC_VAR (c));
422 if (SCM_EQ_P (sym, SCM_BOOL_F))
423 sym = sym_three_question_marks;
424 SCM_SETCAR (form, sym);
425 }
426 #ifdef MEMOIZE_LOCALS
427 #ifdef DEBUG_EXTENSIONS
428 else if (SCM_ILOCP (c))
429 {
430 long ir;
431
432 for (ir = SCM_IFRAME (c); ir != 0; --ir)
433 env = SCM_CDR (env);
434 env = SCM_CAR (SCM_CAR (env));
435 for (ir = SCM_IDIST (c); ir != 0; --ir)
436 env = SCM_CDR (env);
437 SCM_SETCAR (form, SCM_ICDRP (c) ? env : SCM_CAR (env));
438 }
439 #endif
440 #endif
441 return form;
442 }
443
444
445 SCM
446 scm_eval_car (SCM pair, SCM env)
447 {
448 return SCM_XEVALCAR (pair, env);
449 }
450
451 \f
452 /*
453 * The following rewrite expressions and
454 * some memoized forms have different syntax
455 */
456
457 const char scm_s_expression[] = "missing or extra expression";
458 const char scm_s_test[] = "bad test";
459 const char scm_s_body[] = "bad body";
460 const char scm_s_bindings[] = "bad bindings";
461 const char scm_s_duplicate_bindings[] = "duplicate bindings";
462 const char scm_s_variable[] = "bad variable";
463 const char scm_s_clauses[] = "bad or missing clauses";
464 const char scm_s_formals[] = "bad formals";
465 const char scm_s_duplicate_formals[] = "duplicate formals";
466
467 SCM_GLOBAL_SYMBOL (scm_sym_dot, ".");
468 SCM_GLOBAL_SYMBOL (scm_sym_arrow, "=>");
469 SCM_GLOBAL_SYMBOL (scm_sym_else, "else");
470 SCM_GLOBAL_SYMBOL (scm_sym_unquote, "unquote");
471 SCM_GLOBAL_SYMBOL (scm_sym_uq_splicing, "unquote-splicing");
472
473 SCM scm_f_apply;
474
475 #ifdef DEBUG_EXTENSIONS
476 SCM_GLOBAL_SYMBOL (scm_sym_enter_frame, "enter-frame");
477 SCM_GLOBAL_SYMBOL (scm_sym_apply_frame, "apply-frame");
478 SCM_GLOBAL_SYMBOL (scm_sym_exit_frame, "exit-frame");
479 SCM_GLOBAL_SYMBOL (scm_sym_trace, "trace");
480 #endif
481
482
483 /* Check that the body denoted by XORIG is valid and rewrite it into
484 its internal form. The internal form of a body is just the body
485 itself, but prefixed with an ISYM that denotes to what kind of
486 outer construct this body belongs. A lambda body starts with
487 SCM_IM_LAMBDA, for example, a body of a let starts with SCM_IM_LET,
488 etc. The one exception is a body that belongs to a letrec that has
489 been formed by rewriting internal defines: it starts with
490 SCM_IM_DEFINE. */
491
492 /* XXX - Besides controlling the rewriting of internal defines, the
493 additional ISYM could be used for improved error messages.
494 This is not done yet. */
495
496 static SCM
497 scm_m_body (SCM op, SCM xorig, const char *what)
498 {
499 SCM_ASSYNT (scm_ilength (xorig) >= 1, scm_s_expression, what);
500
501 /* Don't add another ISYM if one is present already. */
502 if (SCM_ISYMP (SCM_CAR (xorig)))
503 return xorig;
504
505 /* Retain possible doc string. */
506 if (!SCM_CONSP (SCM_CAR (xorig)))
507 {
508 if (SCM_NNULLP (SCM_CDR(xorig)))
509 return scm_cons (SCM_CAR (xorig),
510 scm_m_body (op, SCM_CDR(xorig), what));
511 return xorig;
512 }
513
514 return scm_cons (op, xorig);
515 }
516
517 SCM_SYNTAX(s_quote,"quote", scm_makmmacro, scm_m_quote);
518 SCM_GLOBAL_SYMBOL(scm_sym_quote, s_quote);
519
520 SCM
521 scm_m_quote (SCM xorig, SCM env SCM_UNUSED)
522 {
523 SCM x = scm_copy_tree (SCM_CDR (xorig));
524
525 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, s_quote);
526 return scm_cons (SCM_IM_QUOTE, x);
527 }
528
529
530
531 SCM_SYNTAX(s_begin, "begin", scm_makmmacro, scm_m_begin);
532 SCM_GLOBAL_SYMBOL(scm_sym_begin, s_begin);
533
534 SCM
535 scm_m_begin (SCM xorig, SCM env SCM_UNUSED)
536 {
537 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) >= 1, scm_s_expression, s_begin);
538 return scm_cons (SCM_IM_BEGIN, SCM_CDR (xorig));
539 }
540
541 SCM_SYNTAX(s_if, "if", scm_makmmacro, scm_m_if);
542 SCM_GLOBAL_SYMBOL(scm_sym_if, s_if);
543
544 SCM
545 scm_m_if (SCM xorig, SCM env SCM_UNUSED)
546 {
547 long len = scm_ilength (SCM_CDR (xorig));
548 SCM_ASSYNT (len >= 2 && len <= 3, scm_s_expression, "if");
549 return scm_cons (SCM_IM_IF, SCM_CDR (xorig));
550 }
551
552
553 /* Will go into the RnRS module when Guile is factorized.
554 SCM_SYNTAX(scm_s_set_x,"set!", scm_makmmacro, scm_m_set_x); */
555 const char scm_s_set_x[] = "set!";
556 SCM_GLOBAL_SYMBOL(scm_sym_set_x, scm_s_set_x);
557
558 SCM
559 scm_m_set_x (SCM xorig, SCM env SCM_UNUSED)
560 {
561 SCM x = SCM_CDR (xorig);
562 SCM_ASSYNT (2 == scm_ilength (x), scm_s_expression, scm_s_set_x);
563 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (x)), scm_s_variable, scm_s_set_x);
564 return scm_cons (SCM_IM_SET_X, x);
565 }
566
567
568 SCM_SYNTAX(s_and, "and", scm_makmmacro, scm_m_and);
569 SCM_GLOBAL_SYMBOL(scm_sym_and, s_and);
570
571 SCM
572 scm_m_and (SCM xorig, SCM env SCM_UNUSED)
573 {
574 long len = scm_ilength (SCM_CDR (xorig));
575 SCM_ASSYNT (len >= 0, scm_s_test, s_and);
576 if (len >= 1)
577 return scm_cons (SCM_IM_AND, SCM_CDR (xorig));
578 else
579 return SCM_BOOL_T;
580 }
581
582 SCM_SYNTAX(s_or,"or", scm_makmmacro, scm_m_or);
583 SCM_GLOBAL_SYMBOL(scm_sym_or,s_or);
584
585 SCM
586 scm_m_or (SCM xorig, SCM env SCM_UNUSED)
587 {
588 long len = scm_ilength (SCM_CDR (xorig));
589 SCM_ASSYNT (len >= 0, scm_s_test, s_or);
590 if (len >= 1)
591 return scm_cons (SCM_IM_OR, SCM_CDR (xorig));
592 else
593 return SCM_BOOL_F;
594 }
595
596
597 SCM_SYNTAX(s_case, "case", scm_makmmacro, scm_m_case);
598 SCM_GLOBAL_SYMBOL(scm_sym_case, s_case);
599
600 SCM
601 scm_m_case (SCM xorig, SCM env SCM_UNUSED)
602 {
603 SCM proc, cdrx = scm_list_copy (SCM_CDR (xorig)), x = cdrx;
604 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_clauses, s_case);
605 while (SCM_NIMP (x = SCM_CDR (x)))
606 {
607 proc = SCM_CAR (x);
608 SCM_ASSYNT (scm_ilength (proc) >= 2, scm_s_clauses, s_case);
609 SCM_ASSYNT (scm_ilength (SCM_CAR (proc)) >= 0
610 || (SCM_EQ_P (scm_sym_else, SCM_CAR (proc))
611 && SCM_NULLP (SCM_CDR (x))),
612 scm_s_clauses, s_case);
613 }
614 return scm_cons (SCM_IM_CASE, cdrx);
615 }
616
617
618 SCM_SYNTAX(s_cond, "cond", scm_makmmacro, scm_m_cond);
619 SCM_GLOBAL_SYMBOL(scm_sym_cond, s_cond);
620
621
622 SCM
623 scm_m_cond (SCM xorig, SCM env SCM_UNUSED)
624 {
625 SCM arg1, cdrx = scm_list_copy (SCM_CDR (xorig)), x = cdrx;
626 long len = scm_ilength (x);
627 SCM_ASSYNT (len >= 1, scm_s_clauses, s_cond);
628 while (SCM_NIMP (x))
629 {
630 arg1 = SCM_CAR (x);
631 len = scm_ilength (arg1);
632 SCM_ASSYNT (len >= 1, scm_s_clauses, s_cond);
633 if (SCM_EQ_P (scm_sym_else, SCM_CAR (arg1)))
634 {
635 SCM_ASSYNT (SCM_NULLP (SCM_CDR (x)) && len >= 2,
636 "bad ELSE clause", s_cond);
637 SCM_SETCAR (arg1, SCM_BOOL_T);
638 }
639 if (len >= 2 && SCM_EQ_P (scm_sym_arrow, SCM_CAR (SCM_CDR (arg1))))
640 SCM_ASSYNT (3 == len && SCM_NIMP (SCM_CAR (SCM_CDR (SCM_CDR (arg1)))),
641 "bad recipient", s_cond);
642 x = SCM_CDR (x);
643 }
644 return scm_cons (SCM_IM_COND, cdrx);
645 }
646
647 SCM_SYNTAX(s_lambda, "lambda", scm_makmmacro, scm_m_lambda);
648 SCM_GLOBAL_SYMBOL(scm_sym_lambda, s_lambda);
649
650 /* Return true if OBJ is `eq?' to one of the elements of LIST or to the
651 cdr of the last cons. (Thus, LIST is not required to be a proper
652 list and when OBJ also found in the improper ending.) */
653
654 static int
655 scm_c_improper_memq (SCM obj, SCM list)
656 {
657 for (; SCM_CONSP (list); list = SCM_CDR (list))
658 {
659 if (SCM_EQ_P (SCM_CAR (list), obj))
660 return 1;
661 }
662 return SCM_EQ_P (list, obj);
663 }
664
665 SCM
666 scm_m_lambda (SCM xorig, SCM env SCM_UNUSED)
667 {
668 SCM proc, x = SCM_CDR (xorig);
669 if (scm_ilength (x) < 2)
670 goto badforms;
671 proc = SCM_CAR (x);
672 if (SCM_NULLP (proc))
673 goto memlambda;
674 if (SCM_EQ_P (SCM_IM_LET, proc)) /* named let */
675 goto memlambda;
676 if (SCM_IMP (proc))
677 goto badforms;
678 if (SCM_SYMBOLP (proc))
679 goto memlambda;
680 if (SCM_NCONSP (proc))
681 goto badforms;
682 while (SCM_NIMP (proc))
683 {
684 if (SCM_NCONSP (proc))
685 {
686 if (!SCM_SYMBOLP (proc))
687 goto badforms;
688 else
689 goto memlambda;
690 }
691 if (!SCM_SYMBOLP (SCM_CAR (proc)))
692 goto badforms;
693 else if (scm_c_improper_memq (SCM_CAR(proc), SCM_CDR(proc)))
694 scm_misc_error (s_lambda, scm_s_duplicate_formals, SCM_EOL);
695 proc = SCM_CDR (proc);
696 }
697 if (SCM_NNULLP (proc))
698 {
699 badforms:
700 scm_misc_error (s_lambda, scm_s_formals, SCM_EOL);
701 }
702
703 memlambda:
704 return scm_cons2 (SCM_IM_LAMBDA, SCM_CAR (x),
705 scm_m_body (SCM_IM_LAMBDA, SCM_CDR (x), s_lambda));
706 }
707
708 SCM_SYNTAX(s_letstar,"let*", scm_makmmacro, scm_m_letstar);
709 SCM_GLOBAL_SYMBOL(scm_sym_letstar,s_letstar);
710
711
712 SCM
713 scm_m_letstar (SCM xorig, SCM env SCM_UNUSED)
714 {
715 SCM x = SCM_CDR (xorig), arg1, proc, vars = SCM_EOL, *varloc = &vars;
716 long len = scm_ilength (x);
717 SCM_ASSYNT (len >= 2, scm_s_body, s_letstar);
718 proc = SCM_CAR (x);
719 SCM_ASSYNT (scm_ilength (proc) >= 0, scm_s_bindings, s_letstar);
720 while (SCM_NIMP (proc))
721 {
722 arg1 = SCM_CAR (proc);
723 SCM_ASSYNT (2 == scm_ilength (arg1), scm_s_bindings, s_letstar);
724 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), scm_s_variable, s_letstar);
725 *varloc = scm_cons2 (SCM_CAR (arg1), SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
726 varloc = SCM_CDRLOC (SCM_CDR (*varloc));
727 proc = SCM_CDR (proc);
728 }
729 x = scm_cons (vars, SCM_CDR (x));
730
731 return scm_cons2 (SCM_IM_LETSTAR, SCM_CAR (x),
732 scm_m_body (SCM_IM_LETSTAR, SCM_CDR (x), s_letstar));
733 }
734
735 /* DO gets the most radically altered syntax
736 (do ((<var1> <init1> <step1>)
737 (<var2> <init2>)
738 ... )
739 (<test> <return>)
740 <body>)
741 ;; becomes
742 (do_mem (varn ... var2 var1)
743 (<init1> <init2> ... <initn>)
744 (<test> <return>)
745 (<body>)
746 <step1> <step2> ... <stepn>) ;; missing steps replaced by var
747 */
748
749 SCM_SYNTAX(s_do, "do", scm_makmmacro, scm_m_do);
750 SCM_GLOBAL_SYMBOL(scm_sym_do, s_do);
751
752 SCM
753 scm_m_do (SCM xorig, SCM env SCM_UNUSED)
754 {
755 SCM x = SCM_CDR (xorig), arg1, proc;
756 SCM vars = SCM_EOL, inits = SCM_EOL, steps = SCM_EOL;
757 SCM *initloc = &inits, *steploc = &steps;
758 long len = scm_ilength (x);
759 SCM_ASSYNT (len >= 2, scm_s_test, "do");
760 proc = SCM_CAR (x);
761 SCM_ASSYNT (scm_ilength (proc) >= 0, scm_s_bindings, "do");
762 while (SCM_NIMP(proc))
763 {
764 arg1 = SCM_CAR (proc);
765 len = scm_ilength (arg1);
766 SCM_ASSYNT (2 == len || 3 == len, scm_s_bindings, "do");
767 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), scm_s_variable, "do");
768 /* vars reversed here, inits and steps reversed at evaluation */
769 vars = scm_cons (SCM_CAR (arg1), vars); /* variable */
770 arg1 = SCM_CDR (arg1);
771 *initloc = scm_cons (SCM_CAR (arg1), SCM_EOL); /* init */
772 initloc = SCM_CDRLOC (*initloc);
773 arg1 = SCM_CDR (arg1);
774 *steploc = scm_cons (SCM_IMP (arg1) ? SCM_CAR (vars) : SCM_CAR (arg1), SCM_EOL); /* step */
775 steploc = SCM_CDRLOC (*steploc);
776 proc = SCM_CDR (proc);
777 }
778 x = SCM_CDR (x);
779 SCM_ASSYNT (scm_ilength (SCM_CAR (x)) >= 1, scm_s_test, "do");
780 x = scm_cons2 (SCM_CAR (x), SCM_CDR (x), steps);
781 x = scm_cons2 (vars, inits, x);
782 return scm_cons (SCM_IM_DO, x);
783 }
784
785 /* evalcar is small version of inline EVALCAR when we don't care about
786 * speed
787 */
788 #define evalcar scm_eval_car
789
790
791 static SCM iqq (SCM form, SCM env, long depth);
792
793 SCM_SYNTAX(s_quasiquote, "quasiquote", scm_makacro, scm_m_quasiquote);
794 SCM_GLOBAL_SYMBOL(scm_sym_quasiquote, s_quasiquote);
795
796 SCM
797 scm_m_quasiquote (SCM xorig, SCM env)
798 {
799 SCM x = SCM_CDR (xorig);
800 SCM_ASSYNT (scm_ilength (x) == 1, scm_s_expression, s_quasiquote);
801 return iqq (SCM_CAR (x), env, 1);
802 }
803
804
805 static SCM
806 iqq (SCM form, SCM env, long depth)
807 {
808 SCM tmp;
809 long edepth = depth;
810 if (SCM_IMP (form))
811 return form;
812 if (SCM_VECTORP (form))
813 {
814 long i = SCM_VECTOR_LENGTH (form);
815 SCM *data = SCM_VELTS (form);
816 tmp = SCM_EOL;
817 for (; --i >= 0;)
818 tmp = scm_cons (data[i], tmp);
819 return scm_vector (iqq (tmp, env, depth));
820 }
821 if (!SCM_CONSP (form))
822 return form;
823 tmp = SCM_CAR (form);
824 if (SCM_EQ_P (scm_sym_quasiquote, tmp))
825 {
826 depth++;
827 goto label;
828 }
829 if (SCM_EQ_P (scm_sym_unquote, tmp))
830 {
831 --depth;
832 label:
833 form = SCM_CDR (form);
834 SCM_ASSERT (SCM_ECONSP (form) && SCM_NULLP (SCM_CDR (form)),
835 form, SCM_ARG1, s_quasiquote);
836 if (0 == depth)
837 return evalcar (form, env);
838 return scm_cons2 (tmp, iqq (SCM_CAR (form), env, depth), SCM_EOL);
839 }
840 if (SCM_CONSP (tmp) && (SCM_EQ_P (scm_sym_uq_splicing, SCM_CAR (tmp))))
841 {
842 tmp = SCM_CDR (tmp);
843 if (0 == --edepth)
844 return scm_append (scm_cons2 (evalcar (tmp, env), iqq (SCM_CDR (form), env, depth), SCM_EOL));
845 }
846 return scm_cons (iqq (SCM_CAR (form), env, edepth), iqq (SCM_CDR (form), env, depth));
847 }
848
849 /* Here are acros which return values rather than code. */
850
851 SCM_SYNTAX (s_delay, "delay", scm_makmmacro, scm_m_delay);
852 SCM_GLOBAL_SYMBOL (scm_sym_delay, s_delay);
853
854 SCM
855 scm_m_delay (SCM xorig, SCM env SCM_UNUSED)
856 {
857 SCM_ASSYNT (scm_ilength (xorig) == 2, scm_s_expression, s_delay);
858 return scm_cons2 (SCM_IM_DELAY, SCM_EOL, SCM_CDR (xorig));
859 }
860
861
862 SCM_SYNTAX(s_define, "define", scm_makmmacro, scm_m_define);
863 SCM_GLOBAL_SYMBOL(scm_sym_define, s_define);
864
865 SCM
866 scm_m_define (SCM x, SCM env)
867 {
868 SCM proc, arg1 = x;
869 x = SCM_CDR (x);
870 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_expression, s_define);
871 proc = SCM_CAR (x);
872 x = SCM_CDR (x);
873 while (SCM_CONSP (proc))
874 { /* nested define syntax */
875 x = scm_cons (scm_cons2 (scm_sym_lambda, SCM_CDR (proc), x), SCM_EOL);
876 proc = SCM_CAR (proc);
877 }
878 SCM_ASSYNT (SCM_SYMBOLP (proc), scm_s_variable, s_define);
879 SCM_ASSYNT (1 == scm_ilength (x), scm_s_expression, s_define);
880 if (SCM_TOP_LEVEL (env))
881 {
882 x = evalcar (x, env);
883 #ifdef DEBUG_EXTENSIONS
884 if (SCM_REC_PROCNAMES_P && SCM_NIMP (x))
885 {
886 arg1 = x;
887 proc:
888 if (SCM_CLOSUREP (arg1)
889 /* Only the first definition determines the name. */
890 && SCM_FALSEP (scm_procedure_property (arg1, scm_sym_name)))
891 scm_set_procedure_property_x (arg1, scm_sym_name, proc);
892 else if (SCM_MACROP (arg1)
893 /* Dirk::FIXME: Does the following test make sense? */
894 && !SCM_EQ_P (SCM_MACRO_CODE (arg1), arg1))
895 {
896 arg1 = SCM_MACRO_CODE (arg1);
897 goto proc;
898 }
899 }
900 #endif
901 arg1 = scm_sym2var (proc, scm_env_top_level (env), SCM_BOOL_T);
902 SCM_VARIABLE_SET (arg1, x);
903 #ifdef SICP
904 return scm_cons2 (scm_sym_quote, proc, SCM_EOL);
905 #else
906 return SCM_UNSPECIFIED;
907 #endif
908 }
909 return scm_cons2 (SCM_IM_DEFINE, proc, x);
910 }
911
912 /* end of acros */
913
914 static SCM
915 scm_m_letrec1 (SCM op, SCM imm, SCM xorig, SCM env SCM_UNUSED)
916 {
917 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
918 char *what = SCM_SYMBOL_CHARS (SCM_CAR (xorig));
919 SCM x = cdrx, proc, arg1; /* structure traversers */
920 SCM vars = SCM_EOL, inits = SCM_EOL, *initloc = &inits;
921
922 proc = SCM_CAR (x);
923 SCM_ASSYNT (scm_ilength (proc) >= 1, scm_s_bindings, what);
924 do
925 {
926 /* vars scm_list reversed here, inits reversed at evaluation */
927 arg1 = SCM_CAR (proc);
928 SCM_ASSYNT (2 == scm_ilength (arg1), scm_s_bindings, what);
929 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), scm_s_variable, what);
930 if (scm_c_improper_memq (SCM_CAR (arg1), vars))
931 scm_misc_error (what, scm_s_duplicate_bindings, SCM_EOL);
932 vars = scm_cons (SCM_CAR (arg1), vars);
933 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
934 initloc = SCM_CDRLOC (*initloc);
935 }
936 while (SCM_NIMP (proc = SCM_CDR (proc)));
937
938 return scm_cons2 (op, vars,
939 scm_cons (inits, scm_m_body (imm, SCM_CDR (x), what)));
940 }
941
942 SCM_SYNTAX(s_letrec, "letrec", scm_makmmacro, scm_m_letrec);
943 SCM_GLOBAL_SYMBOL(scm_sym_letrec, s_letrec);
944
945 SCM
946 scm_m_letrec (SCM xorig, SCM env)
947 {
948 SCM x = SCM_CDR (xorig);
949 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_body, s_letrec);
950
951 if (SCM_NULLP (SCM_CAR (x))) /* null binding, let* faster */
952 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), SCM_EOL,
953 scm_m_body (SCM_IM_LETREC,
954 SCM_CDR (x),
955 s_letrec)),
956 env);
957 else
958 return scm_m_letrec1 (SCM_IM_LETREC, SCM_IM_LETREC, xorig, env);
959 }
960
961 SCM_SYNTAX(s_let, "let", scm_makmmacro, scm_m_let);
962 SCM_GLOBAL_SYMBOL(scm_sym_let, s_let);
963
964 SCM
965 scm_m_let (SCM xorig, SCM env)
966 {
967 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
968 SCM x = cdrx, proc, arg1, name; /* structure traversers */
969 SCM vars = SCM_EOL, inits = SCM_EOL, *varloc = &vars, *initloc = &inits;
970
971 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_body, s_let);
972 proc = SCM_CAR (x);
973 if (SCM_NULLP (proc)
974 || (SCM_CONSP (proc)
975 && SCM_CONSP (SCM_CAR (proc)) && SCM_NULLP (SCM_CDR (proc))))
976 {
977 /* null or single binding, let* is faster */
978 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), proc,
979 scm_m_body (SCM_IM_LET,
980 SCM_CDR (x),
981 s_let)),
982 env);
983 }
984
985 SCM_ASSYNT (SCM_NIMP (proc), scm_s_bindings, s_let);
986 if (SCM_CONSP (proc))
987 {
988 /* plain let, proc is <bindings> */
989 return scm_m_letrec1 (SCM_IM_LET, SCM_IM_LET, xorig, env);
990 }
991
992 if (!SCM_SYMBOLP (proc))
993 scm_misc_error (s_let, scm_s_bindings, SCM_EOL); /* bad let */
994 name = proc; /* named let, build equiv letrec */
995 x = SCM_CDR (x);
996 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_body, s_let);
997 proc = SCM_CAR (x); /* bindings list */
998 SCM_ASSYNT (scm_ilength (proc) >= 0, scm_s_bindings, s_let);
999 while (SCM_NIMP (proc))
1000 { /* vars and inits both in order */
1001 arg1 = SCM_CAR (proc);
1002 SCM_ASSYNT (2 == scm_ilength (arg1), scm_s_bindings, s_let);
1003 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), scm_s_variable, s_let);
1004 *varloc = scm_cons (SCM_CAR (arg1), SCM_EOL);
1005 varloc = SCM_CDRLOC (*varloc);
1006 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
1007 initloc = SCM_CDRLOC (*initloc);
1008 proc = SCM_CDR (proc);
1009 }
1010
1011 proc = scm_cons2 (scm_sym_lambda, vars,
1012 scm_m_body (SCM_IM_LET, SCM_CDR (x), "let"));
1013 proc = scm_cons2 (scm_sym_let, scm_cons (scm_cons2 (name, proc, SCM_EOL),
1014 SCM_EOL),
1015 scm_acons (name, inits, SCM_EOL));
1016 return scm_m_letrec1 (SCM_IM_LETREC, SCM_IM_LET, proc, env);
1017 }
1018
1019
1020 SCM_SYNTAX (s_atapply,"@apply", scm_makmmacro, scm_m_apply);
1021 SCM_GLOBAL_SYMBOL (scm_sym_atapply, s_atapply);
1022 SCM_GLOBAL_SYMBOL (scm_sym_apply, s_atapply + 1);
1023
1024 SCM
1025 scm_m_apply (SCM xorig, SCM env SCM_UNUSED)
1026 {
1027 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2, scm_s_expression, s_atapply);
1028 return scm_cons (SCM_IM_APPLY, SCM_CDR (xorig));
1029 }
1030
1031
1032 SCM_SYNTAX(s_atcall_cc,"@call-with-current-continuation", scm_makmmacro, scm_m_cont);
1033 SCM_GLOBAL_SYMBOL(scm_sym_atcall_cc,s_atcall_cc);
1034
1035
1036 SCM
1037 scm_m_cont (SCM xorig, SCM env SCM_UNUSED)
1038 {
1039 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
1040 scm_s_expression, s_atcall_cc);
1041 return scm_cons (SCM_IM_CONT, SCM_CDR (xorig));
1042 }
1043
1044 /* Multi-language support */
1045
1046 SCM_GLOBAL_SYMBOL (scm_lisp_nil, "nil");
1047 SCM_GLOBAL_SYMBOL (scm_lisp_t, "t");
1048
1049 SCM_SYNTAX (s_nil_cond, "nil-cond", scm_makmmacro, scm_m_nil_cond);
1050
1051 SCM
1052 scm_m_nil_cond (SCM xorig, SCM env SCM_UNUSED)
1053 {
1054 long len = scm_ilength (SCM_CDR (xorig));
1055 SCM_ASSYNT (len >= 1 && (len & 1) == 1, scm_s_expression, "nil-cond");
1056 return scm_cons (SCM_IM_NIL_COND, SCM_CDR (xorig));
1057 }
1058
1059 SCM_SYNTAX (s_nil_ify, "nil-ify", scm_makmmacro, scm_m_nil_ify);
1060
1061 SCM
1062 scm_m_nil_ify (SCM xorig, SCM env SCM_UNUSED)
1063 {
1064 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, "nil-ify");
1065 return scm_cons (SCM_IM_NIL_IFY, SCM_CDR (xorig));
1066 }
1067
1068 SCM_SYNTAX (s_t_ify, "t-ify", scm_makmmacro, scm_m_t_ify);
1069
1070 SCM
1071 scm_m_t_ify (SCM xorig, SCM env SCM_UNUSED)
1072 {
1073 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, "t-ify");
1074 return scm_cons (SCM_IM_T_IFY, SCM_CDR (xorig));
1075 }
1076
1077 SCM_SYNTAX (s_0_cond, "0-cond", scm_makmmacro, scm_m_0_cond);
1078
1079 SCM
1080 scm_m_0_cond (SCM xorig, SCM env SCM_UNUSED)
1081 {
1082 long len = scm_ilength (SCM_CDR (xorig));
1083 SCM_ASSYNT (len >= 1 && (len & 1) == 1, scm_s_expression, "0-cond");
1084 return scm_cons (SCM_IM_0_COND, SCM_CDR (xorig));
1085 }
1086
1087 SCM_SYNTAX (s_0_ify, "0-ify", scm_makmmacro, scm_m_0_ify);
1088
1089 SCM
1090 scm_m_0_ify (SCM xorig, SCM env SCM_UNUSED)
1091 {
1092 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, "0-ify");
1093 return scm_cons (SCM_IM_0_IFY, SCM_CDR (xorig));
1094 }
1095
1096 SCM_SYNTAX (s_1_ify, "1-ify", scm_makmmacro, scm_m_1_ify);
1097
1098 SCM
1099 scm_m_1_ify (SCM xorig, SCM env SCM_UNUSED)
1100 {
1101 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, "1-ify");
1102 return scm_cons (SCM_IM_1_IFY, SCM_CDR (xorig));
1103 }
1104
1105 SCM_SYNTAX (s_atfop, "@fop", scm_makmmacro, scm_m_atfop);
1106
1107 SCM
1108 scm_m_atfop (SCM xorig, SCM env SCM_UNUSED)
1109 {
1110 SCM x = SCM_CDR (xorig), var;
1111 SCM_ASSYNT (scm_ilength (x) >= 1, scm_s_expression, "@fop");
1112 var = scm_symbol_fref (SCM_CAR (x));
1113 SCM_ASSYNT (SCM_VARIABLEP (var),
1114 "Symbol's function definition is void", NULL);
1115 SCM_SET_CELL_WORD_0 (x, SCM_UNPACK (var) + scm_tc3_cons_gloc);
1116 return x;
1117 }
1118
1119 SCM_SYNTAX (s_atbind, "@bind", scm_makmmacro, scm_m_atbind);
1120
1121 SCM
1122 scm_m_atbind (SCM xorig, SCM env)
1123 {
1124 SCM x = SCM_CDR (xorig);
1125 SCM_ASSYNT (scm_ilength (x) > 1, scm_s_expression, "@bind");
1126
1127 if (SCM_IMP (env))
1128 env = SCM_BOOL_F;
1129 else
1130 {
1131 while (SCM_NIMP (SCM_CDR (env)))
1132 env = SCM_CDR (env);
1133 env = SCM_CAR (env);
1134 if (SCM_CONSP (env))
1135 env = SCM_BOOL_F;
1136 }
1137
1138 x = SCM_CAR (x);
1139 while (SCM_NIMP (x))
1140 {
1141 SCM_SET_CELL_WORD_0 (x, SCM_UNPACK (scm_sym2var (SCM_CAR (x), env, SCM_BOOL_T)) + scm_tc3_cons_gloc);
1142 x = SCM_CDR (x);
1143 }
1144 return scm_cons (SCM_IM_BIND, SCM_CDR (xorig));
1145 }
1146
1147 SCM_SYNTAX (s_at_call_with_values, "@call-with-values", scm_makmmacro, scm_m_at_call_with_values);
1148 SCM_GLOBAL_SYMBOL(scm_sym_at_call_with_values, s_at_call_with_values);
1149
1150 SCM
1151 scm_m_at_call_with_values (SCM xorig, SCM env SCM_UNUSED)
1152 {
1153 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2,
1154 scm_s_expression, s_at_call_with_values);
1155 return scm_cons (SCM_IM_CALL_WITH_VALUES, SCM_CDR (xorig));
1156 }
1157
1158 SCM
1159 scm_m_expand_body (SCM xorig, SCM env)
1160 {
1161 SCM x = SCM_CDR (xorig), defs = SCM_EOL;
1162 char *what = SCM_ISYMCHARS (SCM_CAR (xorig)) + 2;
1163
1164 while (SCM_NIMP (x))
1165 {
1166 SCM form = SCM_CAR (x);
1167 if (!SCM_CONSP (form))
1168 break;
1169 if (!SCM_SYMBOLP (SCM_CAR (form)))
1170 break;
1171
1172 form = scm_macroexp (scm_cons_source (form,
1173 SCM_CAR (form),
1174 SCM_CDR (form)),
1175 env);
1176
1177 if (SCM_EQ_P (SCM_IM_DEFINE, SCM_CAR (form)))
1178 {
1179 defs = scm_cons (SCM_CDR (form), defs);
1180 x = SCM_CDR (x);
1181 }
1182 else if (!SCM_IMP (defs))
1183 {
1184 break;
1185 }
1186 else if (SCM_EQ_P (SCM_IM_BEGIN, SCM_CAR (form)))
1187 {
1188 x = scm_append (scm_cons2 (SCM_CDR (form), SCM_CDR (x), SCM_EOL));
1189 }
1190 else
1191 {
1192 x = scm_cons (form, SCM_CDR (x));
1193 break;
1194 }
1195 }
1196
1197 SCM_ASSYNT (SCM_NIMP (x), scm_s_body, what);
1198 if (SCM_NIMP (defs))
1199 {
1200 x = scm_cons (scm_m_letrec1 (SCM_IM_LETREC,
1201 SCM_IM_DEFINE,
1202 scm_cons2 (scm_sym_define, defs, x),
1203 env),
1204 SCM_EOL);
1205 }
1206
1207 SCM_DEFER_INTS;
1208 SCM_SETCAR (xorig, SCM_CAR (x));
1209 SCM_SETCDR (xorig, SCM_CDR (x));
1210 SCM_ALLOW_INTS;
1211
1212 return xorig;
1213 }
1214
1215 SCM
1216 scm_macroexp (SCM x, SCM env)
1217 {
1218 SCM res, proc, orig_sym;
1219
1220 /* Don't bother to produce error messages here. We get them when we
1221 eventually execute the code for real. */
1222
1223 macro_tail:
1224 orig_sym = SCM_CAR (x);
1225 if (!SCM_SYMBOLP (orig_sym))
1226 return x;
1227
1228 #ifdef USE_THREADS
1229 {
1230 SCM *proc_ptr = scm_lookupcar1 (x, env, 0);
1231 if (proc_ptr == NULL)
1232 {
1233 /* We have lost the race. */
1234 goto macro_tail;
1235 }
1236 proc = *proc_ptr;
1237 }
1238 #else
1239 proc = *scm_lookupcar (x, env, 0);
1240 #endif
1241
1242 /* Only handle memoizing macros. `Acros' and `macros' are really
1243 special forms and should not be evaluated here. */
1244
1245 if (!SCM_MACROP (proc) || SCM_MACRO_TYPE (proc) != 2)
1246 return x;
1247
1248 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of lookupcar */
1249 res = scm_apply (SCM_MACRO_CODE (proc), x, scm_cons (env, scm_listofnull));
1250
1251 if (scm_ilength (res) <= 0)
1252 res = scm_cons2 (SCM_IM_BEGIN, res, SCM_EOL);
1253
1254 SCM_DEFER_INTS;
1255 SCM_SETCAR (x, SCM_CAR (res));
1256 SCM_SETCDR (x, SCM_CDR (res));
1257 SCM_ALLOW_INTS;
1258
1259 goto macro_tail;
1260 }
1261
1262 /* scm_unmemocopy takes a memoized expression together with its
1263 * environment and rewrites it to its original form. Thus, it is the
1264 * inversion of the rewrite rules above. The procedure is not
1265 * optimized for speed. It's used in scm_iprin1 when printing the
1266 * code of a closure, in scm_procedure_source, in display_frame when
1267 * generating the source for a stackframe in a backtrace, and in
1268 * display_expression.
1269 *
1270 * Unmemoizing is not a realiable process. You can not in general
1271 * expect to get the original source back.
1272 *
1273 * However, GOOPS currently relies on this for method compilation.
1274 * This ought to change.
1275 */
1276
1277 #define SCM_BIT8(x) (127 & SCM_UNPACK (x))
1278
1279 static SCM
1280 unmemocopy (SCM x, SCM env)
1281 {
1282 SCM ls, z;
1283 #ifdef DEBUG_EXTENSIONS
1284 SCM p;
1285 #endif
1286 if (SCM_NCELLP (x) || SCM_NECONSP (x))
1287 return x;
1288 #ifdef DEBUG_EXTENSIONS
1289 p = scm_whash_lookup (scm_source_whash, x);
1290 #endif
1291 switch (SCM_TYP7 (x))
1292 {
1293 case SCM_BIT8(SCM_IM_AND):
1294 ls = z = scm_cons (scm_sym_and, SCM_UNSPECIFIED);
1295 break;
1296 case SCM_BIT8(SCM_IM_BEGIN):
1297 ls = z = scm_cons (scm_sym_begin, SCM_UNSPECIFIED);
1298 break;
1299 case SCM_BIT8(SCM_IM_CASE):
1300 ls = z = scm_cons (scm_sym_case, SCM_UNSPECIFIED);
1301 break;
1302 case SCM_BIT8(SCM_IM_COND):
1303 ls = z = scm_cons (scm_sym_cond, SCM_UNSPECIFIED);
1304 break;
1305 case SCM_BIT8(SCM_IM_DO):
1306 ls = scm_cons (scm_sym_do, SCM_UNSPECIFIED);
1307 goto transform;
1308 case SCM_BIT8(SCM_IM_IF):
1309 ls = z = scm_cons (scm_sym_if, SCM_UNSPECIFIED);
1310 break;
1311 case SCM_BIT8(SCM_IM_LET):
1312 ls = scm_cons (scm_sym_let, SCM_UNSPECIFIED);
1313 goto transform;
1314 case SCM_BIT8(SCM_IM_LETREC):
1315 {
1316 SCM f, v, e, s;
1317 ls = scm_cons (scm_sym_letrec, SCM_UNSPECIFIED);
1318 transform:
1319 x = SCM_CDR (x);
1320 /* binding names */
1321 f = v = SCM_CAR (x);
1322 x = SCM_CDR (x);
1323 z = EXTEND_ENV (f, SCM_EOL, env);
1324 /* inits */
1325 e = scm_reverse (unmemocopy (SCM_CAR (x),
1326 SCM_EQ_P (SCM_CAR (ls), scm_sym_letrec) ? z : env));
1327 env = z;
1328 /* increments */
1329 s = SCM_EQ_P (SCM_CAR (ls), scm_sym_do)
1330 ? scm_reverse (unmemocopy (SCM_CDR (SCM_CDR (SCM_CDR (x))), env))
1331 : f;
1332 /* build transformed binding list */
1333 z = SCM_EOL;
1334 while (SCM_NIMP (v))
1335 {
1336 z = scm_acons (SCM_CAR (v),
1337 scm_cons (SCM_CAR (e),
1338 SCM_EQ_P (SCM_CAR (s), SCM_CAR (v))
1339 ? SCM_EOL
1340 : scm_cons (SCM_CAR (s), SCM_EOL)),
1341 z);
1342 v = SCM_CDR (v);
1343 e = SCM_CDR (e);
1344 s = SCM_CDR (s);
1345 }
1346 z = scm_cons (z, SCM_UNSPECIFIED);
1347 SCM_SETCDR (ls, z);
1348 if (SCM_EQ_P (SCM_CAR (ls), scm_sym_do))
1349 {
1350 x = SCM_CDR (x);
1351 /* test clause */
1352 SCM_SETCDR (z, scm_cons (unmemocopy (SCM_CAR (x), env),
1353 SCM_UNSPECIFIED));
1354 z = SCM_CDR (z);
1355 x = (SCM) (SCM_CARLOC (SCM_CDR (x)) - 1);
1356 /* body forms are now to be found in SCM_CDR (x)
1357 (this is how *real* code look like! :) */
1358 }
1359 break;
1360 }
1361 case SCM_BIT8(SCM_IM_LETSTAR):
1362 {
1363 SCM b, y;
1364 x = SCM_CDR (x);
1365 b = SCM_CAR (x);
1366 y = SCM_EOL;
1367 if SCM_IMP (b)
1368 {
1369 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
1370 goto letstar;
1371 }
1372 y = z = scm_acons (SCM_CAR (b),
1373 unmemocar (
1374 scm_cons (unmemocopy (SCM_CAR (SCM_CDR (b)), env), SCM_EOL), env),
1375 SCM_UNSPECIFIED);
1376 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
1377 b = SCM_CDR (SCM_CDR (b));
1378 if (SCM_IMP (b))
1379 {
1380 SCM_SETCDR (y, SCM_EOL);
1381 ls = scm_cons (scm_sym_let, z = scm_cons (y, SCM_UNSPECIFIED));
1382 break;
1383 }
1384 do
1385 {
1386 SCM_SETCDR (z, scm_acons (SCM_CAR (b),
1387 unmemocar (
1388 scm_cons (unmemocopy (SCM_CAR (SCM_CDR (b)), env), SCM_EOL), env),
1389 SCM_UNSPECIFIED));
1390 z = SCM_CDR (z);
1391 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
1392 b = SCM_CDR (SCM_CDR (b));
1393 }
1394 while (SCM_NIMP (b));
1395 SCM_SETCDR (z, SCM_EOL);
1396 letstar:
1397 ls = scm_cons (scm_sym_letstar, z = scm_cons (y, SCM_UNSPECIFIED));
1398 break;
1399 }
1400 case SCM_BIT8(SCM_IM_OR):
1401 ls = z = scm_cons (scm_sym_or, SCM_UNSPECIFIED);
1402 break;
1403 case SCM_BIT8(SCM_IM_LAMBDA):
1404 x = SCM_CDR (x);
1405 ls = scm_cons (scm_sym_lambda,
1406 z = scm_cons (SCM_CAR (x), SCM_UNSPECIFIED));
1407 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, env);
1408 break;
1409 case SCM_BIT8(SCM_IM_QUOTE):
1410 ls = z = scm_cons (scm_sym_quote, SCM_UNSPECIFIED);
1411 break;
1412 case SCM_BIT8(SCM_IM_SET_X):
1413 ls = z = scm_cons (scm_sym_set_x, SCM_UNSPECIFIED);
1414 break;
1415 case SCM_BIT8(SCM_IM_DEFINE):
1416 {
1417 SCM n;
1418 x = SCM_CDR (x);
1419 ls = scm_cons (scm_sym_define,
1420 z = scm_cons (n = SCM_CAR (x), SCM_UNSPECIFIED));
1421 if (SCM_NNULLP (env))
1422 SCM_SETCAR (SCM_CAR (env), scm_cons (n, SCM_CAR (SCM_CAR (env))));
1423 break;
1424 }
1425 case SCM_BIT8(SCM_MAKISYM (0)):
1426 z = SCM_CAR (x);
1427 if (!SCM_ISYMP (z))
1428 goto unmemo;
1429 switch (SCM_ISYMNUM (z))
1430 {
1431 case (SCM_ISYMNUM (SCM_IM_APPLY)):
1432 ls = z = scm_cons (scm_sym_atapply, SCM_UNSPECIFIED);
1433 goto loop;
1434 case (SCM_ISYMNUM (SCM_IM_CONT)):
1435 ls = z = scm_cons (scm_sym_atcall_cc, SCM_UNSPECIFIED);
1436 goto loop;
1437 case (SCM_ISYMNUM (SCM_IM_DELAY)):
1438 ls = z = scm_cons (scm_sym_delay, SCM_UNSPECIFIED);
1439 x = SCM_CDR (x);
1440 goto loop;
1441 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
1442 ls = z = scm_cons (scm_sym_at_call_with_values, SCM_UNSPECIFIED);
1443 goto loop;
1444 default:
1445 /* appease the Sun compiler god: */ ;
1446 }
1447 unmemo:
1448 default:
1449 ls = z = unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1450 SCM_UNSPECIFIED),
1451 env);
1452 }
1453 loop:
1454 while (SCM_CELLP (x = SCM_CDR (x)) && SCM_ECONSP (x))
1455 {
1456 if (SCM_ISYMP (SCM_CAR (x)))
1457 /* skip body markers */
1458 continue;
1459 SCM_SETCDR (z, unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1460 SCM_UNSPECIFIED),
1461 env));
1462 z = SCM_CDR (z);
1463 }
1464 SCM_SETCDR (z, x);
1465 #ifdef DEBUG_EXTENSIONS
1466 if (SCM_NFALSEP (p))
1467 scm_whash_insert (scm_source_whash, ls, p);
1468 #endif
1469 return ls;
1470 }
1471
1472
1473 SCM
1474 scm_unmemocopy (SCM x, SCM env)
1475 {
1476 if (SCM_NNULLP (env))
1477 /* Make a copy of the lowest frame to protect it from
1478 modifications by SCM_IM_DEFINE */
1479 return unmemocopy (x, scm_cons (SCM_CAR (env), SCM_CDR (env)));
1480 else
1481 return unmemocopy (x, env);
1482 }
1483
1484 #ifndef SCM_RECKLESS
1485
1486 int
1487 scm_badargsp (SCM formals, SCM args)
1488 {
1489 while (SCM_NIMP (formals))
1490 {
1491 if (SCM_NCONSP (formals))
1492 return 0;
1493 if (SCM_IMP(args))
1494 return 1;
1495 formals = SCM_CDR (formals);
1496 args = SCM_CDR (args);
1497 }
1498 return SCM_NNULLP (args) ? 1 : 0;
1499 }
1500 #endif
1501
1502 static int
1503 scm_badformalsp (SCM closure, int n)
1504 {
1505 SCM formals = SCM_CLOSURE_FORMALS (closure);
1506 while (!SCM_NULLP (formals))
1507 {
1508 if (!SCM_CONSP (formals))
1509 return 0;
1510 if (n == 0)
1511 return 1;
1512 --n;
1513 formals = SCM_CDR (formals);
1514 }
1515 return n;
1516 }
1517
1518 \f
1519 SCM
1520 scm_eval_args (SCM l, SCM env, SCM proc)
1521 {
1522 SCM results = SCM_EOL, *lloc = &results, res;
1523 while (!SCM_IMP (l))
1524 {
1525 #ifdef SCM_CAUTIOUS
1526 if (SCM_CONSP (l))
1527 {
1528 if (SCM_IMP (SCM_CAR (l)))
1529 res = SCM_EVALIM (SCM_CAR (l), env);
1530 else
1531 res = EVALCELLCAR (l, env);
1532 }
1533 else if (SCM_TYP3 (l) == scm_tc3_cons_gloc)
1534 {
1535 scm_t_bits vcell =
1536 SCM_STRUCT_VTABLE_DATA (l) [scm_vtable_index_vcell];
1537 if (vcell == 0)
1538 res = SCM_CAR (l); /* struct planted in code */
1539 else
1540 res = SCM_GLOC_VAL (SCM_CAR (l));
1541 }
1542 else
1543 goto wrongnumargs;
1544 #else
1545 res = EVALCAR (l, env);
1546 #endif
1547 *lloc = scm_cons (res, SCM_EOL);
1548 lloc = SCM_CDRLOC (*lloc);
1549 l = SCM_CDR (l);
1550 }
1551 #ifdef SCM_CAUTIOUS
1552 if (!SCM_NULLP (l))
1553 {
1554 wrongnumargs:
1555 scm_wrong_num_args (proc);
1556 }
1557 #endif
1558 return results;
1559 }
1560
1561 SCM
1562 scm_eval_body (SCM code, SCM env)
1563 {
1564 SCM next;
1565 again:
1566 next = code;
1567 while (SCM_NNULLP (next = SCM_CDR (next)))
1568 {
1569 if (SCM_IMP (SCM_CAR (code)))
1570 {
1571 if (SCM_ISYMP (SCM_CAR (code)))
1572 {
1573 code = scm_m_expand_body (code, env);
1574 goto again;
1575 }
1576 }
1577 else
1578 SCM_XEVAL (SCM_CAR (code), env);
1579 code = next;
1580 }
1581 return SCM_XEVALCAR (code, env);
1582 }
1583
1584
1585 #endif /* !DEVAL */
1586
1587
1588 /* SECTION: This code is specific for the debugging support. One
1589 * branch is read when DEVAL isn't defined, the other when DEVAL is
1590 * defined.
1591 */
1592
1593 #ifndef DEVAL
1594
1595 #define SCM_APPLY scm_apply
1596 #define PREP_APPLY(proc, args)
1597 #define ENTER_APPLY
1598 #define RETURN(x) return x;
1599 #ifdef STACK_CHECKING
1600 #ifndef NO_CEVAL_STACK_CHECKING
1601 #define EVAL_STACK_CHECKING
1602 #endif
1603 #endif
1604
1605 #else /* !DEVAL */
1606
1607 #undef SCM_CEVAL
1608 #define SCM_CEVAL scm_deval /* Substitute all uses of scm_ceval */
1609 #undef SCM_APPLY
1610 #define SCM_APPLY scm_dapply
1611 #undef PREP_APPLY
1612 #define PREP_APPLY(p, l) \
1613 { ++debug.info; debug.info->a.proc = p; debug.info->a.args = l; }
1614 #undef ENTER_APPLY
1615 #define ENTER_APPLY \
1616 do { \
1617 SCM_SET_ARGSREADY (debug);\
1618 if (CHECK_APPLY && SCM_TRAPS_P)\
1619 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && PROCTRACEP (proc)))\
1620 {\
1621 SCM tmp, tail = SCM_BOOL(SCM_TRACED_FRAME_P (debug)); \
1622 SCM_SET_TRACED_FRAME (debug); \
1623 if (SCM_CHEAPTRAPS_P)\
1624 {\
1625 tmp = scm_make_debugobj (&debug);\
1626 scm_ithrow (scm_sym_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
1627 }\
1628 else\
1629 {\
1630 int first;\
1631 tmp = scm_make_continuation (&first);\
1632 if (first)\
1633 scm_ithrow (scm_sym_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
1634 }\
1635 }\
1636 } while (0)
1637 #undef RETURN
1638 #define RETURN(e) {proc = (e); goto exit;}
1639 #ifdef STACK_CHECKING
1640 #ifndef EVAL_STACK_CHECKING
1641 #define EVAL_STACK_CHECKING
1642 #endif
1643 #endif
1644
1645 /* scm_ceval_ptr points to the currently selected evaluator.
1646 * *fixme*: Although efficiency is important here, this state variable
1647 * should probably not be a global. It should be related to the
1648 * current repl.
1649 */
1650
1651
1652 SCM (*scm_ceval_ptr) (SCM x, SCM env);
1653
1654 /* scm_last_debug_frame contains a pointer to the last debugging
1655 * information stack frame. It is accessed very often from the
1656 * debugging evaluator, so it should probably not be indirectly
1657 * addressed. Better to save and restore it from the current root at
1658 * any stack swaps.
1659 */
1660
1661 #ifndef USE_THREADS
1662 scm_t_debug_frame *scm_last_debug_frame;
1663 #endif
1664
1665 /* scm_debug_eframe_size is the number of slots available for pseudo
1666 * stack frames at each real stack frame.
1667 */
1668
1669 long scm_debug_eframe_size;
1670
1671 int scm_debug_mode, scm_check_entry_p, scm_check_apply_p, scm_check_exit_p;
1672
1673 long scm_eval_stack;
1674
1675 scm_t_option scm_eval_opts[] = {
1676 { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." }
1677 };
1678
1679 scm_t_option scm_debug_opts[] = {
1680 { SCM_OPTION_BOOLEAN, "cheap", 1,
1681 "*Flyweight representation of the stack at traps." },
1682 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
1683 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
1684 { SCM_OPTION_BOOLEAN, "procnames", 1,
1685 "Record procedure names at definition." },
1686 { SCM_OPTION_BOOLEAN, "backwards", 0,
1687 "Display backtrace in anti-chronological order." },
1688 { SCM_OPTION_INTEGER, "width", 79, "Maximal width of backtrace." },
1689 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
1690 { SCM_OPTION_INTEGER, "frames", 3,
1691 "Maximum number of tail-recursive frames in backtrace." },
1692 { SCM_OPTION_INTEGER, "maxdepth", 1000,
1693 "Maximal number of stored backtrace frames." },
1694 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
1695 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
1696 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
1697 { SCM_OPTION_INTEGER, "stack", 20000, "Stack size limit (measured in words; 0 = no check)." },
1698 { SCM_OPTION_SCM, "show-file-name", SCM_BOOL_T, "Show file names and line numbers in backtraces when not `#f'. A value of `base' displays only base names, while `#t' displays full names."}
1699 };
1700
1701 scm_t_option scm_evaluator_trap_table[] = {
1702 { SCM_OPTION_BOOLEAN, "traps", 0, "Enable evaluator traps." },
1703 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
1704 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
1705 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." }
1706 };
1707
1708 SCM_DEFINE (scm_eval_options_interface, "eval-options-interface", 0, 1, 0,
1709 (SCM setting),
1710 "Option interface for the evaluation options. Instead of using\n"
1711 "this procedure directly, use the procedures @code{eval-enable},\n"
1712 "@code{eval-disable}, @code{eval-set!} and @var{eval-options}.")
1713 #define FUNC_NAME s_scm_eval_options_interface
1714 {
1715 SCM ans;
1716 SCM_DEFER_INTS;
1717 ans = scm_options (setting,
1718 scm_eval_opts,
1719 SCM_N_EVAL_OPTIONS,
1720 FUNC_NAME);
1721 scm_eval_stack = SCM_EVAL_STACK * sizeof (void *);
1722 SCM_ALLOW_INTS;
1723 return ans;
1724 }
1725 #undef FUNC_NAME
1726
1727 SCM_DEFINE (scm_evaluator_traps, "evaluator-traps-interface", 0, 1, 0,
1728 (SCM setting),
1729 "Option interface for the evaluator trap options.")
1730 #define FUNC_NAME s_scm_evaluator_traps
1731 {
1732 SCM ans;
1733 SCM_DEFER_INTS;
1734 ans = scm_options (setting,
1735 scm_evaluator_trap_table,
1736 SCM_N_EVALUATOR_TRAPS,
1737 FUNC_NAME);
1738 SCM_RESET_DEBUG_MODE;
1739 SCM_ALLOW_INTS;
1740 return ans;
1741 }
1742 #undef FUNC_NAME
1743
1744 SCM
1745 scm_deval_args (SCM l, SCM env, SCM proc, SCM *lloc)
1746 {
1747 SCM *results = lloc, res;
1748 while (!SCM_IMP (l))
1749 {
1750 #ifdef SCM_CAUTIOUS
1751 if (SCM_CONSP (l))
1752 {
1753 if (SCM_IMP (SCM_CAR (l)))
1754 res = SCM_EVALIM (SCM_CAR (l), env);
1755 else
1756 res = EVALCELLCAR (l, env);
1757 }
1758 else if (SCM_TYP3 (l) == scm_tc3_cons_gloc)
1759 {
1760 scm_t_bits vcell =
1761 SCM_STRUCT_VTABLE_DATA (l) [scm_vtable_index_vcell];
1762 if (vcell == 0)
1763 res = SCM_CAR (l); /* struct planted in code */
1764 else
1765 res = SCM_GLOC_VAL (SCM_CAR (l));
1766 }
1767 else
1768 goto wrongnumargs;
1769 #else
1770 res = EVALCAR (l, env);
1771 #endif
1772 *lloc = scm_cons (res, SCM_EOL);
1773 lloc = SCM_CDRLOC (*lloc);
1774 l = SCM_CDR (l);
1775 }
1776 #ifdef SCM_CAUTIOUS
1777 if (!SCM_NULLP (l))
1778 {
1779 wrongnumargs:
1780 scm_wrong_num_args (proc);
1781 }
1782 #endif
1783 return *results;
1784 }
1785
1786 #endif /* !DEVAL */
1787
1788
1789 /* SECTION: Some local definitions for the evaluator.
1790 */
1791
1792 /* Update the toplevel environment frame ENV so that it refers to the
1793 current module.
1794 */
1795 #define UPDATE_TOPLEVEL_ENV(env) \
1796 do { \
1797 SCM p = scm_current_module_lookup_closure (); \
1798 if (p != SCM_CAR(env)) \
1799 env = scm_top_level_env (p); \
1800 } while (0)
1801
1802 #ifndef DEVAL
1803 #define CHECK_EQVISH(A,B) (SCM_EQ_P ((A), (B)) || (SCM_NFALSEP (scm_eqv_p ((A), (B)))))
1804 #endif /* DEVAL */
1805
1806 #define BUILTIN_RPASUBR /* Handle rpsubrs and asubrs without calling apply */
1807
1808 /* SECTION: This is the evaluator. Like any real monster, it has
1809 * three heads. This code is compiled twice.
1810 */
1811
1812 #if 0
1813
1814 SCM
1815 scm_ceval (SCM x, SCM env)
1816 {}
1817 #endif
1818 #if 0
1819
1820 SCM
1821 scm_deval (SCM x, SCM env)
1822 {}
1823 #endif
1824
1825 SCM
1826 SCM_CEVAL (SCM x, SCM env)
1827 {
1828 union
1829 {
1830 SCM *lloc;
1831 SCM arg1;
1832 } t;
1833 SCM proc, arg2, orig_sym;
1834 #ifdef DEVAL
1835 scm_t_debug_frame debug;
1836 scm_t_debug_info *debug_info_end;
1837 debug.prev = scm_last_debug_frame;
1838 debug.status = scm_debug_eframe_size;
1839 /*
1840 * The debug.vect contains twice as much scm_t_debug_info frames as the
1841 * user has specified with (debug-set! frames <n>).
1842 *
1843 * Even frames are eval frames, odd frames are apply frames.
1844 */
1845 debug.vect = (scm_t_debug_info *) alloca (scm_debug_eframe_size
1846 * sizeof (debug.vect[0]));
1847 debug.info = debug.vect;
1848 debug_info_end = debug.vect + scm_debug_eframe_size;
1849 scm_last_debug_frame = &debug;
1850 #endif
1851 #ifdef EVAL_STACK_CHECKING
1852 if (scm_stack_checking_enabled_p
1853 && SCM_STACK_OVERFLOW_P ((SCM_STACKITEM *) &proc))
1854 {
1855 #ifdef DEVAL
1856 debug.info->e.exp = x;
1857 debug.info->e.env = env;
1858 #endif
1859 scm_report_stack_overflow ();
1860 }
1861 #endif
1862 #ifdef DEVAL
1863 goto start;
1864 #endif
1865 loopnoap:
1866 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1867 loop:
1868 #ifdef DEVAL
1869 SCM_CLEAR_ARGSREADY (debug);
1870 if (SCM_OVERFLOWP (debug))
1871 --debug.info;
1872 /*
1873 * In theory, this should be the only place where it is necessary to
1874 * check for space in debug.vect since both eval frames and
1875 * available space are even.
1876 *
1877 * For this to be the case, however, it is necessary that primitive
1878 * special forms which jump back to `loop', `begin' or some similar
1879 * label call PREP_APPLY. A convenient way to do this is to jump to
1880 * `loopnoap' or `cdrxnoap'.
1881 */
1882 else if (++debug.info >= debug_info_end)
1883 {
1884 SCM_SET_OVERFLOW (debug);
1885 debug.info -= 2;
1886 }
1887 start:
1888 debug.info->e.exp = x;
1889 debug.info->e.env = env;
1890 if (CHECK_ENTRY && SCM_TRAPS_P)
1891 if (SCM_ENTER_FRAME_P || (SCM_BREAKPOINTS_P && SRCBRKP (x)))
1892 {
1893 SCM tail = SCM_BOOL(SCM_TAILRECP (debug));
1894 SCM_SET_TAILREC (debug);
1895 if (SCM_CHEAPTRAPS_P)
1896 t.arg1 = scm_make_debugobj (&debug);
1897 else
1898 {
1899 int first;
1900 SCM val = scm_make_continuation (&first);
1901
1902 if (first)
1903 t.arg1 = val;
1904 else
1905 {
1906 x = val;
1907 if (SCM_IMP (x))
1908 {
1909 RETURN (x);
1910 }
1911 else
1912 /* This gives the possibility for the debugger to
1913 modify the source expression before evaluation. */
1914 goto dispatch;
1915 }
1916 }
1917 scm_ithrow (scm_sym_enter_frame,
1918 scm_cons2 (t.arg1, tail,
1919 scm_cons (scm_unmemocopy (x, env), SCM_EOL)),
1920 0);
1921 }
1922 #endif
1923 #if defined (USE_THREADS) || defined (DEVAL)
1924 dispatch:
1925 #endif
1926 SCM_TICK;
1927 switch (SCM_TYP7 (x))
1928 {
1929 case scm_tc7_symbol:
1930 /* Only happens when called at top level.
1931 */
1932 x = scm_cons (x, SCM_UNDEFINED);
1933 goto retval;
1934
1935 case SCM_BIT8(SCM_IM_AND):
1936 x = SCM_CDR (x);
1937 t.arg1 = x;
1938 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1939 if (SCM_FALSEP (EVALCAR (x, env)))
1940 {
1941 RETURN (SCM_BOOL_F);
1942 }
1943 else
1944 x = t.arg1;
1945 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1946 goto carloop;
1947
1948 case SCM_BIT8(SCM_IM_BEGIN):
1949 /* (currently unused)
1950 cdrxnoap: */
1951 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1952 /* (currently unused)
1953 cdrxbegin: */
1954 x = SCM_CDR (x);
1955
1956 begin:
1957 /* If we are on toplevel with a lookup closure, we need to sync
1958 with the current module. */
1959 if (SCM_CONSP (env) && !SCM_CONSP (SCM_CAR (env)))
1960 {
1961 t.arg1 = x;
1962 UPDATE_TOPLEVEL_ENV (env);
1963 while (!SCM_NULLP (t.arg1 = SCM_CDR (t.arg1)))
1964 {
1965 EVALCAR (x, env);
1966 x = t.arg1;
1967 UPDATE_TOPLEVEL_ENV (env);
1968 }
1969 goto carloop;
1970 }
1971 else
1972 goto nontoplevel_begin;
1973
1974 nontoplevel_cdrxnoap:
1975 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1976 nontoplevel_cdrxbegin:
1977 x = SCM_CDR (x);
1978 nontoplevel_begin:
1979 t.arg1 = x;
1980 while (!SCM_NULLP (t.arg1 = SCM_CDR (t.arg1)))
1981 {
1982 if (SCM_IMP (SCM_CAR (x)))
1983 {
1984 if (SCM_ISYMP (SCM_CAR (x)))
1985 {
1986 x = scm_m_expand_body (x, env);
1987 goto nontoplevel_begin;
1988 }
1989 else
1990 SCM_VALIDATE_NON_EMPTY_COMBINATION (SCM_CAR (x));
1991 }
1992 else
1993 SCM_CEVAL (SCM_CAR (x), env);
1994 x = t.arg1;
1995 }
1996
1997 carloop: /* scm_eval car of last form in list */
1998 if (!SCM_CELLP (SCM_CAR (x)))
1999 {
2000 x = SCM_CAR (x);
2001 RETURN (SCM_IMP (x) ? SCM_EVALIM (x, env) : SCM_GLOC_VAL (x))
2002 }
2003
2004 if (SCM_SYMBOLP (SCM_CAR (x)))
2005 {
2006 retval:
2007 RETURN (*scm_lookupcar (x, env, 1))
2008 }
2009
2010 x = SCM_CAR (x);
2011 goto loop; /* tail recurse */
2012
2013
2014 case SCM_BIT8(SCM_IM_CASE):
2015 x = SCM_CDR (x);
2016 t.arg1 = EVALCAR (x, env);
2017 while (SCM_NIMP (x = SCM_CDR (x)))
2018 {
2019 proc = SCM_CAR (x);
2020 if (SCM_EQ_P (scm_sym_else, SCM_CAR (proc)))
2021 {
2022 x = SCM_CDR (proc);
2023 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2024 goto begin;
2025 }
2026 proc = SCM_CAR (proc);
2027 while (SCM_NIMP (proc))
2028 {
2029 if (CHECK_EQVISH (SCM_CAR (proc), t.arg1))
2030 {
2031 x = SCM_CDR (SCM_CAR (x));
2032 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2033 goto begin;
2034 }
2035 proc = SCM_CDR (proc);
2036 }
2037 }
2038 RETURN (SCM_UNSPECIFIED)
2039
2040
2041 case SCM_BIT8(SCM_IM_COND):
2042 while (!SCM_IMP (x = SCM_CDR (x)))
2043 {
2044 proc = SCM_CAR (x);
2045 t.arg1 = EVALCAR (proc, env);
2046 if (SCM_NFALSEP (t.arg1))
2047 {
2048 x = SCM_CDR (proc);
2049 if (SCM_NULLP (x))
2050 {
2051 RETURN (t.arg1)
2052 }
2053 if (!SCM_EQ_P (scm_sym_arrow, SCM_CAR (x)))
2054 {
2055 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2056 goto begin;
2057 }
2058 proc = SCM_CDR (x);
2059 proc = EVALCAR (proc, env);
2060 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2061 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
2062 ENTER_APPLY;
2063 if (SCM_CLOSUREP(proc) && scm_badformalsp (proc, 1))
2064 goto umwrongnumargs;
2065 goto evap1;
2066 }
2067 }
2068 RETURN (SCM_UNSPECIFIED)
2069
2070
2071 case SCM_BIT8(SCM_IM_DO):
2072 x = SCM_CDR (x);
2073 proc = SCM_CAR (SCM_CDR (x)); /* inits */
2074 t.arg1 = SCM_EOL; /* values */
2075 while (SCM_NIMP (proc))
2076 {
2077 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
2078 proc = SCM_CDR (proc);
2079 }
2080 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
2081 x = SCM_CDR (SCM_CDR (x));
2082 while (proc = SCM_CAR (x), SCM_FALSEP (EVALCAR (proc, env)))
2083 {
2084 for (proc = SCM_CADR (x); SCM_NIMP (proc); proc = SCM_CDR (proc))
2085 {
2086 t.arg1 = SCM_CAR (proc); /* body */
2087 SIDEVAL (t.arg1, env);
2088 }
2089 for (t.arg1 = SCM_EOL, proc = SCM_CDDR (x);
2090 SCM_NIMP (proc);
2091 proc = SCM_CDR (proc))
2092 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1); /* steps */
2093 env = EXTEND_ENV (SCM_CAR (SCM_CAR (env)), t.arg1, SCM_CDR (env));
2094 }
2095 x = SCM_CDR (proc);
2096 if (SCM_NULLP (x))
2097 RETURN (SCM_UNSPECIFIED);
2098 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2099 goto nontoplevel_begin;
2100
2101
2102 case SCM_BIT8(SCM_IM_IF):
2103 x = SCM_CDR (x);
2104 if (SCM_NFALSEP (EVALCAR (x, env)))
2105 x = SCM_CDR (x);
2106 else if (SCM_IMP (x = SCM_CDR (SCM_CDR (x))))
2107 {
2108 RETURN (SCM_UNSPECIFIED);
2109 }
2110 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2111 goto carloop;
2112
2113
2114 case SCM_BIT8(SCM_IM_LET):
2115 x = SCM_CDR (x);
2116 proc = SCM_CAR (SCM_CDR (x));
2117 t.arg1 = SCM_EOL;
2118 do
2119 {
2120 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
2121 }
2122 while (SCM_NIMP (proc = SCM_CDR (proc)));
2123 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
2124 x = SCM_CDR (x);
2125 goto nontoplevel_cdrxnoap;
2126
2127
2128 case SCM_BIT8(SCM_IM_LETREC):
2129 x = SCM_CDR (x);
2130 env = EXTEND_ENV (SCM_CAR (x), scm_undefineds, env);
2131 x = SCM_CDR (x);
2132 proc = SCM_CAR (x);
2133 t.arg1 = SCM_EOL;
2134 do
2135 {
2136 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
2137 }
2138 while (SCM_NIMP (proc = SCM_CDR (proc)));
2139 SCM_SETCDR (SCM_CAR (env), t.arg1);
2140 goto nontoplevel_cdrxnoap;
2141
2142
2143 case SCM_BIT8(SCM_IM_LETSTAR):
2144 x = SCM_CDR (x);
2145 proc = SCM_CAR (x);
2146 if (SCM_IMP (proc))
2147 {
2148 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
2149 goto nontoplevel_cdrxnoap;
2150 }
2151 do
2152 {
2153 t.arg1 = SCM_CAR (proc);
2154 proc = SCM_CDR (proc);
2155 env = EXTEND_ENV (t.arg1, EVALCAR (proc, env), env);
2156 }
2157 while (SCM_NIMP (proc = SCM_CDR (proc)));
2158 goto nontoplevel_cdrxnoap;
2159
2160 case SCM_BIT8(SCM_IM_OR):
2161 x = SCM_CDR (x);
2162 t.arg1 = x;
2163 while (!SCM_NULLP (t.arg1 = SCM_CDR (t.arg1)))
2164 {
2165 x = EVALCAR (x, env);
2166 if (!SCM_FALSEP (x))
2167 {
2168 RETURN (x);
2169 }
2170 x = t.arg1;
2171 }
2172 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2173 goto carloop;
2174
2175
2176 case SCM_BIT8(SCM_IM_LAMBDA):
2177 RETURN (scm_closure (SCM_CDR (x), env));
2178
2179
2180 case SCM_BIT8(SCM_IM_QUOTE):
2181 RETURN (SCM_CAR (SCM_CDR (x)));
2182
2183
2184 case SCM_BIT8(SCM_IM_SET_X):
2185 x = SCM_CDR (x);
2186 proc = SCM_CAR (x);
2187 switch (SCM_ITAG3 (proc))
2188 {
2189 case scm_tc3_cons:
2190 t.lloc = scm_lookupcar (x, env, 1);
2191 break;
2192 case scm_tc3_cons_gloc:
2193 t.lloc = SCM_GLOC_VAL_LOC (proc);
2194 break;
2195 #ifdef MEMOIZE_LOCALS
2196 case scm_tc3_imm24:
2197 t.lloc = scm_ilookup (proc, env);
2198 break;
2199 #endif
2200 }
2201 x = SCM_CDR (x);
2202 *t.lloc = EVALCAR (x, env);
2203 #ifdef SICP
2204 RETURN (*t.lloc);
2205 #else
2206 RETURN (SCM_UNSPECIFIED);
2207 #endif
2208
2209
2210 case SCM_BIT8(SCM_IM_DEFINE): /* only for internal defines */
2211 scm_misc_error (NULL, "Bad define placement", SCM_EOL);
2212
2213 /* new syntactic forms go here. */
2214 case SCM_BIT8(SCM_MAKISYM (0)):
2215 proc = SCM_CAR (x);
2216 SCM_ASRTGO (SCM_ISYMP (proc), badfun);
2217 switch SCM_ISYMNUM (proc)
2218 {
2219 case (SCM_ISYMNUM (SCM_IM_APPLY)):
2220 proc = SCM_CDR (x);
2221 proc = EVALCAR (proc, env);
2222 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2223 if (SCM_CLOSUREP (proc))
2224 {
2225 SCM argl, tl;
2226 PREP_APPLY (proc, SCM_EOL);
2227 t.arg1 = SCM_CDR (SCM_CDR (x));
2228 t.arg1 = EVALCAR (t.arg1, env);
2229 apply_closure:
2230 /* Go here to tail-call a closure. PROC is the closure
2231 and T.ARG1 is the list of arguments. Do not forget to
2232 call PREP_APPLY. */
2233 #ifdef DEVAL
2234 debug.info->a.args = t.arg1;
2235 #endif
2236 #ifndef SCM_RECKLESS
2237 if (scm_badargsp (SCM_CLOSURE_FORMALS (proc), t.arg1))
2238 goto wrongnumargs;
2239 #endif
2240 ENTER_APPLY;
2241 /* Copy argument list */
2242 if (SCM_IMP (t.arg1))
2243 argl = t.arg1;
2244 else
2245 {
2246 argl = tl = scm_cons (SCM_CAR (t.arg1), SCM_UNSPECIFIED);
2247 while (SCM_NIMP (t.arg1 = SCM_CDR (t.arg1))
2248 && SCM_CONSP (t.arg1))
2249 {
2250 SCM_SETCDR (tl, scm_cons (SCM_CAR (t.arg1),
2251 SCM_UNSPECIFIED));
2252 tl = SCM_CDR (tl);
2253 }
2254 SCM_SETCDR (tl, t.arg1);
2255 }
2256
2257 env = EXTEND_ENV (SCM_CLOSURE_FORMALS (proc), argl, SCM_ENV (proc));
2258 x = SCM_CODE (proc);
2259 goto nontoplevel_cdrxbegin;
2260 }
2261 proc = scm_f_apply;
2262 goto evapply;
2263
2264 case (SCM_ISYMNUM (SCM_IM_CONT)):
2265 {
2266 int first;
2267 SCM val = scm_make_continuation (&first);
2268
2269 if (first)
2270 t.arg1 = val;
2271 else
2272 RETURN (val);
2273 }
2274 proc = SCM_CDR (x);
2275 proc = evalcar (proc, env);
2276 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2277 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
2278 ENTER_APPLY;
2279 if (SCM_CLOSUREP(proc) && scm_badformalsp (proc, 1))
2280 goto umwrongnumargs;
2281 goto evap1;
2282
2283 case (SCM_ISYMNUM (SCM_IM_DELAY)):
2284 RETURN (scm_makprom (scm_closure (SCM_CDR (x), env)))
2285
2286 case (SCM_ISYMNUM (SCM_IM_DISPATCH)):
2287 proc = SCM_CADR (x); /* unevaluated operands */
2288 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2289 if (SCM_IMP (proc))
2290 arg2 = *scm_ilookup (proc, env);
2291 else if (SCM_NCONSP (proc))
2292 {
2293 if (SCM_NCELLP (proc))
2294 arg2 = SCM_GLOC_VAL (proc);
2295 else
2296 arg2 = *scm_lookupcar (SCM_CDR (x), env, 1);
2297 }
2298 else
2299 {
2300 arg2 = scm_cons (EVALCAR (proc, env), SCM_EOL);
2301 t.lloc = SCM_CDRLOC (arg2);
2302 while (SCM_NIMP (proc = SCM_CDR (proc)))
2303 {
2304 *t.lloc = scm_cons (EVALCAR (proc, env), SCM_EOL);
2305 t.lloc = SCM_CDRLOC (*t.lloc);
2306 }
2307 }
2308
2309 type_dispatch:
2310 /* The type dispatch code is duplicated here
2311 * (c.f. objects.c:scm_mcache_compute_cmethod) since that
2312 * cuts down execution time for type dispatch to 50%.
2313 */
2314 {
2315 long i, n, end, mask;
2316 SCM z = SCM_CDDR (x);
2317 n = SCM_INUM (SCM_CAR (z)); /* maximum number of specializers */
2318 proc = SCM_CADR (z);
2319
2320 if (SCM_NIMP (proc))
2321 {
2322 /* Prepare for linear search */
2323 mask = -1;
2324 i = 0;
2325 end = SCM_VECTOR_LENGTH (proc);
2326 }
2327 else
2328 {
2329 /* Compute a hash value */
2330 long hashset = SCM_INUM (proc);
2331 long j = n;
2332 z = SCM_CDDR (z);
2333 mask = SCM_INUM (SCM_CAR (z));
2334 proc = SCM_CADR (z);
2335 i = 0;
2336 t.arg1 = arg2;
2337 if (SCM_NIMP (t.arg1))
2338 do
2339 {
2340 i += SCM_STRUCT_DATA (scm_class_of (SCM_CAR (t.arg1)))
2341 [scm_si_hashsets + hashset];
2342 t.arg1 = SCM_CDR (t.arg1);
2343 }
2344 while (j-- && SCM_NIMP (t.arg1));
2345 i &= mask;
2346 end = i;
2347 }
2348
2349 /* Search for match */
2350 do
2351 {
2352 long j = n;
2353 z = SCM_VELTS (proc)[i];
2354 t.arg1 = arg2; /* list of arguments */
2355 if (SCM_NIMP (t.arg1))
2356 do
2357 {
2358 /* More arguments than specifiers => CLASS != ENV */
2359 if (! SCM_EQ_P (scm_class_of (SCM_CAR (t.arg1)), SCM_CAR (z)))
2360 goto next_method;
2361 t.arg1 = SCM_CDR (t.arg1);
2362 z = SCM_CDR (z);
2363 }
2364 while (j-- && SCM_NIMP (t.arg1));
2365 /* Fewer arguments than specifiers => CAR != ENV */
2366 if (!(SCM_IMP (SCM_CAR (z)) || SCM_CONSP (SCM_CAR (z))))
2367 goto next_method;
2368 apply_cmethod:
2369 env = EXTEND_ENV (SCM_CAR (SCM_CMETHOD_CODE (z)),
2370 arg2,
2371 SCM_CMETHOD_ENV (z));
2372 x = SCM_CMETHOD_CODE (z);
2373 goto nontoplevel_cdrxbegin;
2374 next_method:
2375 i = (i + 1) & mask;
2376 } while (i != end);
2377
2378 z = scm_memoize_method (x, arg2);
2379 goto apply_cmethod;
2380 }
2381
2382 case (SCM_ISYMNUM (SCM_IM_SLOT_REF)):
2383 x = SCM_CDR (x);
2384 t.arg1 = EVALCAR (x, env);
2385 RETURN (SCM_PACK (SCM_STRUCT_DATA (t.arg1) [SCM_INUM (SCM_CADR (x))]))
2386
2387 case (SCM_ISYMNUM (SCM_IM_SLOT_SET_X)):
2388 x = SCM_CDR (x);
2389 t.arg1 = EVALCAR (x, env);
2390 x = SCM_CDR (x);
2391 proc = SCM_CDR (x);
2392 SCM_STRUCT_DATA (t.arg1) [SCM_INUM (SCM_CAR (x))]
2393 = SCM_UNPACK (EVALCAR (proc, env));
2394 RETURN (SCM_UNSPECIFIED)
2395
2396 case (SCM_ISYMNUM (SCM_IM_NIL_COND)):
2397 proc = SCM_CDR (x);
2398 while (SCM_NIMP (x = SCM_CDR (proc)))
2399 {
2400 if (!(SCM_FALSEP (t.arg1 = EVALCAR (proc, env))
2401 || SCM_EQ_P (t.arg1, scm_lisp_nil)))
2402 {
2403 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
2404 RETURN (t.arg1);
2405 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2406 goto carloop;
2407 }
2408 proc = SCM_CDR (x);
2409 }
2410 x = proc;
2411 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2412 goto carloop;
2413
2414 case (SCM_ISYMNUM (SCM_IM_NIL_IFY)):
2415 x = SCM_CDR (x);
2416 RETURN ((SCM_FALSEP (proc = EVALCAR (x, env)) || SCM_NULLP (proc))
2417 ? scm_lisp_nil
2418 : proc)
2419
2420 case (SCM_ISYMNUM (SCM_IM_T_IFY)):
2421 x = SCM_CDR (x);
2422 RETURN (SCM_NFALSEP (EVALCAR (x, env)) ? scm_lisp_t : scm_lisp_nil)
2423
2424 case (SCM_ISYMNUM (SCM_IM_0_COND)):
2425 proc = SCM_CDR (x);
2426 while (SCM_NIMP (x = SCM_CDR (proc)))
2427 {
2428 if (!(SCM_FALSEP (t.arg1 = EVALCAR (proc, env))
2429 || SCM_EQ_P (t.arg1, SCM_INUM0)))
2430 {
2431 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
2432 RETURN (t.arg1);
2433 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2434 goto carloop;
2435 }
2436 proc = SCM_CDR (x);
2437 }
2438 x = proc;
2439 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2440 goto carloop;
2441
2442 case (SCM_ISYMNUM (SCM_IM_0_IFY)):
2443 x = SCM_CDR (x);
2444 RETURN (SCM_FALSEP (proc = EVALCAR (x, env))
2445 ? SCM_INUM0
2446 : proc)
2447
2448 case (SCM_ISYMNUM (SCM_IM_1_IFY)):
2449 x = SCM_CDR (x);
2450 RETURN (SCM_NFALSEP (EVALCAR (x, env))
2451 ? SCM_MAKINUM (1)
2452 : SCM_INUM0)
2453
2454 case (SCM_ISYMNUM (SCM_IM_BIND)):
2455 x = SCM_CDR (x);
2456
2457 t.arg1 = SCM_CAR (x);
2458 arg2 = SCM_CDAR (env);
2459 while (SCM_NIMP (arg2))
2460 {
2461 proc = SCM_GLOC_VAL (SCM_CAR (t.arg1));
2462 SCM_SETCDR (SCM_PACK (SCM_UNPACK (SCM_CAR (t.arg1)) - 1L),
2463 SCM_CAR (arg2));
2464 SCM_SETCAR (arg2, proc);
2465 t.arg1 = SCM_CDR (t.arg1);
2466 arg2 = SCM_CDR (arg2);
2467 }
2468 t.arg1 = SCM_CAR (x);
2469 scm_dynwinds = scm_acons (t.arg1, SCM_CDAR (env), scm_dynwinds);
2470
2471 arg2 = x = SCM_CDR (x);
2472 while (SCM_NNULLP (arg2 = SCM_CDR (arg2)))
2473 {
2474 SIDEVAL (SCM_CAR (x), env);
2475 x = arg2;
2476 }
2477 proc = EVALCAR (x, env);
2478
2479 scm_dynwinds = SCM_CDR (scm_dynwinds);
2480 arg2 = SCM_CDAR (env);
2481 while (SCM_NIMP (arg2))
2482 {
2483 SCM_SETCDR (SCM_PACK (SCM_UNPACK (SCM_CAR (t.arg1)) - 1L),
2484 SCM_CAR (arg2));
2485 t.arg1 = SCM_CDR (t.arg1);
2486 arg2 = SCM_CDR (arg2);
2487 }
2488
2489 RETURN (proc);
2490
2491 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
2492 {
2493 proc = SCM_CDR (x);
2494 x = EVALCAR (proc, env);
2495 proc = SCM_CDR (proc);
2496 proc = EVALCAR (proc, env);
2497 t.arg1 = SCM_APPLY (x, SCM_EOL, SCM_EOL);
2498 if (SCM_VALUESP (t.arg1))
2499 t.arg1 = scm_struct_ref (t.arg1, SCM_INUM0);
2500 else
2501 t.arg1 = scm_cons (t.arg1, SCM_EOL);
2502 if (SCM_CLOSUREP (proc))
2503 {
2504 PREP_APPLY (proc, t.arg1);
2505 goto apply_closure;
2506 }
2507 return SCM_APPLY (proc, t.arg1, SCM_EOL);
2508 }
2509
2510 default:
2511 goto badfun;
2512 }
2513
2514 default:
2515 proc = x;
2516 badfun:
2517 /* scm_everr (x, env,...) */
2518 scm_misc_error (NULL, "Wrong type to apply: ~S", SCM_LIST1 (proc));
2519 case scm_tc7_vector:
2520 case scm_tc7_wvect:
2521 #ifdef HAVE_ARRAYS
2522 case scm_tc7_bvect:
2523 case scm_tc7_byvect:
2524 case scm_tc7_svect:
2525 case scm_tc7_ivect:
2526 case scm_tc7_uvect:
2527 case scm_tc7_fvect:
2528 case scm_tc7_dvect:
2529 case scm_tc7_cvect:
2530 #ifdef HAVE_LONG_LONGS
2531 case scm_tc7_llvect:
2532 #endif
2533 #endif
2534 case scm_tc7_string:
2535 case scm_tc7_substring:
2536 case scm_tc7_smob:
2537 case scm_tcs_closures:
2538 case scm_tc7_cclo:
2539 case scm_tc7_pws:
2540 case scm_tcs_subrs:
2541 RETURN (x);
2542
2543 #ifdef MEMOIZE_LOCALS
2544 case SCM_BIT8(SCM_ILOC00):
2545 proc = *scm_ilookup (SCM_CAR (x), env);
2546 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2547 #ifndef SCM_RECKLESS
2548 #ifdef SCM_CAUTIOUS
2549 goto checkargs;
2550 #endif
2551 #endif
2552 break;
2553 #endif /* ifdef MEMOIZE_LOCALS */
2554
2555
2556 case scm_tcs_cons_gloc: {
2557 scm_t_bits vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2558 if (vcell == 0) {
2559 /* This is a struct implanted in the code, not a gloc. */
2560 RETURN (x);
2561 } else {
2562 proc = SCM_GLOC_VAL (SCM_CAR (x));
2563 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2564 #ifndef SCM_RECKLESS
2565 #ifdef SCM_CAUTIOUS
2566 goto checkargs;
2567 #endif
2568 #endif
2569 }
2570 break;
2571 }
2572
2573 case scm_tcs_cons_nimcar:
2574 orig_sym = SCM_CAR (x);
2575 if (SCM_SYMBOLP (orig_sym))
2576 {
2577 #ifdef USE_THREADS
2578 t.lloc = scm_lookupcar1 (x, env, 1);
2579 if (t.lloc == NULL)
2580 {
2581 /* we have lost the race, start again. */
2582 goto dispatch;
2583 }
2584 proc = *t.lloc;
2585 #else
2586 proc = *scm_lookupcar (x, env, 1);
2587 #endif
2588
2589 if (SCM_IMP (proc))
2590 {
2591 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of
2592 lookupcar */
2593 goto badfun;
2594 }
2595 if (SCM_MACROP (proc))
2596 {
2597 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of
2598 lookupcar */
2599 handle_a_macro:
2600 #ifdef DEVAL
2601 /* Set a flag during macro expansion so that macro
2602 application frames can be deleted from the backtrace. */
2603 SCM_SET_MACROEXP (debug);
2604 #endif
2605 t.arg1 = SCM_APPLY (SCM_MACRO_CODE (proc), x,
2606 scm_cons (env, scm_listofnull));
2607
2608 #ifdef DEVAL
2609 SCM_CLEAR_MACROEXP (debug);
2610 #endif
2611 switch (SCM_MACRO_TYPE (proc))
2612 {
2613 case 2:
2614 if (scm_ilength (t.arg1) <= 0)
2615 t.arg1 = scm_cons2 (SCM_IM_BEGIN, t.arg1, SCM_EOL);
2616 #ifdef DEVAL
2617 if (!SCM_CLOSUREP (SCM_MACRO_CODE (proc)))
2618 {
2619 SCM_DEFER_INTS;
2620 SCM_SETCAR (x, SCM_CAR (t.arg1));
2621 SCM_SETCDR (x, SCM_CDR (t.arg1));
2622 SCM_ALLOW_INTS;
2623 goto dispatch;
2624 }
2625 /* Prevent memoizing of debug info expression. */
2626 debug.info->e.exp = scm_cons_source (debug.info->e.exp,
2627 SCM_CAR (x),
2628 SCM_CDR (x));
2629 #endif
2630 SCM_DEFER_INTS;
2631 SCM_SETCAR (x, SCM_CAR (t.arg1));
2632 SCM_SETCDR (x, SCM_CDR (t.arg1));
2633 SCM_ALLOW_INTS;
2634 goto loopnoap;
2635 case 1:
2636 if (SCM_NIMP (x = t.arg1))
2637 goto loopnoap;
2638 case 0:
2639 RETURN (t.arg1);
2640 }
2641 }
2642 }
2643 else
2644 proc = SCM_CEVAL (SCM_CAR (x), env);
2645 SCM_ASRTGO (!SCM_IMP (proc), badfun);
2646 #ifndef SCM_RECKLESS
2647 #ifdef SCM_CAUTIOUS
2648 checkargs:
2649 #endif
2650 if (SCM_CLOSUREP (proc))
2651 {
2652 arg2 = SCM_CLOSURE_FORMALS (proc);
2653 t.arg1 = SCM_CDR (x);
2654 while (!SCM_NULLP (arg2))
2655 {
2656 if (!SCM_CONSP (arg2))
2657 goto evapply;
2658 if (SCM_IMP (t.arg1))
2659 goto umwrongnumargs;
2660 arg2 = SCM_CDR (arg2);
2661 t.arg1 = SCM_CDR (t.arg1);
2662 }
2663 if (!SCM_NULLP (t.arg1))
2664 goto umwrongnumargs;
2665 }
2666 else if (SCM_MACROP (proc))
2667 goto handle_a_macro;
2668 #endif
2669 }
2670
2671
2672 evapply:
2673 PREP_APPLY (proc, SCM_EOL);
2674 if (SCM_NULLP (SCM_CDR (x))) {
2675 ENTER_APPLY;
2676 evap0:
2677 switch (SCM_TYP7 (proc))
2678 { /* no arguments given */
2679 case scm_tc7_subr_0:
2680 RETURN (SCM_SUBRF (proc) ());
2681 case scm_tc7_subr_1o:
2682 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
2683 case scm_tc7_lsubr:
2684 RETURN (SCM_SUBRF (proc) (SCM_EOL));
2685 case scm_tc7_rpsubr:
2686 RETURN (SCM_BOOL_T);
2687 case scm_tc7_asubr:
2688 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
2689 case scm_tc7_smob:
2690 if (!SCM_SMOB_APPLICABLE_P (proc))
2691 goto badfun;
2692 RETURN (SCM_SMOB_APPLY_0 (proc));
2693 case scm_tc7_cclo:
2694 t.arg1 = proc;
2695 proc = SCM_CCLO_SUBR (proc);
2696 #ifdef DEVAL
2697 debug.info->a.proc = proc;
2698 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2699 #endif
2700 goto evap1;
2701 case scm_tc7_pws:
2702 proc = SCM_PROCEDURE (proc);
2703 #ifdef DEVAL
2704 debug.info->a.proc = proc;
2705 #endif
2706 if (!SCM_CLOSUREP (proc))
2707 goto evap0;
2708 if (scm_badformalsp (proc, 0))
2709 goto umwrongnumargs;
2710 case scm_tcs_closures:
2711 x = SCM_CODE (proc);
2712 env = EXTEND_ENV (SCM_CLOSURE_FORMALS (proc), SCM_EOL, SCM_ENV (proc));
2713 goto nontoplevel_cdrxbegin;
2714 case scm_tcs_cons_gloc: /* really structs, not glocs */
2715 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2716 {
2717 x = SCM_ENTITY_PROCEDURE (proc);
2718 arg2 = SCM_EOL;
2719 goto type_dispatch;
2720 }
2721 else if (!SCM_I_OPERATORP (proc))
2722 goto badfun;
2723 else
2724 {
2725 t.arg1 = proc;
2726 proc = (SCM_I_ENTITYP (proc)
2727 ? SCM_ENTITY_PROCEDURE (proc)
2728 : SCM_OPERATOR_PROCEDURE (proc));
2729 #ifdef DEVAL
2730 debug.info->a.proc = proc;
2731 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2732 #endif
2733 if (SCM_NIMP (proc))
2734 goto evap1;
2735 else
2736 goto badfun;
2737 }
2738 case scm_tc7_subr_1:
2739 case scm_tc7_subr_2:
2740 case scm_tc7_subr_2o:
2741 case scm_tc7_cxr:
2742 case scm_tc7_subr_3:
2743 case scm_tc7_lsubr_2:
2744 umwrongnumargs:
2745 unmemocar (x, env);
2746 wrongnumargs:
2747 /* scm_everr (x, env,...) */
2748 scm_wrong_num_args (proc);
2749 default:
2750 /* handle macros here */
2751 goto badfun;
2752 }
2753 }
2754
2755 /* must handle macros by here */
2756 x = SCM_CDR (x);
2757 #ifdef SCM_CAUTIOUS
2758 if (SCM_IMP (x))
2759 goto wrongnumargs;
2760 else if (SCM_CONSP (x))
2761 {
2762 if (SCM_IMP (SCM_CAR (x)))
2763 t.arg1 = SCM_EVALIM (SCM_CAR (x), env);
2764 else
2765 t.arg1 = EVALCELLCAR (x, env);
2766 }
2767 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
2768 {
2769 scm_t_bits vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2770 if (vcell == 0)
2771 t.arg1 = SCM_CAR (x); /* struct planted in code */
2772 else
2773 t.arg1 = SCM_GLOC_VAL (SCM_CAR (x));
2774 }
2775 else
2776 goto wrongnumargs;
2777 #else
2778 t.arg1 = EVALCAR (x, env);
2779 #endif
2780 #ifdef DEVAL
2781 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2782 #endif
2783 x = SCM_CDR (x);
2784 if (SCM_NULLP (x))
2785 {
2786 ENTER_APPLY;
2787 evap1:
2788 switch (SCM_TYP7 (proc))
2789 { /* have one argument in t.arg1 */
2790 case scm_tc7_subr_2o:
2791 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2792 case scm_tc7_subr_1:
2793 case scm_tc7_subr_1o:
2794 RETURN (SCM_SUBRF (proc) (t.arg1));
2795 case scm_tc7_cxr:
2796 if (SCM_SUBRF (proc))
2797 {
2798 if (SCM_INUMP (t.arg1))
2799 {
2800 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (t.arg1))));
2801 }
2802 SCM_ASRTGO (SCM_NIMP (t.arg1), floerr);
2803 if (SCM_REALP (t.arg1))
2804 {
2805 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (t.arg1))));
2806 }
2807 #ifdef SCM_BIGDIG
2808 if (SCM_BIGP (t.arg1))
2809 {
2810 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (t.arg1))));
2811 }
2812 #endif
2813 floerr:
2814 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), t.arg1,
2815 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
2816 }
2817 proc = SCM_SNAME (proc);
2818 {
2819 char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
2820 while ('c' != *--chrs)
2821 {
2822 SCM_ASSERT (SCM_CONSP (t.arg1),
2823 t.arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
2824 t.arg1 = ('a' == *chrs) ? SCM_CAR (t.arg1) : SCM_CDR (t.arg1);
2825 }
2826 RETURN (t.arg1);
2827 }
2828 case scm_tc7_rpsubr:
2829 RETURN (SCM_BOOL_T);
2830 case scm_tc7_asubr:
2831 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2832 case scm_tc7_lsubr:
2833 #ifdef DEVAL
2834 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2835 #else
2836 RETURN (SCM_SUBRF (proc) (scm_cons (t.arg1, SCM_EOL)));
2837 #endif
2838 case scm_tc7_smob:
2839 if (!SCM_SMOB_APPLICABLE_P (proc))
2840 goto badfun;
2841 RETURN (SCM_SMOB_APPLY_1 (proc, t.arg1));
2842 case scm_tc7_cclo:
2843 arg2 = t.arg1;
2844 t.arg1 = proc;
2845 proc = SCM_CCLO_SUBR (proc);
2846 #ifdef DEVAL
2847 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2848 debug.info->a.proc = proc;
2849 #endif
2850 goto evap2;
2851 case scm_tc7_pws:
2852 proc = SCM_PROCEDURE (proc);
2853 #ifdef DEVAL
2854 debug.info->a.proc = proc;
2855 #endif
2856 if (!SCM_CLOSUREP (proc))
2857 goto evap1;
2858 if (scm_badformalsp (proc, 1))
2859 goto umwrongnumargs;
2860 case scm_tcs_closures:
2861 /* clos1: */
2862 x = SCM_CODE (proc);
2863 #ifdef DEVAL
2864 env = EXTEND_ENV (SCM_CLOSURE_FORMALS (proc), debug.info->a.args, SCM_ENV (proc));
2865 #else
2866 env = EXTEND_ENV (SCM_CLOSURE_FORMALS (proc), scm_cons (t.arg1, SCM_EOL), SCM_ENV (proc));
2867 #endif
2868 goto nontoplevel_cdrxbegin;
2869 case scm_tcs_cons_gloc: /* really structs, not glocs */
2870 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2871 {
2872 x = SCM_ENTITY_PROCEDURE (proc);
2873 #ifdef DEVAL
2874 arg2 = debug.info->a.args;
2875 #else
2876 arg2 = scm_cons (t.arg1, SCM_EOL);
2877 #endif
2878 goto type_dispatch;
2879 }
2880 else if (!SCM_I_OPERATORP (proc))
2881 goto badfun;
2882 else
2883 {
2884 arg2 = t.arg1;
2885 t.arg1 = proc;
2886 proc = (SCM_I_ENTITYP (proc)
2887 ? SCM_ENTITY_PROCEDURE (proc)
2888 : SCM_OPERATOR_PROCEDURE (proc));
2889 #ifdef DEVAL
2890 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2891 debug.info->a.proc = proc;
2892 #endif
2893 if (SCM_NIMP (proc))
2894 goto evap2;
2895 else
2896 goto badfun;
2897 }
2898 case scm_tc7_subr_2:
2899 case scm_tc7_subr_0:
2900 case scm_tc7_subr_3:
2901 case scm_tc7_lsubr_2:
2902 goto wrongnumargs;
2903 default:
2904 goto badfun;
2905 }
2906 }
2907 #ifdef SCM_CAUTIOUS
2908 if (SCM_IMP (x))
2909 goto wrongnumargs;
2910 else if (SCM_CONSP (x))
2911 {
2912 if (SCM_IMP (SCM_CAR (x)))
2913 arg2 = SCM_EVALIM (SCM_CAR (x), env);
2914 else
2915 arg2 = EVALCELLCAR (x, env);
2916 }
2917 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
2918 {
2919 scm_t_bits vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2920 if (vcell == 0)
2921 arg2 = SCM_CAR (x); /* struct planted in code */
2922 else
2923 arg2 = SCM_GLOC_VAL (SCM_CAR (x));
2924 }
2925 else
2926 goto wrongnumargs;
2927 #else
2928 arg2 = EVALCAR (x, env);
2929 #endif
2930 { /* have two or more arguments */
2931 #ifdef DEVAL
2932 debug.info->a.args = scm_cons2 (t.arg1, arg2, SCM_EOL);
2933 #endif
2934 x = SCM_CDR (x);
2935 if (SCM_NULLP (x)) {
2936 ENTER_APPLY;
2937 evap2:
2938 switch (SCM_TYP7 (proc))
2939 { /* have two arguments */
2940 case scm_tc7_subr_2:
2941 case scm_tc7_subr_2o:
2942 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2943 case scm_tc7_lsubr:
2944 #ifdef DEVAL
2945 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2946 #else
2947 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, SCM_EOL)));
2948 #endif
2949 case scm_tc7_lsubr_2:
2950 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_EOL));
2951 case scm_tc7_rpsubr:
2952 case scm_tc7_asubr:
2953 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2954 case scm_tc7_smob:
2955 if (!SCM_SMOB_APPLICABLE_P (proc))
2956 goto badfun;
2957 RETURN (SCM_SMOB_APPLY_2 (proc, t.arg1, arg2));
2958 cclon:
2959 case scm_tc7_cclo:
2960 #ifdef DEVAL
2961 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2962 scm_cons (proc, debug.info->a.args),
2963 SCM_EOL));
2964 #else
2965 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2966 scm_cons2 (proc, t.arg1,
2967 scm_cons (arg2,
2968 scm_eval_args (x,
2969 env,
2970 proc))),
2971 SCM_EOL));
2972 #endif
2973 case scm_tcs_cons_gloc: /* really structs, not glocs */
2974 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2975 {
2976 x = SCM_ENTITY_PROCEDURE (proc);
2977 #ifdef DEVAL
2978 arg2 = debug.info->a.args;
2979 #else
2980 arg2 = scm_cons2 (t.arg1, arg2, SCM_EOL);
2981 #endif
2982 goto type_dispatch;
2983 }
2984 else if (!SCM_I_OPERATORP (proc))
2985 goto badfun;
2986 else
2987 {
2988 operatorn:
2989 #ifdef DEVAL
2990 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2991 ? SCM_ENTITY_PROCEDURE (proc)
2992 : SCM_OPERATOR_PROCEDURE (proc),
2993 scm_cons (proc, debug.info->a.args),
2994 SCM_EOL));
2995 #else
2996 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2997 ? SCM_ENTITY_PROCEDURE (proc)
2998 : SCM_OPERATOR_PROCEDURE (proc),
2999 scm_cons2 (proc, t.arg1,
3000 scm_cons (arg2,
3001 scm_eval_args (x,
3002 env,
3003 proc))),
3004 SCM_EOL));
3005 #endif
3006 }
3007 case scm_tc7_subr_0:
3008 case scm_tc7_cxr:
3009 case scm_tc7_subr_1o:
3010 case scm_tc7_subr_1:
3011 case scm_tc7_subr_3:
3012 goto wrongnumargs;
3013 default:
3014 goto badfun;
3015 case scm_tc7_pws:
3016 proc = SCM_PROCEDURE (proc);
3017 #ifdef DEVAL
3018 debug.info->a.proc = proc;
3019 #endif
3020 if (!SCM_CLOSUREP (proc))
3021 goto evap2;
3022 if (scm_badformalsp (proc, 2))
3023 goto umwrongnumargs;
3024 case scm_tcs_closures:
3025 /* clos2: */
3026 #ifdef DEVAL
3027 env = EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3028 debug.info->a.args,
3029 SCM_ENV (proc));
3030 #else
3031 env = EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3032 scm_cons2 (t.arg1, arg2, SCM_EOL), SCM_ENV (proc));
3033 #endif
3034 x = SCM_CODE (proc);
3035 goto nontoplevel_cdrxbegin;
3036 }
3037 }
3038 #ifdef SCM_CAUTIOUS
3039 if (SCM_IMP (x) || SCM_NECONSP (x))
3040 goto wrongnumargs;
3041 #endif
3042 #ifdef DEVAL
3043 debug.info->a.args = scm_cons2 (t.arg1, arg2,
3044 scm_deval_args (x, env, proc,
3045 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
3046 #endif
3047 ENTER_APPLY;
3048 evap3:
3049 switch (SCM_TYP7 (proc))
3050 { /* have 3 or more arguments */
3051 #ifdef DEVAL
3052 case scm_tc7_subr_3:
3053 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
3054 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
3055 SCM_CADDR (debug.info->a.args)));
3056 case scm_tc7_asubr:
3057 #ifdef BUILTIN_RPASUBR
3058 t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
3059 arg2 = SCM_CDR (SCM_CDR (debug.info->a.args));
3060 do
3061 {
3062 t.arg1 = SCM_SUBRF(proc)(t.arg1, SCM_CAR (arg2));
3063 arg2 = SCM_CDR (arg2);
3064 }
3065 while (SCM_NIMP (arg2));
3066 RETURN (t.arg1)
3067 #endif /* BUILTIN_RPASUBR */
3068 case scm_tc7_rpsubr:
3069 #ifdef BUILTIN_RPASUBR
3070 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
3071 RETURN (SCM_BOOL_F)
3072 t.arg1 = SCM_CDR (SCM_CDR (debug.info->a.args));
3073 do
3074 {
3075 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, SCM_CAR (t.arg1))))
3076 RETURN (SCM_BOOL_F)
3077 arg2 = SCM_CAR (t.arg1);
3078 t.arg1 = SCM_CDR (t.arg1);
3079 }
3080 while (SCM_NIMP (t.arg1));
3081 RETURN (SCM_BOOL_T)
3082 #else /* BUILTIN_RPASUBR */
3083 RETURN (SCM_APPLY (proc, t.arg1,
3084 scm_acons (arg2,
3085 SCM_CDR (SCM_CDR (debug.info->a.args)),
3086 SCM_EOL)))
3087 #endif /* BUILTIN_RPASUBR */
3088 case scm_tc7_lsubr_2:
3089 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
3090 SCM_CDR (SCM_CDR (debug.info->a.args))))
3091 case scm_tc7_lsubr:
3092 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
3093 case scm_tc7_smob:
3094 if (!SCM_SMOB_APPLICABLE_P (proc))
3095 goto badfun;
3096 RETURN (SCM_SMOB_APPLY_3 (proc, t.arg1, arg2,
3097 SCM_CDDR (debug.info->a.args)));
3098 case scm_tc7_cclo:
3099 goto cclon;
3100 case scm_tc7_pws:
3101 proc = SCM_PROCEDURE (proc);
3102 debug.info->a.proc = proc;
3103 if (!SCM_CLOSUREP (proc))
3104 goto evap3;
3105 if (scm_badargsp (SCM_CLOSURE_FORMALS (proc), debug.info->a.args))
3106 goto umwrongnumargs;
3107 case scm_tcs_closures:
3108 SCM_SET_ARGSREADY (debug);
3109 env = EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3110 debug.info->a.args,
3111 SCM_ENV (proc));
3112 x = SCM_CODE (proc);
3113 goto nontoplevel_cdrxbegin;
3114 #else /* DEVAL */
3115 case scm_tc7_subr_3:
3116 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
3117 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, EVALCAR (x, env)));
3118 case scm_tc7_asubr:
3119 #ifdef BUILTIN_RPASUBR
3120 t.arg1 = SCM_SUBRF (proc) (t.arg1, arg2);
3121 do
3122 {
3123 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
3124 x = SCM_CDR(x);
3125 }
3126 while (SCM_NIMP (x));
3127 RETURN (t.arg1)
3128 #endif /* BUILTIN_RPASUBR */
3129 case scm_tc7_rpsubr:
3130 #ifdef BUILTIN_RPASUBR
3131 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
3132 RETURN (SCM_BOOL_F)
3133 do
3134 {
3135 t.arg1 = EVALCAR (x, env);
3136 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, t.arg1)))
3137 RETURN (SCM_BOOL_F)
3138 arg2 = t.arg1;
3139 x = SCM_CDR (x);
3140 }
3141 while (SCM_NIMP (x));
3142 RETURN (SCM_BOOL_T)
3143 #else /* BUILTIN_RPASUBR */
3144 RETURN (SCM_APPLY (proc, t.arg1,
3145 scm_acons (arg2,
3146 scm_eval_args (x, env, proc),
3147 SCM_EOL)));
3148 #endif /* BUILTIN_RPASUBR */
3149 case scm_tc7_lsubr_2:
3150 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, scm_eval_args (x, env, proc)));
3151 case scm_tc7_lsubr:
3152 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1,
3153 arg2,
3154 scm_eval_args (x, env, proc))));
3155 case scm_tc7_smob:
3156 if (!SCM_SMOB_APPLICABLE_P (proc))
3157 goto badfun;
3158 RETURN (SCM_SMOB_APPLY_3 (proc, t.arg1, arg2,
3159 scm_eval_args (x, env, proc)));
3160 case scm_tc7_cclo:
3161 goto cclon;
3162 case scm_tc7_pws:
3163 proc = SCM_PROCEDURE (proc);
3164 if (!SCM_CLOSUREP (proc))
3165 goto evap3;
3166 {
3167 SCM formals = SCM_CLOSURE_FORMALS (proc);
3168 if (SCM_NULLP (formals)
3169 || (SCM_CONSP (formals)
3170 && (SCM_NULLP (SCM_CDR (formals))
3171 || (SCM_CONSP (SCM_CDR (formals))
3172 && scm_badargsp (SCM_CDDR (formals), x)))))
3173 goto umwrongnumargs;
3174 }
3175 case scm_tcs_closures:
3176 #ifdef DEVAL
3177 SCM_SET_ARGSREADY (debug);
3178 #endif
3179 env = EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3180 scm_cons2 (t.arg1,
3181 arg2,
3182 scm_eval_args (x, env, proc)),
3183 SCM_ENV (proc));
3184 x = SCM_CODE (proc);
3185 goto nontoplevel_cdrxbegin;
3186 #endif /* DEVAL */
3187 case scm_tcs_cons_gloc: /* really structs, not glocs */
3188 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3189 {
3190 #ifdef DEVAL
3191 arg2 = debug.info->a.args;
3192 #else
3193 arg2 = scm_cons2 (t.arg1, arg2, scm_eval_args (x, env, proc));
3194 #endif
3195 x = SCM_ENTITY_PROCEDURE (proc);
3196 goto type_dispatch;
3197 }
3198 else if (!SCM_I_OPERATORP (proc))
3199 goto badfun;
3200 else
3201 goto operatorn;
3202 case scm_tc7_subr_2:
3203 case scm_tc7_subr_1o:
3204 case scm_tc7_subr_2o:
3205 case scm_tc7_subr_0:
3206 case scm_tc7_cxr:
3207 case scm_tc7_subr_1:
3208 goto wrongnumargs;
3209 default:
3210 goto badfun;
3211 }
3212 }
3213 #ifdef DEVAL
3214 exit:
3215 if (CHECK_EXIT && SCM_TRAPS_P)
3216 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
3217 {
3218 SCM_CLEAR_TRACED_FRAME (debug);
3219 if (SCM_CHEAPTRAPS_P)
3220 t.arg1 = scm_make_debugobj (&debug);
3221 else
3222 {
3223 int first;
3224 SCM val = scm_make_continuation (&first);
3225
3226 if (first)
3227 t.arg1 = val;
3228 else
3229 {
3230 proc = val;
3231 goto ret;
3232 }
3233 }
3234 scm_ithrow (scm_sym_exit_frame, scm_cons2 (t.arg1, proc, SCM_EOL), 0);
3235 }
3236 ret:
3237 scm_last_debug_frame = debug.prev;
3238 return proc;
3239 #endif
3240 }
3241
3242
3243 /* SECTION: This code is compiled once.
3244 */
3245
3246 #ifndef DEVAL
3247
3248 /* This code processes the arguments to apply:
3249
3250 (apply PROC ARG1 ... ARGS)
3251
3252 Given a list (ARG1 ... ARGS), this function conses the ARG1
3253 ... arguments onto the front of ARGS, and returns the resulting
3254 list. Note that ARGS is a list; thus, the argument to this
3255 function is a list whose last element is a list.
3256
3257 Apply calls this function, and applies PROC to the elements of the
3258 result. apply:nconc2last takes care of building the list of
3259 arguments, given (ARG1 ... ARGS).
3260
3261 Rather than do new consing, apply:nconc2last destroys its argument.
3262 On that topic, this code came into my care with the following
3263 beautifully cryptic comment on that topic: "This will only screw
3264 you if you do (scm_apply scm_apply '( ... ))" If you know what
3265 they're referring to, send me a patch to this comment. */
3266
3267 SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
3268 (SCM lst),
3269 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
3270 "conses the @var{arg1} @dots{} arguments onto the front of\n"
3271 "@var{args}, and returns the resulting list. Note that\n"
3272 "@var{args} is a list; thus, the argument to this function is\n"
3273 "a list whose last element is a list.\n"
3274 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
3275 "destroys its argument, so use with care.")
3276 #define FUNC_NAME s_scm_nconc2last
3277 {
3278 SCM *lloc;
3279 SCM_VALIDATE_NONEMPTYLIST (1,lst);
3280 lloc = &lst;
3281 while (SCM_NNULLP (SCM_CDR (*lloc)))
3282 lloc = SCM_CDRLOC (*lloc);
3283 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
3284 *lloc = SCM_CAR (*lloc);
3285 return lst;
3286 }
3287 #undef FUNC_NAME
3288
3289 #endif /* !DEVAL */
3290
3291
3292 /* SECTION: When DEVAL is defined this code yields scm_dapply.
3293 * It is compiled twice.
3294 */
3295
3296 #if 0
3297
3298 SCM
3299 scm_apply (SCM proc, SCM arg1, SCM args)
3300 {}
3301 #endif
3302
3303 #if 0
3304
3305 SCM
3306 scm_dapply (SCM proc, SCM arg1, SCM args)
3307 { /* empty */ }
3308 #endif
3309
3310
3311 /* Apply a function to a list of arguments.
3312
3313 This function is exported to the Scheme level as taking two
3314 required arguments and a tail argument, as if it were:
3315 (lambda (proc arg1 . args) ...)
3316 Thus, if you just have a list of arguments to pass to a procedure,
3317 pass the list as ARG1, and '() for ARGS. If you have some fixed
3318 args, pass the first as ARG1, then cons any remaining fixed args
3319 onto the front of your argument list, and pass that as ARGS. */
3320
3321 SCM
3322 SCM_APPLY (SCM proc, SCM arg1, SCM args)
3323 {
3324 #ifdef DEBUG_EXTENSIONS
3325 #ifdef DEVAL
3326 scm_t_debug_frame debug;
3327 scm_t_debug_info debug_vect_body;
3328 debug.prev = scm_last_debug_frame;
3329 debug.status = SCM_APPLYFRAME;
3330 debug.vect = &debug_vect_body;
3331 debug.vect[0].a.proc = proc;
3332 debug.vect[0].a.args = SCM_EOL;
3333 scm_last_debug_frame = &debug;
3334 #else
3335 if (SCM_DEBUGGINGP)
3336 return scm_dapply (proc, arg1, args);
3337 #endif
3338 #endif
3339
3340 SCM_ASRTGO (SCM_NIMP (proc), badproc);
3341
3342 /* If ARGS is the empty list, then we're calling apply with only two
3343 arguments --- ARG1 is the list of arguments for PROC. Whatever
3344 the case, futz with things so that ARG1 is the first argument to
3345 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
3346 rest.
3347
3348 Setting the debug apply frame args this way is pretty messy.
3349 Perhaps we should store arg1 and args directly in the frame as
3350 received, and let scm_frame_arguments unpack them, because that's
3351 a relatively rare operation. This works for now; if the Guile
3352 developer archives are still around, see Mikael's post of
3353 11-Apr-97. */
3354 if (SCM_NULLP (args))
3355 {
3356 if (SCM_NULLP (arg1))
3357 {
3358 arg1 = SCM_UNDEFINED;
3359 #ifdef DEVAL
3360 debug.vect[0].a.args = SCM_EOL;
3361 #endif
3362 }
3363 else
3364 {
3365 #ifdef DEVAL
3366 debug.vect[0].a.args = arg1;
3367 #endif
3368 args = SCM_CDR (arg1);
3369 arg1 = SCM_CAR (arg1);
3370 }
3371 }
3372 else
3373 {
3374 args = scm_nconc2last (args);
3375 #ifdef DEVAL
3376 debug.vect[0].a.args = scm_cons (arg1, args);
3377 #endif
3378 }
3379 #ifdef DEVAL
3380 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
3381 {
3382 SCM tmp;
3383 if (SCM_CHEAPTRAPS_P)
3384 tmp = scm_make_debugobj (&debug);
3385 else
3386 {
3387 int first;
3388
3389 tmp = scm_make_continuation (&first);
3390 if (!first)
3391 goto entap;
3392 }
3393 scm_ithrow (scm_sym_enter_frame, scm_cons (tmp, SCM_EOL), 0);
3394 }
3395 entap:
3396 ENTER_APPLY;
3397 #endif
3398 tail:
3399 switch (SCM_TYP7 (proc))
3400 {
3401 case scm_tc7_subr_2o:
3402 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
3403 RETURN (SCM_SUBRF (proc) (arg1, args))
3404 case scm_tc7_subr_2:
3405 SCM_ASRTGO (SCM_NNULLP (args) && SCM_NULLP (SCM_CDR (args)),
3406 wrongnumargs);
3407 args = SCM_CAR (args);
3408 RETURN (SCM_SUBRF (proc) (arg1, args))
3409 case scm_tc7_subr_0:
3410 SCM_ASRTGO (SCM_UNBNDP (arg1), wrongnumargs);
3411 RETURN (SCM_SUBRF (proc) ())
3412 case scm_tc7_subr_1:
3413 SCM_ASRTGO (!SCM_UNBNDP (arg1), wrongnumargs);
3414 case scm_tc7_subr_1o:
3415 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
3416 RETURN (SCM_SUBRF (proc) (arg1))
3417 case scm_tc7_cxr:
3418 SCM_ASRTGO (!SCM_UNBNDP (arg1) && SCM_NULLP (args), wrongnumargs);
3419 if (SCM_SUBRF (proc))
3420 {
3421 if (SCM_INUMP (arg1))
3422 {
3423 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
3424 }
3425 SCM_ASRTGO (SCM_NIMP (arg1), floerr);
3426 if (SCM_REALP (arg1))
3427 {
3428 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
3429 }
3430 #ifdef SCM_BIGDIG
3431 if (SCM_BIGP (arg1))
3432 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))))
3433 #endif
3434 floerr:
3435 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3436 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
3437 }
3438 proc = SCM_SNAME (proc);
3439 {
3440 char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
3441 while ('c' != *--chrs)
3442 {
3443 SCM_ASSERT (SCM_CONSP (arg1),
3444 arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
3445 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3446 }
3447 RETURN (arg1)
3448 }
3449 case scm_tc7_subr_3:
3450 SCM_ASRTGO (SCM_NNULLP (args)
3451 && SCM_NNULLP (SCM_CDR (args))
3452 && SCM_NULLP (SCM_CDDR (args)),
3453 wrongnumargs);
3454 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CAR (SCM_CDR (args))))
3455 case scm_tc7_lsubr:
3456 #ifdef DEVAL
3457 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args))
3458 #else
3459 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)))
3460 #endif
3461 case scm_tc7_lsubr_2:
3462 SCM_ASRTGO (SCM_CONSP (args), wrongnumargs);
3463 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)))
3464 case scm_tc7_asubr:
3465 if (SCM_NULLP (args))
3466 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED))
3467 while (SCM_NIMP (args))
3468 {
3469 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3470 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
3471 args = SCM_CDR (args);
3472 }
3473 RETURN (arg1);
3474 case scm_tc7_rpsubr:
3475 if (SCM_NULLP (args))
3476 RETURN (SCM_BOOL_T);
3477 while (SCM_NIMP (args))
3478 {
3479 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3480 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
3481 RETURN (SCM_BOOL_F);
3482 arg1 = SCM_CAR (args);
3483 args = SCM_CDR (args);
3484 }
3485 RETURN (SCM_BOOL_T);
3486 case scm_tcs_closures:
3487 #ifdef DEVAL
3488 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
3489 #else
3490 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
3491 #endif
3492 #ifndef SCM_RECKLESS
3493 if (scm_badargsp (SCM_CLOSURE_FORMALS (proc), arg1))
3494 goto wrongnumargs;
3495 #endif
3496
3497 /* Copy argument list */
3498 if (SCM_IMP (arg1))
3499 args = arg1;
3500 else
3501 {
3502 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
3503 while (arg1 = SCM_CDR (arg1), SCM_CONSP (arg1))
3504 {
3505 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1),
3506 SCM_UNSPECIFIED));
3507 tl = SCM_CDR (tl);
3508 }
3509 SCM_SETCDR (tl, arg1);
3510 }
3511
3512 args = EXTEND_ENV (SCM_CLOSURE_FORMALS (proc), args, SCM_ENV (proc));
3513 proc = SCM_CDR (SCM_CODE (proc));
3514 again:
3515 arg1 = proc;
3516 while (SCM_NNULLP (arg1 = SCM_CDR (arg1)))
3517 {
3518 if (SCM_IMP (SCM_CAR (proc)))
3519 {
3520 if (SCM_ISYMP (SCM_CAR (proc)))
3521 {
3522 proc = scm_m_expand_body (proc, args);
3523 goto again;
3524 }
3525 else
3526 SCM_VALIDATE_NON_EMPTY_COMBINATION (SCM_CAR (proc));
3527 }
3528 else
3529 SCM_CEVAL (SCM_CAR (proc), args);
3530 proc = arg1;
3531 }
3532 RETURN (EVALCAR (proc, args));
3533 case scm_tc7_smob:
3534 if (!SCM_SMOB_APPLICABLE_P (proc))
3535 goto badproc;
3536 if (SCM_UNBNDP (arg1))
3537 RETURN (SCM_SMOB_APPLY_0 (proc))
3538 else if (SCM_NULLP (args))
3539 RETURN (SCM_SMOB_APPLY_1 (proc, arg1))
3540 else if (SCM_NULLP (SCM_CDR (args)))
3541 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, SCM_CAR (args)))
3542 else
3543 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, SCM_CAR (args), SCM_CDR (args)));
3544 case scm_tc7_cclo:
3545 #ifdef DEVAL
3546 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3547 arg1 = proc;
3548 proc = SCM_CCLO_SUBR (proc);
3549 debug.vect[0].a.proc = proc;
3550 debug.vect[0].a.args = scm_cons (arg1, args);
3551 #else
3552 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3553 arg1 = proc;
3554 proc = SCM_CCLO_SUBR (proc);
3555 #endif
3556 goto tail;
3557 case scm_tc7_pws:
3558 proc = SCM_PROCEDURE (proc);
3559 #ifdef DEVAL
3560 debug.vect[0].a.proc = proc;
3561 #endif
3562 goto tail;
3563 case scm_tcs_cons_gloc: /* really structs, not glocs */
3564 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3565 {
3566 #ifdef DEVAL
3567 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3568 #else
3569 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3570 #endif
3571 RETURN (scm_apply_generic (proc, args));
3572 }
3573 else if (!SCM_I_OPERATORP (proc))
3574 goto badproc;
3575 else
3576 {
3577 #ifdef DEVAL
3578 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3579 #else
3580 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3581 #endif
3582 arg1 = proc;
3583 proc = (SCM_I_ENTITYP (proc)
3584 ? SCM_ENTITY_PROCEDURE (proc)
3585 : SCM_OPERATOR_PROCEDURE (proc));
3586 #ifdef DEVAL
3587 debug.vect[0].a.proc = proc;
3588 debug.vect[0].a.args = scm_cons (arg1, args);
3589 #endif
3590 if (SCM_NIMP (proc))
3591 goto tail;
3592 else
3593 goto badproc;
3594 }
3595 wrongnumargs:
3596 scm_wrong_num_args (proc);
3597 default:
3598 badproc:
3599 scm_wrong_type_arg ("apply", SCM_ARG1, proc);
3600 RETURN (arg1);
3601 }
3602 #ifdef DEVAL
3603 exit:
3604 if (CHECK_EXIT && SCM_TRAPS_P)
3605 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
3606 {
3607 SCM_CLEAR_TRACED_FRAME (debug);
3608 if (SCM_CHEAPTRAPS_P)
3609 arg1 = scm_make_debugobj (&debug);
3610 else
3611 {
3612 int first;
3613 SCM val = scm_make_continuation (&first);
3614
3615 if (first)
3616 arg1 = val;
3617 else
3618 {
3619 proc = val;
3620 goto ret;
3621 }
3622 }
3623 scm_ithrow (scm_sym_exit_frame, scm_cons2 (arg1, proc, SCM_EOL), 0);
3624 }
3625 ret:
3626 scm_last_debug_frame = debug.prev;
3627 return proc;
3628 #endif
3629 }
3630
3631
3632 /* SECTION: The rest of this file is only read once.
3633 */
3634
3635 #ifndef DEVAL
3636
3637 /* Typechecking for multi-argument MAP and FOR-EACH.
3638
3639 Verify that each element of the vector ARGV, except for the first,
3640 is a proper list whose length is LEN. Attribute errors to WHO,
3641 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
3642 static inline void
3643 check_map_args (SCM argv,
3644 long len,
3645 SCM gf,
3646 SCM proc,
3647 SCM args,
3648 const char *who)
3649 {
3650 SCM *ve = SCM_VELTS (argv);
3651 long i;
3652
3653 for (i = SCM_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
3654 {
3655 long elt_len = scm_ilength (ve[i]);
3656
3657 if (elt_len < 0)
3658 {
3659 if (gf)
3660 scm_apply_generic (gf, scm_cons (proc, args));
3661 else
3662 scm_wrong_type_arg (who, i + 2, ve[i]);
3663 }
3664
3665 if (elt_len != len)
3666 scm_out_of_range (who, ve[i]);
3667 }
3668
3669 scm_remember_upto_here_1 (argv);
3670 }
3671
3672
3673 SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
3674
3675 /* Note: Currently, scm_map applies PROC to the argument list(s)
3676 sequentially, starting with the first element(s). This is used in
3677 evalext.c where the Scheme procedure `map-in-order', which guarantees
3678 sequential behaviour, is implemented using scm_map. If the
3679 behaviour changes, we need to update `map-in-order'.
3680 */
3681
3682 SCM
3683 scm_map (SCM proc, SCM arg1, SCM args)
3684 #define FUNC_NAME s_map
3685 {
3686 long i, len;
3687 SCM res = SCM_EOL;
3688 SCM *pres = &res;
3689 SCM *ve = &args; /* Keep args from being optimized away. */
3690
3691 len = scm_ilength (arg1);
3692 SCM_GASSERTn (len >= 0,
3693 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
3694 SCM_VALIDATE_REST_ARGUMENT (args);
3695 if (SCM_NULLP (args))
3696 {
3697 while (SCM_NIMP (arg1))
3698 {
3699 *pres = scm_cons (scm_apply (proc, SCM_CAR (arg1), scm_listofnull),
3700 SCM_EOL);
3701 pres = SCM_CDRLOC (*pres);
3702 arg1 = SCM_CDR (arg1);
3703 }
3704 return res;
3705 }
3706 args = scm_vector (arg1 = scm_cons (arg1, args));
3707 ve = SCM_VELTS (args);
3708 #ifndef SCM_RECKLESS
3709 check_map_args (args, len, g_map, proc, arg1, s_map);
3710 #endif
3711 while (1)
3712 {
3713 arg1 = SCM_EOL;
3714 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
3715 {
3716 if (SCM_IMP (ve[i]))
3717 return res;
3718 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3719 ve[i] = SCM_CDR (ve[i]);
3720 }
3721 *pres = scm_cons (scm_apply (proc, arg1, SCM_EOL), SCM_EOL);
3722 pres = SCM_CDRLOC (*pres);
3723 }
3724 }
3725 #undef FUNC_NAME
3726
3727
3728 SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
3729
3730 SCM
3731 scm_for_each (SCM proc, SCM arg1, SCM args)
3732 #define FUNC_NAME s_for_each
3733 {
3734 SCM *ve = &args; /* Keep args from being optimized away. */
3735 long i, len;
3736 len = scm_ilength (arg1);
3737 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
3738 SCM_ARG2, s_for_each);
3739 SCM_VALIDATE_REST_ARGUMENT (args);
3740 if SCM_NULLP (args)
3741 {
3742 while SCM_NIMP (arg1)
3743 {
3744 scm_apply (proc, SCM_CAR (arg1), scm_listofnull);
3745 arg1 = SCM_CDR (arg1);
3746 }
3747 return SCM_UNSPECIFIED;
3748 }
3749 args = scm_vector (arg1 = scm_cons (arg1, args));
3750 ve = SCM_VELTS (args);
3751 #ifndef SCM_RECKLESS
3752 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
3753 #endif
3754 while (1)
3755 {
3756 arg1 = SCM_EOL;
3757 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
3758 {
3759 if SCM_IMP
3760 (ve[i]) return SCM_UNSPECIFIED;
3761 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3762 ve[i] = SCM_CDR (ve[i]);
3763 }
3764 scm_apply (proc, arg1, SCM_EOL);
3765 }
3766 }
3767 #undef FUNC_NAME
3768
3769
3770 SCM
3771 scm_closure (SCM code, SCM env)
3772 {
3773 register SCM z;
3774
3775 SCM_NEWCELL (z);
3776 SCM_SETCODE (z, code);
3777 SCM_SETENV (z, env);
3778 return z;
3779 }
3780
3781
3782 scm_t_bits scm_tc16_promise;
3783
3784 SCM
3785 scm_makprom (SCM code)
3786 {
3787 SCM_RETURN_NEWSMOB (scm_tc16_promise, SCM_UNPACK (code));
3788 }
3789
3790
3791
3792 static int
3793 promise_print (SCM exp, SCM port, scm_print_state *pstate)
3794 {
3795 int writingp = SCM_WRITINGP (pstate);
3796 scm_puts ("#<promise ", port);
3797 SCM_SET_WRITINGP (pstate, 1);
3798 scm_iprin1 (SCM_CELL_OBJECT_1 (exp), port, pstate);
3799 SCM_SET_WRITINGP (pstate, writingp);
3800 scm_putc ('>', port);
3801 return !0;
3802 }
3803
3804
3805 SCM_DEFINE (scm_force, "force", 1, 0, 0,
3806 (SCM x),
3807 "If the promise @var{x} has not been computed yet, compute and\n"
3808 "return @var{x}, otherwise just return the previously computed\n"
3809 "value.")
3810 #define FUNC_NAME s_scm_force
3811 {
3812 SCM_VALIDATE_SMOB (1, x, promise);
3813 if (!((1L << 16) & SCM_CELL_WORD_0 (x)))
3814 {
3815 SCM ans = scm_apply (SCM_CELL_OBJECT_1 (x), SCM_EOL, SCM_EOL);
3816 if (!((1L << 16) & SCM_CELL_WORD_0 (x)))
3817 {
3818 SCM_DEFER_INTS;
3819 SCM_SET_CELL_OBJECT_1 (x, ans);
3820 SCM_SET_CELL_WORD_0 (x, SCM_CELL_WORD_0 (x) | (1L << 16));
3821 SCM_ALLOW_INTS;
3822 }
3823 }
3824 return SCM_CELL_OBJECT_1 (x);
3825 }
3826 #undef FUNC_NAME
3827
3828
3829 SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
3830 (SCM obj),
3831 "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
3832 "(@pxref{Delayed evaluation,,,r5rs.info,The Revised^5 Report on Scheme}).")
3833 #define FUNC_NAME s_scm_promise_p
3834 {
3835 return SCM_BOOL (SCM_TYP16_PREDICATE (scm_tc16_promise, obj));
3836 }
3837 #undef FUNC_NAME
3838
3839
3840 SCM_DEFINE (scm_cons_source, "cons-source", 3, 0, 0,
3841 (SCM xorig, SCM x, SCM y),
3842 "Create and return a new pair whose car and cdr are @var{x} and @var{y}.\n"
3843 "Any source properties associated with @var{xorig} are also associated\n"
3844 "with the new pair.")
3845 #define FUNC_NAME s_scm_cons_source
3846 {
3847 SCM p, z;
3848 SCM_NEWCELL (z);
3849 SCM_SET_CELL_OBJECT_0 (z, x);
3850 SCM_SET_CELL_OBJECT_1 (z, y);
3851 /* Copy source properties possibly associated with xorig. */
3852 p = scm_whash_lookup (scm_source_whash, xorig);
3853 if (!SCM_IMP (p))
3854 scm_whash_insert (scm_source_whash, z, p);
3855 return z;
3856 }
3857 #undef FUNC_NAME
3858
3859
3860 SCM_DEFINE (scm_copy_tree, "copy-tree", 1, 0, 0,
3861 (SCM obj),
3862 "Recursively copy the data tree that is bound to @var{obj}, and return a\n"
3863 "pointer to the new data structure. @code{copy-tree} recurses down the\n"
3864 "contents of both pairs and vectors (since both cons cells and vector\n"
3865 "cells may point to arbitrary objects), and stops recursing when it hits\n"
3866 "any other object.")
3867 #define FUNC_NAME s_scm_copy_tree
3868 {
3869 SCM ans, tl;
3870 if (SCM_IMP (obj))
3871 return obj;
3872 if (SCM_VECTORP (obj))
3873 {
3874 unsigned long i = SCM_VECTOR_LENGTH (obj);
3875 ans = scm_c_make_vector (i, SCM_UNSPECIFIED);
3876 while (i--)
3877 SCM_VELTS (ans)[i] = scm_copy_tree (SCM_VELTS (obj)[i]);
3878 return ans;
3879 }
3880 if (SCM_NCONSP (obj))
3881 return obj;
3882 ans = tl = scm_cons_source (obj,
3883 scm_copy_tree (SCM_CAR (obj)),
3884 SCM_UNSPECIFIED);
3885 while (obj = SCM_CDR (obj), SCM_CONSP (obj))
3886 {
3887 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
3888 SCM_UNSPECIFIED));
3889 tl = SCM_CDR (tl);
3890 }
3891 SCM_SETCDR (tl, obj);
3892 return ans;
3893 }
3894 #undef FUNC_NAME
3895
3896
3897 /* We have three levels of EVAL here:
3898
3899 - scm_i_eval (exp, env)
3900
3901 evaluates EXP in environment ENV. ENV is a lexical environment
3902 structure as used by the actual tree code evaluator. When ENV is
3903 a top-level environment, then changes to the current module are
3904 tracked by updating ENV so that it continues to be in sync with
3905 the current module.
3906
3907 - scm_primitive_eval (exp)
3908
3909 evaluates EXP in the top-level environment as determined by the
3910 current module. This is done by constructing a suitable
3911 environment and calling scm_i_eval. Thus, changes to the
3912 top-level module are tracked normally.
3913
3914 - scm_eval (exp, mod)
3915
3916 evaluates EXP while MOD is the current module. This is done by
3917 setting the current module to MOD, invoking scm_primitive_eval on
3918 EXP, and then restoring the current module to the value it had
3919 previously. That is, while EXP is evaluated, changes to the
3920 current module are tracked, but these changes do not persist when
3921 scm_eval returns.
3922
3923 For each level of evals, there are two variants, distinguished by a
3924 _x suffix: the ordinary variant does not modify EXP while the _x
3925 variant can destructively modify EXP into something completely
3926 unintelligible. A Scheme data structure passed as EXP to one of the
3927 _x variants should not ever be used again for anything. So when in
3928 doubt, use the ordinary variant.
3929
3930 */
3931
3932 SCM
3933 scm_i_eval_x (SCM exp, SCM env)
3934 {
3935 return SCM_XEVAL (exp, env);
3936 }
3937
3938 SCM
3939 scm_i_eval (SCM exp, SCM env)
3940 {
3941 exp = scm_copy_tree (exp);
3942 return SCM_XEVAL (exp, env);
3943 }
3944
3945 SCM
3946 scm_primitive_eval_x (SCM exp)
3947 {
3948 SCM env;
3949 SCM transformer = scm_current_module_transformer ();
3950 if (SCM_NIMP (transformer))
3951 exp = scm_apply (transformer, exp, scm_listofnull);
3952 env = scm_top_level_env (scm_current_module_lookup_closure ());
3953 return scm_i_eval_x (exp, env);
3954 }
3955
3956 SCM_DEFINE (scm_primitive_eval, "primitive-eval", 1, 0, 0,
3957 (SCM exp),
3958 "Evaluate @var{exp} in the top-level environment specified by\n"
3959 "the current module.")
3960 #define FUNC_NAME s_scm_primitive_eval
3961 {
3962 SCM env;
3963 SCM transformer = scm_current_module_transformer ();
3964 if (SCM_NIMP (transformer))
3965 exp = scm_apply (transformer, exp, scm_listofnull);
3966 env = scm_top_level_env (scm_current_module_lookup_closure ());
3967 return scm_i_eval (exp, env);
3968 }
3969 #undef FUNC_NAME
3970
3971 /* Eval does not take the second arg optionally. This is intentional
3972 * in order to be R5RS compatible, and to prepare for the new module
3973 * system, where we would like to make the choice of evaluation
3974 * environment explicit. */
3975
3976 static void
3977 change_environment (void *data)
3978 {
3979 SCM pair = SCM_PACK (data);
3980 SCM new_module = SCM_CAR (pair);
3981 SCM old_module = scm_current_module ();
3982 SCM_SETCDR (pair, old_module);
3983 scm_set_current_module (new_module);
3984 }
3985
3986
3987 static void
3988 restore_environment (void *data)
3989 {
3990 SCM pair = SCM_PACK (data);
3991 SCM old_module = SCM_CDR (pair);
3992 SCM new_module = scm_current_module ();
3993 SCM_SETCAR (pair, new_module);
3994 scm_set_current_module (old_module);
3995 }
3996
3997 static SCM
3998 inner_eval_x (void *data)
3999 {
4000 return scm_primitive_eval_x (SCM_PACK(data));
4001 }
4002
4003 SCM
4004 scm_eval_x (SCM exp, SCM module)
4005 #define FUNC_NAME "eval!"
4006 {
4007 SCM_VALIDATE_MODULE (2, module);
4008
4009 return scm_internal_dynamic_wind
4010 (change_environment, inner_eval_x, restore_environment,
4011 (void *) SCM_UNPACK (exp),
4012 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
4013 }
4014 #undef FUNC_NAME
4015
4016 static SCM
4017 inner_eval (void *data)
4018 {
4019 return scm_primitive_eval (SCM_PACK(data));
4020 }
4021
4022 SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
4023 (SCM exp, SCM module),
4024 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
4025 "in the top-level environment specified by @var{module}.\n"
4026 "While @var{exp} is evaluated (using @var{primitive-eval}),\n"
4027 "@var{module} is made the current module. The current module\n"
4028 "is reset to its previous value when @var{eval} returns.")
4029 #define FUNC_NAME s_scm_eval
4030 {
4031 SCM_VALIDATE_MODULE (2, module);
4032
4033 return scm_internal_dynamic_wind
4034 (change_environment, inner_eval, restore_environment,
4035 (void *) SCM_UNPACK (exp),
4036 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
4037 }
4038 #undef FUNC_NAME
4039
4040 #if (SCM_DEBUG_DEPRECATED == 0)
4041
4042 /* Use scm_current_module () or scm_interaction_environment ()
4043 * instead. The former is the module selected during loading of code.
4044 * The latter is the module in which the user of this thread currently
4045 * types expressions.
4046 */
4047
4048 SCM scm_top_level_lookup_closure_var;
4049 SCM scm_system_transformer;
4050
4051 /* Avoid using this functionality altogether (except for implementing
4052 * libguile, where you can use scm_i_eval or scm_i_eval_x).
4053 *
4054 * Applications should use either C level scm_eval_x or Scheme
4055 * scm_eval; or scm_primitive_eval_x or scm_primitive_eval. */
4056
4057 SCM
4058 scm_eval_3 (SCM obj, int copyp, SCM env)
4059 {
4060 if (copyp)
4061 return scm_i_eval (obj, env);
4062 else
4063 return scm_i_eval_x (obj, env);
4064 }
4065
4066 SCM_DEFINE (scm_eval2, "eval2", 2, 0, 0,
4067 (SCM obj, SCM env_thunk),
4068 "Evaluate @var{exp}, a Scheme expression, in the environment\n"
4069 "designated by @var{lookup}, a symbol-lookup function."
4070 "Do not use this version of eval, it does not play well\n"
4071 "with the module system. Use @code{eval} or\n"
4072 "@code{primitive-eval} instead.")
4073 #define FUNC_NAME s_scm_eval2
4074 {
4075 return scm_i_eval (obj, scm_top_level_env (env_thunk));
4076 }
4077 #undef FUNC_NAME
4078
4079 #endif /* DEPRECATED */
4080
4081
4082 /* At this point, scm_deval and scm_dapply are generated.
4083 */
4084
4085 #ifdef DEBUG_EXTENSIONS
4086 # define DEVAL
4087 # include "eval.c"
4088 #endif
4089
4090
4091
4092 void
4093 scm_init_eval ()
4094 {
4095 scm_init_opts (scm_evaluator_traps,
4096 scm_evaluator_trap_table,
4097 SCM_N_EVALUATOR_TRAPS);
4098 scm_init_opts (scm_eval_options_interface,
4099 scm_eval_opts,
4100 SCM_N_EVAL_OPTIONS);
4101
4102 scm_tc16_promise = scm_make_smob_type ("promise", 0);
4103 scm_set_smob_mark (scm_tc16_promise, scm_markcdr);
4104 scm_set_smob_print (scm_tc16_promise, promise_print);
4105
4106 /* Dirk:Fixme:: make scm_undefineds local to eval.c: it's only used here. */
4107 scm_undefineds = scm_cons (SCM_UNDEFINED, SCM_EOL);
4108 SCM_SETCDR (scm_undefineds, scm_undefineds);
4109 scm_listofnull = scm_cons (SCM_EOL, SCM_EOL);
4110
4111 scm_f_apply = scm_c_define_subr ("apply", scm_tc7_lsubr_2, scm_apply);
4112
4113 /* acros */
4114 /* end of acros */
4115
4116 #if SCM_DEBUG_DEPRECATED == 0
4117 scm_top_level_lookup_closure_var =
4118 scm_c_define ("*top-level-lookup-closure*", scm_make_fluid ());
4119 scm_system_transformer =
4120 scm_c_define ("scm:eval-transformer", scm_make_fluid ());
4121 #endif
4122
4123 #ifndef SCM_MAGIC_SNARFER
4124 #include "libguile/eval.x"
4125 #endif
4126
4127 scm_c_define ("nil", scm_lisp_nil);
4128 scm_c_define ("t", scm_lisp_t);
4129
4130 scm_add_feature ("delay");
4131 }
4132
4133 #endif /* !DEVAL */
4134
4135 /*
4136 Local Variables:
4137 c-file-style: "gnu"
4138 End:
4139 */