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