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