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