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