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