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