* Minor docstring updates.
[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 "Option interface for the evaluation options. Instead of using\n"
1676 "this procedure directly, use the procedures @code{eval-enable},\n"
1677 "@code{eval-disable}, @code{eval-set!} and @var{eval-options}.")
1678 #define FUNC_NAME s_scm_eval_options_interface
1679 {
1680 SCM ans;
1681 SCM_DEFER_INTS;
1682 ans = scm_options (setting,
1683 scm_eval_opts,
1684 SCM_N_EVAL_OPTIONS,
1685 FUNC_NAME);
1686 scm_eval_stack = SCM_EVAL_STACK * sizeof (void *);
1687 SCM_ALLOW_INTS;
1688 return ans;
1689 }
1690 #undef FUNC_NAME
1691
1692 SCM_DEFINE (scm_evaluator_traps, "evaluator-traps-interface", 0, 1, 0,
1693 (SCM setting),
1694 "Option interface for the evaluator trap options.")
1695 #define FUNC_NAME s_scm_evaluator_traps
1696 {
1697 SCM ans;
1698 SCM_DEFER_INTS;
1699 ans = scm_options (setting,
1700 scm_evaluator_trap_table,
1701 SCM_N_EVALUATOR_TRAPS,
1702 FUNC_NAME);
1703 SCM_RESET_DEBUG_MODE;
1704 SCM_ALLOW_INTS;
1705 return ans;
1706 }
1707 #undef FUNC_NAME
1708
1709 SCM
1710 scm_deval_args (SCM l, SCM env, SCM proc, SCM *lloc)
1711 {
1712 SCM *results = lloc, res;
1713 while (SCM_NIMP (l))
1714 {
1715 #ifdef SCM_CAUTIOUS
1716 if (SCM_CONSP (l))
1717 {
1718 if (SCM_IMP (SCM_CAR (l)))
1719 res = SCM_EVALIM (SCM_CAR (l), env);
1720 else
1721 res = EVALCELLCAR (l, env);
1722 }
1723 else if (SCM_TYP3 (l) == scm_tc3_cons_gloc)
1724 {
1725 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (l) [scm_vtable_index_vcell];
1726 if (vcell == 0)
1727 res = SCM_CAR (l); /* struct planted in code */
1728 else
1729 res = SCM_PACK (vcell);
1730 }
1731 else
1732 goto wrongnumargs;
1733 #else
1734 res = EVALCAR (l, env);
1735 #endif
1736 *lloc = scm_cons (res, SCM_EOL);
1737 lloc = SCM_CDRLOC (*lloc);
1738 l = SCM_CDR (l);
1739 }
1740 #ifdef SCM_CAUTIOUS
1741 if (SCM_NNULLP (l))
1742 {
1743 wrongnumargs:
1744 scm_wrong_num_args (proc);
1745 }
1746 #endif
1747 return *results;
1748 }
1749
1750 #endif /* !DEVAL */
1751
1752
1753 /* SECTION: Some local definitions for the evaluator.
1754 */
1755
1756 #ifndef DEVAL
1757 #define CHECK_EQVISH(A,B) (SCM_EQ_P ((A), (B)) || (SCM_NFALSEP (scm_eqv_p ((A), (B)))))
1758 #endif /* DEVAL */
1759
1760 #define BUILTIN_RPASUBR /* Handle rpsubrs and asubrs without calling apply */
1761
1762 /* SECTION: This is the evaluator. Like any real monster, it has
1763 * three heads. This code is compiled twice.
1764 */
1765
1766 #if 0
1767
1768 SCM
1769 scm_ceval (SCM x, SCM env)
1770 {}
1771 #endif
1772 #if 0
1773
1774 SCM
1775 scm_deval (SCM x, SCM env)
1776 {}
1777 #endif
1778
1779 SCM
1780 SCM_CEVAL (SCM x, SCM env)
1781 {
1782 union
1783 {
1784 SCM *lloc;
1785 SCM arg1;
1786 } t;
1787 SCM proc, arg2;
1788 #ifdef DEVAL
1789 scm_debug_frame debug;
1790 scm_debug_info *debug_info_end;
1791 debug.prev = scm_last_debug_frame;
1792 debug.status = scm_debug_eframe_size;
1793 /*
1794 * The debug.vect contains twice as much scm_debug_info frames as the
1795 * user has specified with (debug-set! frames <n>).
1796 *
1797 * Even frames are eval frames, odd frames are apply frames.
1798 */
1799 debug.vect = (scm_debug_info *) alloca (scm_debug_eframe_size
1800 * sizeof (debug.vect[0]));
1801 debug.info = debug.vect;
1802 debug_info_end = debug.vect + scm_debug_eframe_size;
1803 scm_last_debug_frame = &debug;
1804 #endif
1805 #ifdef EVAL_STACK_CHECKING
1806 if (scm_stack_checking_enabled_p
1807 && SCM_STACK_OVERFLOW_P ((SCM_STACKITEM *) &proc))
1808 {
1809 #ifdef DEVAL
1810 debug.info->e.exp = x;
1811 debug.info->e.env = env;
1812 #endif
1813 scm_report_stack_overflow ();
1814 }
1815 #endif
1816 #ifdef DEVAL
1817 goto start;
1818 #endif
1819 loopnoap:
1820 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1821 loop:
1822 #ifdef DEVAL
1823 SCM_CLEAR_ARGSREADY (debug);
1824 if (SCM_OVERFLOWP (debug))
1825 --debug.info;
1826 /*
1827 * In theory, this should be the only place where it is necessary to
1828 * check for space in debug.vect since both eval frames and
1829 * available space are even.
1830 *
1831 * For this to be the case, however, it is necessary that primitive
1832 * special forms which jump back to `loop', `begin' or some similar
1833 * label call PREP_APPLY. A convenient way to do this is to jump to
1834 * `loopnoap' or `cdrxnoap'.
1835 */
1836 else if (++debug.info >= debug_info_end)
1837 {
1838 SCM_SET_OVERFLOW (debug);
1839 debug.info -= 2;
1840 }
1841 start:
1842 debug.info->e.exp = x;
1843 debug.info->e.env = env;
1844 if (CHECK_ENTRY && SCM_TRAPS_P)
1845 if (SCM_ENTER_FRAME_P || (SCM_BREAKPOINTS_P && SRCBRKP (x)))
1846 {
1847 SCM tail = SCM_BOOL(SCM_TAILRECP (debug));
1848 SCM_SET_TAILREC (debug);
1849 if (SCM_CHEAPTRAPS_P)
1850 t.arg1 = scm_make_debugobj (&debug);
1851 else
1852 {
1853 int first;
1854 SCM val = scm_make_continuation (&first);
1855
1856 if (first)
1857 t.arg1 = val;
1858 else
1859 {
1860 x = val;
1861 if (SCM_IMP (x))
1862 {
1863 RETURN (x);
1864 }
1865 else
1866 /* This gives the possibility for the debugger to
1867 modify the source expression before evaluation. */
1868 goto dispatch;
1869 }
1870 }
1871 scm_ithrow (scm_sym_enter_frame,
1872 scm_cons2 (t.arg1, tail,
1873 scm_cons (scm_unmemocopy (x, env), SCM_EOL)),
1874 0);
1875 }
1876 #endif
1877 #if defined (USE_THREADS) || defined (DEVAL)
1878 dispatch:
1879 #endif
1880 SCM_TICK;
1881 switch (SCM_TYP7 (x))
1882 {
1883 case scm_tc7_symbol:
1884 /* Only happens when called at top level.
1885 */
1886 x = scm_cons (x, SCM_UNDEFINED);
1887 goto retval;
1888
1889 case SCM_BIT8(SCM_IM_AND):
1890 x = SCM_CDR (x);
1891 t.arg1 = x;
1892 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1893 if (SCM_FALSEP (EVALCAR (x, env)))
1894 {
1895 RETURN (SCM_BOOL_F);
1896 }
1897 else
1898 x = t.arg1;
1899 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1900 goto carloop;
1901
1902 case SCM_BIT8(SCM_IM_BEGIN):
1903 cdrxnoap:
1904 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1905 cdrxbegin:
1906 x = SCM_CDR (x);
1907
1908 begin:
1909 /* If we are on toplevel with a lookup closure, we need to sync
1910 with the current module. */
1911 if (SCM_CONSP(env) && !SCM_CONSP(SCM_CAR(env)))
1912 {
1913 t.arg1 = x;
1914 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1915 {
1916 env = scm_top_level_env (scm_current_module_lookup_closure ());
1917 SIDEVAL (SCM_CAR(x), env);
1918 x = t.arg1;
1919 }
1920 /* once more, for the last form */
1921 env = scm_top_level_env (scm_current_module_lookup_closure ());
1922 }
1923 else
1924 {
1925 t.arg1 = x;
1926 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1927 {
1928 if (SCM_IMP (SCM_CAR (x)))
1929 {
1930 if (SCM_ISYMP (SCM_CAR (x)))
1931 {
1932 x = scm_m_expand_body (x, env);
1933 goto begin;
1934 }
1935 }
1936 else
1937 SCM_CEVAL (SCM_CAR (x), env);
1938 x = t.arg1;
1939 }
1940 }
1941
1942 carloop: /* scm_eval car of last form in list */
1943 if (SCM_NCELLP (SCM_CAR (x)))
1944 {
1945 x = SCM_CAR (x);
1946 RETURN (SCM_IMP (x) ? SCM_EVALIM (x, env) : SCM_GLOC_VAL (x))
1947 }
1948
1949 if (SCM_SYMBOLP (SCM_CAR (x)))
1950 {
1951 retval:
1952 RETURN (*scm_lookupcar (x, env, 1))
1953 }
1954
1955 x = SCM_CAR (x);
1956 goto loop; /* tail recurse */
1957
1958
1959 case SCM_BIT8(SCM_IM_CASE):
1960 x = SCM_CDR (x);
1961 t.arg1 = EVALCAR (x, env);
1962 while (SCM_NIMP (x = SCM_CDR (x)))
1963 {
1964 proc = SCM_CAR (x);
1965 if (SCM_EQ_P (scm_sym_else, SCM_CAR (proc)))
1966 {
1967 x = SCM_CDR (proc);
1968 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1969 goto begin;
1970 }
1971 proc = SCM_CAR (proc);
1972 while (SCM_NIMP (proc))
1973 {
1974 if (CHECK_EQVISH (SCM_CAR (proc), t.arg1))
1975 {
1976 x = SCM_CDR (SCM_CAR (x));
1977 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1978 goto begin;
1979 }
1980 proc = SCM_CDR (proc);
1981 }
1982 }
1983 RETURN (SCM_UNSPECIFIED)
1984
1985
1986 case SCM_BIT8(SCM_IM_COND):
1987 while (SCM_NIMP (x = SCM_CDR (x)))
1988 {
1989 proc = SCM_CAR (x);
1990 t.arg1 = EVALCAR (proc, env);
1991 if (SCM_NFALSEP (t.arg1))
1992 {
1993 x = SCM_CDR (proc);
1994 if SCM_NULLP (x)
1995 {
1996 RETURN (t.arg1)
1997 }
1998 if (! SCM_EQ_P (scm_sym_arrow, SCM_CAR (x)))
1999 {
2000 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2001 goto begin;
2002 }
2003 proc = SCM_CDR (x);
2004 proc = EVALCAR (proc, env);
2005 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2006 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
2007 ENTER_APPLY;
2008 if (SCM_CLOSUREP(proc) && scm_badformalsp (proc, 1))
2009 goto umwrongnumargs;
2010 goto evap1;
2011 }
2012 }
2013 RETURN (SCM_UNSPECIFIED)
2014
2015
2016 case SCM_BIT8(SCM_IM_DO):
2017 x = SCM_CDR (x);
2018 proc = SCM_CAR (SCM_CDR (x)); /* inits */
2019 t.arg1 = SCM_EOL; /* values */
2020 while (SCM_NIMP (proc))
2021 {
2022 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
2023 proc = SCM_CDR (proc);
2024 }
2025 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
2026 x = SCM_CDR (SCM_CDR (x));
2027 while (proc = SCM_CAR (x), SCM_FALSEP (EVALCAR (proc, env)))
2028 {
2029 for (proc = SCM_CADR (x); SCM_NIMP (proc); proc = SCM_CDR (proc))
2030 {
2031 t.arg1 = SCM_CAR (proc); /* body */
2032 SIDEVAL (t.arg1, env);
2033 }
2034 for (t.arg1 = SCM_EOL, proc = SCM_CDDR (x);
2035 SCM_NIMP (proc);
2036 proc = SCM_CDR (proc))
2037 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1); /* steps */
2038 env = EXTEND_ENV (SCM_CAR (SCM_CAR (env)), t.arg1, SCM_CDR (env));
2039 }
2040 x = SCM_CDR (proc);
2041 if (SCM_NULLP (x))
2042 RETURN (SCM_UNSPECIFIED);
2043 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2044 goto begin;
2045
2046
2047 case SCM_BIT8(SCM_IM_IF):
2048 x = SCM_CDR (x);
2049 if (SCM_NFALSEP (EVALCAR (x, env)))
2050 x = SCM_CDR (x);
2051 else if (SCM_IMP (x = SCM_CDR (SCM_CDR (x))))
2052 {
2053 RETURN (SCM_UNSPECIFIED);
2054 }
2055 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2056 goto carloop;
2057
2058
2059 case SCM_BIT8(SCM_IM_LET):
2060 x = SCM_CDR (x);
2061 proc = SCM_CAR (SCM_CDR (x));
2062 t.arg1 = SCM_EOL;
2063 do
2064 {
2065 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
2066 }
2067 while (SCM_NIMP (proc = SCM_CDR (proc)));
2068 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
2069 x = SCM_CDR (x);
2070 goto cdrxnoap;
2071
2072
2073 case SCM_BIT8(SCM_IM_LETREC):
2074 x = SCM_CDR (x);
2075 env = EXTEND_ENV (SCM_CAR (x), scm_undefineds, env);
2076 x = SCM_CDR (x);
2077 proc = SCM_CAR (x);
2078 t.arg1 = SCM_EOL;
2079 do
2080 {
2081 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
2082 }
2083 while (SCM_NIMP (proc = SCM_CDR (proc)));
2084 SCM_SETCDR (SCM_CAR (env), t.arg1);
2085 goto cdrxnoap;
2086
2087
2088 case SCM_BIT8(SCM_IM_LETSTAR):
2089 x = SCM_CDR (x);
2090 proc = SCM_CAR (x);
2091 if (SCM_IMP (proc))
2092 {
2093 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
2094 goto cdrxnoap;
2095 }
2096 do
2097 {
2098 t.arg1 = SCM_CAR (proc);
2099 proc = SCM_CDR (proc);
2100 env = EXTEND_ENV (t.arg1, EVALCAR (proc, env), env);
2101 }
2102 while (SCM_NIMP (proc = SCM_CDR (proc)));
2103 goto cdrxnoap;
2104
2105 case SCM_BIT8(SCM_IM_OR):
2106 x = SCM_CDR (x);
2107 t.arg1 = x;
2108 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
2109 {
2110 x = EVALCAR (x, env);
2111 if (SCM_NFALSEP (x))
2112 {
2113 RETURN (x);
2114 }
2115 x = t.arg1;
2116 }
2117 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2118 goto carloop;
2119
2120
2121 case SCM_BIT8(SCM_IM_LAMBDA):
2122 RETURN (scm_closure (SCM_CDR (x), env));
2123
2124
2125 case SCM_BIT8(SCM_IM_QUOTE):
2126 RETURN (SCM_CAR (SCM_CDR (x)));
2127
2128
2129 case SCM_BIT8(SCM_IM_SET_X):
2130 x = SCM_CDR (x);
2131 proc = SCM_CAR (x);
2132 switch (SCM_ITAG3 (proc))
2133 {
2134 case scm_tc3_cons:
2135 t.lloc = scm_lookupcar (x, env, 1);
2136 break;
2137 case scm_tc3_cons_gloc:
2138 t.lloc = SCM_GLOC_VAL_LOC (proc);
2139 break;
2140 #ifdef MEMOIZE_LOCALS
2141 case scm_tc3_imm24:
2142 t.lloc = scm_ilookup (proc, env);
2143 break;
2144 #endif
2145 }
2146 x = SCM_CDR (x);
2147 *t.lloc = EVALCAR (x, env);
2148 #ifdef SICP
2149 RETURN (*t.lloc);
2150 #else
2151 RETURN (SCM_UNSPECIFIED);
2152 #endif
2153
2154
2155 case SCM_BIT8(SCM_IM_DEFINE): /* only for internal defines */
2156 scm_misc_error (NULL, "Bad define placement", SCM_EOL);
2157
2158 /* new syntactic forms go here. */
2159 case SCM_BIT8(SCM_MAKISYM (0)):
2160 proc = SCM_CAR (x);
2161 SCM_ASRTGO (SCM_ISYMP (proc), badfun);
2162 switch SCM_ISYMNUM (proc)
2163 {
2164 case (SCM_ISYMNUM (SCM_IM_APPLY)):
2165 proc = SCM_CDR (x);
2166 proc = EVALCAR (proc, env);
2167 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2168 if (SCM_CLOSUREP (proc))
2169 {
2170 SCM argl, tl;
2171 PREP_APPLY (proc, SCM_EOL);
2172 t.arg1 = SCM_CDR (SCM_CDR (x));
2173 t.arg1 = EVALCAR (t.arg1, env);
2174 #ifdef DEVAL
2175 debug.info->a.args = t.arg1;
2176 #endif
2177 #ifndef SCM_RECKLESS
2178 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), t.arg1))
2179 goto wrongnumargs;
2180 #endif
2181 ENTER_APPLY;
2182 /* Copy argument list */
2183 if (SCM_IMP (t.arg1))
2184 argl = t.arg1;
2185 else
2186 {
2187 argl = tl = scm_cons (SCM_CAR (t.arg1), SCM_UNSPECIFIED);
2188 while (SCM_NIMP (t.arg1 = SCM_CDR (t.arg1))
2189 && SCM_CONSP (t.arg1))
2190 {
2191 SCM_SETCDR (tl, scm_cons (SCM_CAR (t.arg1),
2192 SCM_UNSPECIFIED));
2193 tl = SCM_CDR (tl);
2194 }
2195 SCM_SETCDR (tl, t.arg1);
2196 }
2197
2198 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), argl, SCM_ENV (proc));
2199 x = SCM_CODE (proc);
2200 goto cdrxbegin;
2201 }
2202 proc = scm_f_apply;
2203 goto evapply;
2204
2205 case (SCM_ISYMNUM (SCM_IM_CONT)):
2206 {
2207 int first;
2208 SCM val = scm_make_continuation (&first);
2209
2210 if (first)
2211 t.arg1 = val;
2212 else
2213 RETURN (val);
2214 }
2215 proc = SCM_CDR (x);
2216 proc = evalcar (proc, env);
2217 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2218 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
2219 ENTER_APPLY;
2220 if (SCM_CLOSUREP(proc) && scm_badformalsp (proc, 1))
2221 goto umwrongnumargs;
2222 goto evap1;
2223
2224 case (SCM_ISYMNUM (SCM_IM_DELAY)):
2225 RETURN (scm_makprom (scm_closure (SCM_CDR (x), env)))
2226
2227 case (SCM_ISYMNUM (SCM_IM_DISPATCH)):
2228 proc = SCM_CADR (x); /* unevaluated operands */
2229 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2230 if (SCM_IMP (proc))
2231 arg2 = *scm_ilookup (proc, env);
2232 else if (SCM_NCONSP (proc))
2233 {
2234 if (SCM_NCELLP (proc))
2235 arg2 = SCM_GLOC_VAL (proc);
2236 else
2237 arg2 = *scm_lookupcar (SCM_CDR (x), env, 1);
2238 }
2239 else
2240 {
2241 arg2 = scm_cons (EVALCAR (proc, env), SCM_EOL);
2242 t.lloc = SCM_CDRLOC (arg2);
2243 while (SCM_NIMP (proc = SCM_CDR (proc)))
2244 {
2245 *t.lloc = scm_cons (EVALCAR (proc, env), SCM_EOL);
2246 t.lloc = SCM_CDRLOC (*t.lloc);
2247 }
2248 }
2249
2250 type_dispatch:
2251 /* The type dispatch code is duplicated here
2252 * (c.f. objects.c:scm_mcache_compute_cmethod) since that
2253 * cuts down execution time for type dispatch to 50%.
2254 */
2255 {
2256 int i, n, end, mask;
2257 SCM z = SCM_CDDR (x);
2258 n = SCM_INUM (SCM_CAR (z)); /* maximum number of specializers */
2259 proc = SCM_CADR (z);
2260
2261 if (SCM_NIMP (proc))
2262 {
2263 /* Prepare for linear search */
2264 mask = -1;
2265 i = 0;
2266 end = SCM_VECTOR_LENGTH (proc);
2267 }
2268 else
2269 {
2270 /* Compute a hash value */
2271 int hashset = SCM_INUM (proc);
2272 int j = n;
2273 mask = SCM_INUM (SCM_CAR (z = SCM_CDDR (z)));
2274 proc = SCM_CADR (z);
2275 i = 0;
2276 t.arg1 = arg2;
2277 if (SCM_NIMP (t.arg1))
2278 do
2279 {
2280 i += SCM_STRUCT_DATA (scm_class_of (SCM_CAR (t.arg1)))
2281 [scm_si_hashsets + hashset];
2282 t.arg1 = SCM_CDR (t.arg1);
2283 }
2284 while (j-- && SCM_NIMP (t.arg1));
2285 i &= mask;
2286 end = i;
2287 }
2288
2289 /* Search for match */
2290 do
2291 {
2292 int j = n;
2293 z = SCM_VELTS (proc)[i];
2294 t.arg1 = arg2; /* list of arguments */
2295 if (SCM_NIMP (t.arg1))
2296 do
2297 {
2298 /* More arguments than specifiers => CLASS != ENV */
2299 if (! SCM_EQ_P (scm_class_of (SCM_CAR (t.arg1)), SCM_CAR (z)))
2300 goto next_method;
2301 t.arg1 = SCM_CDR (t.arg1);
2302 z = SCM_CDR (z);
2303 }
2304 while (j-- && SCM_NIMP (t.arg1));
2305 /* Fewer arguments than specifiers => CAR != ENV */
2306 if (!(SCM_IMP (SCM_CAR (z)) || SCM_CONSP (SCM_CAR (z))))
2307 goto next_method;
2308 apply_cmethod:
2309 env = EXTEND_ENV (SCM_CAR (SCM_CMETHOD_CODE (z)),
2310 arg2,
2311 SCM_CMETHOD_ENV (z));
2312 x = SCM_CMETHOD_CODE (z);
2313 goto cdrxbegin;
2314 next_method:
2315 i = (i + 1) & mask;
2316 } while (i != end);
2317
2318 z = scm_memoize_method (x, arg2);
2319 goto apply_cmethod;
2320 }
2321
2322 case (SCM_ISYMNUM (SCM_IM_SLOT_REF)):
2323 x = SCM_CDR (x);
2324 t.arg1 = EVALCAR (x, env);
2325 RETURN (SCM_PACK (SCM_STRUCT_DATA (t.arg1) [SCM_INUM (SCM_CADR (x))]))
2326
2327 case (SCM_ISYMNUM (SCM_IM_SLOT_SET_X)):
2328 x = SCM_CDR (x);
2329 t.arg1 = EVALCAR (x, env);
2330 x = SCM_CDR (x);
2331 proc = SCM_CDR (x);
2332 SCM_STRUCT_DATA (t.arg1) [SCM_INUM (SCM_CAR (x))]
2333 = SCM_UNPACK (EVALCAR (proc, env));
2334 RETURN (SCM_UNSPECIFIED)
2335
2336 case (SCM_ISYMNUM (SCM_IM_NIL_COND)):
2337 proc = SCM_CDR (x);
2338 while (SCM_NIMP (x = SCM_CDR (proc)))
2339 {
2340 if (!(SCM_FALSEP (t.arg1 = EVALCAR (proc, env))
2341 || SCM_EQ_P (t.arg1, scm_lisp_nil)))
2342 {
2343 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
2344 RETURN (t.arg1);
2345 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2346 goto carloop;
2347 }
2348 proc = SCM_CDR (x);
2349 }
2350 x = proc;
2351 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2352 goto carloop;
2353
2354 case (SCM_ISYMNUM (SCM_IM_NIL_IFY)):
2355 x = SCM_CDR (x);
2356 RETURN ((SCM_FALSEP (proc = EVALCAR (x, env)) || SCM_NULLP (proc))
2357 ? scm_lisp_nil
2358 : proc)
2359
2360 case (SCM_ISYMNUM (SCM_IM_T_IFY)):
2361 x = SCM_CDR (x);
2362 RETURN (SCM_NFALSEP (EVALCAR (x, env)) ? scm_lisp_t : scm_lisp_nil)
2363
2364 case (SCM_ISYMNUM (SCM_IM_0_COND)):
2365 proc = SCM_CDR (x);
2366 while (SCM_NIMP (x = SCM_CDR (proc)))
2367 {
2368 if (!(SCM_FALSEP (t.arg1 = EVALCAR (proc, env))
2369 || SCM_EQ_P (t.arg1, SCM_INUM0)))
2370 {
2371 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
2372 RETURN (t.arg1);
2373 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2374 goto carloop;
2375 }
2376 proc = SCM_CDR (x);
2377 }
2378 x = proc;
2379 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2380 goto carloop;
2381
2382 case (SCM_ISYMNUM (SCM_IM_0_IFY)):
2383 x = SCM_CDR (x);
2384 RETURN (SCM_FALSEP (proc = EVALCAR (x, env))
2385 ? SCM_INUM0
2386 : proc)
2387
2388 case (SCM_ISYMNUM (SCM_IM_1_IFY)):
2389 x = SCM_CDR (x);
2390 RETURN (SCM_NFALSEP (EVALCAR (x, env))
2391 ? SCM_MAKINUM (1)
2392 : SCM_INUM0)
2393
2394 case (SCM_ISYMNUM (SCM_IM_BIND)):
2395 x = SCM_CDR (x);
2396
2397 t.arg1 = SCM_CAR (x);
2398 arg2 = SCM_CDAR (env);
2399 while (SCM_NIMP (arg2))
2400 {
2401 proc = SCM_GLOC_VAL (SCM_CAR (t.arg1));
2402 SCM_SETCDR (SCM_PACK (SCM_UNPACK (SCM_CAR (t.arg1)) - 1L),
2403 SCM_CAR (arg2));
2404 SCM_SETCAR (arg2, proc);
2405 t.arg1 = SCM_CDR (t.arg1);
2406 arg2 = SCM_CDR (arg2);
2407 }
2408 t.arg1 = SCM_CAR (x);
2409 scm_dynwinds = scm_acons (t.arg1, SCM_CDAR (env), scm_dynwinds);
2410
2411 arg2 = x = SCM_CDR (x);
2412 while (SCM_NNULLP (arg2 = SCM_CDR (arg2)))
2413 {
2414 SIDEVAL (SCM_CAR (x), env);
2415 x = arg2;
2416 }
2417 proc = EVALCAR (x, env);
2418
2419 scm_dynwinds = SCM_CDR (scm_dynwinds);
2420 arg2 = SCM_CDAR (env);
2421 while (SCM_NIMP (arg2))
2422 {
2423 SCM_SETCDR (SCM_PACK (SCM_UNPACK (SCM_CAR (t.arg1)) - 1L),
2424 SCM_CAR (arg2));
2425 t.arg1 = SCM_CDR (t.arg1);
2426 arg2 = SCM_CDR (arg2);
2427 }
2428
2429 RETURN (proc)
2430
2431 default:
2432 goto badfun;
2433 }
2434
2435 default:
2436 proc = x;
2437 badfun:
2438 /* scm_everr (x, env,...) */
2439 scm_misc_error (NULL,
2440 "Wrong type to apply: ~S",
2441 scm_listify (proc, SCM_UNDEFINED));
2442 case scm_tc7_vector:
2443 case scm_tc7_wvect:
2444 #ifdef HAVE_ARRAYS
2445 case scm_tc7_bvect:
2446 case scm_tc7_byvect:
2447 case scm_tc7_svect:
2448 case scm_tc7_ivect:
2449 case scm_tc7_uvect:
2450 case scm_tc7_fvect:
2451 case scm_tc7_dvect:
2452 case scm_tc7_cvect:
2453 #ifdef HAVE_LONG_LONGS
2454 case scm_tc7_llvect:
2455 #endif
2456 #endif
2457 case scm_tc7_string:
2458 case scm_tc7_substring:
2459 case scm_tc7_smob:
2460 case scm_tcs_closures:
2461 case scm_tc7_cclo:
2462 case scm_tc7_pws:
2463 case scm_tcs_subrs:
2464 RETURN (x);
2465
2466 #ifdef MEMOIZE_LOCALS
2467 case SCM_BIT8(SCM_ILOC00):
2468 proc = *scm_ilookup (SCM_CAR (x), env);
2469 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2470 #ifndef SCM_RECKLESS
2471 #ifdef SCM_CAUTIOUS
2472 goto checkargs;
2473 #endif
2474 #endif
2475 break;
2476 #endif /* ifdef MEMOIZE_LOCALS */
2477
2478
2479 case scm_tcs_cons_gloc: {
2480 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2481 if (vcell == 0) {
2482 /* This is a struct implanted in the code, not a gloc. */
2483 RETURN (x);
2484 } else {
2485 proc = SCM_PACK (vcell);
2486 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2487 #ifndef SCM_RECKLESS
2488 #ifdef SCM_CAUTIOUS
2489 goto checkargs;
2490 #endif
2491 #endif
2492 }
2493 break;
2494 }
2495
2496 case scm_tcs_cons_nimcar:
2497 if (SCM_SYMBOLP (SCM_CAR (x)))
2498 {
2499 #ifdef USE_THREADS
2500 t.lloc = scm_lookupcar1 (x, env, 1);
2501 if (t.lloc == NULL)
2502 {
2503 /* we have lost the race, start again. */
2504 goto dispatch;
2505 }
2506 proc = *t.lloc;
2507 #else
2508 proc = *scm_lookupcar (x, env, 1);
2509 #endif
2510
2511 if (SCM_IMP (proc))
2512 {
2513 unmemocar (x, env);
2514 goto badfun;
2515 }
2516 if (scm_tc16_macro == SCM_TYP16 (proc))
2517 {
2518 unmemocar (x, env);
2519
2520 handle_a_macro:
2521 #ifdef DEVAL
2522 /* Set a flag during macro expansion so that macro
2523 application frames can be deleted from the backtrace. */
2524 SCM_SET_MACROEXP (debug);
2525 #endif
2526 t.arg1 = SCM_APPLY (SCM_CDR (proc), x,
2527 scm_cons (env, scm_listofnull));
2528
2529 #ifdef DEVAL
2530 SCM_CLEAR_MACROEXP (debug);
2531 #endif
2532 switch (SCM_CELL_WORD_0 (proc) >> 16)
2533 {
2534 case 2:
2535 if (scm_ilength (t.arg1) <= 0)
2536 t.arg1 = scm_cons2 (SCM_IM_BEGIN, t.arg1, SCM_EOL);
2537 #ifdef DEVAL
2538 if (!SCM_CLOSUREP (SCM_CDR (proc)))
2539 {
2540 SCM_DEFER_INTS;
2541 SCM_SETCAR (x, SCM_CAR (t.arg1));
2542 SCM_SETCDR (x, SCM_CDR (t.arg1));
2543 SCM_ALLOW_INTS;
2544 goto dispatch;
2545 }
2546 /* Prevent memoizing of debug info expression. */
2547 debug.info->e.exp = scm_cons_source (debug.info->e.exp,
2548 SCM_CAR (x),
2549 SCM_CDR (x));
2550 #endif
2551 SCM_DEFER_INTS;
2552 SCM_SETCAR (x, SCM_CAR (t.arg1));
2553 SCM_SETCDR (x, SCM_CDR (t.arg1));
2554 SCM_ALLOW_INTS;
2555 goto loopnoap;
2556 case 1:
2557 if (SCM_NIMP (x = t.arg1))
2558 goto loopnoap;
2559 case 0:
2560 RETURN (t.arg1);
2561 }
2562 }
2563 }
2564 else
2565 proc = SCM_CEVAL (SCM_CAR (x), env);
2566 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2567 #ifndef SCM_RECKLESS
2568 #ifdef SCM_CAUTIOUS
2569 checkargs:
2570 #endif
2571 if (SCM_CLOSUREP (proc))
2572 {
2573 arg2 = SCM_CAR (SCM_CODE (proc));
2574 t.arg1 = SCM_CDR (x);
2575 while (SCM_NIMP (arg2))
2576 {
2577 if (SCM_NCONSP (arg2))
2578 goto evapply;
2579 if (SCM_IMP (t.arg1))
2580 goto umwrongnumargs;
2581 arg2 = SCM_CDR (arg2);
2582 t.arg1 = SCM_CDR (t.arg1);
2583 }
2584 if (SCM_NNULLP (t.arg1))
2585 goto umwrongnumargs;
2586 }
2587 else if (scm_tc16_macro == SCM_TYP16 (proc))
2588 goto handle_a_macro;
2589 #endif
2590 }
2591
2592
2593 evapply:
2594 PREP_APPLY (proc, SCM_EOL);
2595 if (SCM_NULLP (SCM_CDR (x))) {
2596 ENTER_APPLY;
2597 evap0:
2598 switch (SCM_TYP7 (proc))
2599 { /* no arguments given */
2600 case scm_tc7_subr_0:
2601 RETURN (SCM_SUBRF (proc) ());
2602 case scm_tc7_subr_1o:
2603 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
2604 case scm_tc7_lsubr:
2605 RETURN (SCM_SUBRF (proc) (SCM_EOL));
2606 case scm_tc7_rpsubr:
2607 RETURN (SCM_BOOL_T);
2608 case scm_tc7_asubr:
2609 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
2610 case scm_tc7_smob:
2611 if (!SCM_SMOB_APPLICABLE_P (proc))
2612 goto badfun;
2613 RETURN (SCM_SMOB_APPLY_0 (proc));
2614 case scm_tc7_cclo:
2615 t.arg1 = proc;
2616 proc = SCM_CCLO_SUBR (proc);
2617 #ifdef DEVAL
2618 debug.info->a.proc = proc;
2619 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2620 #endif
2621 goto evap1;
2622 case scm_tc7_pws:
2623 proc = SCM_PROCEDURE (proc);
2624 #ifdef DEVAL
2625 debug.info->a.proc = proc;
2626 #endif
2627 if (!SCM_CLOSUREP (proc))
2628 goto evap0;
2629 if (scm_badformalsp (proc, 0))
2630 goto umwrongnumargs;
2631 case scm_tcs_closures:
2632 x = SCM_CODE (proc);
2633 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, SCM_ENV (proc));
2634 goto cdrxbegin;
2635 case scm_tcs_cons_gloc:
2636 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2637 {
2638 x = SCM_ENTITY_PROCEDURE (proc);
2639 arg2 = SCM_EOL;
2640 goto type_dispatch;
2641 }
2642 else if (!SCM_I_OPERATORP (proc))
2643 goto badfun;
2644 else
2645 {
2646 t.arg1 = proc;
2647 proc = (SCM_I_ENTITYP (proc)
2648 ? SCM_ENTITY_PROCEDURE (proc)
2649 : SCM_OPERATOR_PROCEDURE (proc));
2650 #ifdef DEVAL
2651 debug.info->a.proc = proc;
2652 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2653 #endif
2654 if (SCM_NIMP (proc))
2655 goto evap1;
2656 else
2657 goto badfun;
2658 }
2659 case scm_tc7_subr_1:
2660 case scm_tc7_subr_2:
2661 case scm_tc7_subr_2o:
2662 case scm_tc7_cxr:
2663 case scm_tc7_subr_3:
2664 case scm_tc7_lsubr_2:
2665 umwrongnumargs:
2666 unmemocar (x, env);
2667 wrongnumargs:
2668 /* scm_everr (x, env,...) */
2669 scm_wrong_num_args (proc);
2670 default:
2671 /* handle macros here */
2672 goto badfun;
2673 }
2674 }
2675
2676 /* must handle macros by here */
2677 x = SCM_CDR (x);
2678 #ifdef SCM_CAUTIOUS
2679 if (SCM_IMP (x))
2680 goto wrongnumargs;
2681 else if (SCM_CONSP (x))
2682 {
2683 if (SCM_IMP (SCM_CAR (x)))
2684 t.arg1 = SCM_EVALIM (SCM_CAR (x), env);
2685 else
2686 t.arg1 = EVALCELLCAR (x, env);
2687 }
2688 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
2689 {
2690 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2691 if (vcell == 0)
2692 t.arg1 = SCM_CAR (x); /* struct planted in code */
2693 else
2694 t.arg1 = SCM_PACK (vcell);
2695 }
2696 else
2697 goto wrongnumargs;
2698 #else
2699 t.arg1 = EVALCAR (x, env);
2700 #endif
2701 #ifdef DEVAL
2702 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2703 #endif
2704 x = SCM_CDR (x);
2705 if (SCM_NULLP (x))
2706 {
2707 ENTER_APPLY;
2708 evap1:
2709 switch (SCM_TYP7 (proc))
2710 { /* have one argument in t.arg1 */
2711 case scm_tc7_subr_2o:
2712 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2713 case scm_tc7_subr_1:
2714 case scm_tc7_subr_1o:
2715 RETURN (SCM_SUBRF (proc) (t.arg1));
2716 case scm_tc7_cxr:
2717 if (SCM_SUBRF (proc))
2718 {
2719 if (SCM_INUMP (t.arg1))
2720 {
2721 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (t.arg1))));
2722 }
2723 SCM_ASRTGO (SCM_NIMP (t.arg1), floerr);
2724 if (SCM_REALP (t.arg1))
2725 {
2726 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (t.arg1))));
2727 }
2728 #ifdef SCM_BIGDIG
2729 if (SCM_BIGP (t.arg1))
2730 {
2731 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_big2dbl (t.arg1))));
2732 }
2733 #endif
2734 floerr:
2735 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), t.arg1,
2736 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
2737 }
2738 proc = SCM_SNAME (proc);
2739 {
2740 char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
2741 while ('c' != *--chrs)
2742 {
2743 SCM_ASSERT (SCM_CONSP (t.arg1),
2744 t.arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
2745 t.arg1 = ('a' == *chrs) ? SCM_CAR (t.arg1) : SCM_CDR (t.arg1);
2746 }
2747 RETURN (t.arg1);
2748 }
2749 case scm_tc7_rpsubr:
2750 RETURN (SCM_BOOL_T);
2751 case scm_tc7_asubr:
2752 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2753 case scm_tc7_lsubr:
2754 #ifdef DEVAL
2755 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2756 #else
2757 RETURN (SCM_SUBRF (proc) (scm_cons (t.arg1, SCM_EOL)));
2758 #endif
2759 case scm_tc7_smob:
2760 if (!SCM_SMOB_APPLICABLE_P (proc))
2761 goto badfun;
2762 RETURN (SCM_SMOB_APPLY_1 (proc, t.arg1));
2763 case scm_tc7_cclo:
2764 arg2 = t.arg1;
2765 t.arg1 = proc;
2766 proc = SCM_CCLO_SUBR (proc);
2767 #ifdef DEVAL
2768 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2769 debug.info->a.proc = proc;
2770 #endif
2771 goto evap2;
2772 case scm_tc7_pws:
2773 proc = SCM_PROCEDURE (proc);
2774 #ifdef DEVAL
2775 debug.info->a.proc = proc;
2776 #endif
2777 if (!SCM_CLOSUREP (proc))
2778 goto evap1;
2779 if (scm_badformalsp (proc, 1))
2780 goto umwrongnumargs;
2781 case scm_tcs_closures:
2782 /* clos1: */
2783 x = SCM_CODE (proc);
2784 #ifdef DEVAL
2785 env = EXTEND_ENV (SCM_CAR (x), debug.info->a.args, SCM_ENV (proc));
2786 #else
2787 env = EXTEND_ENV (SCM_CAR (x), scm_cons (t.arg1, SCM_EOL), SCM_ENV (proc));
2788 #endif
2789 goto cdrxbegin;
2790 case scm_tcs_cons_gloc:
2791 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2792 {
2793 x = SCM_ENTITY_PROCEDURE (proc);
2794 #ifdef DEVAL
2795 arg2 = debug.info->a.args;
2796 #else
2797 arg2 = scm_cons (t.arg1, SCM_EOL);
2798 #endif
2799 goto type_dispatch;
2800 }
2801 else if (!SCM_I_OPERATORP (proc))
2802 goto badfun;
2803 else
2804 {
2805 arg2 = t.arg1;
2806 t.arg1 = proc;
2807 proc = (SCM_I_ENTITYP (proc)
2808 ? SCM_ENTITY_PROCEDURE (proc)
2809 : SCM_OPERATOR_PROCEDURE (proc));
2810 #ifdef DEVAL
2811 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2812 debug.info->a.proc = proc;
2813 #endif
2814 if (SCM_NIMP (proc))
2815 goto evap2;
2816 else
2817 goto badfun;
2818 }
2819 case scm_tc7_subr_2:
2820 case scm_tc7_subr_0:
2821 case scm_tc7_subr_3:
2822 case scm_tc7_lsubr_2:
2823 goto wrongnumargs;
2824 default:
2825 goto badfun;
2826 }
2827 }
2828 #ifdef SCM_CAUTIOUS
2829 if (SCM_IMP (x))
2830 goto wrongnumargs;
2831 else if (SCM_CONSP (x))
2832 {
2833 if (SCM_IMP (SCM_CAR (x)))
2834 arg2 = SCM_EVALIM (SCM_CAR (x), env);
2835 else
2836 arg2 = EVALCELLCAR (x, env);
2837 }
2838 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
2839 {
2840 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2841 if (vcell == 0)
2842 arg2 = SCM_CAR (x); /* struct planted in code */
2843 else
2844 arg2 = SCM_PACK (vcell);
2845 }
2846 else
2847 goto wrongnumargs;
2848 #else
2849 arg2 = EVALCAR (x, env);
2850 #endif
2851 { /* have two or more arguments */
2852 #ifdef DEVAL
2853 debug.info->a.args = scm_cons2 (t.arg1, arg2, SCM_EOL);
2854 #endif
2855 x = SCM_CDR (x);
2856 if (SCM_NULLP (x)) {
2857 ENTER_APPLY;
2858 evap2:
2859 switch (SCM_TYP7 (proc))
2860 { /* have two arguments */
2861 case scm_tc7_subr_2:
2862 case scm_tc7_subr_2o:
2863 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2864 case scm_tc7_lsubr:
2865 #ifdef DEVAL
2866 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2867 #else
2868 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, SCM_EOL)));
2869 #endif
2870 case scm_tc7_lsubr_2:
2871 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_EOL));
2872 case scm_tc7_rpsubr:
2873 case scm_tc7_asubr:
2874 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2875 case scm_tc7_smob:
2876 if (!SCM_SMOB_APPLICABLE_P (proc))
2877 goto badfun;
2878 RETURN (SCM_SMOB_APPLY_2 (proc, t.arg1, arg2));
2879 cclon:
2880 case scm_tc7_cclo:
2881 #ifdef DEVAL
2882 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2883 scm_cons (proc, debug.info->a.args),
2884 SCM_EOL));
2885 #else
2886 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2887 scm_cons2 (proc, t.arg1,
2888 scm_cons (arg2,
2889 scm_eval_args (x,
2890 env,
2891 proc))),
2892 SCM_EOL));
2893 #endif
2894 case scm_tcs_cons_gloc:
2895 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2896 {
2897 x = SCM_ENTITY_PROCEDURE (proc);
2898 #ifdef DEVAL
2899 arg2 = debug.info->a.args;
2900 #else
2901 arg2 = scm_cons2 (t.arg1, arg2, SCM_EOL);
2902 #endif
2903 goto type_dispatch;
2904 }
2905 else if (!SCM_I_OPERATORP (proc))
2906 goto badfun;
2907 else
2908 {
2909 operatorn:
2910 #ifdef DEVAL
2911 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2912 ? SCM_ENTITY_PROCEDURE (proc)
2913 : SCM_OPERATOR_PROCEDURE (proc),
2914 scm_cons (proc, debug.info->a.args),
2915 SCM_EOL));
2916 #else
2917 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2918 ? SCM_ENTITY_PROCEDURE (proc)
2919 : SCM_OPERATOR_PROCEDURE (proc),
2920 scm_cons2 (proc, t.arg1,
2921 scm_cons (arg2,
2922 scm_eval_args (x,
2923 env,
2924 proc))),
2925 SCM_EOL));
2926 #endif
2927 }
2928 case scm_tc7_subr_0:
2929 case scm_tc7_cxr:
2930 case scm_tc7_subr_1o:
2931 case scm_tc7_subr_1:
2932 case scm_tc7_subr_3:
2933 goto wrongnumargs;
2934 default:
2935 goto badfun;
2936 case scm_tc7_pws:
2937 proc = SCM_PROCEDURE (proc);
2938 #ifdef DEVAL
2939 debug.info->a.proc = proc;
2940 #endif
2941 if (!SCM_CLOSUREP (proc))
2942 goto evap2;
2943 if (scm_badformalsp (proc, 2))
2944 goto umwrongnumargs;
2945 case scm_tcs_closures:
2946 /* clos2: */
2947 #ifdef DEVAL
2948 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
2949 debug.info->a.args,
2950 SCM_ENV (proc));
2951 #else
2952 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
2953 scm_cons2 (t.arg1, arg2, SCM_EOL), SCM_ENV (proc));
2954 #endif
2955 x = SCM_CODE (proc);
2956 goto cdrxbegin;
2957 }
2958 }
2959 #ifdef SCM_CAUTIOUS
2960 if (SCM_IMP (x) || SCM_NECONSP (x))
2961 goto wrongnumargs;
2962 #endif
2963 #ifdef DEVAL
2964 debug.info->a.args = scm_cons2 (t.arg1, arg2,
2965 scm_deval_args (x, env, proc,
2966 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
2967 #endif
2968 ENTER_APPLY;
2969 evap3:
2970 switch (SCM_TYP7 (proc))
2971 { /* have 3 or more arguments */
2972 #ifdef DEVAL
2973 case scm_tc7_subr_3:
2974 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
2975 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
2976 SCM_CADDR (debug.info->a.args)));
2977 case scm_tc7_asubr:
2978 #ifdef BUILTIN_RPASUBR
2979 t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
2980 arg2 = SCM_CDR (SCM_CDR (debug.info->a.args));
2981 do
2982 {
2983 t.arg1 = SCM_SUBRF(proc)(t.arg1, SCM_CAR (arg2));
2984 arg2 = SCM_CDR (arg2);
2985 }
2986 while (SCM_NIMP (arg2));
2987 RETURN (t.arg1)
2988 #endif /* BUILTIN_RPASUBR */
2989 case scm_tc7_rpsubr:
2990 #ifdef BUILTIN_RPASUBR
2991 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
2992 RETURN (SCM_BOOL_F)
2993 t.arg1 = SCM_CDR (SCM_CDR (debug.info->a.args));
2994 do
2995 {
2996 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, SCM_CAR (t.arg1))))
2997 RETURN (SCM_BOOL_F)
2998 arg2 = SCM_CAR (t.arg1);
2999 t.arg1 = SCM_CDR (t.arg1);
3000 }
3001 while (SCM_NIMP (t.arg1));
3002 RETURN (SCM_BOOL_T)
3003 #else /* BUILTIN_RPASUBR */
3004 RETURN (SCM_APPLY (proc, t.arg1,
3005 scm_acons (arg2,
3006 SCM_CDR (SCM_CDR (debug.info->a.args)),
3007 SCM_EOL)))
3008 #endif /* BUILTIN_RPASUBR */
3009 case scm_tc7_lsubr_2:
3010 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
3011 SCM_CDR (SCM_CDR (debug.info->a.args))))
3012 case scm_tc7_lsubr:
3013 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
3014 case scm_tc7_smob:
3015 if (!SCM_SMOB_APPLICABLE_P (proc))
3016 goto badfun;
3017 RETURN (SCM_SMOB_APPLY_3 (proc, t.arg1, arg2,
3018 SCM_CDDR (debug.info->a.args)));
3019 case scm_tc7_cclo:
3020 goto cclon;
3021 case scm_tc7_pws:
3022 proc = SCM_PROCEDURE (proc);
3023 debug.info->a.proc = proc;
3024 if (!SCM_CLOSUREP (proc))
3025 goto evap3;
3026 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), debug.info->a.args))
3027 goto umwrongnumargs;
3028 case scm_tcs_closures:
3029 SCM_SET_ARGSREADY (debug);
3030 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
3031 debug.info->a.args,
3032 SCM_ENV (proc));
3033 x = SCM_CODE (proc);
3034 goto cdrxbegin;
3035 #else /* DEVAL */
3036 case scm_tc7_subr_3:
3037 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
3038 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, EVALCAR (x, env)));
3039 case scm_tc7_asubr:
3040 #ifdef BUILTIN_RPASUBR
3041 t.arg1 = SCM_SUBRF (proc) (t.arg1, arg2);
3042 do
3043 {
3044 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
3045 x = SCM_CDR(x);
3046 }
3047 while (SCM_NIMP (x));
3048 RETURN (t.arg1)
3049 #endif /* BUILTIN_RPASUBR */
3050 case scm_tc7_rpsubr:
3051 #ifdef BUILTIN_RPASUBR
3052 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
3053 RETURN (SCM_BOOL_F)
3054 do
3055 {
3056 t.arg1 = EVALCAR (x, env);
3057 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, t.arg1)))
3058 RETURN (SCM_BOOL_F)
3059 arg2 = t.arg1;
3060 x = SCM_CDR (x);
3061 }
3062 while (SCM_NIMP (x));
3063 RETURN (SCM_BOOL_T)
3064 #else /* BUILTIN_RPASUBR */
3065 RETURN (SCM_APPLY (proc, t.arg1,
3066 scm_acons (arg2,
3067 scm_eval_args (x, env, proc),
3068 SCM_EOL)));
3069 #endif /* BUILTIN_RPASUBR */
3070 case scm_tc7_lsubr_2:
3071 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, scm_eval_args (x, env, proc)));
3072 case scm_tc7_lsubr:
3073 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1,
3074 arg2,
3075 scm_eval_args (x, env, proc))));
3076 case scm_tc7_smob:
3077 if (!SCM_SMOB_APPLICABLE_P (proc))
3078 goto badfun;
3079 RETURN (SCM_SMOB_APPLY_3 (proc, t.arg1, arg2,
3080 scm_eval_args (x, env, proc)));
3081 case scm_tc7_cclo:
3082 goto cclon;
3083 case scm_tc7_pws:
3084 proc = SCM_PROCEDURE (proc);
3085 if (!SCM_CLOSUREP (proc))
3086 goto evap3;
3087 {
3088 SCM formals = SCM_CAR (SCM_CODE (proc));
3089 if (SCM_NULLP (formals)
3090 || (SCM_CONSP (formals)
3091 && (SCM_NULLP (SCM_CDR (formals))
3092 || (SCM_CONSP (SCM_CDR (formals))
3093 && scm_badargsp (SCM_CDDR (formals), x)))))
3094 goto umwrongnumargs;
3095 }
3096 case scm_tcs_closures:
3097 #ifdef DEVAL
3098 SCM_SET_ARGSREADY (debug);
3099 #endif
3100 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
3101 scm_cons2 (t.arg1,
3102 arg2,
3103 scm_eval_args (x, env, proc)),
3104 SCM_ENV (proc));
3105 x = SCM_CODE (proc);
3106 goto cdrxbegin;
3107 #endif /* DEVAL */
3108 case scm_tcs_cons_gloc:
3109 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3110 {
3111 #ifdef DEVAL
3112 arg2 = debug.info->a.args;
3113 #else
3114 arg2 = scm_cons2 (t.arg1, arg2, scm_eval_args (x, env, proc));
3115 #endif
3116 x = SCM_ENTITY_PROCEDURE (proc);
3117 goto type_dispatch;
3118 }
3119 else if (!SCM_I_OPERATORP (proc))
3120 goto badfun;
3121 else
3122 goto operatorn;
3123 case scm_tc7_subr_2:
3124 case scm_tc7_subr_1o:
3125 case scm_tc7_subr_2o:
3126 case scm_tc7_subr_0:
3127 case scm_tc7_cxr:
3128 case scm_tc7_subr_1:
3129 goto wrongnumargs;
3130 default:
3131 goto badfun;
3132 }
3133 }
3134 #ifdef DEVAL
3135 exit:
3136 if (CHECK_EXIT && SCM_TRAPS_P)
3137 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
3138 {
3139 SCM_CLEAR_TRACED_FRAME (debug);
3140 if (SCM_CHEAPTRAPS_P)
3141 t.arg1 = scm_make_debugobj (&debug);
3142 else
3143 {
3144 int first;
3145 SCM val = scm_make_continuation (&first);
3146
3147 if (first)
3148 t.arg1 = val;
3149 else
3150 {
3151 proc = val;
3152 goto ret;
3153 }
3154 }
3155 scm_ithrow (scm_sym_exit_frame, scm_cons2 (t.arg1, proc, SCM_EOL), 0);
3156 }
3157 ret:
3158 scm_last_debug_frame = debug.prev;
3159 return proc;
3160 #endif
3161 }
3162
3163
3164 /* SECTION: This code is compiled once.
3165 */
3166
3167 #ifndef DEVAL
3168
3169 /* This code processes the arguments to apply:
3170
3171 (apply PROC ARG1 ... ARGS)
3172
3173 Given a list (ARG1 ... ARGS), this function conses the ARG1
3174 ... arguments onto the front of ARGS, and returns the resulting
3175 list. Note that ARGS is a list; thus, the argument to this
3176 function is a list whose last element is a list.
3177
3178 Apply calls this function, and applies PROC to the elements of the
3179 result. apply:nconc2last takes care of building the list of
3180 arguments, given (ARG1 ... ARGS).
3181
3182 Rather than do new consing, apply:nconc2last destroys its argument.
3183 On that topic, this code came into my care with the following
3184 beautifully cryptic comment on that topic: "This will only screw
3185 you if you do (scm_apply scm_apply '( ... ))" If you know what
3186 they're referring to, send me a patch to this comment. */
3187
3188 SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
3189 (SCM lst),
3190 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
3191 "conses the @var{arg1} @dots{} arguments onto the front of\n"
3192 "@var{args}, and returns the resulting list. Note that\n"
3193 "@var{args} is a list; thus, the argument to this function is\n"
3194 "a list whose last element is a list.\n"
3195 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
3196 "destroys its argument, so use with care.")
3197 #define FUNC_NAME s_scm_nconc2last
3198 {
3199 SCM *lloc;
3200 SCM_VALIDATE_NONEMPTYLIST (1,lst);
3201 lloc = &lst;
3202 while (SCM_NNULLP (SCM_CDR (*lloc)))
3203 lloc = SCM_CDRLOC (*lloc);
3204 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
3205 *lloc = SCM_CAR (*lloc);
3206 return lst;
3207 }
3208 #undef FUNC_NAME
3209
3210 #endif /* !DEVAL */
3211
3212
3213 /* SECTION: When DEVAL is defined this code yields scm_dapply.
3214 * It is compiled twice.
3215 */
3216
3217 #if 0
3218
3219 SCM
3220 scm_apply (SCM proc, SCM arg1, SCM args)
3221 {}
3222 #endif
3223
3224 #if 0
3225
3226 SCM
3227 scm_dapply (SCM proc, SCM arg1, SCM args)
3228 { /* empty */ }
3229 #endif
3230
3231
3232 /* Apply a function to a list of arguments.
3233
3234 This function is exported to the Scheme level as taking two
3235 required arguments and a tail argument, as if it were:
3236 (lambda (proc arg1 . args) ...)
3237 Thus, if you just have a list of arguments to pass to a procedure,
3238 pass the list as ARG1, and '() for ARGS. If you have some fixed
3239 args, pass the first as ARG1, then cons any remaining fixed args
3240 onto the front of your argument list, and pass that as ARGS. */
3241
3242 SCM
3243 SCM_APPLY (SCM proc, SCM arg1, SCM args)
3244 {
3245 #ifdef DEBUG_EXTENSIONS
3246 #ifdef DEVAL
3247 scm_debug_frame debug;
3248 scm_debug_info debug_vect_body;
3249 debug.prev = scm_last_debug_frame;
3250 debug.status = SCM_APPLYFRAME;
3251 debug.vect = &debug_vect_body;
3252 debug.vect[0].a.proc = proc;
3253 debug.vect[0].a.args = SCM_EOL;
3254 scm_last_debug_frame = &debug;
3255 #else
3256 if (SCM_DEBUGGINGP)
3257 return scm_dapply (proc, arg1, args);
3258 #endif
3259 #endif
3260
3261 SCM_ASRTGO (SCM_NIMP (proc), badproc);
3262
3263 /* If ARGS is the empty list, then we're calling apply with only two
3264 arguments --- ARG1 is the list of arguments for PROC. Whatever
3265 the case, futz with things so that ARG1 is the first argument to
3266 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
3267 rest.
3268
3269 Setting the debug apply frame args this way is pretty messy.
3270 Perhaps we should store arg1 and args directly in the frame as
3271 received, and let scm_frame_arguments unpack them, because that's
3272 a relatively rare operation. This works for now; if the Guile
3273 developer archives are still around, see Mikael's post of
3274 11-Apr-97. */
3275 if (SCM_NULLP (args))
3276 {
3277 if (SCM_NULLP (arg1))
3278 {
3279 arg1 = SCM_UNDEFINED;
3280 #ifdef DEVAL
3281 debug.vect[0].a.args = SCM_EOL;
3282 #endif
3283 }
3284 else
3285 {
3286 #ifdef DEVAL
3287 debug.vect[0].a.args = arg1;
3288 #endif
3289 args = SCM_CDR (arg1);
3290 arg1 = SCM_CAR (arg1);
3291 }
3292 }
3293 else
3294 {
3295 args = scm_nconc2last (args);
3296 #ifdef DEVAL
3297 debug.vect[0].a.args = scm_cons (arg1, args);
3298 #endif
3299 }
3300 #ifdef DEVAL
3301 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
3302 {
3303 SCM tmp;
3304 if (SCM_CHEAPTRAPS_P)
3305 tmp = scm_make_debugobj (&debug);
3306 else
3307 {
3308 int first;
3309
3310 tmp = scm_make_continuation (&first);
3311 if (!first)
3312 goto entap;
3313 }
3314 scm_ithrow (scm_sym_enter_frame, scm_cons (tmp, SCM_EOL), 0);
3315 }
3316 entap:
3317 ENTER_APPLY;
3318 #endif
3319 tail:
3320 switch (SCM_TYP7 (proc))
3321 {
3322 case scm_tc7_subr_2o:
3323 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
3324 RETURN (SCM_SUBRF (proc) (arg1, args))
3325 case scm_tc7_subr_2:
3326 SCM_ASRTGO (SCM_NNULLP (args) && SCM_NULLP (SCM_CDR (args)),
3327 wrongnumargs);
3328 args = SCM_CAR (args);
3329 RETURN (SCM_SUBRF (proc) (arg1, args))
3330 case scm_tc7_subr_0:
3331 SCM_ASRTGO (SCM_UNBNDP (arg1), wrongnumargs);
3332 RETURN (SCM_SUBRF (proc) ())
3333 case scm_tc7_subr_1:
3334 SCM_ASRTGO (!SCM_UNBNDP (arg1), wrongnumargs);
3335 case scm_tc7_subr_1o:
3336 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
3337 RETURN (SCM_SUBRF (proc) (arg1))
3338 case scm_tc7_cxr:
3339 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
3340 if (SCM_SUBRF (proc))
3341 {
3342 if (SCM_INUMP (arg1))
3343 {
3344 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
3345 }
3346 SCM_ASRTGO (SCM_NIMP (arg1), floerr);
3347 if (SCM_REALP (arg1))
3348 {
3349 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
3350 }
3351 #ifdef SCM_BIGDIG
3352 if (SCM_BIGP (arg1))
3353 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_big2dbl (arg1))))
3354 #endif
3355 floerr:
3356 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3357 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
3358 }
3359 proc = SCM_SNAME (proc);
3360 {
3361 char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
3362 while ('c' != *--chrs)
3363 {
3364 SCM_ASSERT (SCM_CONSP (arg1),
3365 arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
3366 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3367 }
3368 RETURN (arg1)
3369 }
3370 case scm_tc7_subr_3:
3371 SCM_ASRTGO (SCM_NNULLP (args)
3372 && SCM_NNULLP (SCM_CDR (args))
3373 && SCM_NULLP (SCM_CDDR (args)),
3374 wrongnumargs);
3375 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CAR (SCM_CDR (args))))
3376 case scm_tc7_lsubr:
3377 #ifdef DEVAL
3378 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args))
3379 #else
3380 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)))
3381 #endif
3382 case scm_tc7_lsubr_2:
3383 SCM_ASRTGO (SCM_CONSP (args), wrongnumargs);
3384 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)))
3385 case scm_tc7_asubr:
3386 if (SCM_NULLP (args))
3387 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED))
3388 while (SCM_NIMP (args))
3389 {
3390 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3391 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
3392 args = SCM_CDR (args);
3393 }
3394 RETURN (arg1);
3395 case scm_tc7_rpsubr:
3396 if (SCM_NULLP (args))
3397 RETURN (SCM_BOOL_T);
3398 while (SCM_NIMP (args))
3399 {
3400 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3401 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
3402 RETURN (SCM_BOOL_F);
3403 arg1 = SCM_CAR (args);
3404 args = SCM_CDR (args);
3405 }
3406 RETURN (SCM_BOOL_T);
3407 case scm_tcs_closures:
3408 #ifdef DEVAL
3409 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
3410 #else
3411 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
3412 #endif
3413 #ifndef SCM_RECKLESS
3414 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), arg1))
3415 goto wrongnumargs;
3416 #endif
3417
3418 /* Copy argument list */
3419 if (SCM_IMP (arg1))
3420 args = arg1;
3421 else
3422 {
3423 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
3424 while (arg1 = SCM_CDR (arg1), SCM_CONSP (arg1))
3425 {
3426 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1),
3427 SCM_UNSPECIFIED));
3428 tl = SCM_CDR (tl);
3429 }
3430 SCM_SETCDR (tl, arg1);
3431 }
3432
3433 args = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), args, SCM_ENV (proc));
3434 proc = SCM_CDR (SCM_CODE (proc));
3435 again:
3436 arg1 = proc;
3437 while (SCM_NNULLP (arg1 = SCM_CDR (arg1)))
3438 {
3439 if (SCM_IMP (SCM_CAR (proc)))
3440 {
3441 if (SCM_ISYMP (SCM_CAR (proc)))
3442 {
3443 proc = scm_m_expand_body (proc, args);
3444 goto again;
3445 }
3446 }
3447 else
3448 SCM_CEVAL (SCM_CAR (proc), args);
3449 proc = arg1;
3450 }
3451 RETURN (EVALCAR (proc, args));
3452 case scm_tc7_smob:
3453 if (!SCM_SMOB_APPLICABLE_P (proc))
3454 goto badproc;
3455 if (SCM_UNBNDP (arg1))
3456 RETURN (SCM_SMOB_APPLY_0 (proc))
3457 else if (SCM_NULLP (args))
3458 RETURN (SCM_SMOB_APPLY_1 (proc, arg1))
3459 else if (SCM_NULLP (SCM_CDR (args)))
3460 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, SCM_CAR (args)))
3461 else
3462 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, SCM_CAR (args), SCM_CDR (args)));
3463 case scm_tc7_cclo:
3464 #ifdef DEVAL
3465 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3466 arg1 = proc;
3467 proc = SCM_CCLO_SUBR (proc);
3468 debug.vect[0].a.proc = proc;
3469 debug.vect[0].a.args = scm_cons (arg1, args);
3470 #else
3471 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3472 arg1 = proc;
3473 proc = SCM_CCLO_SUBR (proc);
3474 #endif
3475 goto tail;
3476 case scm_tc7_pws:
3477 proc = SCM_PROCEDURE (proc);
3478 #ifdef DEVAL
3479 debug.vect[0].a.proc = proc;
3480 #endif
3481 goto tail;
3482 case scm_tcs_cons_gloc:
3483 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3484 {
3485 #ifdef DEVAL
3486 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3487 #else
3488 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3489 #endif
3490 RETURN (scm_apply_generic (proc, args));
3491 }
3492 else if (!SCM_I_OPERATORP (proc))
3493 goto badproc;
3494 else
3495 {
3496 #ifdef DEVAL
3497 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3498 #else
3499 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3500 #endif
3501 arg1 = proc;
3502 proc = (SCM_I_ENTITYP (proc)
3503 ? SCM_ENTITY_PROCEDURE (proc)
3504 : SCM_OPERATOR_PROCEDURE (proc));
3505 #ifdef DEVAL
3506 debug.vect[0].a.proc = proc;
3507 debug.vect[0].a.args = scm_cons (arg1, args);
3508 #endif
3509 if (SCM_NIMP (proc))
3510 goto tail;
3511 else
3512 goto badproc;
3513 }
3514 wrongnumargs:
3515 scm_wrong_num_args (proc);
3516 default:
3517 badproc:
3518 scm_wta (proc, (char *) SCM_ARG1, "apply");
3519 RETURN (arg1);
3520 }
3521 #ifdef DEVAL
3522 exit:
3523 if (CHECK_EXIT && SCM_TRAPS_P)
3524 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
3525 {
3526 SCM_CLEAR_TRACED_FRAME (debug);
3527 if (SCM_CHEAPTRAPS_P)
3528 arg1 = scm_make_debugobj (&debug);
3529 else
3530 {
3531 int first;
3532 SCM val = scm_make_continuation (&first);
3533
3534 if (first)
3535 arg1 = val;
3536 else
3537 {
3538 proc = val;
3539 goto ret;
3540 }
3541 }
3542 scm_ithrow (scm_sym_exit_frame, scm_cons2 (arg1, proc, SCM_EOL), 0);
3543 }
3544 ret:
3545 scm_last_debug_frame = debug.prev;
3546 return proc;
3547 #endif
3548 }
3549
3550
3551 /* SECTION: The rest of this file is only read once.
3552 */
3553
3554 #ifndef DEVAL
3555
3556 /* Typechecking for multi-argument MAP and FOR-EACH.
3557
3558 Verify that each element of the vector ARGV, except for the first,
3559 is a proper list whose length is LEN. Attribute errors to WHO,
3560 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
3561 static inline void
3562 check_map_args (SCM argv,
3563 long len,
3564 SCM gf,
3565 SCM proc,
3566 SCM args,
3567 const char *who)
3568 {
3569 SCM *ve = SCM_VELTS (argv);
3570 int i;
3571
3572 for (i = SCM_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
3573 {
3574 int elt_len = scm_ilength (ve[i]);
3575
3576 if (elt_len < 0)
3577 {
3578 if (gf)
3579 scm_apply_generic (gf, scm_cons (proc, args));
3580 else
3581 scm_wrong_type_arg (who, i + 2, ve[i]);
3582 }
3583
3584 if (elt_len != len)
3585 scm_out_of_range (who, ve[i]);
3586 }
3587
3588 scm_remember_upto_here_1 (argv);
3589 }
3590
3591
3592 SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
3593
3594 /* Note: Currently, scm_map applies PROC to the argument list(s)
3595 sequentially, starting with the first element(s). This is used in
3596 evalext.c where the Scheme procedure `map-in-order', which guarantees
3597 sequential behaviour, is implemented using scm_map. If the
3598 behaviour changes, we need to update `map-in-order'.
3599 */
3600
3601 SCM
3602 scm_map (SCM proc, SCM arg1, SCM args)
3603 #define FUNC_NAME s_map
3604 {
3605 long i, len;
3606 SCM res = SCM_EOL;
3607 SCM *pres = &res;
3608 SCM *ve = &args; /* Keep args from being optimized away. */
3609
3610 len = scm_ilength (arg1);
3611 SCM_GASSERTn (len >= 0,
3612 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
3613 SCM_VALIDATE_REST_ARGUMENT (args);
3614 if (SCM_NULLP (args))
3615 {
3616 while (SCM_NIMP (arg1))
3617 {
3618 *pres = scm_cons (scm_apply (proc, SCM_CAR (arg1), scm_listofnull),
3619 SCM_EOL);
3620 pres = SCM_CDRLOC (*pres);
3621 arg1 = SCM_CDR (arg1);
3622 }
3623 return res;
3624 }
3625 args = scm_vector (arg1 = scm_cons (arg1, args));
3626 ve = SCM_VELTS (args);
3627 #ifndef SCM_RECKLESS
3628 check_map_args (args, len, g_map, proc, arg1, s_map);
3629 #endif
3630 while (1)
3631 {
3632 arg1 = SCM_EOL;
3633 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
3634 {
3635 if (SCM_IMP (ve[i]))
3636 return res;
3637 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3638 ve[i] = SCM_CDR (ve[i]);
3639 }
3640 *pres = scm_cons (scm_apply (proc, arg1, SCM_EOL), SCM_EOL);
3641 pres = SCM_CDRLOC (*pres);
3642 }
3643 }
3644 #undef FUNC_NAME
3645
3646
3647 SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
3648
3649 SCM
3650 scm_for_each (SCM proc, SCM arg1, SCM args)
3651 #define FUNC_NAME s_for_each
3652 {
3653 SCM *ve = &args; /* Keep args from being optimized away. */
3654 long i, len;
3655 len = scm_ilength (arg1);
3656 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
3657 SCM_ARG2, s_for_each);
3658 SCM_VALIDATE_REST_ARGUMENT (args);
3659 if SCM_NULLP (args)
3660 {
3661 while SCM_NIMP (arg1)
3662 {
3663 scm_apply (proc, SCM_CAR (arg1), scm_listofnull);
3664 arg1 = SCM_CDR (arg1);
3665 }
3666 return SCM_UNSPECIFIED;
3667 }
3668 args = scm_vector (arg1 = scm_cons (arg1, args));
3669 ve = SCM_VELTS (args);
3670 #ifndef SCM_RECKLESS
3671 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
3672 #endif
3673 while (1)
3674 {
3675 arg1 = SCM_EOL;
3676 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
3677 {
3678 if SCM_IMP
3679 (ve[i]) return SCM_UNSPECIFIED;
3680 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3681 ve[i] = SCM_CDR (ve[i]);
3682 }
3683 scm_apply (proc, arg1, SCM_EOL);
3684 }
3685 }
3686 #undef FUNC_NAME
3687
3688
3689 SCM
3690 scm_closure (SCM code, SCM env)
3691 {
3692 register SCM z;
3693 SCM_NEWCELL (z);
3694 SCM_SETCODE (z, code);
3695 SCM_SETENV (z, env);
3696 return z;
3697 }
3698
3699
3700 scm_bits_t scm_tc16_promise;
3701
3702 SCM
3703 scm_makprom (SCM code)
3704 {
3705 SCM_RETURN_NEWSMOB (scm_tc16_promise, SCM_UNPACK (code));
3706 }
3707
3708
3709
3710 static int
3711 promise_print (SCM exp, SCM port, scm_print_state *pstate)
3712 {
3713 int writingp = SCM_WRITINGP (pstate);
3714 scm_puts ("#<promise ", port);
3715 SCM_SET_WRITINGP (pstate, 1);
3716 scm_iprin1 (SCM_CDR (exp), port, pstate);
3717 SCM_SET_WRITINGP (pstate, writingp);
3718 scm_putc ('>', port);
3719 return !0;
3720 }
3721
3722
3723 SCM_DEFINE (scm_force, "force", 1, 0, 0,
3724 (SCM x),
3725 "If the promise X has not been computed yet, compute and return\n"
3726 "X, otherwise just return the previously computed value.")
3727 #define FUNC_NAME s_scm_force
3728 {
3729 SCM_VALIDATE_SMOB (1, x, promise);
3730 if (!((1L << 16) & SCM_CELL_WORD_0 (x)))
3731 {
3732 SCM ans = scm_apply (SCM_CELL_OBJECT_1 (x), SCM_EOL, SCM_EOL);
3733 if (!((1L << 16) & SCM_CELL_WORD_0 (x)))
3734 {
3735 SCM_DEFER_INTS;
3736 SCM_SET_CELL_OBJECT_1 (x, ans);
3737 SCM_SET_CELL_WORD_0 (x, SCM_CELL_WORD_0 (x) | (1L << 16));
3738 SCM_ALLOW_INTS;
3739 }
3740 }
3741 return SCM_CELL_OBJECT_1 (x);
3742 }
3743 #undef FUNC_NAME
3744
3745
3746 SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
3747 (SCM x),
3748 "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
3749 "(@pxref{Delayed evaluation,,,r4rs.info,The Revised^4 Report on Scheme}).")
3750 #define FUNC_NAME s_scm_promise_p
3751 {
3752 return SCM_BOOL (SCM_TYP16_PREDICATE (scm_tc16_promise, x));
3753 }
3754 #undef FUNC_NAME
3755
3756
3757 SCM_DEFINE (scm_cons_source, "cons-source", 3, 0, 0,
3758 (SCM xorig, SCM x, SCM y),
3759 "Create and return a new pair whose car and cdr are @var{x} and @var{y}.\n"
3760 "Any source properties associated with @var{xorig} are also associated\n"
3761 "with the new pair.")
3762 #define FUNC_NAME s_scm_cons_source
3763 {
3764 SCM p, z;
3765 SCM_NEWCELL (z);
3766 SCM_SET_CELL_OBJECT_0 (z, x);
3767 SCM_SET_CELL_OBJECT_1 (z, y);
3768 /* Copy source properties possibly associated with xorig. */
3769 p = scm_whash_lookup (scm_source_whash, xorig);
3770 if (!SCM_IMP (p))
3771 scm_whash_insert (scm_source_whash, z, p);
3772 return z;
3773 }
3774 #undef FUNC_NAME
3775
3776
3777 SCM_DEFINE (scm_copy_tree, "copy-tree", 1, 0, 0,
3778 (SCM obj),
3779 "Recursively copy the data tree that is bound to @var{obj}, and return a\n"
3780 "pointer to the new data structure. @code{copy-tree} recurses down the\n"
3781 "contents of both pairs and vectors (since both cons cells and vector\n"
3782 "cells may point to arbitrary objects), and stops recursing when it hits\n"
3783 "any other object.")
3784 #define FUNC_NAME s_scm_copy_tree
3785 {
3786 SCM ans, tl;
3787 if (SCM_IMP (obj))
3788 return obj;
3789 if (SCM_VECTORP (obj))
3790 {
3791 scm_sizet i = SCM_VECTOR_LENGTH (obj);
3792 ans = scm_c_make_vector (i, SCM_UNSPECIFIED);
3793 while (i--)
3794 SCM_VELTS (ans)[i] = scm_copy_tree (SCM_VELTS (obj)[i]);
3795 return ans;
3796 }
3797 if (SCM_NCONSP (obj))
3798 return obj;
3799 ans = tl = scm_cons_source (obj,
3800 scm_copy_tree (SCM_CAR (obj)),
3801 SCM_UNSPECIFIED);
3802 while (obj = SCM_CDR (obj), SCM_CONSP (obj))
3803 {
3804 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
3805 SCM_UNSPECIFIED));
3806 tl = SCM_CDR (tl);
3807 }
3808 SCM_SETCDR (tl, obj);
3809 return ans;
3810 }
3811 #undef FUNC_NAME
3812
3813
3814 /* We have three levels of EVAL here:
3815
3816 - scm_i_eval (exp, env)
3817
3818 evaluates EXP in environment ENV. ENV is a lexical environment
3819 structure as used by the actual tree code evaluator. When ENV is
3820 a top-level environment, then changes to the current module are
3821 tracked by modifying ENV so that it continues to be in sync with
3822 the current module.
3823
3824 - scm_primitive_eval (exp)
3825
3826 evaluates EXP in the top-level environment as determined by the
3827 current module. This is done by constructing a suitable
3828 environment and calling scm_i_eval. Thus, changes to the
3829 top-level module are tracked normally.
3830
3831 - scm_eval (exp, mod)
3832
3833 evaluates EXP while MOD is the current module. Thius is done by
3834 setting the current module to MOD, invoking scm_primitive_eval on
3835 EXP, and then restoring the current module to the value it had
3836 previously. That is, while EXP is evaluated, changes to the
3837 current module are tracked, but these changes do not persist when
3838 scm_eval returns.
3839
3840 For each level of evals, there are two variants, distinguished by a
3841 _x suffix: the ordinary variant does not modify EXP while the _x
3842 variant can destructively modify EXP into something completely
3843 unintelligible. A Scheme data structure passed as EXP to one of the
3844 _x variants should not ever be used again for anything. So when in
3845 doubt, use the ordinary variant.
3846
3847 */
3848
3849 SCM scm_system_transformer;
3850
3851 /* XXX - scm_i_eval is meant to be useable for evaluation in
3852 non-toplevel environments, for example when used by the debugger.
3853 Can the system transform deal with this? */
3854
3855 SCM
3856 scm_i_eval_x (SCM exp, SCM env)
3857 {
3858 SCM transformer = scm_fluid_ref (SCM_CDR (scm_system_transformer));
3859 if (SCM_NIMP (transformer))
3860 exp = scm_apply (transformer, exp, scm_listofnull);
3861 return SCM_XEVAL (exp, env);
3862 }
3863
3864 SCM
3865 scm_i_eval (SCM exp, SCM env)
3866 {
3867 SCM transformer = scm_fluid_ref (SCM_CDR (scm_system_transformer));
3868 if (SCM_NIMP (transformer))
3869 exp = scm_apply (transformer, exp, scm_listofnull);
3870 exp = scm_copy_tree (exp);
3871 return SCM_XEVAL (exp, env);
3872 }
3873
3874 SCM
3875 scm_primitive_eval_x (SCM exp)
3876 {
3877 SCM env = scm_top_level_env (scm_current_module_lookup_closure ());
3878 return scm_i_eval_x (exp, env);
3879 }
3880
3881 SCM_DEFINE (scm_primitive_eval, "primitive-eval", 1, 0, 0,
3882 (SCM exp),
3883 "Evaluate @var{exp} in the top-level environment specified by\n"
3884 "the current module.")
3885 #define FUNC_NAME s_scm_primitive_eval
3886 {
3887 SCM env = scm_top_level_env (scm_current_module_lookup_closure ());
3888 return scm_i_eval (exp, env);
3889 }
3890 #undef FUNC_NAME
3891
3892 /* Eval does not take the second arg optionally. This is intentional
3893 * in order to be R5RS compatible, and to prepare for the new module
3894 * system, where we would like to make the choice of evaluation
3895 * environment explicit. */
3896
3897 static void
3898 change_environment (void *data)
3899 {
3900 SCM pair = SCM_PACK (data);
3901 SCM new_module = SCM_CAR (pair);
3902 SCM old_module = scm_current_module ();
3903 SCM_SETCDR (pair, old_module);
3904 scm_set_current_module (new_module);
3905 }
3906
3907
3908 static void
3909 restore_environment (void *data)
3910 {
3911 SCM pair = SCM_PACK (data);
3912 SCM old_module = SCM_CDR (pair);
3913 SCM new_module = scm_current_module ();
3914 SCM_SETCAR (pair, new_module);
3915 scm_set_current_module (old_module);
3916 }
3917
3918 static SCM
3919 inner_eval_x (void *data)
3920 {
3921 return scm_primitive_eval_x (SCM_PACK(data));
3922 }
3923
3924 SCM
3925 scm_eval_x (SCM exp, SCM module)
3926 #define FUNC_NAME "eval!"
3927 {
3928 SCM_VALIDATE_MODULE (2, module);
3929
3930 return scm_internal_dynamic_wind
3931 (change_environment, inner_eval_x, restore_environment,
3932 (void *) SCM_UNPACK (exp),
3933 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
3934 }
3935 #undef FUNC_NAME
3936
3937 static SCM
3938 inner_eval (void *data)
3939 {
3940 return scm_primitive_eval (SCM_PACK(data));
3941 }
3942
3943 SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
3944 (SCM exp, SCM module),
3945 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
3946 "in the top-level environment specified by @var{module}.\n"
3947 "While @var{exp} is evaluated (using @var{primitive-eval}),\n"
3948 "@var{module} is made the current module. The current module\n"
3949 "is reset to its previous value when @var{eval} returns.")
3950 #define FUNC_NAME s_scm_eval
3951 {
3952 SCM_VALIDATE_MODULE (2, module);
3953
3954 return scm_internal_dynamic_wind
3955 (change_environment, inner_eval, restore_environment,
3956 (void *) SCM_UNPACK (exp),
3957 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
3958 }
3959 #undef FUNC_NAME
3960
3961 #if (SCM_DEBUG_DEPRECATED == 0)
3962
3963 /* Use scm_current_module () or scm_interaction_environment ()
3964 * instead. The former is the module selected during loading of code.
3965 * The latter is the module in which the user of this thread currently
3966 * types expressions.
3967 */
3968
3969 SCM scm_top_level_lookup_closure_var;
3970
3971 /* Avoid using this functionality altogether (except for implementing
3972 * libguile, where you can use scm_i_eval or scm_i_eval_x).
3973 *
3974 * Applications should use either C level scm_eval_x or Scheme
3975 * scm_eval; or scm_primitive_eval_x or scm_primitive_eval. */
3976
3977 SCM
3978 scm_eval_3 (SCM obj, int copyp, SCM env)
3979 {
3980 if (copyp)
3981 return scm_i_eval (obj, env);
3982 else
3983 return scm_i_eval_x (obj, env);
3984 }
3985
3986 SCM_DEFINE (scm_eval2, "eval2", 2, 0, 0,
3987 (SCM obj, SCM env_thunk),
3988 "Evaluate @var{exp}, a Scheme expression, in the environment\n"
3989 "designated by @var{lookup}, a symbol-lookup function."
3990 "Do not use this version of eval, it does not play well\n"
3991 "with the module system. Use @code{eval} or\n"
3992 "@code{primitive-eval} instead.")
3993 #define FUNC_NAME s_scm_eval2
3994 {
3995 return scm_i_eval (obj, scm_top_level_env (env_thunk));
3996 }
3997 #undef FUNC_NAME
3998
3999 #endif /* DEPRECATED */
4000
4001
4002 /* At this point, scm_deval and scm_dapply are generated.
4003 */
4004
4005 #ifdef DEBUG_EXTENSIONS
4006 # define DEVAL
4007 # include "eval.c"
4008 #endif
4009
4010
4011
4012 void
4013 scm_init_eval ()
4014 {
4015 scm_init_opts (scm_evaluator_traps,
4016 scm_evaluator_trap_table,
4017 SCM_N_EVALUATOR_TRAPS);
4018 scm_init_opts (scm_eval_options_interface,
4019 scm_eval_opts,
4020 SCM_N_EVAL_OPTIONS);
4021
4022 scm_tc16_promise = scm_make_smob_type ("promise", 0);
4023 scm_set_smob_mark (scm_tc16_promise, scm_markcdr);
4024 scm_set_smob_print (scm_tc16_promise, promise_print);
4025
4026 scm_f_apply = scm_make_subr ("apply", scm_tc7_lsubr_2, scm_apply);
4027 scm_system_transformer = scm_sysintern ("scm:eval-transformer",
4028 scm_make_fluid ());
4029
4030 scm_lisp_nil = scm_sysintern ("nil", SCM_UNDEFINED);
4031 SCM_SETCDR (scm_lisp_nil, SCM_CAR (scm_lisp_nil));
4032 scm_lisp_nil = SCM_CAR (scm_lisp_nil);
4033 scm_lisp_t = scm_sysintern ("t", SCM_UNDEFINED);
4034 SCM_SETCDR (scm_lisp_t, SCM_CAR (scm_lisp_t));
4035 scm_lisp_t = SCM_CAR (scm_lisp_t);
4036
4037 /* acros */
4038 /* end of acros */
4039
4040 #if SCM_DEBUG_DEPRECATED == 0
4041 scm_top_level_lookup_closure_var =
4042 scm_sysintern ("*top-level-lookup-closure*", scm_make_fluid ());
4043 #endif
4044
4045 #ifndef SCM_MAGIC_SNARFER
4046 #include "libguile/eval.x"
4047 #endif
4048
4049 scm_add_feature ("delay");
4050 }
4051
4052 #endif /* !DEVAL */
4053
4054 /*
4055 Local Variables:
4056 c-file-style: "gnu"
4057 End:
4058 */