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