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