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