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