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