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