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