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