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