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