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