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