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