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