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