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