* Replaced a lot of calls to SCM_C[AD]R with more appropriate macros.
[bpt/guile.git] / libguile / eval.c
CommitLineData
22a52da1 1/* Copyright (C) 1995,1996,1997,1998,1999,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"
a513ead3 103#include "libguile/values.h"
a0599745
MD
104
105#include "libguile/validate.h"
106#include "libguile/eval.h"
89efbff4 107
0f2d19dd
JB
108\f
109
6dbd0af5
MD
110/* The evaluator contains a plethora of EVAL symbols.
111 * This is an attempt at explanation.
112 *
113 * The following macros should be used in code which is read twice
114 * (where the choice of evaluator is hard soldered):
115 *
116 * SCM_CEVAL is the symbol used within one evaluator to call itself.
117 * Originally, it is defined to scm_ceval, but is redefined to
118 * scm_deval during the second pass.
119 *
120 * SIDEVAL corresponds to SCM_CEVAL, but is used in situations where
121 * only side effects of expressions matter. All immediates are
122 * ignored.
123 *
6cb702da 124 * SCM_EVALIM is used when it is known that the expression is an
6dbd0af5
MD
125 * immediate. (This macro never calls an evaluator.)
126 *
127 * EVALCAR evaluates the car of an expression.
128 *
129 * EVALCELLCAR is like EVALCAR, but is used when it is known that the
130 * car is a lisp cell.
131 *
132 * The following macros should be used in code which is read once
133 * (where the choice of evaluator is dynamic):
134 *
6cb702da 135 * SCM_XEVAL takes care of immediates without calling an evaluator. It
6dbd0af5
MD
136 * then calls scm_ceval *or* scm_deval, depending on the debugging
137 * mode.
138 *
6cb702da 139 * SCM_XEVALCAR corresponds to EVALCAR, but uses scm_ceval *or* scm_deval
6dbd0af5
MD
140 * depending on the debugging mode.
141 *
142 * The main motivation for keeping this plethora is efficiency
143 * together with maintainability (=> locality of code).
144 */
145
6cb702da 146#define SCM_CEVAL scm_ceval
7d2b68a8 147#define SIDEVAL(x, env) if (SCM_NIMP (x)) SCM_CEVAL((x), (env))
6cb702da 148
7d2b68a8
MD
149#define EVALCELLCAR(x, env) (SCM_SYMBOLP (SCM_CAR (x)) \
150 ? *scm_lookupcar (x, env, 1) \
151 : SCM_CEVAL (SCM_CAR (x), env))
0f2d19dd 152
22a52da1 153#define EVALCAR(x, env) (!SCM_CELLP (SCM_CAR (x)) \
7d2b68a8
MD
154 ? (SCM_IMP (SCM_CAR (x)) \
155 ? SCM_EVALIM (SCM_CAR (x), env) \
156 : SCM_GLOC_VAL (SCM_CAR (x))) \
157 : EVALCELLCAR (x, env))
0f2d19dd 158
e2806c10 159#define EXTEND_ENV SCM_EXTEND_ENV
0f2d19dd
JB
160
161#ifdef MEMOIZE_LOCALS
1cc91f1b 162
0f2d19dd 163SCM *
6e8d25a6 164scm_ilookup (SCM iloc, SCM env)
0f2d19dd
JB
165{
166 register int ir = SCM_IFRAME (iloc);
167 register SCM er = env;
168 for (; 0 != ir; --ir)
169 er = SCM_CDR (er);
170 er = SCM_CAR (er);
171 for (ir = SCM_IDIST (iloc); 0 != ir; --ir)
172 er = SCM_CDR (er);
173 if (SCM_ICDRP (iloc))
a23afe53
MD
174 return SCM_CDRLOC (er);
175 return SCM_CARLOC (SCM_CDR (er));
0f2d19dd
JB
176}
177#endif
178
f8769b1d
MV
179#ifdef USE_THREADS
180
181/* The Lookup Car Race
182 - by Eva Luator
183
184 Memoization of variables and special forms is done while executing
185 the code for the first time. As long as there is only one thread
186 everything is fine, but as soon as two threads execute the same
187 code concurrently `for the first time' they can come into conflict.
188
189 This memoization includes rewriting variable references into more
190 efficient forms and expanding macros. Furthermore, macro expansion
191 includes `compiling' special forms like `let', `cond', etc. into
192 tree-code instructions.
193
194 There shouldn't normally be a problem with memoizing local and
195 global variable references (into ilocs and glocs), because all
196 threads will mutate the code in *exactly* the same way and (if I
197 read the C code correctly) it is not possible to observe a half-way
198 mutated cons cell. The lookup procedure can handle this
199 transparently without any critical sections.
200
201 It is different with macro expansion, because macro expansion
202 happens outside of the lookup procedure and can't be
203 undone. Therefore it can't cope with it. It has to indicate
204 failure when it detects a lost race and hope that the caller can
205 handle it. Luckily, it turns out that this is the case.
206
207 An example to illustrate this: Suppose that the follwing form will
208 be memoized concurrently by two threads
209
210 (let ((x 12)) x)
211
212 Let's first examine the lookup of X in the body. The first thread
213 decides that it has to find the symbol "x" in the environment and
214 starts to scan it. Then the other thread takes over and actually
215 overtakes the first. It looks up "x" and substitutes an
216 appropriate iloc for it. Now the first thread continues and
217 completes its lookup. It comes to exactly the same conclusions as
218 the second one and could - without much ado - just overwrite the
219 iloc with the same iloc.
220
221 But let's see what will happen when the race occurs while looking
222 up the symbol "let" at the start of the form. It could happen that
223 the second thread interrupts the lookup of the first thread and not
224 only substitutes a gloc for it but goes right ahead and replaces it
225 with the compiled form (#@let* (x 12) x). Now, when the first
226 thread completes its lookup, it would replace the #@let* with a
227 gloc pointing to the "let" binding, effectively reverting the form
228 to (let (x 12) x). This is wrong. It has to detect that it has
229 lost the race and the evaluator has to reconsider the changed form
230 completely.
231
232 This race condition could be resolved with some kind of traffic
233 light (like mutexes) around scm_lookupcar, but I think that it is
234 best to avoid them in this case. They would serialize memoization
235 completely and because lookup involves calling arbitrary Scheme
236 code (via the lookup-thunk), threads could be blocked for an
237 arbitrary amount of time or even deadlock. But with the current
238 solution a lot of unnecessary work is potentially done. */
239
240/* SCM_LOOKUPCAR1 is was SCM_LOOKUPCAR used to be but is allowed to
241 return NULL to indicate a failed lookup due to some race conditions
242 between threads. This only happens when VLOC is the first cell of
243 a special form that will eventually be memoized (like `let', etc.)
244 In that case the whole lookup is bogus and the caller has to
245 reconsider the complete special form.
246
247 SCM_LOOKUPCAR is still there, of course. It just calls
248 SCM_LOOKUPCAR1 and aborts on recieving NULL. So SCM_LOOKUPCAR
249 should only be called when it is known that VLOC is not the first
250 pair of a special form. Otherwise, use SCM_LOOKUPCAR1 and check
26d5b9b4
MD
251 for NULL. I think I've found the only places where this
252 applies. */
f8769b1d
MV
253
254#endif /* USE_THREADS */
1cc91f1b 255
f25f761d
GH
256SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
257
d0b7bad7 258#ifdef USE_THREADS
8ecf1f13 259static SCM *
26d5b9b4 260scm_lookupcar1 (SCM vloc, SCM genv, int check)
d0b7bad7
MD
261#else
262SCM *
26d5b9b4 263scm_lookupcar (SCM vloc, SCM genv, int check)
d0b7bad7 264#endif
0f2d19dd
JB
265{
266 SCM env = genv;
e3173f93
JB
267 register SCM *al, fl, var = SCM_CAR (vloc);
268#ifdef USE_THREADS
269 register SCM var2 = var;
270#endif
0f2d19dd
JB
271#ifdef MEMOIZE_LOCALS
272 register SCM iloc = SCM_ILOC00;
273#endif
274 for (; SCM_NIMP (env); env = SCM_CDR (env))
275 {
790071cd 276 if (!SCM_CONSP (SCM_CAR (env)))
0f2d19dd 277 break;
a23afe53 278 al = SCM_CARLOC (env);
0f2d19dd
JB
279 for (fl = SCM_CAR (*al); SCM_NIMP (fl); fl = SCM_CDR (fl))
280 {
281 if (SCM_NCONSP (fl))
33b97402 282 {
cf498326 283 if (SCM_EQ_P (fl, var))
0f2d19dd
JB
284 {
285#ifdef MEMOIZE_LOCALS
f8769b1d 286#ifdef USE_THREADS
cf498326 287 if (! SCM_EQ_P (SCM_CAR (vloc), var))
f8769b1d
MV
288 goto race;
289#endif
3201d763 290 SCM_SET_CELL_WORD_0 (vloc, SCM_UNPACK (iloc) + SCM_ICDR);
0f2d19dd 291#endif
a23afe53 292 return SCM_CDRLOC (*al);
0f2d19dd 293 }
33b97402
MD
294 else
295 break;
296 }
a23afe53 297 al = SCM_CDRLOC (*al);
cf498326 298 if (SCM_EQ_P (SCM_CAR (fl), var))
0f2d19dd
JB
299 {
300#ifdef MEMOIZE_LOCALS
cf7c17e9 301#ifndef SCM_RECKLESS /* letrec inits to SCM_UNDEFINED */
0f2d19dd
JB
302 if (SCM_UNBNDP (SCM_CAR (*al)))
303 {
304 env = SCM_EOL;
305 goto errout;
306 }
f8769b1d
MV
307#endif
308#ifdef USE_THREADS
309 if (SCM_CAR (vloc) != var)
310 goto race;
0f2d19dd 311#endif
a23afe53 312 SCM_SETCAR (vloc, iloc);
0f2d19dd 313#endif
a23afe53 314 return SCM_CARLOC (*al);
0f2d19dd
JB
315 }
316#ifdef MEMOIZE_LOCALS
3201d763 317 iloc = SCM_PACK (SCM_UNPACK (iloc) + SCM_IDINC);
0f2d19dd
JB
318#endif
319 }
320#ifdef MEMOIZE_LOCALS
3201d763 321 iloc = SCM_PACK ((~SCM_IDSTMSK) & (SCM_UNPACK(iloc) + SCM_IFRINC));
0f2d19dd
JB
322#endif
323 }
324 {
325 SCM top_thunk, vcell;
790071cd 326 if (SCM_NIMP (env))
0f2d19dd 327 {
790071cd 328 top_thunk = SCM_CAR (env); /* env now refers to a top level env thunk */
0f2d19dd
JB
329 env = SCM_CDR (env);
330 }
331 else
332 top_thunk = SCM_BOOL_F;
333 vcell = scm_sym2vcell (var, top_thunk, SCM_BOOL_F);
cf498326 334 if (SCM_FALSEP (vcell))
0f2d19dd
JB
335 goto errout;
336 else
337 var = vcell;
338 }
cf7c17e9 339#ifndef SCM_RECKLESS
0f2d19dd
JB
340 if (SCM_NNULLP (env) || SCM_UNBNDP (SCM_CDR (var)))
341 {
342 var = SCM_CAR (var);
343 errout:
f5bf2977 344 /* scm_everr (vloc, genv,...) */
26d5b9b4 345 if (check)
f25f761d
GH
346 {
347 if (SCM_NULLP (env))
70d63753 348 scm_error (scm_unbound_variable_key, NULL, "Unbound variable: ~S",
f25f761d
GH
349 scm_cons (var, SCM_EOL), SCM_BOOL_F);
350 else
70d63753 351 scm_misc_error (NULL, "Damaged environment: ~S",
f25f761d
GH
352 scm_cons (var, SCM_EOL));
353 }
09e4d064
DH
354 else {
355 /* A variable could not be found, but we shall not throw an error. */
356 static SCM undef_object = SCM_UNDEFINED;
3201d763 357 return &undef_object;
09e4d064 358 }
0f2d19dd
JB
359 }
360#endif
f8769b1d
MV
361#ifdef USE_THREADS
362 if (SCM_CAR (vloc) != var2)
363 {
364 /* Some other thread has changed the very cell we are working
365 on. In effect, it must have done our job or messed it up
366 completely. */
367 race:
368 var = SCM_CAR (vloc);
3201d763 369 if (SCM_ITAG3 (var) == scm_tc3_cons_gloc)
f8769b1d
MV
370 return SCM_GLOC_VAL_LOC (var);
371#ifdef MEMOIZE_LOCALS
d1ca2c64 372 if (SCM_ITAG7 (var) == SCM_ITAG7 (SCM_ILOC00))
f8769b1d
MV
373 return scm_ilookup (var, genv);
374#endif
375 /* We can't cope with anything else than glocs and ilocs. When
376 a special form has been memoized (i.e. `let' into `#@let') we
377 return NULL and expect the calling function to do the right
378 thing. For the evaluator, this means going back and redoing
379 the dispatch on the car of the form. */
380 return NULL;
381 }
382#endif /* USE_THREADS */
383
3201d763 384 SCM_SET_CELL_WORD_0 (vloc, SCM_UNPACK (var) + scm_tc3_cons_gloc);
0f2d19dd 385 /* Except wait...what if the var is not a vcell,
f8769b1d 386 * but syntax or something.... */
a23afe53 387 return SCM_CDRLOC (var);
0f2d19dd
JB
388}
389
f8769b1d
MV
390#ifdef USE_THREADS
391SCM *
6e8d25a6 392scm_lookupcar (SCM vloc, SCM genv, int check)
f8769b1d 393{
26d5b9b4 394 SCM *loc = scm_lookupcar1 (vloc, genv, check);
f8769b1d
MV
395 if (loc == NULL)
396 abort ();
397 return loc;
398}
f8769b1d
MV
399#endif
400
0f2d19dd 401#define unmemocar scm_unmemocar
1cc91f1b 402
0f2d19dd 403SCM
6e8d25a6 404scm_unmemocar (SCM form, SCM env)
0f2d19dd 405{
0f2d19dd
JB
406 SCM c;
407
408 if (SCM_IMP (form))
409 return form;
410 c = SCM_CAR (form);
b0c54567 411 if (SCM_ITAG3 (c) == scm_tc3_cons_gloc)
a963f787 412 SCM_SETCAR (form, SCM_GLOC_SYM (c));
0f2d19dd 413#ifdef MEMOIZE_LOCALS
6dbd0af5 414#ifdef DEBUG_EXTENSIONS
0f2d19dd
JB
415 else if (SCM_ILOCP (c))
416 {
b0c54567
DH
417 int ir;
418
0f2d19dd
JB
419 for (ir = SCM_IFRAME (c); ir != 0; --ir)
420 env = SCM_CDR (env);
421 env = SCM_CAR (SCM_CAR (env));
422 for (ir = SCM_IDIST (c); ir != 0; --ir)
423 env = SCM_CDR (env);
a23afe53 424 SCM_SETCAR (form, SCM_ICDRP (c) ? env : SCM_CAR (env));
0f2d19dd 425 }
6dbd0af5 426#endif
0f2d19dd
JB
427#endif
428 return form;
429}
430
1cc91f1b 431
0f2d19dd 432SCM
6e8d25a6 433scm_eval_car (SCM pair, SCM env)
0f2d19dd 434{
6cb702da 435 return SCM_XEVALCAR (pair, env);
0f2d19dd
JB
436}
437
438\f
439/*
440 * The following rewrite expressions and
441 * some memoized forms have different syntax
442 */
443
3eeba8d4
JB
444const char scm_s_expression[] = "missing or extra expression";
445const char scm_s_test[] = "bad test";
446const char scm_s_body[] = "bad body";
447const char scm_s_bindings[] = "bad bindings";
185ab0ef 448const char scm_s_duplicate_bindings[] = "duplicate bindings";
3eeba8d4
JB
449const char scm_s_variable[] = "bad variable";
450const char scm_s_clauses[] = "bad or missing clauses";
451const char scm_s_formals[] = "bad formals";
5280aaca 452const char scm_s_duplicate_formals[] = "duplicate formals";
0f2d19dd 453
85db4a2c
DH
454SCM_GLOBAL_SYMBOL (scm_sym_dot, ".");
455SCM_GLOBAL_SYMBOL (scm_sym_arrow, "=>");
456SCM_GLOBAL_SYMBOL (scm_sym_else, "else");
457SCM_GLOBAL_SYMBOL (scm_sym_unquote, "unquote");
458SCM_GLOBAL_SYMBOL (scm_sym_uq_splicing, "unquote-splicing");
81123e6d
MD
459
460SCM scm_f_apply;
b8229a3b 461
6dbd0af5 462#ifdef DEBUG_EXTENSIONS
85db4a2c
DH
463SCM_GLOBAL_SYMBOL (scm_sym_enter_frame, "enter-frame");
464SCM_GLOBAL_SYMBOL (scm_sym_apply_frame, "apply-frame");
465SCM_GLOBAL_SYMBOL (scm_sym_exit_frame, "exit-frame");
466SCM_GLOBAL_SYMBOL (scm_sym_trace, "trace");
6dbd0af5 467#endif
0f2d19dd 468
0f2d19dd 469
26d5b9b4
MD
470/* Check that the body denoted by XORIG is valid and rewrite it into
471 its internal form. The internal form of a body is just the body
472 itself, but prefixed with an ISYM that denotes to what kind of
473 outer construct this body belongs. A lambda body starts with
474 SCM_IM_LAMBDA, for example, a body of a let starts with SCM_IM_LET,
475 etc. The one exception is a body that belongs to a letrec that has
476 been formed by rewriting internal defines: it starts with
477 SCM_IM_DEFINE. */
478
479/* XXX - Besides controlling the rewriting of internal defines, the
480 additional ISYM could be used for improved error messages.
481 This is not done yet. */
482
483static SCM
6e8d25a6 484scm_m_body (SCM op, SCM xorig, const char *what)
26d5b9b4 485{
160bb34a 486 SCM_ASSYNT (scm_ilength (xorig) >= 1, scm_s_expression, what);
26d5b9b4
MD
487
488 /* Don't add another ISYM if one is present already. */
489 if (SCM_ISYMP (SCM_CAR (xorig)))
490 return xorig;
491
492 /* Retain possible doc string. */
44d3cb0d 493 if (!SCM_CONSP (SCM_CAR (xorig)))
26d5b9b4
MD
494 {
495 if (SCM_NNULLP (SCM_CDR(xorig)))
496 return scm_cons (SCM_CAR (xorig),
497 scm_m_body (op, SCM_CDR(xorig), what));
498 return xorig;
499 }
500
ab66ae47 501 return scm_cons (op, xorig);
26d5b9b4
MD
502}
503
b8229a3b 504SCM_SYNTAX(s_quote,"quote", scm_makmmacro, scm_m_quote);
2f0d1375 505SCM_GLOBAL_SYMBOL(scm_sym_quote, s_quote);
1cc91f1b 506
0f2d19dd 507SCM
6e8d25a6 508scm_m_quote (SCM xorig, SCM env)
0f2d19dd 509{
26d5b9b4
MD
510 SCM x = scm_copy_tree (SCM_CDR (xorig));
511
160bb34a 512 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, 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{
160bb34a 524 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) >= 1, scm_s_expression, s_begin);
3a3111a8 525 return scm_cons (SCM_IM_BEGIN, SCM_CDR (xorig));
0f2d19dd
JB
526}
527
b8229a3b 528SCM_SYNTAX(s_if, "if", scm_makmmacro, scm_m_if);
2f0d1375 529SCM_GLOBAL_SYMBOL(scm_sym_if, s_if);
1cc91f1b 530
0f2d19dd 531SCM
6e8d25a6 532scm_m_if (SCM xorig, SCM env)
0f2d19dd
JB
533{
534 int len = scm_ilength (SCM_CDR (xorig));
160bb34a 535 SCM_ASSYNT (len >= 2 && len <= 3, scm_s_expression, "if");
3a3111a8 536 return scm_cons (SCM_IM_IF, SCM_CDR (xorig));
0f2d19dd
JB
537}
538
539
89efbff4
MD
540/* Will go into the RnRS module when Guile is factorized.
541SCM_SYNTAX(scm_s_set_x,"set!", scm_makmmacro, scm_m_set_x); */
542const char scm_s_set_x[] = "set!";
543SCM_GLOBAL_SYMBOL(scm_sym_set_x, scm_s_set_x);
1cc91f1b 544
0f2d19dd 545SCM
6e8d25a6 546scm_m_set_x (SCM xorig, SCM env)
0f2d19dd 547{
6dbd0af5 548 SCM x = SCM_CDR (xorig);
160bb34a
DH
549 SCM_ASSYNT (2 == scm_ilength (x), scm_s_expression, scm_s_set_x);
550 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (x)), scm_s_variable, scm_s_set_x);
3a3111a8 551 return scm_cons (SCM_IM_SET_X, x);
0f2d19dd
JB
552}
553
554
b8229a3b 555SCM_SYNTAX(s_and, "and", scm_makmmacro, scm_m_and);
2f0d1375 556SCM_GLOBAL_SYMBOL(scm_sym_and, s_and);
1cc91f1b 557
0f2d19dd 558SCM
6e8d25a6 559scm_m_and (SCM xorig, SCM env)
0f2d19dd
JB
560{
561 int len = scm_ilength (SCM_CDR (xorig));
160bb34a 562 SCM_ASSYNT (len >= 0, scm_s_test, s_and);
0f2d19dd 563 if (len >= 1)
3a3111a8 564 return scm_cons (SCM_IM_AND, SCM_CDR (xorig));
0f2d19dd
JB
565 else
566 return SCM_BOOL_T;
567}
568
b8229a3b 569SCM_SYNTAX(s_or,"or", scm_makmmacro, scm_m_or);
2f0d1375 570SCM_GLOBAL_SYMBOL(scm_sym_or,s_or);
1cc91f1b 571
0f2d19dd 572SCM
6e8d25a6 573scm_m_or (SCM xorig, SCM env)
0f2d19dd
JB
574{
575 int len = scm_ilength (SCM_CDR (xorig));
160bb34a 576 SCM_ASSYNT (len >= 0, scm_s_test, s_or);
0f2d19dd 577 if (len >= 1)
3a3111a8 578 return scm_cons (SCM_IM_OR, SCM_CDR (xorig));
0f2d19dd
JB
579 else
580 return SCM_BOOL_F;
581}
582
583
b8229a3b 584SCM_SYNTAX(s_case, "case", scm_makmmacro, scm_m_case);
2f0d1375 585SCM_GLOBAL_SYMBOL(scm_sym_case, s_case);
1cc91f1b 586
0f2d19dd 587SCM
6e8d25a6 588scm_m_case (SCM xorig, SCM env)
0f2d19dd 589{
26d5b9b4 590 SCM proc, cdrx = scm_list_copy (SCM_CDR (xorig)), x = cdrx;
160bb34a 591 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_clauses, s_case);
0f2d19dd
JB
592 while (SCM_NIMP (x = SCM_CDR (x)))
593 {
594 proc = SCM_CAR (x);
160bb34a 595 SCM_ASSYNT (scm_ilength (proc) >= 2, scm_s_clauses, s_case);
6cb702da 596 SCM_ASSYNT (scm_ilength (SCM_CAR (proc)) >= 0
4567ed78
DH
597 || (SCM_EQ_P (scm_sym_else, SCM_CAR (proc))
598 && SCM_NULLP (SCM_CDR (x))),
160bb34a 599 scm_s_clauses, s_case);
0f2d19dd 600 }
3a3111a8 601 return scm_cons (SCM_IM_CASE, cdrx);
0f2d19dd
JB
602}
603
604
b8229a3b 605SCM_SYNTAX(s_cond, "cond", scm_makmmacro, scm_m_cond);
2f0d1375 606SCM_GLOBAL_SYMBOL(scm_sym_cond, s_cond);
b8229a3b 607
1cc91f1b 608
0f2d19dd 609SCM
6e8d25a6 610scm_m_cond (SCM xorig, SCM env)
0f2d19dd 611{
26d5b9b4 612 SCM arg1, cdrx = scm_list_copy (SCM_CDR (xorig)), x = cdrx;
0f2d19dd 613 int len = scm_ilength (x);
160bb34a 614 SCM_ASSYNT (len >= 1, scm_s_clauses, s_cond);
0f2d19dd
JB
615 while (SCM_NIMP (x))
616 {
617 arg1 = SCM_CAR (x);
618 len = scm_ilength (arg1);
160bb34a 619 SCM_ASSYNT (len >= 1, scm_s_clauses, s_cond);
cf498326 620 if (SCM_EQ_P (scm_sym_else, SCM_CAR (arg1)))
0f2d19dd 621 {
6cb702da 622 SCM_ASSYNT (SCM_NULLP (SCM_CDR (x)) && len >= 2,
160bb34a 623 "bad ELSE clause", s_cond);
a23afe53 624 SCM_SETCAR (arg1, SCM_BOOL_T);
0f2d19dd 625 }
cf498326 626 if (len >= 2 && SCM_EQ_P (scm_sym_arrow, SCM_CAR (SCM_CDR (arg1))))
6cb702da 627 SCM_ASSYNT (3 == len && SCM_NIMP (SCM_CAR (SCM_CDR (SCM_CDR (arg1)))),
160bb34a 628 "bad recipient", s_cond);
0f2d19dd
JB
629 x = SCM_CDR (x);
630 }
3a3111a8 631 return scm_cons (SCM_IM_COND, cdrx);
0f2d19dd
JB
632}
633
b8229a3b 634SCM_SYNTAX(s_lambda, "lambda", scm_makmmacro, scm_m_lambda);
2f0d1375 635SCM_GLOBAL_SYMBOL(scm_sym_lambda, s_lambda);
1cc91f1b 636
5280aaca
MV
637/* Return #t if OBJ is `eq?' to one of the elements of LIST or to the
638 cdr of the last cons. (Thus, LIST is not required to be a proper
639 list and when OBJ also found in the improper ending.) */
640
641static int
642scm_c_improper_memq (SCM obj, SCM list)
643{
644 for (; SCM_CONSP (list); list = SCM_CDR (list))
645 {
646 if (SCM_EQ_P (SCM_CAR (list), obj))
647 return SCM_BOOL_T;
648 }
649 return SCM_EQ_P (list, obj);
650}
651
0f2d19dd 652SCM
6e8d25a6 653scm_m_lambda (SCM xorig, SCM env)
0f2d19dd
JB
654{
655 SCM proc, x = SCM_CDR (xorig);
26d5b9b4 656 if (scm_ilength (x) < 2)
0f2d19dd
JB
657 goto badforms;
658 proc = SCM_CAR (x);
33b97402
MD
659 if (SCM_NULLP (proc))
660 goto memlambda;
cf498326 661 if (SCM_EQ_P (SCM_IM_LET, proc)) /* named let */
26d5b9b4 662 goto memlambda;
33b97402
MD
663 if (SCM_IMP (proc))
664 goto badforms;
665 if (SCM_SYMBOLP (proc))
666 goto memlambda;
667 if (SCM_NCONSP (proc))
668 goto badforms;
669 while (SCM_NIMP (proc))
0f2d19dd 670 {
33b97402
MD
671 if (SCM_NCONSP (proc))
672 {
0f2d19dd 673 if (!SCM_SYMBOLP (proc))
33b97402
MD
674 goto badforms;
675 else
676 goto memlambda;
677 }
0c95b57d 678 if (!SCM_SYMBOLP (SCM_CAR (proc)))
0f2d19dd 679 goto badforms;
5280aaca 680 else if (scm_c_improper_memq (SCM_CAR(proc), SCM_CDR(proc)))
db4b4ca6 681 scm_misc_error (s_lambda, scm_s_duplicate_formals, SCM_EOL);
0f2d19dd
JB
682 proc = SCM_CDR (proc);
683 }
ff467021 684 if (SCM_NNULLP (proc))
26d5b9b4
MD
685 {
686 badforms:
db4b4ca6 687 scm_misc_error (s_lambda, scm_s_formals, SCM_EOL);
26d5b9b4
MD
688 }
689
690 memlambda:
3a3111a8
MD
691 return scm_cons2 (SCM_IM_LAMBDA, SCM_CAR (x),
692 scm_m_body (SCM_IM_LAMBDA, SCM_CDR (x), s_lambda));
0f2d19dd
JB
693}
694
b8229a3b 695SCM_SYNTAX(s_letstar,"let*", scm_makmmacro, scm_m_letstar);
2f0d1375 696SCM_GLOBAL_SYMBOL(scm_sym_letstar,s_letstar);
0f2d19dd 697
1cc91f1b 698
0f2d19dd 699SCM
6e8d25a6 700scm_m_letstar (SCM xorig, SCM env)
0f2d19dd
JB
701{
702 SCM x = SCM_CDR (xorig), arg1, proc, vars = SCM_EOL, *varloc = &vars;
703 int len = scm_ilength (x);
160bb34a 704 SCM_ASSYNT (len >= 2, scm_s_body, s_letstar);
0f2d19dd 705 proc = SCM_CAR (x);
160bb34a 706 SCM_ASSYNT (scm_ilength (proc) >= 0, scm_s_bindings, s_letstar);
ff467021 707 while (SCM_NIMP (proc))
0f2d19dd
JB
708 {
709 arg1 = SCM_CAR (proc);
160bb34a
DH
710 SCM_ASSYNT (2 == scm_ilength (arg1), scm_s_bindings, s_letstar);
711 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), scm_s_variable, s_letstar);
0f2d19dd 712 *varloc = scm_cons2 (SCM_CAR (arg1), SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 713 varloc = SCM_CDRLOC (SCM_CDR (*varloc));
0f2d19dd
JB
714 proc = SCM_CDR (proc);
715 }
716 x = scm_cons (vars, SCM_CDR (x));
26d5b9b4 717
3a3111a8
MD
718 return scm_cons2 (SCM_IM_LETSTAR, SCM_CAR (x),
719 scm_m_body (SCM_IM_LETSTAR, SCM_CDR (x), s_letstar));
0f2d19dd
JB
720}
721
722/* DO gets the most radically altered syntax
723 (do ((<var1> <init1> <step1>)
724 (<var2> <init2>)
725 ... )
726 (<test> <return>)
727 <body>)
728 ;; becomes
729 (do_mem (varn ... var2 var1)
730 (<init1> <init2> ... <initn>)
731 (<test> <return>)
732 (<body>)
733 <step1> <step2> ... <stepn>) ;; missing steps replaced by var
734 */
735
b8229a3b 736SCM_SYNTAX(s_do, "do", scm_makmmacro, scm_m_do);
2f0d1375 737SCM_GLOBAL_SYMBOL(scm_sym_do, s_do);
1cc91f1b 738
0f2d19dd 739SCM
6e8d25a6 740scm_m_do (SCM xorig, SCM env)
0f2d19dd
JB
741{
742 SCM x = SCM_CDR (xorig), arg1, proc;
743 SCM vars = SCM_EOL, inits = SCM_EOL, steps = SCM_EOL;
744 SCM *initloc = &inits, *steploc = &steps;
745 int len = scm_ilength (x);
160bb34a 746 SCM_ASSYNT (len >= 2, scm_s_test, "do");
0f2d19dd 747 proc = SCM_CAR (x);
160bb34a 748 SCM_ASSYNT (scm_ilength (proc) >= 0, scm_s_bindings, "do");
ff467021 749 while (SCM_NIMP(proc))
0f2d19dd
JB
750 {
751 arg1 = SCM_CAR (proc);
752 len = scm_ilength (arg1);
160bb34a
DH
753 SCM_ASSYNT (2 == len || 3 == len, scm_s_bindings, "do");
754 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), scm_s_variable, "do");
0f2d19dd
JB
755 /* vars reversed here, inits and steps reversed at evaluation */
756 vars = scm_cons (SCM_CAR (arg1), vars); /* variable */
757 arg1 = SCM_CDR (arg1);
758 *initloc = scm_cons (SCM_CAR (arg1), SCM_EOL); /* init */
a23afe53 759 initloc = SCM_CDRLOC (*initloc);
0f2d19dd
JB
760 arg1 = SCM_CDR (arg1);
761 *steploc = scm_cons (SCM_IMP (arg1) ? SCM_CAR (vars) : SCM_CAR (arg1), SCM_EOL); /* step */
a23afe53 762 steploc = SCM_CDRLOC (*steploc);
0f2d19dd
JB
763 proc = SCM_CDR (proc);
764 }
765 x = SCM_CDR (x);
160bb34a 766 SCM_ASSYNT (scm_ilength (SCM_CAR (x)) >= 1, scm_s_test, "do");
0f2d19dd
JB
767 x = scm_cons2 (SCM_CAR (x), SCM_CDR (x), steps);
768 x = scm_cons2 (vars, inits, x);
3a3111a8 769 return scm_cons (SCM_IM_DO, x);
0f2d19dd
JB
770}
771
6dbd0af5
MD
772/* evalcar is small version of inline EVALCAR when we don't care about
773 * speed
774 */
775#define evalcar scm_eval_car
0f2d19dd 776
1cc91f1b 777
1bbd0b84 778static SCM iqq (SCM form, SCM env, int depth);
1cc91f1b 779
b8229a3b 780SCM_SYNTAX(s_quasiquote, "quasiquote", scm_makacro, scm_m_quasiquote);
2f0d1375 781SCM_GLOBAL_SYMBOL(scm_sym_quasiquote, s_quasiquote);
b8229a3b
MS
782
783SCM
6e8d25a6 784scm_m_quasiquote (SCM xorig, SCM env)
b8229a3b
MS
785{
786 SCM x = SCM_CDR (xorig);
160bb34a 787 SCM_ASSYNT (scm_ilength (x) == 1, scm_s_expression, s_quasiquote);
b8229a3b
MS
788 return iqq (SCM_CAR (x), env, 1);
789}
790
791
0f2d19dd 792static SCM
22a52da1 793iqq (SCM form, SCM env, int depth)
0f2d19dd
JB
794{
795 SCM tmp;
796 int edepth = depth;
22a52da1 797 if (SCM_IMP (form))
ff467021 798 return form;
0f2d19dd
JB
799 if (SCM_VECTORP (form))
800 {
b5c2579a 801 long i = SCM_VECTOR_LENGTH (form);
0f2d19dd
JB
802 SCM *data = SCM_VELTS (form);
803 tmp = SCM_EOL;
804 for (; --i >= 0;)
805 tmp = scm_cons (data[i], tmp);
806 return scm_vector (iqq (tmp, env, depth));
807 }
22a52da1 808 if (!SCM_CONSP (form))
ff467021 809 return form;
0f2d19dd 810 tmp = SCM_CAR (form);
cf498326 811 if (SCM_EQ_P (scm_sym_quasiquote, tmp))
0f2d19dd
JB
812 {
813 depth++;
814 goto label;
815 }
cf498326 816 if (SCM_EQ_P (scm_sym_unquote, tmp))
0f2d19dd
JB
817 {
818 --depth;
819 label:
820 form = SCM_CDR (form);
0c95b57d
GB
821 SCM_ASSERT (SCM_ECONSP (form) && SCM_NULLP (SCM_CDR (form)),
822 form, SCM_ARG1, s_quasiquote);
0f2d19dd
JB
823 if (0 == depth)
824 return evalcar (form, env);
825 return scm_cons2 (tmp, iqq (SCM_CAR (form), env, depth), SCM_EOL);
826 }
22a52da1 827 if (SCM_CONSP (tmp) && (SCM_EQ_P (scm_sym_uq_splicing, SCM_CAR (tmp))))
0f2d19dd
JB
828 {
829 tmp = SCM_CDR (tmp);
830 if (0 == --edepth)
831 return scm_append (scm_cons2 (evalcar (tmp, env), iqq (SCM_CDR (form), env, depth), SCM_EOL));
832 }
833 return scm_cons (iqq (SCM_CAR (form), env, edepth), iqq (SCM_CDR (form), env, depth));
834}
835
836/* Here are acros which return values rather than code. */
837
a570e93a
MD
838SCM_SYNTAX (s_delay, "delay", scm_makmmacro, scm_m_delay);
839SCM_GLOBAL_SYMBOL (scm_sym_delay, s_delay);
1cc91f1b 840
0f2d19dd 841SCM
6e8d25a6 842scm_m_delay (SCM xorig, SCM env)
0f2d19dd 843{
160bb34a 844 SCM_ASSYNT (scm_ilength (xorig) == 2, scm_s_expression, s_delay);
a570e93a 845 return scm_cons2 (SCM_IM_DELAY, SCM_EOL, SCM_CDR (xorig));
0f2d19dd
JB
846}
847
1cc91f1b 848
b8229a3b 849SCM_SYNTAX(s_define, "define", scm_makmmacro, scm_m_define);
2f0d1375 850SCM_GLOBAL_SYMBOL(scm_sym_define, s_define);
1cc91f1b 851
0f2d19dd 852SCM
6e8d25a6 853scm_m_define (SCM x, SCM env)
0f2d19dd
JB
854{
855 SCM proc, arg1 = x;
856 x = SCM_CDR (x);
160bb34a 857 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_expression, s_define);
0f2d19dd
JB
858 proc = SCM_CAR (x);
859 x = SCM_CDR (x);
0c95b57d 860 while (SCM_CONSP (proc))
0f2d19dd 861 { /* nested define syntax */
2f0d1375 862 x = scm_cons (scm_cons2 (scm_sym_lambda, SCM_CDR (proc), x), SCM_EOL);
0f2d19dd
JB
863 proc = SCM_CAR (proc);
864 }
160bb34a
DH
865 SCM_ASSYNT (SCM_SYMBOLP (proc), scm_s_variable, s_define);
866 SCM_ASSYNT (1 == scm_ilength (x), scm_s_expression, s_define);
0f2d19dd
JB
867 if (SCM_TOP_LEVEL (env))
868 {
869 x = evalcar (x, env);
6dbd0af5 870#ifdef DEBUG_EXTENSIONS
80ea260c
MD
871 if (SCM_REC_PROCNAMES_P && SCM_NIMP (x))
872 {
873 arg1 = x;
874 proc:
875 if (SCM_CLOSUREP (arg1)
876 /* Only the first definition determines the name. */
cf498326 877 && SCM_FALSEP (scm_procedure_property (arg1, scm_sym_name)))
2f0d1375 878 scm_set_procedure_property_x (arg1, scm_sym_name, proc);
22a52da1
DH
879 else if (SCM_MACROP (arg1)
880 /* Dirk::FIXME: Does the following test make sense? */
881 && !SCM_EQ_P (SCM_MACRO_CODE (arg1), arg1))
80ea260c 882 {
22a52da1 883 arg1 = SCM_MACRO_CODE (arg1);
80ea260c
MD
884 goto proc;
885 }
886 }
6dbd0af5 887#endif
6cb702da 888 arg1 = scm_sym2vcell (proc, scm_env_top_level (env), SCM_BOOL_T);
a23afe53 889 SCM_SETCDR (arg1, x);
0f2d19dd 890#ifdef SICP
2f0d1375 891 return scm_cons2 (scm_sym_quote, SCM_CAR (arg1), SCM_EOL);
0f2d19dd
JB
892#else
893 return SCM_UNSPECIFIED;
894#endif
895 }
896 return scm_cons2 (SCM_IM_DEFINE, proc, x);
897}
6dbd0af5 898
0f2d19dd
JB
899/* end of acros */
900
26d5b9b4 901static SCM
6e8d25a6 902scm_m_letrec1 (SCM op, SCM imm, SCM xorig, SCM env)
0f2d19dd
JB
903{
904 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
3db4adfc 905 char *what = SCM_SYMBOL_CHARS (SCM_CAR (xorig));
0f2d19dd
JB
906 SCM x = cdrx, proc, arg1; /* structure traversers */
907 SCM vars = SCM_EOL, inits = SCM_EOL, *initloc = &inits;
908
0f2d19dd 909 proc = SCM_CAR (x);
160bb34a 910 SCM_ASSYNT (scm_ilength (proc) >= 1, scm_s_bindings, what);
0f2d19dd
JB
911 do
912 {
913 /* vars scm_list reversed here, inits reversed at evaluation */
914 arg1 = SCM_CAR (proc);
160bb34a
DH
915 SCM_ASSYNT (2 == scm_ilength (arg1), scm_s_bindings, what);
916 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), scm_s_variable, what);
185ab0ef 917 if (scm_c_improper_memq (SCM_CAR (arg1), vars))
db4b4ca6 918 scm_misc_error (what, scm_s_duplicate_bindings, SCM_EOL);
0f2d19dd
JB
919 vars = scm_cons (SCM_CAR (arg1), vars);
920 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 921 initloc = SCM_CDRLOC (*initloc);
0f2d19dd 922 }
ff467021 923 while (SCM_NIMP (proc = SCM_CDR (proc)));
26d5b9b4 924
3a3111a8
MD
925 return scm_cons2 (op, vars,
926 scm_cons (inits, scm_m_body (imm, SCM_CDR (x), what)));
0f2d19dd
JB
927}
928
26d5b9b4 929SCM_SYNTAX(s_letrec, "letrec", scm_makmmacro, scm_m_letrec);
2f0d1375 930SCM_GLOBAL_SYMBOL(scm_sym_letrec, s_letrec);
26d5b9b4
MD
931
932SCM
6e8d25a6 933scm_m_letrec (SCM xorig, SCM env)
26d5b9b4
MD
934{
935 SCM x = SCM_CDR (xorig);
160bb34a 936 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_body, s_letrec);
26d5b9b4
MD
937
938 if (SCM_NULLP (SCM_CAR (x))) /* null binding, let* faster */
3a3111a8
MD
939 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), SCM_EOL,
940 scm_m_body (SCM_IM_LETREC,
941 SCM_CDR (x),
942 s_letrec)),
26d5b9b4
MD
943 env);
944 else
945 return scm_m_letrec1 (SCM_IM_LETREC, SCM_IM_LETREC, xorig, env);
946}
1cc91f1b 947
b8229a3b 948SCM_SYNTAX(s_let, "let", scm_makmmacro, scm_m_let);
2f0d1375 949SCM_GLOBAL_SYMBOL(scm_sym_let, s_let);
b8229a3b 950
0f2d19dd 951SCM
6e8d25a6 952scm_m_let (SCM xorig, SCM env)
0f2d19dd
JB
953{
954 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
955 SCM x = cdrx, proc, arg1, name; /* structure traversers */
956 SCM vars = SCM_EOL, inits = SCM_EOL, *varloc = &vars, *initloc = &inits;
957
160bb34a 958 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_body, s_let);
0f2d19dd
JB
959 proc = SCM_CAR (x);
960 if (SCM_NULLP (proc)
0c95b57d 961 || (SCM_CONSP (proc)
26d5b9b4
MD
962 && SCM_CONSP (SCM_CAR (proc)) && SCM_NULLP (SCM_CDR (proc))))
963 {
964 /* null or single binding, let* is faster */
3a3111a8
MD
965 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), proc,
966 scm_m_body (SCM_IM_LET,
967 SCM_CDR (x),
968 s_let)),
26d5b9b4
MD
969 env);
970 }
971
160bb34a 972 SCM_ASSYNT (SCM_NIMP (proc), scm_s_bindings, s_let);
185ab0ef 973 if (SCM_CONSP (proc))
26d5b9b4
MD
974 {
975 /* plain let, proc is <bindings> */
976 return scm_m_letrec1 (SCM_IM_LET, SCM_IM_LET, xorig, env);
977 }
978
0f2d19dd 979 if (!SCM_SYMBOLP (proc))
db4b4ca6 980 scm_misc_error (s_let, scm_s_bindings, SCM_EOL); /* bad let */
0f2d19dd
JB
981 name = proc; /* named let, build equiv letrec */
982 x = SCM_CDR (x);
160bb34a 983 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_body, s_let);
26d5b9b4 984 proc = SCM_CAR (x); /* bindings list */
160bb34a 985 SCM_ASSYNT (scm_ilength (proc) >= 0, scm_s_bindings, s_let);
ff467021 986 while (SCM_NIMP (proc))
0f2d19dd
JB
987 { /* vars and inits both in order */
988 arg1 = SCM_CAR (proc);
160bb34a
DH
989 SCM_ASSYNT (2 == scm_ilength (arg1), scm_s_bindings, s_let);
990 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), scm_s_variable, s_let);
0f2d19dd 991 *varloc = scm_cons (SCM_CAR (arg1), SCM_EOL);
a23afe53 992 varloc = SCM_CDRLOC (*varloc);
0f2d19dd 993 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 994 initloc = SCM_CDRLOC (*initloc);
0f2d19dd
JB
995 proc = SCM_CDR (proc);
996 }
26d5b9b4 997
2f0d1375 998 proc = scm_cons2 (scm_sym_lambda, vars,
26d5b9b4 999 scm_m_body (SCM_IM_LET, SCM_CDR (x), "let"));
2f0d1375 1000 proc = scm_cons2 (scm_sym_let, scm_cons (scm_cons2 (name, proc, SCM_EOL),
26d5b9b4
MD
1001 SCM_EOL),
1002 scm_acons (name, inits, SCM_EOL));
1003 return scm_m_letrec1 (SCM_IM_LETREC, SCM_IM_LET, proc, env);
0f2d19dd
JB
1004}
1005
1006
81123e6d
MD
1007SCM_SYNTAX (s_atapply,"@apply", scm_makmmacro, scm_m_apply);
1008SCM_GLOBAL_SYMBOL (scm_sym_atapply, s_atapply);
1009SCM_GLOBAL_SYMBOL (scm_sym_apply, s_atapply + 1);
1cc91f1b 1010
0f2d19dd 1011SCM
6e8d25a6 1012scm_m_apply (SCM xorig, SCM env)
0f2d19dd 1013{
160bb34a 1014 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2, scm_s_expression, s_atapply);
0f2d19dd
JB
1015 return scm_cons (SCM_IM_APPLY, SCM_CDR (xorig));
1016}
1017
b8229a3b
MS
1018
1019SCM_SYNTAX(s_atcall_cc,"@call-with-current-continuation", scm_makmmacro, scm_m_cont);
2f0d1375 1020SCM_GLOBAL_SYMBOL(scm_sym_atcall_cc,s_atcall_cc);
0f2d19dd 1021
1cc91f1b 1022
0f2d19dd 1023SCM
6e8d25a6 1024scm_m_cont (SCM xorig, SCM env)
0f2d19dd 1025{
6cb702da 1026 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
160bb34a 1027 scm_s_expression, s_atcall_cc);
3a3111a8 1028 return scm_cons (SCM_IM_CONT, SCM_CDR (xorig));
0f2d19dd
JB
1029}
1030
73b64342
MD
1031/* Multi-language support */
1032
43a912cf
MD
1033SCM scm_lisp_nil;
1034SCM scm_lisp_t;
73b64342
MD
1035
1036SCM_SYNTAX (s_nil_cond, "nil-cond", scm_makmmacro, scm_m_nil_cond);
1037
1038SCM
1039scm_m_nil_cond (SCM xorig, SCM env)
1040{
1041 int len = scm_ilength (SCM_CDR (xorig));
160bb34a 1042 SCM_ASSYNT (len >= 1 && (len & 1) == 1, scm_s_expression, "nil-cond");
73b64342
MD
1043 return scm_cons (SCM_IM_NIL_COND, SCM_CDR (xorig));
1044}
1045
1046SCM_SYNTAX (s_nil_ify, "nil-ify", scm_makmmacro, scm_m_nil_ify);
1047
1048SCM
1049scm_m_nil_ify (SCM xorig, SCM env)
1050{
160bb34a 1051 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, "nil-ify");
73b64342
MD
1052 return scm_cons (SCM_IM_NIL_IFY, SCM_CDR (xorig));
1053}
1054
1055SCM_SYNTAX (s_t_ify, "t-ify", scm_makmmacro, scm_m_t_ify);
1056
1057SCM
1058scm_m_t_ify (SCM xorig, SCM env)
1059{
160bb34a 1060 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, "t-ify");
73b64342
MD
1061 return scm_cons (SCM_IM_T_IFY, SCM_CDR (xorig));
1062}
1063
1064SCM_SYNTAX (s_0_cond, "0-cond", scm_makmmacro, scm_m_0_cond);
1065
1066SCM
1067scm_m_0_cond (SCM xorig, SCM env)
1068{
1069 int len = scm_ilength (SCM_CDR (xorig));
160bb34a 1070 SCM_ASSYNT (len >= 1 && (len & 1) == 1, scm_s_expression, "0-cond");
73b64342
MD
1071 return scm_cons (SCM_IM_0_COND, SCM_CDR (xorig));
1072}
1073
1074SCM_SYNTAX (s_0_ify, "0-ify", scm_makmmacro, scm_m_0_ify);
1075
1076SCM
1077scm_m_0_ify (SCM xorig, SCM env)
1078{
160bb34a 1079 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, "0-ify");
73b64342
MD
1080 return scm_cons (SCM_IM_0_IFY, SCM_CDR (xorig));
1081}
1082
1083SCM_SYNTAX (s_1_ify, "1-ify", scm_makmmacro, scm_m_1_ify);
1084
1085SCM
1086scm_m_1_ify (SCM xorig, SCM env)
1087{
160bb34a 1088 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, "1-ify");
73b64342
MD
1089 return scm_cons (SCM_IM_1_IFY, SCM_CDR (xorig));
1090}
1091
1092SCM_SYNTAX (s_atfop, "@fop", scm_makmmacro, scm_m_atfop);
1093
1094SCM
1095scm_m_atfop (SCM xorig, SCM env)
1096{
1097 SCM x = SCM_CDR (xorig), vcell;
160bb34a 1098 SCM_ASSYNT (scm_ilength (x) >= 1, scm_s_expression, "@fop");
73b64342 1099 vcell = scm_symbol_fref (SCM_CAR (x));
160bb34a 1100 SCM_ASSYNT (SCM_CONSP (vcell),
73b64342 1101 "Symbol's function definition is void", NULL);
3201d763 1102 SCM_SET_CELL_WORD_0 (x, SCM_UNPACK (vcell) + scm_tc3_cons_gloc);
73b64342
MD
1103 return x;
1104}
1105
1106SCM_SYNTAX (s_atbind, "@bind", scm_makmmacro, scm_m_atbind);
1107
1108SCM
1109scm_m_atbind (SCM xorig, SCM env)
1110{
1111 SCM x = SCM_CDR (xorig);
160bb34a 1112 SCM_ASSYNT (scm_ilength (x) > 1, scm_s_expression, "@bind");
73b64342
MD
1113
1114 if (SCM_IMP (env))
1115 env = SCM_BOOL_F;
1116 else
1117 {
1118 while (SCM_NIMP (SCM_CDR (env)))
1119 env = SCM_CDR (env);
1120 env = SCM_CAR (env);
1121 if (SCM_CONSP (env))
1122 env = SCM_BOOL_F;
1123 }
1124
1125 x = SCM_CAR (x);
1126 while (SCM_NIMP (x))
1127 {
3201d763 1128 SCM_SET_CELL_WORD_0 (x, SCM_UNPACK (scm_sym2vcell (SCM_CAR (x), env, SCM_BOOL_T)) + scm_tc3_cons_gloc);
73b64342
MD
1129 x = SCM_CDR (x);
1130 }
1131 return scm_cons (SCM_IM_BIND, SCM_CDR (xorig));
1132}
73b64342 1133
a513ead3
MV
1134SCM_SYNTAX (s_at_call_with_values, "@call-with-values", scm_makmmacro, scm_m_at_call_with_values);
1135SCM_GLOBAL_SYMBOL(scm_sym_at_call_with_values, s_at_call_with_values);
1136
1137SCM
1138scm_m_at_call_with_values (SCM xorig, SCM env)
1139{
1140 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2,
1141 scm_s_expression, s_at_call_with_values);
1142 return scm_cons (SCM_IM_CALL_WITH_VALUES, SCM_CDR (xorig));
1143}
1144
26d5b9b4
MD
1145SCM
1146scm_m_expand_body (SCM xorig, SCM env)
1147{
22a52da1 1148 SCM x = SCM_CDR (xorig), defs = SCM_EOL;
26d5b9b4
MD
1149 char *what = SCM_ISYMCHARS (SCM_CAR (xorig)) + 2;
1150
1151 while (SCM_NIMP (x))
1152 {
22a52da1
DH
1153 SCM form = SCM_CAR (x);
1154 if (!SCM_CONSP (form))
26d5b9b4
MD
1155 break;
1156 if (!SCM_SYMBOLP (SCM_CAR (form)))
1157 break;
22a52da1 1158
3a3111a8
MD
1159 form = scm_macroexp (scm_cons_source (form,
1160 SCM_CAR (form),
1161 SCM_CDR (form)),
1162 env);
26d5b9b4 1163
cf498326 1164 if (SCM_EQ_P (SCM_IM_DEFINE, SCM_CAR (form)))
26d5b9b4
MD
1165 {
1166 defs = scm_cons (SCM_CDR (form), defs);
22a52da1 1167 x = SCM_CDR (x);
26d5b9b4 1168 }
22a52da1 1169 else if (!SCM_IMP (defs))
26d5b9b4
MD
1170 {
1171 break;
1172 }
cf498326 1173 else if (SCM_EQ_P (SCM_IM_BEGIN, SCM_CAR (form)))
26d5b9b4
MD
1174 {
1175 x = scm_append (scm_cons2 (SCM_CDR (form), SCM_CDR (x), SCM_EOL));
1176 }
1177 else
1178 {
22a52da1 1179 x = scm_cons (form, SCM_CDR (x));
26d5b9b4
MD
1180 break;
1181 }
1182 }
1183
160bb34a 1184 SCM_ASSYNT (SCM_NIMP (x), scm_s_body, what);
26d5b9b4
MD
1185 if (SCM_NIMP (defs))
1186 {
1187 x = scm_cons (scm_m_letrec1 (SCM_IM_LETREC,
1188 SCM_IM_DEFINE,
2f0d1375 1189 scm_cons2 (scm_sym_define, defs, x),
26d5b9b4
MD
1190 env),
1191 SCM_EOL);
1192 }
1193
1194 SCM_DEFER_INTS;
1195 SCM_SETCAR (xorig, SCM_CAR (x));
1196 SCM_SETCDR (xorig, SCM_CDR (x));
1197 SCM_ALLOW_INTS;
1198
1199 return xorig;
1200}
1201
1202SCM
1203scm_macroexp (SCM x, SCM env)
1204{
1205 SCM res, proc;
1206
1207 /* Don't bother to produce error messages here. We get them when we
1208 eventually execute the code for real. */
1209
1210 macro_tail:
44d3cb0d 1211 if (!SCM_SYMBOLP (SCM_CAR (x)))
26d5b9b4
MD
1212 return x;
1213
1214#ifdef USE_THREADS
1215 {
1216 SCM *proc_ptr = scm_lookupcar1 (x, env, 0);
1217 if (proc_ptr == NULL)
1218 {
1219 /* We have lost the race. */
1220 goto macro_tail;
1221 }
1222 proc = *proc_ptr;
1223 }
1224#else
1225 proc = *scm_lookupcar (x, env, 0);
1226#endif
1227
1228 /* Only handle memoizing macros. `Acros' and `macros' are really
1229 special forms and should not be evaluated here. */
1230
22a52da1 1231 if (!SCM_MACROP (proc) || SCM_MACRO_TYPE (proc) != 2)
26d5b9b4
MD
1232 return x;
1233
1234 unmemocar (x, env);
22a52da1 1235 res = scm_apply (SCM_MACRO_CODE (proc), x, scm_cons (env, scm_listofnull));
26d5b9b4
MD
1236
1237 if (scm_ilength (res) <= 0)
1238 res = scm_cons2 (SCM_IM_BEGIN, res, SCM_EOL);
1239
26d5b9b4
MD
1240 SCM_DEFER_INTS;
1241 SCM_SETCAR (x, SCM_CAR (res));
1242 SCM_SETCDR (x, SCM_CDR (res));
1243 SCM_ALLOW_INTS;
1244
1245 goto macro_tail;
1246}
73b64342 1247
6dbd0af5
MD
1248/* scm_unmemocopy takes a memoized expression together with its
1249 * environment and rewrites it to its original form. Thus, it is the
1250 * inversion of the rewrite rules above. The procedure is not
1251 * optimized for speed. It's used in scm_iprin1 when printing the
220ff1eb
MD
1252 * code of a closure, in scm_procedure_source, in display_frame when
1253 * generating the source for a stackframe in a backtrace, and in
1254 * display_expression.
6dbd0af5
MD
1255 */
1256
26d5b9b4
MD
1257/* We should introduce an anti-macro interface so that it is possible
1258 * to plug in transformers in both directions from other compilation
1259 * units. unmemocopy could then dispatch to anti-macro transformers.
1260 * (Those transformers could perhaps be written in slightly more
1261 * readable style... :)
1262 */
1263
f1267706 1264#define SCM_BIT8(x) (127 & SCM_UNPACK (x))
c209c88e 1265
6dbd0af5 1266static SCM
1bbd0b84 1267unmemocopy (SCM x, SCM env)
6dbd0af5
MD
1268{
1269 SCM ls, z;
1270#ifdef DEBUG_EXTENSIONS
1271 SCM p;
1272#endif
1273 if (SCM_NCELLP (x) || SCM_NECONSP (x))
1274 return x;
1275#ifdef DEBUG_EXTENSIONS
1276 p = scm_whash_lookup (scm_source_whash, x);
1277#endif
1278 switch (SCM_TYP7 (x))
1279 {
c209c88e 1280 case SCM_BIT8(SCM_IM_AND):
2f0d1375 1281 ls = z = scm_cons (scm_sym_and, SCM_UNSPECIFIED);
6dbd0af5 1282 break;
c209c88e 1283 case SCM_BIT8(SCM_IM_BEGIN):
2f0d1375 1284 ls = z = scm_cons (scm_sym_begin, SCM_UNSPECIFIED);
6dbd0af5 1285 break;
c209c88e 1286 case SCM_BIT8(SCM_IM_CASE):
2f0d1375 1287 ls = z = scm_cons (scm_sym_case, SCM_UNSPECIFIED);
6dbd0af5 1288 break;
c209c88e 1289 case SCM_BIT8(SCM_IM_COND):
2f0d1375 1290 ls = z = scm_cons (scm_sym_cond, SCM_UNSPECIFIED);
6dbd0af5 1291 break;
c209c88e 1292 case SCM_BIT8(SCM_IM_DO):
2f0d1375 1293 ls = scm_cons (scm_sym_do, SCM_UNSPECIFIED);
6dbd0af5 1294 goto transform;
c209c88e 1295 case SCM_BIT8(SCM_IM_IF):
2f0d1375 1296 ls = z = scm_cons (scm_sym_if, SCM_UNSPECIFIED);
6dbd0af5 1297 break;
c209c88e 1298 case SCM_BIT8(SCM_IM_LET):
2f0d1375 1299 ls = scm_cons (scm_sym_let, SCM_UNSPECIFIED);
6dbd0af5 1300 goto transform;
c209c88e 1301 case SCM_BIT8(SCM_IM_LETREC):
6dbd0af5
MD
1302 {
1303 SCM f, v, e, s;
2f0d1375 1304 ls = scm_cons (scm_sym_letrec, SCM_UNSPECIFIED);
6dbd0af5
MD
1305 transform:
1306 x = SCM_CDR (x);
26d5b9b4 1307 /* binding names */
6dbd0af5
MD
1308 f = v = SCM_CAR (x);
1309 x = SCM_CDR (x);
e2806c10 1310 z = EXTEND_ENV (f, SCM_EOL, env);
26d5b9b4 1311 /* inits */
6dbd0af5 1312 e = scm_reverse (unmemocopy (SCM_CAR (x),
cf498326 1313 SCM_EQ_P (SCM_CAR (ls), scm_sym_letrec) ? z : env));
6dbd0af5 1314 env = z;
26d5b9b4 1315 /* increments */
cf498326 1316 s = SCM_EQ_P (SCM_CAR (ls), scm_sym_do)
6dbd0af5
MD
1317 ? scm_reverse (unmemocopy (SCM_CDR (SCM_CDR (SCM_CDR (x))), env))
1318 : f;
26d5b9b4 1319 /* build transformed binding list */
6dbd0af5 1320 z = SCM_EOL;
1bd07992 1321 while (SCM_NIMP (v))
6dbd0af5
MD
1322 {
1323 z = scm_acons (SCM_CAR (v),
1324 scm_cons (SCM_CAR (e),
cf498326 1325 SCM_EQ_P (SCM_CAR (s), SCM_CAR (v))
6dbd0af5
MD
1326 ? SCM_EOL
1327 : scm_cons (SCM_CAR (s), SCM_EOL)),
1328 z);
1329 v = SCM_CDR (v);
1330 e = SCM_CDR (e);
1331 s = SCM_CDR (s);
1332 }
a23afe53
MD
1333 z = scm_cons (z, SCM_UNSPECIFIED);
1334 SCM_SETCDR (ls, z);
cf498326 1335 if (SCM_EQ_P (SCM_CAR (ls), scm_sym_do))
6dbd0af5
MD
1336 {
1337 x = SCM_CDR (x);
26d5b9b4 1338 /* test clause */
a23afe53 1339 SCM_SETCDR (z, scm_cons (unmemocopy (SCM_CAR (x), env),
6dbd0af5 1340 SCM_UNSPECIFIED));
a23afe53
MD
1341 z = SCM_CDR (z);
1342 x = (SCM) (SCM_CARLOC (SCM_CDR (x)) - 1);
26d5b9b4
MD
1343 /* body forms are now to be found in SCM_CDR (x)
1344 (this is how *real* code look like! :) */
6dbd0af5
MD
1345 }
1346 break;
1347 }
c209c88e 1348 case SCM_BIT8(SCM_IM_LETSTAR):
6dbd0af5
MD
1349 {
1350 SCM b, y;
1351 x = SCM_CDR (x);
1352 b = SCM_CAR (x);
1353 y = SCM_EOL;
1354 if SCM_IMP (b)
1355 {
e2806c10 1356 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5
MD
1357 goto letstar;
1358 }
1359 y = z = scm_acons (SCM_CAR (b),
1360 unmemocar (
1361 scm_cons (unmemocopy (SCM_CAR (SCM_CDR (b)), env), SCM_EOL), env),
1362 SCM_UNSPECIFIED);
e2806c10 1363 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
6dbd0af5
MD
1364 b = SCM_CDR (SCM_CDR (b));
1365 if (SCM_IMP (b))
1366 {
1367 SCM_SETCDR (y, SCM_EOL);
2f0d1375 1368 ls = scm_cons (scm_sym_let, z = scm_cons (y, SCM_UNSPECIFIED));
6dbd0af5
MD
1369 break;
1370 }
1371 do
1372 {
a23afe53
MD
1373 SCM_SETCDR (z, scm_acons (SCM_CAR (b),
1374 unmemocar (
6dbd0af5 1375 scm_cons (unmemocopy (SCM_CAR (SCM_CDR (b)), env), SCM_EOL), env),
a23afe53
MD
1376 SCM_UNSPECIFIED));
1377 z = SCM_CDR (z);
e2806c10 1378 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
6dbd0af5
MD
1379 b = SCM_CDR (SCM_CDR (b));
1380 }
ff467021 1381 while (SCM_NIMP (b));
a23afe53 1382 SCM_SETCDR (z, SCM_EOL);
6dbd0af5 1383 letstar:
2f0d1375 1384 ls = scm_cons (scm_sym_letstar, z = scm_cons (y, SCM_UNSPECIFIED));
6dbd0af5
MD
1385 break;
1386 }
c209c88e 1387 case SCM_BIT8(SCM_IM_OR):
2f0d1375 1388 ls = z = scm_cons (scm_sym_or, SCM_UNSPECIFIED);
6dbd0af5 1389 break;
c209c88e 1390 case SCM_BIT8(SCM_IM_LAMBDA):
6dbd0af5 1391 x = SCM_CDR (x);
2f0d1375 1392 ls = scm_cons (scm_sym_lambda,
6dbd0af5 1393 z = scm_cons (SCM_CAR (x), SCM_UNSPECIFIED));
e2806c10 1394 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, env);
6dbd0af5 1395 break;
c209c88e 1396 case SCM_BIT8(SCM_IM_QUOTE):
2f0d1375 1397 ls = z = scm_cons (scm_sym_quote, SCM_UNSPECIFIED);
6dbd0af5 1398 break;
c209c88e 1399 case SCM_BIT8(SCM_IM_SET_X):
89efbff4 1400 ls = z = scm_cons (scm_sym_set_x, SCM_UNSPECIFIED);
6dbd0af5 1401 break;
c209c88e 1402 case SCM_BIT8(SCM_IM_DEFINE):
6dbd0af5
MD
1403 {
1404 SCM n;
1405 x = SCM_CDR (x);
2f0d1375 1406 ls = scm_cons (scm_sym_define,
6dbd0af5
MD
1407 z = scm_cons (n = SCM_CAR (x), SCM_UNSPECIFIED));
1408 if (SCM_NNULLP (env))
a23afe53 1409 SCM_SETCAR (SCM_CAR (env), scm_cons (n, SCM_CAR (SCM_CAR (env))));
6dbd0af5
MD
1410 break;
1411 }
c209c88e 1412 case SCM_BIT8(SCM_MAKISYM (0)):
6dbd0af5
MD
1413 z = SCM_CAR (x);
1414 if (!SCM_ISYMP (z))
1415 goto unmemo;
ff467021 1416 switch (SCM_ISYMNUM (z))
6dbd0af5
MD
1417 {
1418 case (SCM_ISYMNUM (SCM_IM_APPLY)):
2f0d1375 1419 ls = z = scm_cons (scm_sym_atapply, SCM_UNSPECIFIED);
6dbd0af5
MD
1420 goto loop;
1421 case (SCM_ISYMNUM (SCM_IM_CONT)):
2f0d1375 1422 ls = z = scm_cons (scm_sym_atcall_cc, SCM_UNSPECIFIED);
6dbd0af5 1423 goto loop;
a570e93a
MD
1424 case (SCM_ISYMNUM (SCM_IM_DELAY)):
1425 ls = z = scm_cons (scm_sym_delay, SCM_UNSPECIFIED);
1426 x = SCM_CDR (x);
1427 goto loop;
a513ead3
MV
1428 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
1429 ls = z = scm_cons (scm_sym_at_call_with_values, SCM_UNSPECIFIED);
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;
22a52da1 1510 while (!SCM_IMP (l))
6dbd0af5 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
22a52da1 1538 if (!SCM_NULLP (l))
680ed4a8
MD
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;
22a52da1 1733 while (!SCM_IMP (l))
0f2d19dd 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
22a52da1 1761 if (!SCM_NULLP (l))
680ed4a8
MD
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. */
22a52da1 1943 if (SCM_CONSP (env) && !SCM_CONSP (SCM_CAR (env)))
4163eb72
MV
1944 {
1945 t.arg1 = x;
d9d39d76 1946 UPDATE_TOPLEVEL_ENV (env);
22a52da1 1947 while (!SCM_NULLP (t.arg1 = SCM_CDR (t.arg1)))
4163eb72 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;
22a52da1 1964 while (!SCM_NULLP (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
22a52da1 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 1981 carloop: /* scm_eval car of last form in list */
22a52da1 1982 if (!SCM_CELLP (SCM_CAR (x)))
0f2d19dd
JB
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):
22a52da1 2026 while (!SCM_IMP (x = SCM_CDR (x)))
0f2d19dd
JB
2027 {
2028 proc = SCM_CAR (x);
2029 t.arg1 = EVALCAR (proc, env);
2030 if (SCM_NFALSEP (t.arg1))
2031 {
2032 x = SCM_CDR (proc);
22a52da1 2033 if (SCM_NULLP (x))
0f2d19dd 2034 {
6dbd0af5 2035 RETURN (t.arg1)
0f2d19dd 2036 }
22a52da1 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;
22a52da1 2147 while (!SCM_NULLP (t.arg1 = SCM_CDR (t.arg1)))
0f2d19dd
JB
2148 {
2149 x = EVALCAR (x, env);
22a52da1 2150 if (!SCM_FALSEP (x))
0f2d19dd
JB
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);
a513ead3
MV
2213 apply_closure:
2214 /* Go here to tail-call a closure. PROC is the closure
2215 and T.ARG1 is the list of arguments. Do not forget to
2216 call PREP_APPLY. */
6dbd0af5
MD
2217#ifdef DEVAL
2218 debug.info->a.args = t.arg1;
2219#endif
cf7c17e9 2220#ifndef SCM_RECKLESS
0f2d19dd
JB
2221 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), t.arg1))
2222 goto wrongnumargs;
2223#endif
c79450dd 2224 ENTER_APPLY;
1609038c
MD
2225 /* Copy argument list */
2226 if (SCM_IMP (t.arg1))
2227 argl = t.arg1;
2228 else
2229 {
2230 argl = tl = scm_cons (SCM_CAR (t.arg1), SCM_UNSPECIFIED);
2231 while (SCM_NIMP (t.arg1 = SCM_CDR (t.arg1))
2232 && SCM_CONSP (t.arg1))
2233 {
2234 SCM_SETCDR (tl, scm_cons (SCM_CAR (t.arg1),
2235 SCM_UNSPECIFIED));
2236 tl = SCM_CDR (tl);
2237 }
2238 SCM_SETCDR (tl, t.arg1);
2239 }
2240
2241 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), argl, SCM_ENV (proc));
0f2d19dd 2242 x = SCM_CODE (proc);
5280aaca 2243 goto nontoplevel_cdrxbegin;
0f2d19dd 2244 }
81123e6d 2245 proc = scm_f_apply;
0f2d19dd
JB
2246 goto evapply;
2247
2248 case (SCM_ISYMNUM (SCM_IM_CONT)):
5f144b10
GH
2249 {
2250 int first;
2251 SCM val = scm_make_continuation (&first);
2252
2253 if (first)
2254 t.arg1 = val;
2255 else
2256 RETURN (val);
2257 }
0f2d19dd
JB
2258 proc = SCM_CDR (x);
2259 proc = evalcar (proc, env);
2260 SCM_ASRTGO (SCM_NIMP (proc), badfun);
6dbd0af5
MD
2261 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
2262 ENTER_APPLY;
a820af98 2263 if (SCM_CLOSUREP(proc) && scm_badformalsp (proc, 1))
e37a4fba 2264 goto umwrongnumargs;
0f2d19dd
JB
2265 goto evap1;
2266
a570e93a
MD
2267 case (SCM_ISYMNUM (SCM_IM_DELAY)):
2268 RETURN (scm_makprom (scm_closure (SCM_CDR (x), env)))
2269
89efbff4 2270 case (SCM_ISYMNUM (SCM_IM_DISPATCH)):
195847fa
MD
2271 proc = SCM_CADR (x); /* unevaluated operands */
2272 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2273 if (SCM_IMP (proc))
2274 arg2 = *scm_ilookup (proc, env);
2275 else if (SCM_NCONSP (proc))
2276 {
2277 if (SCM_NCELLP (proc))
2278 arg2 = SCM_GLOC_VAL (proc);
2279 else
2280 arg2 = *scm_lookupcar (SCM_CDR (x), env, 1);
2281 }
2282 else
2283 {
2284 arg2 = scm_cons (EVALCAR (proc, env), SCM_EOL);
2285 t.lloc = SCM_CDRLOC (arg2);
2286 while (SCM_NIMP (proc = SCM_CDR (proc)))
2287 {
2288 *t.lloc = scm_cons (EVALCAR (proc, env), SCM_EOL);
2289 t.lloc = SCM_CDRLOC (*t.lloc);
2290 }
2291 }
2292
2293 type_dispatch:
61364ba6
MD
2294 /* The type dispatch code is duplicated here
2295 * (c.f. objects.c:scm_mcache_compute_cmethod) since that
2296 * cuts down execution time for type dispatch to 50%.
2297 */
2298 {
2299 int i, n, end, mask;
2300 SCM z = SCM_CDDR (x);
2301 n = SCM_INUM (SCM_CAR (z)); /* maximum number of specializers */
2302 proc = SCM_CADR (z);
2303
2304 if (SCM_NIMP (proc))
2305 {
2306 /* Prepare for linear search */
2307 mask = -1;
2308 i = 0;
b5c2579a 2309 end = SCM_VECTOR_LENGTH (proc);
61364ba6
MD
2310 }
2311 else
2312 {
2313 /* Compute a hash value */
2314 int hashset = SCM_INUM (proc);
2315 int j = n;
2316 mask = SCM_INUM (SCM_CAR (z = SCM_CDDR (z)));
2317 proc = SCM_CADR (z);
2318 i = 0;
2319 t.arg1 = arg2;
2320 if (SCM_NIMP (t.arg1))
2321 do
2322 {
d8c40b9f
DH
2323 i += SCM_STRUCT_DATA (scm_class_of (SCM_CAR (t.arg1)))
2324 [scm_si_hashsets + hashset];
61364ba6
MD
2325 t.arg1 = SCM_CDR (t.arg1);
2326 }
4ea6a431 2327 while (j-- && SCM_NIMP (t.arg1));
61364ba6
MD
2328 i &= mask;
2329 end = i;
2330 }
2331
2332 /* Search for match */
2333 do
2334 {
2335 int j = n;
2336 z = SCM_VELTS (proc)[i];
2337 t.arg1 = arg2; /* list of arguments */
2338 if (SCM_NIMP (t.arg1))
2339 do
2340 {
2341 /* More arguments than specifiers => CLASS != ENV */
cf498326 2342 if (! SCM_EQ_P (scm_class_of (SCM_CAR (t.arg1)), SCM_CAR (z)))
61364ba6
MD
2343 goto next_method;
2344 t.arg1 = SCM_CDR (t.arg1);
2345 z = SCM_CDR (z);
2346 }
4ea6a431 2347 while (j-- && SCM_NIMP (t.arg1));
61364ba6
MD
2348 /* Fewer arguments than specifiers => CAR != ENV */
2349 if (!(SCM_IMP (SCM_CAR (z)) || SCM_CONSP (SCM_CAR (z))))
2350 goto next_method;
2351 apply_cmethod:
2352 env = EXTEND_ENV (SCM_CAR (SCM_CMETHOD_CODE (z)),
2353 arg2,
2354 SCM_CMETHOD_ENV (z));
2355 x = SCM_CMETHOD_CODE (z);
5280aaca 2356 goto nontoplevel_cdrxbegin;
61364ba6
MD
2357 next_method:
2358 i = (i + 1) & mask;
2359 } while (i != end);
2360
2361 z = scm_memoize_method (x, arg2);
2362 goto apply_cmethod;
2363 }
73b64342 2364
ca4be6ea
MD
2365 case (SCM_ISYMNUM (SCM_IM_SLOT_REF)):
2366 x = SCM_CDR (x);
2367 t.arg1 = EVALCAR (x, env);
d8c40b9f 2368 RETURN (SCM_PACK (SCM_STRUCT_DATA (t.arg1) [SCM_INUM (SCM_CADR (x))]))
ca4be6ea
MD
2369
2370 case (SCM_ISYMNUM (SCM_IM_SLOT_SET_X)):
2371 x = SCM_CDR (x);
2372 t.arg1 = EVALCAR (x, env);
2373 x = SCM_CDR (x);
2374 proc = SCM_CDR (x);
d8c40b9f
DH
2375 SCM_STRUCT_DATA (t.arg1) [SCM_INUM (SCM_CAR (x))]
2376 = SCM_UNPACK (EVALCAR (proc, env));
5623a9b4 2377 RETURN (SCM_UNSPECIFIED)
ca4be6ea 2378
73b64342
MD
2379 case (SCM_ISYMNUM (SCM_IM_NIL_COND)):
2380 proc = SCM_CDR (x);
2381 while (SCM_NIMP (x = SCM_CDR (proc)))
2382 {
2383 if (!(SCM_FALSEP (t.arg1 = EVALCAR (proc, env))
3201d763 2384 || SCM_EQ_P (t.arg1, scm_lisp_nil)))
73b64342 2385 {
cf498326 2386 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
73b64342
MD
2387 RETURN (t.arg1);
2388 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2389 goto carloop;
2390 }
2391 proc = SCM_CDR (x);
2392 }
2393 x = proc;
2394 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2395 goto carloop;
2396
2397 case (SCM_ISYMNUM (SCM_IM_NIL_IFY)):
2398 x = SCM_CDR (x);
2399 RETURN ((SCM_FALSEP (proc = EVALCAR (x, env)) || SCM_NULLP (proc))
43a912cf 2400 ? scm_lisp_nil
73b64342
MD
2401 : proc)
2402
2403 case (SCM_ISYMNUM (SCM_IM_T_IFY)):
2404 x = SCM_CDR (x);
43a912cf 2405 RETURN (SCM_NFALSEP (EVALCAR (x, env)) ? scm_lisp_t : scm_lisp_nil)
73b64342
MD
2406
2407 case (SCM_ISYMNUM (SCM_IM_0_COND)):
2408 proc = SCM_CDR (x);
2409 while (SCM_NIMP (x = SCM_CDR (proc)))
2410 {
2411 if (!(SCM_FALSEP (t.arg1 = EVALCAR (proc, env))
3201d763 2412 || SCM_EQ_P (t.arg1, SCM_INUM0)))
73b64342 2413 {
cf498326 2414 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
73b64342
MD
2415 RETURN (t.arg1);
2416 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2417 goto carloop;
2418 }
2419 proc = SCM_CDR (x);
2420 }
2421 x = proc;
2422 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2423 goto carloop;
2424
2425 case (SCM_ISYMNUM (SCM_IM_0_IFY)):
2426 x = SCM_CDR (x);
2427 RETURN (SCM_FALSEP (proc = EVALCAR (x, env))
2428 ? SCM_INUM0
2429 : proc)
2430
2431 case (SCM_ISYMNUM (SCM_IM_1_IFY)):
2432 x = SCM_CDR (x);
2433 RETURN (SCM_NFALSEP (EVALCAR (x, env))
2434 ? SCM_MAKINUM (1)
2435 : SCM_INUM0)
2436
2437 case (SCM_ISYMNUM (SCM_IM_BIND)):
2438 x = SCM_CDR (x);
2439
2440 t.arg1 = SCM_CAR (x);
2441 arg2 = SCM_CDAR (env);
2442 while (SCM_NIMP (arg2))
2443 {
2444 proc = SCM_GLOC_VAL (SCM_CAR (t.arg1));
a963f787
MD
2445 SCM_SETCDR (SCM_PACK (SCM_UNPACK (SCM_CAR (t.arg1)) - 1L),
2446 SCM_CAR (arg2));
73b64342
MD
2447 SCM_SETCAR (arg2, proc);
2448 t.arg1 = SCM_CDR (t.arg1);
2449 arg2 = SCM_CDR (arg2);
2450 }
2451 t.arg1 = SCM_CAR (x);
2452 scm_dynwinds = scm_acons (t.arg1, SCM_CDAR (env), scm_dynwinds);
89efbff4 2453
73b64342
MD
2454 arg2 = x = SCM_CDR (x);
2455 while (SCM_NNULLP (arg2 = SCM_CDR (arg2)))
2456 {
2457 SIDEVAL (SCM_CAR (x), env);
2458 x = arg2;
2459 }
2460 proc = EVALCAR (x, env);
2461
2462 scm_dynwinds = SCM_CDR (scm_dynwinds);
2463 arg2 = SCM_CDAR (env);
2464 while (SCM_NIMP (arg2))
2465 {
a963f787
MD
2466 SCM_SETCDR (SCM_PACK (SCM_UNPACK (SCM_CAR (t.arg1)) - 1L),
2467 SCM_CAR (arg2));
73b64342
MD
2468 t.arg1 = SCM_CDR (t.arg1);
2469 arg2 = SCM_CDR (arg2);
2470 }
2471
a513ead3 2472 RETURN (proc);
73b64342 2473
a513ead3
MV
2474 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
2475 {
2476 proc = SCM_CDR (x);
2477 x = EVALCAR (proc, env);
2478 proc = SCM_CDR (proc);
2479 proc = EVALCAR (proc, env);
2480 t.arg1 = SCM_APPLY (x, SCM_EOL, SCM_EOL);
2481 if (SCM_VALUESP (t.arg1))
2482 t.arg1 = scm_struct_ref (t.arg1, SCM_INUM0);
2483 else
2484 t.arg1 = scm_cons (t.arg1, SCM_EOL);
2485 if (SCM_CLOSUREP (proc))
2486 {
2487 PREP_APPLY (proc, t.arg1);
2488 goto apply_closure;
2489 }
2490 return SCM_APPLY (proc, t.arg1, SCM_EOL);
2491 }
2492
0f2d19dd
JB
2493 default:
2494 goto badfun;
2495 }
2496
2497 default:
2498 proc = x;
2499 badfun:
f5bf2977 2500 /* scm_everr (x, env,...) */
e0c08f17 2501 scm_misc_error (NULL, "Wrong type to apply: ~S", SCM_LIST1 (proc));
0f2d19dd
JB
2502 case scm_tc7_vector:
2503 case scm_tc7_wvect:
afe5177e 2504#ifdef HAVE_ARRAYS
0f2d19dd
JB
2505 case scm_tc7_bvect:
2506 case scm_tc7_byvect:
2507 case scm_tc7_svect:
2508 case scm_tc7_ivect:
2509 case scm_tc7_uvect:
2510 case scm_tc7_fvect:
2511 case scm_tc7_dvect:
2512 case scm_tc7_cvect:
5c11cc9d 2513#ifdef HAVE_LONG_LONGS
0f2d19dd 2514 case scm_tc7_llvect:
afe5177e 2515#endif
0f2d19dd
JB
2516#endif
2517 case scm_tc7_string:
0f2d19dd 2518 case scm_tc7_substring:
0f2d19dd
JB
2519 case scm_tc7_smob:
2520 case scm_tcs_closures:
224822be 2521 case scm_tc7_cclo:
89efbff4 2522 case scm_tc7_pws:
0f2d19dd
JB
2523 case scm_tcs_subrs:
2524 RETURN (x);
2525
2526#ifdef MEMOIZE_LOCALS
c209c88e 2527 case SCM_BIT8(SCM_ILOC00):
0f2d19dd
JB
2528 proc = *scm_ilookup (SCM_CAR (x), env);
2529 SCM_ASRTGO (SCM_NIMP (proc), badfun);
cf7c17e9
JB
2530#ifndef SCM_RECKLESS
2531#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2532 goto checkargs;
2533#endif
2534#endif
2535 break;
2536#endif /* ifdef MEMOIZE_LOCALS */
2537
2538
3201d763
DH
2539 case scm_tcs_cons_gloc: {
2540 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2541 if (vcell == 0) {
aa00bd1e
MD
2542 /* This is a struct implanted in the code, not a gloc. */
2543 RETURN (x);
3201d763
DH
2544 } else {
2545 proc = SCM_PACK (vcell);
2546 SCM_ASRTGO (SCM_NIMP (proc), badfun);
cf7c17e9
JB
2547#ifndef SCM_RECKLESS
2548#ifdef SCM_CAUTIOUS
3201d763 2549 goto checkargs;
0f2d19dd
JB
2550#endif
2551#endif
3201d763 2552 }
0f2d19dd 2553 break;
3201d763 2554 }
0f2d19dd
JB
2555
2556 case scm_tcs_cons_nimcar:
2557 if (SCM_SYMBOLP (SCM_CAR (x)))
2558 {
f8769b1d 2559#ifdef USE_THREADS
26d5b9b4 2560 t.lloc = scm_lookupcar1 (x, env, 1);
f8769b1d
MV
2561 if (t.lloc == NULL)
2562 {
2563 /* we have lost the race, start again. */
2564 goto dispatch;
2565 }
2566 proc = *t.lloc;
2567#else
26d5b9b4 2568 proc = *scm_lookupcar (x, env, 1);
f8769b1d
MV
2569#endif
2570
0f2d19dd
JB
2571 if (SCM_IMP (proc))
2572 {
2573 unmemocar (x, env);
2574 goto badfun;
2575 }
22a52da1 2576 if (SCM_MACROP (proc))
0f2d19dd
JB
2577 {
2578 unmemocar (x, env);
2579
2580 handle_a_macro:
368bf056 2581#ifdef DEVAL
7c354052
MD
2582 /* Set a flag during macro expansion so that macro
2583 application frames can be deleted from the backtrace. */
2584 SCM_SET_MACROEXP (debug);
368bf056 2585#endif
22a52da1 2586 t.arg1 = SCM_APPLY (SCM_MACRO_CODE (proc), x,
f8769b1d
MV
2587 scm_cons (env, scm_listofnull));
2588
7c354052
MD
2589#ifdef DEVAL
2590 SCM_CLEAR_MACROEXP (debug);
2591#endif
22a52da1 2592 switch (SCM_MACRO_TYPE (proc))
0f2d19dd
JB
2593 {
2594 case 2:
2595 if (scm_ilength (t.arg1) <= 0)
2596 t.arg1 = scm_cons2 (SCM_IM_BEGIN, t.arg1, SCM_EOL);
6dbd0af5 2597#ifdef DEVAL
22a52da1 2598 if (!SCM_CLOSUREP (SCM_MACRO_CODE (proc)))
6dbd0af5 2599 {
6dbd0af5 2600 SCM_DEFER_INTS;
a23afe53
MD
2601 SCM_SETCAR (x, SCM_CAR (t.arg1));
2602 SCM_SETCDR (x, SCM_CDR (t.arg1));
6dbd0af5
MD
2603 SCM_ALLOW_INTS;
2604 goto dispatch;
2605 }
2606 /* Prevent memoizing of debug info expression. */
6203706f
MD
2607 debug.info->e.exp = scm_cons_source (debug.info->e.exp,
2608 SCM_CAR (x),
2609 SCM_CDR (x));
6dbd0af5 2610#endif
0f2d19dd 2611 SCM_DEFER_INTS;
a23afe53
MD
2612 SCM_SETCAR (x, SCM_CAR (t.arg1));
2613 SCM_SETCDR (x, SCM_CDR (t.arg1));
0f2d19dd 2614 SCM_ALLOW_INTS;
6dbd0af5 2615 goto loopnoap;
0f2d19dd
JB
2616 case 1:
2617 if (SCM_NIMP (x = t.arg1))
6dbd0af5 2618 goto loopnoap;
0f2d19dd
JB
2619 case 0:
2620 RETURN (t.arg1);
2621 }
2622 }
2623 }
2624 else
2625 proc = SCM_CEVAL (SCM_CAR (x), env);
22a52da1 2626 SCM_ASRTGO (!SCM_IMP (proc), badfun);
cf7c17e9
JB
2627#ifndef SCM_RECKLESS
2628#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2629 checkargs:
2630#endif
2631 if (SCM_CLOSUREP (proc))
2632 {
2633 arg2 = SCM_CAR (SCM_CODE (proc));
2634 t.arg1 = SCM_CDR (x);
22a52da1 2635 while (!SCM_IMP (arg2))
0f2d19dd 2636 {
22a52da1 2637 if (!SCM_CONSP (arg2))
0f2d19dd
JB
2638 goto evapply;
2639 if (SCM_IMP (t.arg1))
2640 goto umwrongnumargs;
2641 arg2 = SCM_CDR (arg2);
2642 t.arg1 = SCM_CDR (t.arg1);
2643 }
22a52da1 2644 if (!SCM_NULLP (t.arg1))
0f2d19dd
JB
2645 goto umwrongnumargs;
2646 }
22a52da1 2647 else if (SCM_MACROP (proc))
0f2d19dd
JB
2648 goto handle_a_macro;
2649#endif
2650 }
2651
2652
6dbd0af5
MD
2653evapply:
2654 PREP_APPLY (proc, SCM_EOL);
2655 if (SCM_NULLP (SCM_CDR (x))) {
2656 ENTER_APPLY;
89efbff4 2657 evap0:
0f2d19dd
JB
2658 switch (SCM_TYP7 (proc))
2659 { /* no arguments given */
2660 case scm_tc7_subr_0:
2661 RETURN (SCM_SUBRF (proc) ());
2662 case scm_tc7_subr_1o:
2663 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
2664 case scm_tc7_lsubr:
2665 RETURN (SCM_SUBRF (proc) (SCM_EOL));
2666 case scm_tc7_rpsubr:
2667 RETURN (SCM_BOOL_T);
2668 case scm_tc7_asubr:
2669 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
0717dfd8 2670 case scm_tc7_smob:
68b06924 2671 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 2672 goto badfun;
68b06924 2673 RETURN (SCM_SMOB_APPLY_0 (proc));
0f2d19dd
JB
2674 case scm_tc7_cclo:
2675 t.arg1 = proc;
2676 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2677#ifdef DEVAL
2678 debug.info->a.proc = proc;
2679 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2680#endif
0f2d19dd 2681 goto evap1;
89efbff4
MD
2682 case scm_tc7_pws:
2683 proc = SCM_PROCEDURE (proc);
2684#ifdef DEVAL
2685 debug.info->a.proc = proc;
2686#endif
002f1a5d
MD
2687 if (!SCM_CLOSUREP (proc))
2688 goto evap0;
2689 if (scm_badformalsp (proc, 0))
2690 goto umwrongnumargs;
0f2d19dd
JB
2691 case scm_tcs_closures:
2692 x = SCM_CODE (proc);
e2806c10 2693 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, SCM_ENV (proc));
5280aaca 2694 goto nontoplevel_cdrxbegin;
da7f71d7 2695 case scm_tcs_cons_gloc:
195847fa
MD
2696 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2697 {
2698 x = SCM_ENTITY_PROCEDURE (proc);
2699 arg2 = SCM_EOL;
2700 goto type_dispatch;
2701 }
2702 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2703 goto badfun;
2704 else
da7f71d7 2705 {
195847fa
MD
2706 t.arg1 = proc;
2707 proc = (SCM_I_ENTITYP (proc)
2708 ? SCM_ENTITY_PROCEDURE (proc)
2709 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7 2710#ifdef DEVAL
195847fa
MD
2711 debug.info->a.proc = proc;
2712 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
da7f71d7 2713#endif
195847fa
MD
2714 if (SCM_NIMP (proc))
2715 goto evap1;
2716 else
2717 goto badfun;
da7f71d7 2718 }
0f2d19dd
JB
2719 case scm_tc7_subr_1:
2720 case scm_tc7_subr_2:
2721 case scm_tc7_subr_2o:
2722 case scm_tc7_cxr:
2723 case scm_tc7_subr_3:
2724 case scm_tc7_lsubr_2:
2725 umwrongnumargs:
2726 unmemocar (x, env);
2727 wrongnumargs:
f5bf2977
GH
2728 /* scm_everr (x, env,...) */
2729 scm_wrong_num_args (proc);
0f2d19dd
JB
2730 default:
2731 /* handle macros here */
2732 goto badfun;
2733 }
6dbd0af5 2734 }
0f2d19dd
JB
2735
2736 /* must handle macros by here */
2737 x = SCM_CDR (x);
cf7c17e9 2738#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2739 if (SCM_IMP (x))
2740 goto wrongnumargs;
680ed4a8
MD
2741 else if (SCM_CONSP (x))
2742 {
2743 if (SCM_IMP (SCM_CAR (x)))
6cb702da 2744 t.arg1 = SCM_EVALIM (SCM_CAR (x), env);
680ed4a8
MD
2745 else
2746 t.arg1 = EVALCELLCAR (x, env);
2747 }
3201d763 2748 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
680ed4a8 2749 {
3201d763
DH
2750 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2751 if (vcell == 0)
680ed4a8 2752 t.arg1 = SCM_CAR (x); /* struct planted in code */
3201d763
DH
2753 else
2754 t.arg1 = SCM_PACK (vcell);
680ed4a8
MD
2755 }
2756 else
2757 goto wrongnumargs;
2758#else
0f2d19dd 2759 t.arg1 = EVALCAR (x, env);
680ed4a8 2760#endif
6dbd0af5
MD
2761#ifdef DEVAL
2762 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2763#endif
0f2d19dd
JB
2764 x = SCM_CDR (x);
2765 if (SCM_NULLP (x))
2766 {
6dbd0af5 2767 ENTER_APPLY;
0f2d19dd
JB
2768 evap1:
2769 switch (SCM_TYP7 (proc))
6dbd0af5 2770 { /* have one argument in t.arg1 */
0f2d19dd
JB
2771 case scm_tc7_subr_2o:
2772 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2773 case scm_tc7_subr_1:
2774 case scm_tc7_subr_1o:
2775 RETURN (SCM_SUBRF (proc) (t.arg1));
2776 case scm_tc7_cxr:
0f2d19dd
JB
2777 if (SCM_SUBRF (proc))
2778 {
2779 if (SCM_INUMP (t.arg1))
2780 {
f8de44c1 2781 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (t.arg1))));
0f2d19dd
JB
2782 }
2783 SCM_ASRTGO (SCM_NIMP (t.arg1), floerr);
2784 if (SCM_REALP (t.arg1))
2785 {
eb42e2f0 2786 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (t.arg1))));
0f2d19dd
JB
2787 }
2788#ifdef SCM_BIGDIG
2789 if (SCM_BIGP (t.arg1))
2790 {
f8de44c1 2791 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_big2dbl (t.arg1))));
0f2d19dd
JB
2792 }
2793#endif
2794 floerr:
9de33deb 2795 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), t.arg1,
3db4adfc 2796 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
0f2d19dd 2797 }
3201d763 2798 proc = SCM_SNAME (proc);
0f2d19dd 2799 {
b5c2579a 2800 char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
0f2d19dd
JB
2801 while ('c' != *--chrs)
2802 {
0c95b57d 2803 SCM_ASSERT (SCM_CONSP (t.arg1),
3db4adfc 2804 t.arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
0f2d19dd
JB
2805 t.arg1 = ('a' == *chrs) ? SCM_CAR (t.arg1) : SCM_CDR (t.arg1);
2806 }
2807 RETURN (t.arg1);
2808 }
2809 case scm_tc7_rpsubr:
2810 RETURN (SCM_BOOL_T);
2811 case scm_tc7_asubr:
2812 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2813 case scm_tc7_lsubr:
2814#ifdef DEVAL
6dbd0af5 2815 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd
JB
2816#else
2817 RETURN (SCM_SUBRF (proc) (scm_cons (t.arg1, SCM_EOL)));
2818#endif
0717dfd8 2819 case scm_tc7_smob:
68b06924 2820 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 2821 goto badfun;
68b06924 2822 RETURN (SCM_SMOB_APPLY_1 (proc, t.arg1));
0f2d19dd
JB
2823 case scm_tc7_cclo:
2824 arg2 = t.arg1;
2825 t.arg1 = proc;
2826 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2827#ifdef DEVAL
2828 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2829 debug.info->a.proc = proc;
2830#endif
0f2d19dd 2831 goto evap2;
89efbff4
MD
2832 case scm_tc7_pws:
2833 proc = SCM_PROCEDURE (proc);
2834#ifdef DEVAL
2835 debug.info->a.proc = proc;
2836#endif
002f1a5d
MD
2837 if (!SCM_CLOSUREP (proc))
2838 goto evap1;
2839 if (scm_badformalsp (proc, 1))
2840 goto umwrongnumargs;
0f2d19dd 2841 case scm_tcs_closures:
195847fa 2842 /* clos1: */
0f2d19dd
JB
2843 x = SCM_CODE (proc);
2844#ifdef DEVAL
e2806c10 2845 env = EXTEND_ENV (SCM_CAR (x), debug.info->a.args, SCM_ENV (proc));
0f2d19dd 2846#else
e2806c10 2847 env = EXTEND_ENV (SCM_CAR (x), scm_cons (t.arg1, SCM_EOL), SCM_ENV (proc));
0f2d19dd 2848#endif
5280aaca 2849 goto nontoplevel_cdrxbegin;
0c32d76c 2850 case scm_tcs_cons_gloc:
f3d2630a
MD
2851 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2852 {
195847fa 2853 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a
MD
2854#ifdef DEVAL
2855 arg2 = debug.info->a.args;
2856#else
2857 arg2 = scm_cons (t.arg1, SCM_EOL);
2858#endif
f3d2630a
MD
2859 goto type_dispatch;
2860 }
2861 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2862 goto badfun;
2863 else
0c32d76c 2864 {
195847fa
MD
2865 arg2 = t.arg1;
2866 t.arg1 = proc;
2867 proc = (SCM_I_ENTITYP (proc)
2868 ? SCM_ENTITY_PROCEDURE (proc)
2869 : SCM_OPERATOR_PROCEDURE (proc));
0c32d76c 2870#ifdef DEVAL
195847fa
MD
2871 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2872 debug.info->a.proc = proc;
0c32d76c 2873#endif
195847fa
MD
2874 if (SCM_NIMP (proc))
2875 goto evap2;
2876 else
2877 goto badfun;
0c32d76c 2878 }
0f2d19dd
JB
2879 case scm_tc7_subr_2:
2880 case scm_tc7_subr_0:
2881 case scm_tc7_subr_3:
2882 case scm_tc7_lsubr_2:
2883 goto wrongnumargs;
2884 default:
2885 goto badfun;
2886 }
2887 }
cf7c17e9 2888#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2889 if (SCM_IMP (x))
2890 goto wrongnumargs;
680ed4a8
MD
2891 else if (SCM_CONSP (x))
2892 {
2893 if (SCM_IMP (SCM_CAR (x)))
6cb702da 2894 arg2 = SCM_EVALIM (SCM_CAR (x), env);
680ed4a8
MD
2895 else
2896 arg2 = EVALCELLCAR (x, env);
2897 }
3201d763 2898 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
680ed4a8 2899 {
3201d763
DH
2900 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2901 if (vcell == 0)
680ed4a8 2902 arg2 = SCM_CAR (x); /* struct planted in code */
3201d763
DH
2903 else
2904 arg2 = SCM_PACK (vcell);
680ed4a8
MD
2905 }
2906 else
2907 goto wrongnumargs;
2908#else
2909 arg2 = EVALCAR (x, env);
0f2d19dd
JB
2910#endif
2911 { /* have two or more arguments */
6dbd0af5
MD
2912#ifdef DEVAL
2913 debug.info->a.args = scm_cons2 (t.arg1, arg2, SCM_EOL);
2914#endif
0f2d19dd
JB
2915 x = SCM_CDR (x);
2916 if (SCM_NULLP (x)) {
6dbd0af5 2917 ENTER_APPLY;
0f2d19dd 2918 evap2:
6dbd0af5
MD
2919 switch (SCM_TYP7 (proc))
2920 { /* have two arguments */
2921 case scm_tc7_subr_2:
2922 case scm_tc7_subr_2o:
2923 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2924 case scm_tc7_lsubr:
0f2d19dd 2925#ifdef DEVAL
6dbd0af5
MD
2926 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2927#else
2928 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, SCM_EOL)));
0f2d19dd 2929#endif
6dbd0af5
MD
2930 case scm_tc7_lsubr_2:
2931 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_EOL));
2932 case scm_tc7_rpsubr:
2933 case scm_tc7_asubr:
2934 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
0717dfd8 2935 case scm_tc7_smob:
68b06924 2936 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 2937 goto badfun;
68b06924 2938 RETURN (SCM_SMOB_APPLY_2 (proc, t.arg1, arg2));
6dbd0af5
MD
2939 cclon:
2940 case scm_tc7_cclo:
0f2d19dd 2941#ifdef DEVAL
195847fa
MD
2942 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2943 scm_cons (proc, debug.info->a.args),
2944 SCM_EOL));
0f2d19dd 2945#else
195847fa
MD
2946 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2947 scm_cons2 (proc, t.arg1,
2948 scm_cons (arg2,
2949 scm_eval_args (x,
2950 env,
2951 proc))),
2952 SCM_EOL));
6dbd0af5 2953#endif
0c32d76c 2954 case scm_tcs_cons_gloc:
f3d2630a
MD
2955 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2956 {
195847fa 2957 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a
MD
2958#ifdef DEVAL
2959 arg2 = debug.info->a.args;
2960#else
2961 arg2 = scm_cons2 (t.arg1, arg2, SCM_EOL);
2962#endif
f3d2630a
MD
2963 goto type_dispatch;
2964 }
2965 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2966 goto badfun;
2967 else
0c32d76c 2968 {
195847fa 2969 operatorn:
0c32d76c 2970#ifdef DEVAL
195847fa
MD
2971 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2972 ? SCM_ENTITY_PROCEDURE (proc)
2973 : SCM_OPERATOR_PROCEDURE (proc),
2974 scm_cons (proc, debug.info->a.args),
2975 SCM_EOL));
2976#else
2977 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2978 ? SCM_ENTITY_PROCEDURE (proc)
2979 : SCM_OPERATOR_PROCEDURE (proc),
2980 scm_cons2 (proc, t.arg1,
2981 scm_cons (arg2,
2982 scm_eval_args (x,
2983 env,
2984 proc))),
2985 SCM_EOL));
2986#endif
0c32d76c 2987 }
6dbd0af5
MD
2988 case scm_tc7_subr_0:
2989 case scm_tc7_cxr:
2990 case scm_tc7_subr_1o:
2991 case scm_tc7_subr_1:
2992 case scm_tc7_subr_3:
6dbd0af5
MD
2993 goto wrongnumargs;
2994 default:
2995 goto badfun;
002f1a5d
MD
2996 case scm_tc7_pws:
2997 proc = SCM_PROCEDURE (proc);
2998#ifdef DEVAL
2999 debug.info->a.proc = proc;
3000#endif
3001 if (!SCM_CLOSUREP (proc))
3002 goto evap2;
3003 if (scm_badformalsp (proc, 2))
3004 goto umwrongnumargs;
6dbd0af5 3005 case scm_tcs_closures:
195847fa 3006 /* clos2: */
0f2d19dd 3007#ifdef DEVAL
da7f71d7
MD
3008 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
3009 debug.info->a.args,
3010 SCM_ENV (proc));
0f2d19dd 3011#else
da7f71d7
MD
3012 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
3013 scm_cons2 (t.arg1, arg2, SCM_EOL), SCM_ENV (proc));
0f2d19dd 3014#endif
6dbd0af5 3015 x = SCM_CODE (proc);
5280aaca 3016 goto nontoplevel_cdrxbegin;
6dbd0af5 3017 }
0f2d19dd 3018 }
cf7c17e9 3019#ifdef SCM_CAUTIOUS
680ed4a8
MD
3020 if (SCM_IMP (x) || SCM_NECONSP (x))
3021 goto wrongnumargs;
3022#endif
0f2d19dd 3023#ifdef DEVAL
6dbd0af5 3024 debug.info->a.args = scm_cons2 (t.arg1, arg2,
680ed4a8
MD
3025 scm_deval_args (x, env, proc,
3026 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
0f2d19dd 3027#endif
6dbd0af5 3028 ENTER_APPLY;
89efbff4 3029 evap3:
6dbd0af5
MD
3030 switch (SCM_TYP7 (proc))
3031 { /* have 3 or more arguments */
0f2d19dd 3032#ifdef DEVAL
6dbd0af5
MD
3033 case scm_tc7_subr_3:
3034 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
da7f71d7
MD
3035 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
3036 SCM_CADDR (debug.info->a.args)));
6dbd0af5 3037 case scm_tc7_asubr:
399dedcc
MD
3038#ifdef BUILTIN_RPASUBR
3039 t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
3040 arg2 = SCM_CDR (SCM_CDR (debug.info->a.args));
da7f71d7
MD
3041 do
3042 {
3043 t.arg1 = SCM_SUBRF(proc)(t.arg1, SCM_CAR (arg2));
3044 arg2 = SCM_CDR (arg2);
3045 }
3046 while (SCM_NIMP (arg2));
399dedcc
MD
3047 RETURN (t.arg1)
3048#endif /* BUILTIN_RPASUBR */
6dbd0af5 3049 case scm_tc7_rpsubr:
71d3aa6d
MD
3050#ifdef BUILTIN_RPASUBR
3051 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
3052 RETURN (SCM_BOOL_F)
3053 t.arg1 = SCM_CDR (SCM_CDR (debug.info->a.args));
da7f71d7
MD
3054 do
3055 {
3056 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, SCM_CAR (t.arg1))))
3057 RETURN (SCM_BOOL_F)
3058 arg2 = SCM_CAR (t.arg1);
3059 t.arg1 = SCM_CDR (t.arg1);
3060 }
3061 while (SCM_NIMP (t.arg1));
71d3aa6d
MD
3062 RETURN (SCM_BOOL_T)
3063#else /* BUILTIN_RPASUBR */
da7f71d7
MD
3064 RETURN (SCM_APPLY (proc, t.arg1,
3065 scm_acons (arg2,
3066 SCM_CDR (SCM_CDR (debug.info->a.args)),
3067 SCM_EOL)))
71d3aa6d 3068#endif /* BUILTIN_RPASUBR */
399dedcc 3069 case scm_tc7_lsubr_2:
da7f71d7
MD
3070 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
3071 SCM_CDR (SCM_CDR (debug.info->a.args))))
399dedcc
MD
3072 case scm_tc7_lsubr:
3073 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0717dfd8 3074 case scm_tc7_smob:
68b06924 3075 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 3076 goto badfun;
68b06924
KN
3077 RETURN (SCM_SMOB_APPLY_3 (proc, t.arg1, arg2,
3078 SCM_CDDR (debug.info->a.args)));
6dbd0af5
MD
3079 case scm_tc7_cclo:
3080 goto cclon;
89efbff4
MD
3081 case scm_tc7_pws:
3082 proc = SCM_PROCEDURE (proc);
3083 debug.info->a.proc = proc;
002f1a5d
MD
3084 if (!SCM_CLOSUREP (proc))
3085 goto evap3;
3086 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), debug.info->a.args))
3087 goto umwrongnumargs;
6dbd0af5 3088 case scm_tcs_closures:
b7ff98dd 3089 SCM_SET_ARGSREADY (debug);
e2806c10 3090 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
6dbd0af5
MD
3091 debug.info->a.args,
3092 SCM_ENV (proc));
3093 x = SCM_CODE (proc);
5280aaca 3094 goto nontoplevel_cdrxbegin;
6dbd0af5
MD
3095#else /* DEVAL */
3096 case scm_tc7_subr_3:
3097 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
3098 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, EVALCAR (x, env)));
3099 case scm_tc7_asubr:
399dedcc 3100#ifdef BUILTIN_RPASUBR
da7f71d7
MD
3101 t.arg1 = SCM_SUBRF (proc) (t.arg1, arg2);
3102 do
3103 {
3104 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
3105 x = SCM_CDR(x);
3106 }
3107 while (SCM_NIMP (x));
399dedcc
MD
3108 RETURN (t.arg1)
3109#endif /* BUILTIN_RPASUBR */
6dbd0af5 3110 case scm_tc7_rpsubr:
71d3aa6d
MD
3111#ifdef BUILTIN_RPASUBR
3112 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
3113 RETURN (SCM_BOOL_F)
da7f71d7
MD
3114 do
3115 {
3116 t.arg1 = EVALCAR (x, env);
3117 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, t.arg1)))
3118 RETURN (SCM_BOOL_F)
3119 arg2 = t.arg1;
3120 x = SCM_CDR (x);
3121 }
3122 while (SCM_NIMP (x));
71d3aa6d
MD
3123 RETURN (SCM_BOOL_T)
3124#else /* BUILTIN_RPASUBR */
da7f71d7 3125 RETURN (SCM_APPLY (proc, t.arg1,
680ed4a8
MD
3126 scm_acons (arg2,
3127 scm_eval_args (x, env, proc),
3128 SCM_EOL)));
71d3aa6d 3129#endif /* BUILTIN_RPASUBR */
6dbd0af5 3130 case scm_tc7_lsubr_2:
680ed4a8 3131 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, scm_eval_args (x, env, proc)));
6dbd0af5 3132 case scm_tc7_lsubr:
680ed4a8
MD
3133 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1,
3134 arg2,
3135 scm_eval_args (x, env, proc))));
0717dfd8 3136 case scm_tc7_smob:
68b06924 3137 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 3138 goto badfun;
68b06924
KN
3139 RETURN (SCM_SMOB_APPLY_3 (proc, t.arg1, arg2,
3140 scm_eval_args (x, env, proc)));
6dbd0af5
MD
3141 case scm_tc7_cclo:
3142 goto cclon;
89efbff4
MD
3143 case scm_tc7_pws:
3144 proc = SCM_PROCEDURE (proc);
002f1a5d
MD
3145 if (!SCM_CLOSUREP (proc))
3146 goto evap3;
3147 {
3148 SCM formals = SCM_CAR (SCM_CODE (proc));
3149 if (SCM_NULLP (formals)
3150 || (SCM_CONSP (formals)
3151 && (SCM_NULLP (SCM_CDR (formals))
3152 || (SCM_CONSP (SCM_CDR (formals))
3153 && scm_badargsp (SCM_CDDR (formals), x)))))
3154 goto umwrongnumargs;
3155 }
6dbd0af5
MD
3156 case scm_tcs_closures:
3157#ifdef DEVAL
b7ff98dd 3158 SCM_SET_ARGSREADY (debug);
6dbd0af5 3159#endif
e2806c10 3160 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
680ed4a8
MD
3161 scm_cons2 (t.arg1,
3162 arg2,
3163 scm_eval_args (x, env, proc)),
6dbd0af5
MD
3164 SCM_ENV (proc));
3165 x = SCM_CODE (proc);
5280aaca 3166 goto nontoplevel_cdrxbegin;
0f2d19dd 3167#endif /* DEVAL */
0c32d76c 3168 case scm_tcs_cons_gloc:
f3d2630a
MD
3169 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3170 {
3171#ifdef DEVAL
3172 arg2 = debug.info->a.args;
3173#else
3174 arg2 = scm_cons2 (t.arg1, arg2, scm_eval_args (x, env, proc));
3175#endif
195847fa 3176 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a
MD
3177 goto type_dispatch;
3178 }
3179 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
3180 goto badfun;
3181 else
195847fa 3182 goto operatorn;
6dbd0af5
MD
3183 case scm_tc7_subr_2:
3184 case scm_tc7_subr_1o:
3185 case scm_tc7_subr_2o:
3186 case scm_tc7_subr_0:
3187 case scm_tc7_cxr:
3188 case scm_tc7_subr_1:
6dbd0af5
MD
3189 goto wrongnumargs;
3190 default:
3191 goto badfun;
3192 }
0f2d19dd
JB
3193 }
3194#ifdef DEVAL
6dbd0af5 3195exit:
b6d75948 3196 if (CHECK_EXIT && SCM_TRAPS_P)
b7ff98dd 3197 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3198 {
b7ff98dd
MD
3199 SCM_CLEAR_TRACED_FRAME (debug);
3200 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3201 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3202 else
3203 {
5f144b10
GH
3204 int first;
3205 SCM val = scm_make_continuation (&first);
3206
3207 if (first)
3208 t.arg1 = val;
3209 else
6dbd0af5 3210 {
5f144b10 3211 proc = val;
6dbd0af5
MD
3212 goto ret;
3213 }
3214 }
2f0d1375 3215 scm_ithrow (scm_sym_exit_frame, scm_cons2 (t.arg1, proc, SCM_EOL), 0);
6dbd0af5
MD
3216 }
3217ret:
1646d37b 3218 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3219 return proc;
3220#endif
3221}
3222
6dbd0af5
MD
3223
3224/* SECTION: This code is compiled once.
3225 */
3226
0f2d19dd
JB
3227#ifndef DEVAL
3228
82a2622a 3229/* This code processes the arguments to apply:
b145c172
JB
3230
3231 (apply PROC ARG1 ... ARGS)
3232
82a2622a
JB
3233 Given a list (ARG1 ... ARGS), this function conses the ARG1
3234 ... arguments onto the front of ARGS, and returns the resulting
3235 list. Note that ARGS is a list; thus, the argument to this
3236 function is a list whose last element is a list.
3237
3238 Apply calls this function, and applies PROC to the elements of the
b145c172
JB
3239 result. apply:nconc2last takes care of building the list of
3240 arguments, given (ARG1 ... ARGS).
3241
82a2622a
JB
3242 Rather than do new consing, apply:nconc2last destroys its argument.
3243 On that topic, this code came into my care with the following
3244 beautifully cryptic comment on that topic: "This will only screw
3245 you if you do (scm_apply scm_apply '( ... ))" If you know what
3246 they're referring to, send me a patch to this comment. */
b145c172 3247
3b3b36dd 3248SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
b3f26b14
MG
3249 (SCM lst),
3250 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
3251 "conses the @var{arg1} @dots{} arguments onto the front of\n"
3252 "@var{args}, and returns the resulting list. Note that\n"
3253 "@var{args} is a list; thus, the argument to this function is\n"
3254 "a list whose last element is a list.\n"
3255 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
3256 "destroys its argument, so use with care.")
1bbd0b84 3257#define FUNC_NAME s_scm_nconc2last
0f2d19dd
JB
3258{
3259 SCM *lloc;
c1bfcf60 3260 SCM_VALIDATE_NONEMPTYLIST (1,lst);
0f2d19dd
JB
3261 lloc = &lst;
3262 while (SCM_NNULLP (SCM_CDR (*lloc)))
a23afe53 3263 lloc = SCM_CDRLOC (*lloc);
1bbd0b84 3264 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
0f2d19dd
JB
3265 *lloc = SCM_CAR (*lloc);
3266 return lst;
3267}
1bbd0b84 3268#undef FUNC_NAME
0f2d19dd
JB
3269
3270#endif /* !DEVAL */
3271
6dbd0af5
MD
3272
3273/* SECTION: When DEVAL is defined this code yields scm_dapply.
3274 * It is compiled twice.
3275 */
3276
0f2d19dd 3277#if 0
1cc91f1b 3278
0f2d19dd 3279SCM
6e8d25a6 3280scm_apply (SCM proc, SCM arg1, SCM args)
0f2d19dd
JB
3281{}
3282#endif
3283
3284#if 0
1cc91f1b 3285
0f2d19dd 3286SCM
6e8d25a6
GB
3287scm_dapply (SCM proc, SCM arg1, SCM args)
3288{ /* empty */ }
0f2d19dd
JB
3289#endif
3290
1cc91f1b 3291
82a2622a
JB
3292/* Apply a function to a list of arguments.
3293
3294 This function is exported to the Scheme level as taking two
3295 required arguments and a tail argument, as if it were:
3296 (lambda (proc arg1 . args) ...)
3297 Thus, if you just have a list of arguments to pass to a procedure,
3298 pass the list as ARG1, and '() for ARGS. If you have some fixed
3299 args, pass the first as ARG1, then cons any remaining fixed args
3300 onto the front of your argument list, and pass that as ARGS. */
3301
0f2d19dd 3302SCM
1bbd0b84 3303SCM_APPLY (SCM proc, SCM arg1, SCM args)
0f2d19dd
JB
3304{
3305#ifdef DEBUG_EXTENSIONS
3306#ifdef DEVAL
6dbd0af5 3307 scm_debug_frame debug;
c0ab1b8d 3308 scm_debug_info debug_vect_body;
1646d37b 3309 debug.prev = scm_last_debug_frame;
b7ff98dd 3310 debug.status = SCM_APPLYFRAME;
c0ab1b8d 3311 debug.vect = &debug_vect_body;
6dbd0af5
MD
3312 debug.vect[0].a.proc = proc;
3313 debug.vect[0].a.args = SCM_EOL;
1646d37b 3314 scm_last_debug_frame = &debug;
0f2d19dd 3315#else
b7ff98dd 3316 if (SCM_DEBUGGINGP)
0f2d19dd
JB
3317 return scm_dapply (proc, arg1, args);
3318#endif
3319#endif
3320
3321 SCM_ASRTGO (SCM_NIMP (proc), badproc);
82a2622a
JB
3322
3323 /* If ARGS is the empty list, then we're calling apply with only two
3324 arguments --- ARG1 is the list of arguments for PROC. Whatever
3325 the case, futz with things so that ARG1 is the first argument to
3326 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
30000774
JB
3327 rest.
3328
3329 Setting the debug apply frame args this way is pretty messy.
3330 Perhaps we should store arg1 and args directly in the frame as
3331 received, and let scm_frame_arguments unpack them, because that's
3332 a relatively rare operation. This works for now; if the Guile
3333 developer archives are still around, see Mikael's post of
3334 11-Apr-97. */
0f2d19dd
JB
3335 if (SCM_NULLP (args))
3336 {
3337 if (SCM_NULLP (arg1))
30000774
JB
3338 {
3339 arg1 = SCM_UNDEFINED;
3340#ifdef DEVAL
3341 debug.vect[0].a.args = SCM_EOL;
3342#endif
3343 }
0f2d19dd
JB
3344 else
3345 {
30000774
JB
3346#ifdef DEVAL
3347 debug.vect[0].a.args = arg1;
3348#endif
0f2d19dd
JB
3349 args = SCM_CDR (arg1);
3350 arg1 = SCM_CAR (arg1);
3351 }
3352 }
3353 else
3354 {
0f2d19dd 3355 args = scm_nconc2last (args);
30000774
JB
3356#ifdef DEVAL
3357 debug.vect[0].a.args = scm_cons (arg1, args);
3358#endif
0f2d19dd 3359 }
0f2d19dd 3360#ifdef DEVAL
b6d75948 3361 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
6dbd0af5
MD
3362 {
3363 SCM tmp;
b7ff98dd 3364 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3365 tmp = scm_make_debugobj (&debug);
6dbd0af5
MD
3366 else
3367 {
5f144b10
GH
3368 int first;
3369
3370 tmp = scm_make_continuation (&first);
3371 if (!first)
6dbd0af5
MD
3372 goto entap;
3373 }
2f0d1375 3374 scm_ithrow (scm_sym_enter_frame, scm_cons (tmp, SCM_EOL), 0);
6dbd0af5
MD
3375 }
3376entap:
3377 ENTER_APPLY;
3378#endif
6dbd0af5 3379tail:
0f2d19dd
JB
3380 switch (SCM_TYP7 (proc))
3381 {
3382 case scm_tc7_subr_2o:
3383 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
3384 RETURN (SCM_SUBRF (proc) (arg1, args))
3385 case scm_tc7_subr_2:
269861c7
MD
3386 SCM_ASRTGO (SCM_NNULLP (args) && SCM_NULLP (SCM_CDR (args)),
3387 wrongnumargs);
0f2d19dd
JB
3388 args = SCM_CAR (args);
3389 RETURN (SCM_SUBRF (proc) (arg1, args))
3390 case scm_tc7_subr_0:
3391 SCM_ASRTGO (SCM_UNBNDP (arg1), wrongnumargs);
3392 RETURN (SCM_SUBRF (proc) ())
3393 case scm_tc7_subr_1:
41ee56dd 3394 SCM_ASRTGO (!SCM_UNBNDP (arg1), wrongnumargs);
0f2d19dd
JB
3395 case scm_tc7_subr_1o:
3396 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
3397 RETURN (SCM_SUBRF (proc) (arg1))
3398 case scm_tc7_cxr:
90cd76d9 3399 SCM_ASRTGO (!SCM_UNBNDP (arg1) && SCM_NULLP (args), wrongnumargs);
0f2d19dd
JB
3400 if (SCM_SUBRF (proc))
3401 {
6dbd0af5
MD
3402 if (SCM_INUMP (arg1))
3403 {
f8de44c1 3404 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
6dbd0af5 3405 }
0f2d19dd 3406 SCM_ASRTGO (SCM_NIMP (arg1), floerr);
6dbd0af5
MD
3407 if (SCM_REALP (arg1))
3408 {
eb42e2f0 3409 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
6dbd0af5 3410 }
0f2d19dd 3411#ifdef SCM_BIGDIG
26d5b9b4 3412 if (SCM_BIGP (arg1))
f8de44c1 3413 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_big2dbl (arg1))))
0f2d19dd
JB
3414#endif
3415 floerr:
9de33deb 3416 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3db4adfc 3417 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
0f2d19dd 3418 }
3201d763 3419 proc = SCM_SNAME (proc);
0f2d19dd 3420 {
b5c2579a 3421 char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
0f2d19dd
JB
3422 while ('c' != *--chrs)
3423 {
0c95b57d 3424 SCM_ASSERT (SCM_CONSP (arg1),
3db4adfc 3425 arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
0f2d19dd
JB
3426 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3427 }
3428 RETURN (arg1)
3429 }
3430 case scm_tc7_subr_3:
f1e06a96
MD
3431 SCM_ASRTGO (SCM_NNULLP (args)
3432 && SCM_NNULLP (SCM_CDR (args))
3433 && SCM_NULLP (SCM_CDDR (args)),
3434 wrongnumargs);
0f2d19dd
JB
3435 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CAR (SCM_CDR (args))))
3436 case scm_tc7_lsubr:
3437#ifdef DEVAL
6dbd0af5 3438 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args))
0f2d19dd
JB
3439#else
3440 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)))
3441#endif
3442 case scm_tc7_lsubr_2:
0c95b57d 3443 SCM_ASRTGO (SCM_CONSP (args), wrongnumargs);
0f2d19dd
JB
3444 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)))
3445 case scm_tc7_asubr:
3446 if (SCM_NULLP (args))
3447 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED))
3448 while (SCM_NIMP (args))
3449 {
3450 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3451 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
3452 args = SCM_CDR (args);
3453 }
3454 RETURN (arg1);
3455 case scm_tc7_rpsubr:
3456 if (SCM_NULLP (args))
3457 RETURN (SCM_BOOL_T);
3458 while (SCM_NIMP (args))
3459 {
3460 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3461 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
3462 RETURN (SCM_BOOL_F);
3463 arg1 = SCM_CAR (args);
3464 args = SCM_CDR (args);
3465 }
3466 RETURN (SCM_BOOL_T);
3467 case scm_tcs_closures:
3468#ifdef DEVAL
6dbd0af5 3469 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
0f2d19dd
JB
3470#else
3471 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
3472#endif
cf7c17e9 3473#ifndef SCM_RECKLESS
0f2d19dd
JB
3474 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), arg1))
3475 goto wrongnumargs;
3476#endif
1609038c
MD
3477
3478 /* Copy argument list */
3479 if (SCM_IMP (arg1))
3480 args = arg1;
3481 else
3482 {
3483 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
cabe682c 3484 while (arg1 = SCM_CDR (arg1), SCM_CONSP (arg1))
1609038c
MD
3485 {
3486 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1),
3487 SCM_UNSPECIFIED));
3488 tl = SCM_CDR (tl);
3489 }
3490 SCM_SETCDR (tl, arg1);
3491 }
3492
3493 args = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), args, SCM_ENV (proc));
2ddb0920 3494 proc = SCM_CDR (SCM_CODE (proc));
e791c18f
MD
3495 again:
3496 arg1 = proc;
3497 while (SCM_NNULLP (arg1 = SCM_CDR (arg1)))
2ddb0920
MD
3498 {
3499 if (SCM_IMP (SCM_CAR (proc)))
3500 {
3501 if (SCM_ISYMP (SCM_CAR (proc)))
3502 {
3503 proc = scm_m_expand_body (proc, args);
e791c18f 3504 goto again;
2ddb0920 3505 }
5280aaca
MV
3506 else
3507 SCM_EVALIM2 (SCM_CAR (proc));
2ddb0920
MD
3508 }
3509 else
e791c18f
MD
3510 SCM_CEVAL (SCM_CAR (proc), args);
3511 proc = arg1;
2ddb0920 3512 }
e791c18f 3513 RETURN (EVALCAR (proc, args));
0717dfd8 3514 case scm_tc7_smob:
68b06924 3515 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 3516 goto badproc;
afa38f6e 3517 if (SCM_UNBNDP (arg1))
68b06924 3518 RETURN (SCM_SMOB_APPLY_0 (proc))
afa38f6e 3519 else if (SCM_NULLP (args))
68b06924 3520 RETURN (SCM_SMOB_APPLY_1 (proc, arg1))
0717dfd8 3521 else if (SCM_NULLP (SCM_CDR (args)))
68b06924 3522 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, SCM_CAR (args)))
0717dfd8 3523 else
68b06924 3524 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, SCM_CAR (args), SCM_CDR (args)));
0f2d19dd
JB
3525 case scm_tc7_cclo:
3526#ifdef DEVAL
6dbd0af5
MD
3527 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3528 arg1 = proc;
3529 proc = SCM_CCLO_SUBR (proc);
3530 debug.vect[0].a.proc = proc;
3531 debug.vect[0].a.args = scm_cons (arg1, args);
0f2d19dd
JB
3532#else
3533 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
0f2d19dd
JB
3534 arg1 = proc;
3535 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 3536#endif
0f2d19dd 3537 goto tail;
89efbff4
MD
3538 case scm_tc7_pws:
3539 proc = SCM_PROCEDURE (proc);
3540#ifdef DEVAL
3541 debug.vect[0].a.proc = proc;
3542#endif
3543 goto tail;
0c32d76c 3544 case scm_tcs_cons_gloc:
f3d2630a
MD
3545 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3546 {
3547#ifdef DEVAL
3548 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3549#else
3550 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3551#endif
195847fa 3552 RETURN (scm_apply_generic (proc, args));
f3d2630a
MD
3553 }
3554 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
3555 goto badproc;
3556 else
da7f71d7
MD
3557 {
3558#ifdef DEVAL
3559 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3560#else
3561 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3562#endif
3563 arg1 = proc;
195847fa
MD
3564 proc = (SCM_I_ENTITYP (proc)
3565 ? SCM_ENTITY_PROCEDURE (proc)
3566 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7
MD
3567#ifdef DEVAL
3568 debug.vect[0].a.proc = proc;
3569 debug.vect[0].a.args = scm_cons (arg1, args);
3570#endif
195847fa
MD
3571 if (SCM_NIMP (proc))
3572 goto tail;
3573 else
3574 goto badproc;
da7f71d7 3575 }
0f2d19dd 3576 wrongnumargs:
f5bf2977 3577 scm_wrong_num_args (proc);
0f2d19dd
JB
3578 default:
3579 badproc:
db4b4ca6 3580 scm_wrong_type_arg ("apply", SCM_ARG1, proc);
0f2d19dd
JB
3581 RETURN (arg1);
3582 }
3583#ifdef DEVAL
6dbd0af5 3584exit:
b6d75948 3585 if (CHECK_EXIT && SCM_TRAPS_P)
b7ff98dd 3586 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3587 {
b7ff98dd
MD
3588 SCM_CLEAR_TRACED_FRAME (debug);
3589 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3590 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3591 else
3592 {
5f144b10
GH
3593 int first;
3594 SCM val = scm_make_continuation (&first);
3595
3596 if (first)
3597 arg1 = val;
3598 else
6dbd0af5 3599 {
5f144b10 3600 proc = val;
6dbd0af5
MD
3601 goto ret;
3602 }
3603 }
2f0d1375 3604 scm_ithrow (scm_sym_exit_frame, scm_cons2 (arg1, proc, SCM_EOL), 0);
6dbd0af5
MD
3605 }
3606ret:
1646d37b 3607 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3608 return proc;
3609#endif
3610}
3611
6dbd0af5
MD
3612
3613/* SECTION: The rest of this file is only read once.
3614 */
3615
0f2d19dd
JB
3616#ifndef DEVAL
3617
d9c393f5
JB
3618/* Typechecking for multi-argument MAP and FOR-EACH.
3619
47c3f06d 3620 Verify that each element of the vector ARGV, except for the first,
d9c393f5 3621 is a proper list whose length is LEN. Attribute errors to WHO,
47c3f06d 3622 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
d9c393f5 3623static inline void
47c3f06d
MD
3624check_map_args (SCM argv,
3625 long len,
3626 SCM gf,
3627 SCM proc,
3628 SCM args,
3629 const char *who)
d9c393f5 3630{
47c3f06d 3631 SCM *ve = SCM_VELTS (argv);
d9c393f5
JB
3632 int i;
3633
b5c2579a 3634 for (i = SCM_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
d9c393f5
JB
3635 {
3636 int elt_len = scm_ilength (ve[i]);
3637
3638 if (elt_len < 0)
47c3f06d
MD
3639 {
3640 if (gf)
3641 scm_apply_generic (gf, scm_cons (proc, args));
3642 else
3643 scm_wrong_type_arg (who, i + 2, ve[i]);
3644 }
d9c393f5
JB
3645
3646 if (elt_len != len)
3647 scm_out_of_range (who, ve[i]);
3648 }
3649
5d2b97cd 3650 scm_remember_upto_here_1 (argv);
d9c393f5
JB
3651}
3652
3653
47c3f06d 3654SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
1cc91f1b 3655
368bf056
MD
3656/* Note: Currently, scm_map applies PROC to the argument list(s)
3657 sequentially, starting with the first element(s). This is used in
8878f040 3658 evalext.c where the Scheme procedure `map-in-order', which guarantees
368bf056 3659 sequential behaviour, is implemented using scm_map. If the
8878f040 3660 behaviour changes, we need to update `map-in-order'.
368bf056
MD
3661*/
3662
0f2d19dd 3663SCM
1bbd0b84 3664scm_map (SCM proc, SCM arg1, SCM args)
af45e3b0 3665#define FUNC_NAME s_map
0f2d19dd 3666{
d9c393f5 3667 long i, len;
0f2d19dd
JB
3668 SCM res = SCM_EOL;
3669 SCM *pres = &res;
3670 SCM *ve = &args; /* Keep args from being optimized away. */
3671
d9c393f5 3672 len = scm_ilength (arg1);
47c3f06d
MD
3673 SCM_GASSERTn (len >= 0,
3674 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
af45e3b0 3675 SCM_VALIDATE_REST_ARGUMENT (args);
0f2d19dd
JB
3676 if (SCM_NULLP (args))
3677 {
3678 while (SCM_NIMP (arg1))
3679 {
47c3f06d
MD
3680 *pres = scm_cons (scm_apply (proc, SCM_CAR (arg1), scm_listofnull),
3681 SCM_EOL);
a23afe53 3682 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
3683 arg1 = SCM_CDR (arg1);
3684 }
3685 return res;
3686 }
47c3f06d 3687 args = scm_vector (arg1 = scm_cons (arg1, args));
0f2d19dd 3688 ve = SCM_VELTS (args);
cf7c17e9 3689#ifndef SCM_RECKLESS
47c3f06d 3690 check_map_args (args, len, g_map, proc, arg1, s_map);
0f2d19dd
JB
3691#endif
3692 while (1)
3693 {
3694 arg1 = SCM_EOL;
b5c2579a 3695 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd 3696 {
d9c393f5
JB
3697 if (SCM_IMP (ve[i]))
3698 return res;
0f2d19dd
JB
3699 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3700 ve[i] = SCM_CDR (ve[i]);
3701 }
3702 *pres = scm_cons (scm_apply (proc, arg1, SCM_EOL), SCM_EOL);
a23afe53 3703 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
3704 }
3705}
af45e3b0 3706#undef FUNC_NAME
0f2d19dd
JB
3707
3708
47c3f06d 3709SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
1cc91f1b 3710
0f2d19dd 3711SCM
1bbd0b84 3712scm_for_each (SCM proc, SCM arg1, SCM args)
af45e3b0 3713#define FUNC_NAME s_for_each
0f2d19dd
JB
3714{
3715 SCM *ve = &args; /* Keep args from being optimized away. */
d9c393f5 3716 long i, len;
d9c393f5 3717 len = scm_ilength (arg1);
47c3f06d
MD
3718 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
3719 SCM_ARG2, s_for_each);
af45e3b0 3720 SCM_VALIDATE_REST_ARGUMENT (args);
0f2d19dd
JB
3721 if SCM_NULLP (args)
3722 {
3723 while SCM_NIMP (arg1)
3724 {
0f2d19dd
JB
3725 scm_apply (proc, SCM_CAR (arg1), scm_listofnull);
3726 arg1 = SCM_CDR (arg1);
3727 }
3728 return SCM_UNSPECIFIED;
3729 }
47c3f06d 3730 args = scm_vector (arg1 = scm_cons (arg1, args));
0f2d19dd 3731 ve = SCM_VELTS (args);
cf7c17e9 3732#ifndef SCM_RECKLESS
47c3f06d 3733 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
0f2d19dd
JB
3734#endif
3735 while (1)
3736 {
3737 arg1 = SCM_EOL;
b5c2579a 3738 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd
JB
3739 {
3740 if SCM_IMP
3741 (ve[i]) return SCM_UNSPECIFIED;
3742 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3743 ve[i] = SCM_CDR (ve[i]);
3744 }
3745 scm_apply (proc, arg1, SCM_EOL);
3746 }
3747}
af45e3b0 3748#undef FUNC_NAME
0f2d19dd 3749
1cc91f1b 3750
0f2d19dd 3751SCM
6e8d25a6 3752scm_closure (SCM code, SCM env)
0f2d19dd
JB
3753{
3754 register SCM z;
3755 SCM_NEWCELL (z);
3756 SCM_SETCODE (z, code);
a23afe53 3757 SCM_SETENV (z, env);
0f2d19dd
JB
3758 return z;
3759}
3760
3761
e841c3e0 3762scm_bits_t scm_tc16_promise;
1cc91f1b 3763
0f2d19dd 3764SCM
6e8d25a6 3765scm_makprom (SCM code)
0f2d19dd 3766{
cf498326 3767 SCM_RETURN_NEWSMOB (scm_tc16_promise, SCM_UNPACK (code));
0f2d19dd
JB
3768}
3769
3770
1cc91f1b 3771
0f2d19dd 3772static int
e841c3e0 3773promise_print (SCM exp, SCM port, scm_print_state *pstate)
0f2d19dd 3774{
19402679 3775 int writingp = SCM_WRITINGP (pstate);
b7f3516f 3776 scm_puts ("#<promise ", port);
19402679 3777 SCM_SET_WRITINGP (pstate, 1);
22a52da1 3778 scm_iprin1 (SCM_CELL_WORD_1 (exp), port, pstate);
19402679 3779 SCM_SET_WRITINGP (pstate, writingp);
b7f3516f 3780 scm_putc ('>', port);
0f2d19dd
JB
3781 return !0;
3782}
3783
3784
3b3b36dd 3785SCM_DEFINE (scm_force, "force", 1, 0, 0,
67e8151b
MG
3786 (SCM x),
3787 "If the promise @var{x} has not been computed yet, compute and\n"
3788 "return @var{x}, otherwise just return the previously computed\n"
3789 "value.")
1bbd0b84 3790#define FUNC_NAME s_scm_force
0f2d19dd 3791{
445f675c
DH
3792 SCM_VALIDATE_SMOB (1, x, promise);
3793 if (!((1L << 16) & SCM_CELL_WORD_0 (x)))
0f2d19dd 3794 {
445f675c
DH
3795 SCM ans = scm_apply (SCM_CELL_OBJECT_1 (x), SCM_EOL, SCM_EOL);
3796 if (!((1L << 16) & SCM_CELL_WORD_0 (x)))
0f2d19dd
JB
3797 {
3798 SCM_DEFER_INTS;
445f675c
DH
3799 SCM_SET_CELL_OBJECT_1 (x, ans);
3800 SCM_SET_CELL_WORD_0 (x, SCM_CELL_WORD_0 (x) | (1L << 16));
0f2d19dd
JB
3801 SCM_ALLOW_INTS;
3802 }
3803 }
445f675c 3804 return SCM_CELL_OBJECT_1 (x);
0f2d19dd 3805}
1bbd0b84 3806#undef FUNC_NAME
0f2d19dd 3807
445f675c 3808
a1ec6916 3809SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
67e8151b 3810 (SCM obj),
b380b885
MD
3811 "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
3812 "(@pxref{Delayed evaluation,,,r4rs.info,The Revised^4 Report on Scheme}).")
1bbd0b84 3813#define FUNC_NAME s_scm_promise_p
0f2d19dd 3814{
67e8151b 3815 return SCM_BOOL (SCM_TYP16_PREDICATE (scm_tc16_promise, obj));
0f2d19dd 3816}
1bbd0b84 3817#undef FUNC_NAME
0f2d19dd 3818
445f675c 3819
a1ec6916 3820SCM_DEFINE (scm_cons_source, "cons-source", 3, 0, 0,
1bbd0b84 3821 (SCM xorig, SCM x, SCM y),
11768c04
NJ
3822 "Create and return a new pair whose car and cdr are @var{x} and @var{y}.\n"
3823 "Any source properties associated with @var{xorig} are also associated\n"
3824 "with the new pair.")
1bbd0b84 3825#define FUNC_NAME s_scm_cons_source
26d5b9b4
MD
3826{
3827 SCM p, z;
3828 SCM_NEWCELL (z);
445f675c
DH
3829 SCM_SET_CELL_OBJECT_0 (z, x);
3830 SCM_SET_CELL_OBJECT_1 (z, y);
26d5b9b4
MD
3831 /* Copy source properties possibly associated with xorig. */
3832 p = scm_whash_lookup (scm_source_whash, xorig);
445f675c 3833 if (!SCM_IMP (p))
26d5b9b4
MD
3834 scm_whash_insert (scm_source_whash, z, p);
3835 return z;
3836}
1bbd0b84 3837#undef FUNC_NAME
26d5b9b4 3838
445f675c 3839
a1ec6916 3840SCM_DEFINE (scm_copy_tree, "copy-tree", 1, 0, 0,
1bbd0b84 3841 (SCM obj),
b380b885
MD
3842 "Recursively copy the data tree that is bound to @var{obj}, and return a\n"
3843 "pointer to the new data structure. @code{copy-tree} recurses down the\n"
3844 "contents of both pairs and vectors (since both cons cells and vector\n"
3845 "cells may point to arbitrary objects), and stops recursing when it hits\n"
3846 "any other object.")
1bbd0b84 3847#define FUNC_NAME s_scm_copy_tree
0f2d19dd
JB
3848{
3849 SCM ans, tl;
26d5b9b4 3850 if (SCM_IMP (obj))
ff467021 3851 return obj;
3910272e
MD
3852 if (SCM_VECTORP (obj))
3853 {
b5c2579a 3854 scm_sizet i = SCM_VECTOR_LENGTH (obj);
00ffa0e7 3855 ans = scm_c_make_vector (i, SCM_UNSPECIFIED);
3910272e
MD
3856 while (i--)
3857 SCM_VELTS (ans)[i] = scm_copy_tree (SCM_VELTS (obj)[i]);
3858 return ans;
3859 }
ff467021 3860 if (SCM_NCONSP (obj))
0f2d19dd 3861 return obj;
26d5b9b4
MD
3862 ans = tl = scm_cons_source (obj,
3863 scm_copy_tree (SCM_CAR (obj)),
3864 SCM_UNSPECIFIED);
cabe682c 3865 while (obj = SCM_CDR (obj), SCM_CONSP (obj))
a23afe53
MD
3866 {
3867 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
3868 SCM_UNSPECIFIED));
3869 tl = SCM_CDR (tl);
3870 }
3871 SCM_SETCDR (tl, obj);
0f2d19dd
JB
3872 return ans;
3873}
1bbd0b84 3874#undef FUNC_NAME
0f2d19dd 3875
1cc91f1b 3876
4163eb72
MV
3877/* We have three levels of EVAL here:
3878
3879 - scm_i_eval (exp, env)
3880
3881 evaluates EXP in environment ENV. ENV is a lexical environment
3882 structure as used by the actual tree code evaluator. When ENV is
3883 a top-level environment, then changes to the current module are
a513ead3 3884 tracked by updating ENV so that it continues to be in sync with
4163eb72
MV
3885 the current module.
3886
3887 - scm_primitive_eval (exp)
3888
3889 evaluates EXP in the top-level environment as determined by the
3890 current module. This is done by constructing a suitable
3891 environment and calling scm_i_eval. Thus, changes to the
3892 top-level module are tracked normally.
3893
3894 - scm_eval (exp, mod)
3895
a513ead3 3896 evaluates EXP while MOD is the current module. This is done by
4163eb72
MV
3897 setting the current module to MOD, invoking scm_primitive_eval on
3898 EXP, and then restoring the current module to the value it had
3899 previously. That is, while EXP is evaluated, changes to the
3900 current module are tracked, but these changes do not persist when
3901 scm_eval returns.
3902
3903 For each level of evals, there are two variants, distinguished by a
3904 _x suffix: the ordinary variant does not modify EXP while the _x
3905 variant can destructively modify EXP into something completely
3906 unintelligible. A Scheme data structure passed as EXP to one of the
3907 _x variants should not ever be used again for anything. So when in
3908 doubt, use the ordinary variant.
3909
3910*/
3911
68d8be66
MD
3912SCM scm_system_transformer;
3913
0f2d19dd 3914SCM
68d8be66 3915scm_i_eval_x (SCM exp, SCM env)
0f2d19dd 3916{
68d8be66 3917 return SCM_XEVAL (exp, env);
0f2d19dd
JB
3918}
3919
68d8be66
MD
3920SCM
3921scm_i_eval (SCM exp, SCM env)
3922{
e37a4fba 3923 return SCM_XEVAL (exp, env);
68d8be66
MD
3924}
3925
3926SCM
4163eb72 3927scm_primitive_eval_x (SCM exp)
0f2d19dd 3928{
a513ead3
MV
3929 SCM env;
3930 SCM transformer = scm_fluid_ref (SCM_CDR (scm_system_transformer));
3931 if (SCM_NIMP (transformer))
3932 exp = scm_apply (transformer, exp, scm_listofnull);
3933 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72 3934 return scm_i_eval_x (exp, env);
0f2d19dd
JB
3935}
3936
4163eb72
MV
3937SCM_DEFINE (scm_primitive_eval, "primitive-eval", 1, 0, 0,
3938 (SCM exp),
2069af38 3939 "Evaluate @var{exp} in the top-level environment specified by\n"
4163eb72
MV
3940 "the current module.")
3941#define FUNC_NAME s_scm_primitive_eval
3942{
a513ead3
MV
3943 SCM env;
3944 SCM transformer = scm_fluid_ref (SCM_CDR (scm_system_transformer));
3945 if (SCM_NIMP (transformer))
3946 exp = scm_apply (transformer, exp, scm_listofnull);
3947 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72
MV
3948 return scm_i_eval (exp, env);
3949}
3950#undef FUNC_NAME
3951
68d8be66
MD
3952/* Eval does not take the second arg optionally. This is intentional
3953 * in order to be R5RS compatible, and to prepare for the new module
3954 * system, where we would like to make the choice of evaluation
4163eb72 3955 * environment explicit. */
549e6ec6 3956
09074dbf
DH
3957static void
3958change_environment (void *data)
3959{
3960 SCM pair = SCM_PACK (data);
3961 SCM new_module = SCM_CAR (pair);
aa767bc5 3962 SCM old_module = scm_current_module ();
09074dbf 3963 SCM_SETCDR (pair, old_module);
aa767bc5 3964 scm_set_current_module (new_module);
09074dbf
DH
3965}
3966
3967
09074dbf
DH
3968static void
3969restore_environment (void *data)
3970{
3971 SCM pair = SCM_PACK (data);
3972 SCM old_module = SCM_CDR (pair);
aa767bc5 3973 SCM new_module = scm_current_module ();
2e9c835d 3974 SCM_SETCAR (pair, new_module);
aa767bc5 3975 scm_set_current_module (old_module);
09074dbf
DH
3976}
3977
4163eb72
MV
3978static SCM
3979inner_eval_x (void *data)
3980{
3981 return scm_primitive_eval_x (SCM_PACK(data));
3982}
3983
3984SCM
3985scm_eval_x (SCM exp, SCM module)
3986#define FUNC_NAME "eval!"
3987{
3988 SCM_VALIDATE_MODULE (2, module);
3989
3990 return scm_internal_dynamic_wind
3991 (change_environment, inner_eval_x, restore_environment,
3992 (void *) SCM_UNPACK (exp),
3993 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
3994}
3995#undef FUNC_NAME
3996
3997static SCM
3998inner_eval (void *data)
3999{
4000 return scm_primitive_eval (SCM_PACK(data));
4001}
09074dbf 4002
68d8be66 4003SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
4163eb72
MV
4004 (SCM exp, SCM module),
4005 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
4006 "in the top-level environment specified by @var{module}.\n"
4007 "While @var{exp} is evaluated (using @var{primitive-eval}),\n"
4008 "@var{module} is made the current module. The current module\n"
4009 "is reset to its previous value when @var{eval} returns.")
1bbd0b84 4010#define FUNC_NAME s_scm_eval
0f2d19dd 4011{
4163eb72 4012 SCM_VALIDATE_MODULE (2, module);
09074dbf
DH
4013
4014 return scm_internal_dynamic_wind
4015 (change_environment, inner_eval, restore_environment,
4163eb72
MV
4016 (void *) SCM_UNPACK (exp),
4017 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
0f2d19dd 4018}
1bbd0b84 4019#undef FUNC_NAME
0f2d19dd 4020
68d8be66 4021#if (SCM_DEBUG_DEPRECATED == 0)
1cc91f1b 4022
aa767bc5 4023/* Use scm_current_module () or scm_interaction_environment ()
68d8be66
MD
4024 * instead. The former is the module selected during loading of code.
4025 * The latter is the module in which the user of this thread currently
4026 * types expressions.
4027 */
4028
4029SCM scm_top_level_lookup_closure_var;
4030
4031/* Avoid using this functionality altogether (except for implementing
4032 * libguile, where you can use scm_i_eval or scm_i_eval_x).
4033 *
4163eb72
MV
4034 * Applications should use either C level scm_eval_x or Scheme
4035 * scm_eval; or scm_primitive_eval_x or scm_primitive_eval. */
68d8be66
MD
4036
4037SCM
4038scm_eval_3 (SCM obj, int copyp, SCM env)
4039{
4040 if (copyp)
4041 return scm_i_eval (obj, env);
4042 else
4043 return scm_i_eval_x (obj, env);
4044}
4045
4046SCM_DEFINE (scm_eval2, "eval2", 2, 0, 0,
4047 (SCM obj, SCM env_thunk),
4163eb72
MV
4048 "Evaluate @var{exp}, a Scheme expression, in the environment\n"
4049 "designated by @var{lookup}, a symbol-lookup function."
4050 "Do not use this version of eval, it does not play well\n"
4051 "with the module system. Use @code{eval} or\n"
4052 "@code{primitive-eval} instead.")
68d8be66 4053#define FUNC_NAME s_scm_eval2
0f2d19dd 4054{
68d8be66 4055 return scm_i_eval (obj, scm_top_level_env (env_thunk));
0f2d19dd 4056}
68d8be66
MD
4057#undef FUNC_NAME
4058
4059#endif /* DEPRECATED */
0f2d19dd 4060
6dbd0af5
MD
4061
4062/* At this point, scm_deval and scm_dapply are generated.
4063 */
4064
0f2d19dd 4065#ifdef DEBUG_EXTENSIONS
6dbd0af5
MD
4066# define DEVAL
4067# include "eval.c"
0f2d19dd
JB
4068#endif
4069
4070
1cc91f1b 4071
0f2d19dd
JB
4072void
4073scm_init_eval ()
0f2d19dd 4074{
33b97402
MD
4075 scm_init_opts (scm_evaluator_traps,
4076 scm_evaluator_trap_table,
4077 SCM_N_EVALUATOR_TRAPS);
4078 scm_init_opts (scm_eval_options_interface,
4079 scm_eval_opts,
4080 SCM_N_EVAL_OPTIONS);
4081
f99c9c28
MD
4082 scm_tc16_promise = scm_make_smob_type ("promise", 0);
4083 scm_set_smob_mark (scm_tc16_promise, scm_markcdr);
e841c3e0 4084 scm_set_smob_print (scm_tc16_promise, promise_print);
b8229a3b 4085
81123e6d 4086 scm_f_apply = scm_make_subr ("apply", scm_tc7_lsubr_2, scm_apply);
549e6ec6
MD
4087 scm_system_transformer = scm_sysintern ("scm:eval-transformer",
4088 scm_make_fluid ());
0f2d19dd 4089
43a912cf
MD
4090 scm_lisp_nil = scm_sysintern ("nil", SCM_UNDEFINED);
4091 SCM_SETCDR (scm_lisp_nil, SCM_CAR (scm_lisp_nil));
4092 scm_lisp_nil = SCM_CAR (scm_lisp_nil);
4093 scm_lisp_t = scm_sysintern ("t", SCM_UNDEFINED);
4094 SCM_SETCDR (scm_lisp_t, SCM_CAR (scm_lisp_t));
4095 scm_lisp_t = SCM_CAR (scm_lisp_t);
73b64342 4096
0f2d19dd 4097 /* acros */
0f2d19dd
JB
4098 /* end of acros */
4099
68d8be66 4100#if SCM_DEBUG_DEPRECATED == 0
dc19d1d2 4101 scm_top_level_lookup_closure_var =
549e6ec6 4102 scm_sysintern ("*top-level-lookup-closure*", scm_make_fluid ());
68d8be66 4103#endif
0f2d19dd 4104
8dc9439f 4105#ifndef SCM_MAGIC_SNARFER
a0599745 4106#include "libguile/eval.x"
8dc9439f 4107#endif
25eaf21a
MD
4108
4109 scm_add_feature ("delay");
0f2d19dd 4110}
0f2d19dd 4111
6dbd0af5 4112#endif /* !DEVAL */
89e00824
ML
4113
4114/*
4115 Local Variables:
4116 c-file-style: "gnu"
4117 End:
4118*/