Fix
[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"
102
103#include "libguile/validate.h"
104#include "libguile/eval.h"
89efbff4 105
61364ba6
MD
106SCM (*scm_memoize_method) (SCM, SCM);
107
0f2d19dd
JB
108\f
109
6dbd0af5
MD
110/* The evaluator contains a plethora of EVAL symbols.
111 * This is an attempt at explanation.
112 *
113 * The following macros should be used in code which is read twice
114 * (where the choice of evaluator is hard soldered):
115 *
116 * SCM_CEVAL is the symbol used within one evaluator to call itself.
117 * Originally, it is defined to scm_ceval, but is redefined to
118 * scm_deval during the second pass.
119 *
120 * SIDEVAL corresponds to SCM_CEVAL, but is used in situations where
121 * only side effects of expressions matter. All immediates are
122 * ignored.
123 *
6cb702da 124 * SCM_EVALIM is used when it is known that the expression is an
6dbd0af5
MD
125 * immediate. (This macro never calls an evaluator.)
126 *
127 * EVALCAR evaluates the car of an expression.
128 *
129 * EVALCELLCAR is like EVALCAR, but is used when it is known that the
130 * car is a lisp cell.
131 *
132 * The following macros should be used in code which is read once
133 * (where the choice of evaluator is dynamic):
134 *
6cb702da 135 * SCM_XEVAL takes care of immediates without calling an evaluator. It
6dbd0af5
MD
136 * then calls scm_ceval *or* scm_deval, depending on the debugging
137 * mode.
138 *
6cb702da 139 * SCM_XEVALCAR corresponds to EVALCAR, but uses scm_ceval *or* scm_deval
6dbd0af5
MD
140 * depending on the debugging mode.
141 *
142 * The main motivation for keeping this plethora is efficiency
143 * together with maintainability (=> locality of code).
144 */
145
6cb702da 146#define SCM_CEVAL scm_ceval
7d2b68a8 147#define SIDEVAL(x, env) if (SCM_NIMP (x)) SCM_CEVAL((x), (env))
6cb702da 148
7d2b68a8
MD
149#define EVALCELLCAR(x, env) (SCM_SYMBOLP (SCM_CAR (x)) \
150 ? *scm_lookupcar (x, env, 1) \
151 : SCM_CEVAL (SCM_CAR (x), env))
0f2d19dd 152
7d2b68a8
MD
153#define EVALCAR(x, env) (SCM_NCELLP (SCM_CAR (x)) \
154 ? (SCM_IMP (SCM_CAR (x)) \
155 ? SCM_EVALIM (SCM_CAR (x), env) \
156 : SCM_GLOC_VAL (SCM_CAR (x))) \
157 : EVALCELLCAR (x, env))
0f2d19dd 158
e2806c10 159#define EXTEND_ENV SCM_EXTEND_ENV
0f2d19dd
JB
160
161#ifdef MEMOIZE_LOCALS
1cc91f1b 162
0f2d19dd 163SCM *
6e8d25a6 164scm_ilookup (SCM iloc, SCM env)
0f2d19dd
JB
165{
166 register int ir = SCM_IFRAME (iloc);
167 register SCM er = env;
168 for (; 0 != ir; --ir)
169 er = SCM_CDR (er);
170 er = SCM_CAR (er);
171 for (ir = SCM_IDIST (iloc); 0 != ir; --ir)
172 er = SCM_CDR (er);
173 if (SCM_ICDRP (iloc))
a23afe53
MD
174 return SCM_CDRLOC (er);
175 return SCM_CARLOC (SCM_CDR (er));
0f2d19dd
JB
176}
177#endif
178
f8769b1d
MV
179#ifdef USE_THREADS
180
181/* The Lookup Car Race
182 - by Eva Luator
183
184 Memoization of variables and special forms is done while executing
185 the code for the first time. As long as there is only one thread
186 everything is fine, but as soon as two threads execute the same
187 code concurrently `for the first time' they can come into conflict.
188
189 This memoization includes rewriting variable references into more
190 efficient forms and expanding macros. Furthermore, macro expansion
191 includes `compiling' special forms like `let', `cond', etc. into
192 tree-code instructions.
193
194 There shouldn't normally be a problem with memoizing local and
195 global variable references (into ilocs and glocs), because all
196 threads will mutate the code in *exactly* the same way and (if I
197 read the C code correctly) it is not possible to observe a half-way
198 mutated cons cell. The lookup procedure can handle this
199 transparently without any critical sections.
200
201 It is different with macro expansion, because macro expansion
202 happens outside of the lookup procedure and can't be
203 undone. Therefore it can't cope with it. It has to indicate
204 failure when it detects a lost race and hope that the caller can
205 handle it. Luckily, it turns out that this is the case.
206
207 An example to illustrate this: Suppose that the follwing form will
208 be memoized concurrently by two threads
209
210 (let ((x 12)) x)
211
212 Let's first examine the lookup of X in the body. The first thread
213 decides that it has to find the symbol "x" in the environment and
214 starts to scan it. Then the other thread takes over and actually
215 overtakes the first. It looks up "x" and substitutes an
216 appropriate iloc for it. Now the first thread continues and
217 completes its lookup. It comes to exactly the same conclusions as
218 the second one and could - without much ado - just overwrite the
219 iloc with the same iloc.
220
221 But let's see what will happen when the race occurs while looking
222 up the symbol "let" at the start of the form. It could happen that
223 the second thread interrupts the lookup of the first thread and not
224 only substitutes a gloc for it but goes right ahead and replaces it
225 with the compiled form (#@let* (x 12) x). Now, when the first
226 thread completes its lookup, it would replace the #@let* with a
227 gloc pointing to the "let" binding, effectively reverting the form
228 to (let (x 12) x). This is wrong. It has to detect that it has
229 lost the race and the evaluator has to reconsider the changed form
230 completely.
231
232 This race condition could be resolved with some kind of traffic
233 light (like mutexes) around scm_lookupcar, but I think that it is
234 best to avoid them in this case. They would serialize memoization
235 completely and because lookup involves calling arbitrary Scheme
236 code (via the lookup-thunk), threads could be blocked for an
237 arbitrary amount of time or even deadlock. But with the current
238 solution a lot of unnecessary work is potentially done. */
239
240/* SCM_LOOKUPCAR1 is was SCM_LOOKUPCAR used to be but is allowed to
241 return NULL to indicate a failed lookup due to some race conditions
242 between threads. This only happens when VLOC is the first cell of
243 a special form that will eventually be memoized (like `let', etc.)
244 In that case the whole lookup is bogus and the caller has to
245 reconsider the complete special form.
246
247 SCM_LOOKUPCAR is still there, of course. It just calls
248 SCM_LOOKUPCAR1 and aborts on recieving NULL. So SCM_LOOKUPCAR
249 should only be called when it is known that VLOC is not the first
250 pair of a special form. Otherwise, use SCM_LOOKUPCAR1 and check
26d5b9b4
MD
251 for NULL. I think I've found the only places where this
252 applies. */
f8769b1d
MV
253
254#endif /* USE_THREADS */
1cc91f1b 255
f25f761d
GH
256SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
257
d0b7bad7 258#ifdef USE_THREADS
8ecf1f13 259static SCM *
26d5b9b4 260scm_lookupcar1 (SCM vloc, SCM genv, int check)
d0b7bad7
MD
261#else
262SCM *
26d5b9b4 263scm_lookupcar (SCM vloc, SCM genv, int check)
d0b7bad7 264#endif
0f2d19dd
JB
265{
266 SCM env = genv;
e3173f93
JB
267 register SCM *al, fl, var = SCM_CAR (vloc);
268#ifdef USE_THREADS
269 register SCM var2 = var;
270#endif
0f2d19dd
JB
271#ifdef MEMOIZE_LOCALS
272 register SCM iloc = SCM_ILOC00;
273#endif
274 for (; SCM_NIMP (env); env = SCM_CDR (env))
275 {
790071cd 276 if (!SCM_CONSP (SCM_CAR (env)))
0f2d19dd 277 break;
a23afe53 278 al = SCM_CARLOC (env);
0f2d19dd
JB
279 for (fl = SCM_CAR (*al); SCM_NIMP (fl); fl = SCM_CDR (fl))
280 {
281 if (SCM_NCONSP (fl))
33b97402 282 {
cf498326 283 if (SCM_EQ_P (fl, var))
0f2d19dd
JB
284 {
285#ifdef MEMOIZE_LOCALS
f8769b1d 286#ifdef USE_THREADS
cf498326 287 if (! SCM_EQ_P (SCM_CAR (vloc), var))
f8769b1d
MV
288 goto race;
289#endif
3201d763 290 SCM_SET_CELL_WORD_0 (vloc, SCM_UNPACK (iloc) + SCM_ICDR);
0f2d19dd 291#endif
a23afe53 292 return SCM_CDRLOC (*al);
0f2d19dd 293 }
33b97402
MD
294 else
295 break;
296 }
a23afe53 297 al = SCM_CDRLOC (*al);
cf498326 298 if (SCM_EQ_P (SCM_CAR (fl), var))
0f2d19dd
JB
299 {
300#ifdef MEMOIZE_LOCALS
cf7c17e9 301#ifndef SCM_RECKLESS /* letrec inits to SCM_UNDEFINED */
0f2d19dd
JB
302 if (SCM_UNBNDP (SCM_CAR (*al)))
303 {
304 env = SCM_EOL;
305 goto errout;
306 }
f8769b1d
MV
307#endif
308#ifdef USE_THREADS
309 if (SCM_CAR (vloc) != var)
310 goto race;
0f2d19dd 311#endif
a23afe53 312 SCM_SETCAR (vloc, iloc);
0f2d19dd 313#endif
a23afe53 314 return SCM_CARLOC (*al);
0f2d19dd
JB
315 }
316#ifdef MEMOIZE_LOCALS
3201d763 317 iloc = SCM_PACK (SCM_UNPACK (iloc) + SCM_IDINC);
0f2d19dd
JB
318#endif
319 }
320#ifdef MEMOIZE_LOCALS
3201d763 321 iloc = SCM_PACK ((~SCM_IDSTMSK) & (SCM_UNPACK(iloc) + SCM_IFRINC));
0f2d19dd
JB
322#endif
323 }
324 {
325 SCM top_thunk, vcell;
790071cd 326 if (SCM_NIMP (env))
0f2d19dd 327 {
790071cd 328 top_thunk = SCM_CAR (env); /* env now refers to a top level env thunk */
0f2d19dd
JB
329 env = SCM_CDR (env);
330 }
331 else
332 top_thunk = SCM_BOOL_F;
333 vcell = scm_sym2vcell (var, top_thunk, SCM_BOOL_F);
cf498326 334 if (SCM_FALSEP (vcell))
0f2d19dd
JB
335 goto errout;
336 else
337 var = vcell;
338 }
cf7c17e9 339#ifndef SCM_RECKLESS
0f2d19dd
JB
340 if (SCM_NNULLP (env) || SCM_UNBNDP (SCM_CDR (var)))
341 {
342 var = SCM_CAR (var);
343 errout:
f5bf2977 344 /* scm_everr (vloc, genv,...) */
26d5b9b4 345 if (check)
f25f761d
GH
346 {
347 if (SCM_NULLP (env))
70d63753 348 scm_error (scm_unbound_variable_key, NULL, "Unbound variable: ~S",
f25f761d
GH
349 scm_cons (var, SCM_EOL), SCM_BOOL_F);
350 else
70d63753 351 scm_misc_error (NULL, "Damaged environment: ~S",
f25f761d
GH
352 scm_cons (var, SCM_EOL));
353 }
09e4d064
DH
354 else {
355 /* A variable could not be found, but we shall not throw an error. */
356 static SCM undef_object = SCM_UNDEFINED;
3201d763 357 return &undef_object;
09e4d064 358 }
0f2d19dd
JB
359 }
360#endif
f8769b1d
MV
361#ifdef USE_THREADS
362 if (SCM_CAR (vloc) != var2)
363 {
364 /* Some other thread has changed the very cell we are working
365 on. In effect, it must have done our job or messed it up
366 completely. */
367 race:
368 var = SCM_CAR (vloc);
3201d763 369 if (SCM_ITAG3 (var) == scm_tc3_cons_gloc)
f8769b1d
MV
370 return SCM_GLOC_VAL_LOC (var);
371#ifdef MEMOIZE_LOCALS
f1267706 372 if ((SCM_UNPACK (var) & 127) == (127 & SCM_UNPACK (SCM_ILOC00)))
f8769b1d
MV
373 return scm_ilookup (var, genv);
374#endif
375 /* We can't cope with anything else than glocs and ilocs. When
376 a special form has been memoized (i.e. `let' into `#@let') we
377 return NULL and expect the calling function to do the right
378 thing. For the evaluator, this means going back and redoing
379 the dispatch on the car of the form. */
380 return NULL;
381 }
382#endif /* USE_THREADS */
383
3201d763 384 SCM_SET_CELL_WORD_0 (vloc, SCM_UNPACK (var) + scm_tc3_cons_gloc);
0f2d19dd 385 /* Except wait...what if the var is not a vcell,
f8769b1d 386 * but syntax or something.... */
a23afe53 387 return SCM_CDRLOC (var);
0f2d19dd
JB
388}
389
f8769b1d
MV
390#ifdef USE_THREADS
391SCM *
6e8d25a6 392scm_lookupcar (SCM vloc, SCM genv, int check)
f8769b1d 393{
26d5b9b4 394 SCM *loc = scm_lookupcar1 (vloc, genv, check);
f8769b1d
MV
395 if (loc == NULL)
396 abort ();
397 return loc;
398}
f8769b1d
MV
399#endif
400
0f2d19dd 401#define unmemocar scm_unmemocar
1cc91f1b 402
0f2d19dd 403SCM
6e8d25a6 404scm_unmemocar (SCM form, SCM env)
0f2d19dd 405{
0f2d19dd
JB
406 SCM c;
407
408 if (SCM_IMP (form))
409 return form;
410 c = SCM_CAR (form);
b0c54567 411 if (SCM_ITAG3 (c) == scm_tc3_cons_gloc)
a963f787 412 SCM_SETCAR (form, SCM_GLOC_SYM (c));
0f2d19dd 413#ifdef MEMOIZE_LOCALS
6dbd0af5 414#ifdef DEBUG_EXTENSIONS
0f2d19dd
JB
415 else if (SCM_ILOCP (c))
416 {
b0c54567
DH
417 int ir;
418
0f2d19dd
JB
419 for (ir = SCM_IFRAME (c); ir != 0; --ir)
420 env = SCM_CDR (env);
421 env = SCM_CAR (SCM_CAR (env));
422 for (ir = SCM_IDIST (c); ir != 0; --ir)
423 env = SCM_CDR (env);
a23afe53 424 SCM_SETCAR (form, SCM_ICDRP (c) ? env : SCM_CAR (env));
0f2d19dd 425 }
6dbd0af5 426#endif
0f2d19dd
JB
427#endif
428 return form;
429}
430
1cc91f1b 431
0f2d19dd 432SCM
6e8d25a6 433scm_eval_car (SCM pair, SCM env)
0f2d19dd 434{
6cb702da 435 return SCM_XEVALCAR (pair, env);
0f2d19dd
JB
436}
437
438\f
439/*
440 * The following rewrite expressions and
441 * some memoized forms have different syntax
442 */
443
3eeba8d4
JB
444const char scm_s_expression[] = "missing or extra expression";
445const char scm_s_test[] = "bad test";
446const char scm_s_body[] = "bad body";
447const char scm_s_bindings[] = "bad bindings";
448const char scm_s_variable[] = "bad variable";
449const char scm_s_clauses[] = "bad or missing clauses";
450const char scm_s_formals[] = "bad formals";
0f2d19dd 451
81123e6d
MD
452SCM scm_sym_dot, scm_sym_arrow, scm_sym_else;
453SCM scm_sym_unquote, scm_sym_uq_splicing, scm_sym_apply;
454
455SCM scm_f_apply;
b8229a3b 456
6dbd0af5 457#ifdef DEBUG_EXTENSIONS
2f0d1375
MD
458SCM scm_sym_enter_frame, scm_sym_apply_frame, scm_sym_exit_frame;
459SCM scm_sym_trace;
6dbd0af5 460#endif
0f2d19dd 461
0f2d19dd 462
26d5b9b4
MD
463/* Check that the body denoted by XORIG is valid and rewrite it into
464 its internal form. The internal form of a body is just the body
465 itself, but prefixed with an ISYM that denotes to what kind of
466 outer construct this body belongs. A lambda body starts with
467 SCM_IM_LAMBDA, for example, a body of a let starts with SCM_IM_LET,
468 etc. The one exception is a body that belongs to a letrec that has
469 been formed by rewriting internal defines: it starts with
470 SCM_IM_DEFINE. */
471
472/* XXX - Besides controlling the rewriting of internal defines, the
473 additional ISYM could be used for improved error messages.
474 This is not done yet. */
475
476static SCM
6e8d25a6 477scm_m_body (SCM op, SCM xorig, const char *what)
26d5b9b4 478{
ab66ae47 479 SCM_ASSYNT (scm_ilength (xorig) >= 1, xorig, scm_s_expression, what);
26d5b9b4
MD
480
481 /* Don't add another ISYM if one is present already. */
482 if (SCM_ISYMP (SCM_CAR (xorig)))
483 return xorig;
484
485 /* Retain possible doc string. */
44d3cb0d 486 if (!SCM_CONSP (SCM_CAR (xorig)))
26d5b9b4
MD
487 {
488 if (SCM_NNULLP (SCM_CDR(xorig)))
489 return scm_cons (SCM_CAR (xorig),
490 scm_m_body (op, SCM_CDR(xorig), what));
491 return xorig;
492 }
493
ab66ae47 494 return scm_cons (op, xorig);
26d5b9b4
MD
495}
496
b8229a3b 497SCM_SYNTAX(s_quote,"quote", scm_makmmacro, scm_m_quote);
2f0d1375 498SCM_GLOBAL_SYMBOL(scm_sym_quote, s_quote);
1cc91f1b 499
0f2d19dd 500SCM
6e8d25a6 501scm_m_quote (SCM xorig, SCM env)
0f2d19dd 502{
26d5b9b4
MD
503 SCM x = scm_copy_tree (SCM_CDR (xorig));
504
6cb702da 505 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
b8229a3b 506 xorig, scm_s_expression, s_quote);
3a3111a8 507 return scm_cons (SCM_IM_QUOTE, x);
0f2d19dd
JB
508}
509
510
1cc91f1b 511
b8229a3b 512SCM_SYNTAX(s_begin, "begin", scm_makmmacro, scm_m_begin);
2f0d1375 513SCM_GLOBAL_SYMBOL(scm_sym_begin, s_begin);
b8229a3b 514
0f2d19dd 515SCM
6e8d25a6 516scm_m_begin (SCM xorig, SCM env)
0f2d19dd 517{
6cb702da 518 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) >= 1,
b8229a3b 519 xorig, scm_s_expression, s_begin);
3a3111a8 520 return scm_cons (SCM_IM_BEGIN, SCM_CDR (xorig));
0f2d19dd
JB
521}
522
b8229a3b 523SCM_SYNTAX(s_if, "if", scm_makmmacro, scm_m_if);
2f0d1375 524SCM_GLOBAL_SYMBOL(scm_sym_if, s_if);
1cc91f1b 525
0f2d19dd 526SCM
6e8d25a6 527scm_m_if (SCM xorig, SCM env)
0f2d19dd
JB
528{
529 int len = scm_ilength (SCM_CDR (xorig));
6cb702da 530 SCM_ASSYNT (len >= 2 && len <= 3, xorig, scm_s_expression, "if");
3a3111a8 531 return scm_cons (SCM_IM_IF, SCM_CDR (xorig));
0f2d19dd
JB
532}
533
534
89efbff4
MD
535/* Will go into the RnRS module when Guile is factorized.
536SCM_SYNTAX(scm_s_set_x,"set!", scm_makmmacro, scm_m_set_x); */
537const char scm_s_set_x[] = "set!";
538SCM_GLOBAL_SYMBOL(scm_sym_set_x, scm_s_set_x);
1cc91f1b 539
0f2d19dd 540SCM
6e8d25a6 541scm_m_set_x (SCM xorig, SCM env)
0f2d19dd 542{
6dbd0af5 543 SCM x = SCM_CDR (xorig);
89efbff4 544 SCM_ASSYNT (2 == scm_ilength (x), xorig, scm_s_expression, scm_s_set_x);
cabe682c 545 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (x)),
89efbff4 546 xorig, scm_s_variable, scm_s_set_x);
3a3111a8 547 return scm_cons (SCM_IM_SET_X, x);
0f2d19dd
JB
548}
549
550
551#if 0
1cc91f1b 552
0f2d19dd 553SCM
6e8d25a6 554scm_m_vref (SCM xorig, SCM env)
0f2d19dd
JB
555{
556 SCM x = SCM_CDR (xorig);
6cb702da 557 SCM_ASSYNT (1 == scm_ilength (x), xorig, scm_s_expression, s_vref);
0f2d19dd
JB
558 if (SCM_NIMP(x) && UDSCM_VARIABLEP (SCM_CAR (x)))
559 {
f5bf2977 560 /* scm_everr (SCM_UNDEFINED, env,..., "global variable reference") */
523f5266 561 scm_misc_error (NULL,
70d63753 562 "Bad variable: ~S",
523f5266 563 scm_listify (SCM_CAR (SCM_CDR (x)), SCM_UNDEFINED));
0f2d19dd 564 }
6cb702da
MD
565 SCM_ASSYNT (SCM_NIMP(x) && DEFSCM_VARIABLEP (SCM_CAR (x)),
566 xorig, scm_s_variable, s_vref);
0f2d19dd
JB
567 return scm_cons (IM_VREF, x);
568}
569
570
1cc91f1b 571
0f2d19dd 572SCM
6e8d25a6 573scm_m_vset (SCM xorig, SCM env)
0f2d19dd
JB
574{
575 SCM x = SCM_CDR (xorig);
6cb702da
MD
576 SCM_ASSYNT (3 == scm_ilength (x), xorig, scm_s_expression, s_vset);
577 SCM_ASSYNT ((DEFSCM_VARIABLEP (SCM_CAR (x))
578 || UDSCM_VARIABLEP (SCM_CAR (x))),
579 xorig, scm_s_variable, s_vset);
0f2d19dd
JB
580 return scm_cons (IM_VSET, x);
581}
582#endif
583
584
b8229a3b 585SCM_SYNTAX(s_and, "and", scm_makmmacro, scm_m_and);
2f0d1375 586SCM_GLOBAL_SYMBOL(scm_sym_and, s_and);
1cc91f1b 587
0f2d19dd 588SCM
6e8d25a6 589scm_m_and (SCM xorig, SCM env)
0f2d19dd
JB
590{
591 int len = scm_ilength (SCM_CDR (xorig));
b8229a3b 592 SCM_ASSYNT (len >= 0, xorig, scm_s_test, s_and);
0f2d19dd 593 if (len >= 1)
3a3111a8 594 return scm_cons (SCM_IM_AND, SCM_CDR (xorig));
0f2d19dd
JB
595 else
596 return SCM_BOOL_T;
597}
598
b8229a3b 599SCM_SYNTAX(s_or,"or", scm_makmmacro, scm_m_or);
2f0d1375 600SCM_GLOBAL_SYMBOL(scm_sym_or,s_or);
1cc91f1b 601
0f2d19dd 602SCM
6e8d25a6 603scm_m_or (SCM xorig, SCM env)
0f2d19dd
JB
604{
605 int len = scm_ilength (SCM_CDR (xorig));
b8229a3b 606 SCM_ASSYNT (len >= 0, xorig, scm_s_test, s_or);
0f2d19dd 607 if (len >= 1)
3a3111a8 608 return scm_cons (SCM_IM_OR, SCM_CDR (xorig));
0f2d19dd
JB
609 else
610 return SCM_BOOL_F;
611}
612
613
b8229a3b 614SCM_SYNTAX(s_case, "case", scm_makmmacro, scm_m_case);
2f0d1375 615SCM_GLOBAL_SYMBOL(scm_sym_case, s_case);
1cc91f1b 616
0f2d19dd 617SCM
6e8d25a6 618scm_m_case (SCM xorig, SCM env)
0f2d19dd 619{
26d5b9b4 620 SCM proc, cdrx = scm_list_copy (SCM_CDR (xorig)), x = cdrx;
b8229a3b 621 SCM_ASSYNT (scm_ilength (x) >= 2, xorig, scm_s_clauses, s_case);
0f2d19dd
JB
622 while (SCM_NIMP (x = SCM_CDR (x)))
623 {
624 proc = SCM_CAR (x);
b8229a3b 625 SCM_ASSYNT (scm_ilength (proc) >= 2, xorig, scm_s_clauses, s_case);
6cb702da 626 SCM_ASSYNT (scm_ilength (SCM_CAR (proc)) >= 0
cf498326 627 || SCM_EQ_P (scm_sym_else, SCM_CAR (proc)),
b8229a3b 628 xorig, scm_s_clauses, s_case);
0f2d19dd 629 }
3a3111a8 630 return scm_cons (SCM_IM_CASE, cdrx);
0f2d19dd
JB
631}
632
633
b8229a3b 634SCM_SYNTAX(s_cond, "cond", scm_makmmacro, scm_m_cond);
2f0d1375 635SCM_GLOBAL_SYMBOL(scm_sym_cond, s_cond);
b8229a3b 636
1cc91f1b 637
0f2d19dd 638SCM
6e8d25a6 639scm_m_cond (SCM xorig, SCM env)
0f2d19dd 640{
26d5b9b4 641 SCM arg1, cdrx = scm_list_copy (SCM_CDR (xorig)), x = cdrx;
0f2d19dd 642 int len = scm_ilength (x);
b8229a3b 643 SCM_ASSYNT (len >= 1, xorig, scm_s_clauses, s_cond);
0f2d19dd
JB
644 while (SCM_NIMP (x))
645 {
646 arg1 = SCM_CAR (x);
647 len = scm_ilength (arg1);
b8229a3b 648 SCM_ASSYNT (len >= 1, xorig, scm_s_clauses, s_cond);
cf498326 649 if (SCM_EQ_P (scm_sym_else, SCM_CAR (arg1)))
0f2d19dd 650 {
6cb702da 651 SCM_ASSYNT (SCM_NULLP (SCM_CDR (x)) && len >= 2,
b8229a3b 652 xorig, "bad ELSE clause", s_cond);
a23afe53 653 SCM_SETCAR (arg1, SCM_BOOL_T);
0f2d19dd 654 }
cf498326 655 if (len >= 2 && SCM_EQ_P (scm_sym_arrow, SCM_CAR (SCM_CDR (arg1))))
6cb702da 656 SCM_ASSYNT (3 == len && SCM_NIMP (SCM_CAR (SCM_CDR (SCM_CDR (arg1)))),
b8229a3b 657 xorig, "bad recipient", s_cond);
0f2d19dd
JB
658 x = SCM_CDR (x);
659 }
3a3111a8 660 return scm_cons (SCM_IM_COND, cdrx);
0f2d19dd
JB
661}
662
b8229a3b 663SCM_SYNTAX(s_lambda, "lambda", scm_makmmacro, scm_m_lambda);
2f0d1375 664SCM_GLOBAL_SYMBOL(scm_sym_lambda, s_lambda);
1cc91f1b 665
0f2d19dd 666SCM
6e8d25a6 667scm_m_lambda (SCM xorig, SCM env)
0f2d19dd
JB
668{
669 SCM proc, x = SCM_CDR (xorig);
26d5b9b4 670 if (scm_ilength (x) < 2)
0f2d19dd
JB
671 goto badforms;
672 proc = SCM_CAR (x);
33b97402
MD
673 if (SCM_NULLP (proc))
674 goto memlambda;
cf498326 675 if (SCM_EQ_P (SCM_IM_LET, proc)) /* named let */
26d5b9b4 676 goto memlambda;
33b97402
MD
677 if (SCM_IMP (proc))
678 goto badforms;
679 if (SCM_SYMBOLP (proc))
680 goto memlambda;
681 if (SCM_NCONSP (proc))
682 goto badforms;
683 while (SCM_NIMP (proc))
0f2d19dd 684 {
33b97402
MD
685 if (SCM_NCONSP (proc))
686 {
0f2d19dd 687 if (!SCM_SYMBOLP (proc))
33b97402
MD
688 goto badforms;
689 else
690 goto memlambda;
691 }
0c95b57d 692 if (!SCM_SYMBOLP (SCM_CAR (proc)))
0f2d19dd
JB
693 goto badforms;
694 proc = SCM_CDR (proc);
695 }
ff467021 696 if (SCM_NNULLP (proc))
26d5b9b4
MD
697 {
698 badforms:
699 scm_wta (xorig, scm_s_formals, s_lambda);
700 }
701
702 memlambda:
3a3111a8
MD
703 return scm_cons2 (SCM_IM_LAMBDA, SCM_CAR (x),
704 scm_m_body (SCM_IM_LAMBDA, SCM_CDR (x), s_lambda));
0f2d19dd
JB
705}
706
b8229a3b 707SCM_SYNTAX(s_letstar,"let*", scm_makmmacro, scm_m_letstar);
2f0d1375 708SCM_GLOBAL_SYMBOL(scm_sym_letstar,s_letstar);
0f2d19dd 709
1cc91f1b 710
0f2d19dd 711SCM
6e8d25a6 712scm_m_letstar (SCM xorig, SCM env)
0f2d19dd
JB
713{
714 SCM x = SCM_CDR (xorig), arg1, proc, vars = SCM_EOL, *varloc = &vars;
715 int len = scm_ilength (x);
b8229a3b 716 SCM_ASSYNT (len >= 2, xorig, scm_s_body, s_letstar);
0f2d19dd 717 proc = SCM_CAR (x);
b8229a3b 718 SCM_ASSYNT (scm_ilength (proc) >= 0, xorig, scm_s_bindings, s_letstar);
ff467021 719 while (SCM_NIMP (proc))
0f2d19dd
JB
720 {
721 arg1 = SCM_CAR (proc);
b8229a3b 722 SCM_ASSYNT (2 == scm_ilength (arg1), xorig, scm_s_bindings, s_letstar);
0c95b57d 723 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), xorig, scm_s_variable, s_letstar);
0f2d19dd 724 *varloc = scm_cons2 (SCM_CAR (arg1), SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 725 varloc = SCM_CDRLOC (SCM_CDR (*varloc));
0f2d19dd
JB
726 proc = SCM_CDR (proc);
727 }
728 x = scm_cons (vars, SCM_CDR (x));
26d5b9b4 729
3a3111a8
MD
730 return scm_cons2 (SCM_IM_LETSTAR, SCM_CAR (x),
731 scm_m_body (SCM_IM_LETSTAR, SCM_CDR (x), s_letstar));
0f2d19dd
JB
732}
733
734/* DO gets the most radically altered syntax
735 (do ((<var1> <init1> <step1>)
736 (<var2> <init2>)
737 ... )
738 (<test> <return>)
739 <body>)
740 ;; becomes
741 (do_mem (varn ... var2 var1)
742 (<init1> <init2> ... <initn>)
743 (<test> <return>)
744 (<body>)
745 <step1> <step2> ... <stepn>) ;; missing steps replaced by var
746 */
747
b8229a3b 748SCM_SYNTAX(s_do, "do", scm_makmmacro, scm_m_do);
2f0d1375 749SCM_GLOBAL_SYMBOL(scm_sym_do, s_do);
1cc91f1b 750
0f2d19dd 751SCM
6e8d25a6 752scm_m_do (SCM xorig, SCM env)
0f2d19dd
JB
753{
754 SCM x = SCM_CDR (xorig), arg1, proc;
755 SCM vars = SCM_EOL, inits = SCM_EOL, steps = SCM_EOL;
756 SCM *initloc = &inits, *steploc = &steps;
757 int len = scm_ilength (x);
6cb702da 758 SCM_ASSYNT (len >= 2, xorig, scm_s_test, "do");
0f2d19dd 759 proc = SCM_CAR (x);
6cb702da 760 SCM_ASSYNT (scm_ilength (proc) >= 0, xorig, scm_s_bindings, "do");
ff467021 761 while (SCM_NIMP(proc))
0f2d19dd
JB
762 {
763 arg1 = SCM_CAR (proc);
764 len = scm_ilength (arg1);
6cb702da 765 SCM_ASSYNT (2 == len || 3 == len, xorig, scm_s_bindings, "do");
0c95b57d 766 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), xorig, scm_s_variable, "do");
0f2d19dd
JB
767 /* vars reversed here, inits and steps reversed at evaluation */
768 vars = scm_cons (SCM_CAR (arg1), vars); /* variable */
769 arg1 = SCM_CDR (arg1);
770 *initloc = scm_cons (SCM_CAR (arg1), SCM_EOL); /* init */
a23afe53 771 initloc = SCM_CDRLOC (*initloc);
0f2d19dd
JB
772 arg1 = SCM_CDR (arg1);
773 *steploc = scm_cons (SCM_IMP (arg1) ? SCM_CAR (vars) : SCM_CAR (arg1), SCM_EOL); /* step */
a23afe53 774 steploc = SCM_CDRLOC (*steploc);
0f2d19dd
JB
775 proc = SCM_CDR (proc);
776 }
777 x = SCM_CDR (x);
6cb702da 778 SCM_ASSYNT (scm_ilength (SCM_CAR (x)) >= 1, xorig, scm_s_test, "do");
0f2d19dd
JB
779 x = scm_cons2 (SCM_CAR (x), SCM_CDR (x), steps);
780 x = scm_cons2 (vars, inits, x);
3a3111a8 781 return scm_cons (SCM_IM_DO, x);
0f2d19dd
JB
782}
783
6dbd0af5
MD
784/* evalcar is small version of inline EVALCAR when we don't care about
785 * speed
786 */
787#define evalcar scm_eval_car
0f2d19dd 788
1cc91f1b 789
1bbd0b84 790static SCM iqq (SCM form, SCM env, int depth);
1cc91f1b 791
b8229a3b 792SCM_SYNTAX(s_quasiquote, "quasiquote", scm_makacro, scm_m_quasiquote);
2f0d1375 793SCM_GLOBAL_SYMBOL(scm_sym_quasiquote, s_quasiquote);
b8229a3b
MS
794
795SCM
6e8d25a6 796scm_m_quasiquote (SCM xorig, SCM env)
b8229a3b
MS
797{
798 SCM x = SCM_CDR (xorig);
799 SCM_ASSYNT (scm_ilength (x) == 1, xorig, scm_s_expression, s_quasiquote);
800 return iqq (SCM_CAR (x), env, 1);
801}
802
803
0f2d19dd 804static SCM
1bbd0b84 805iqq (SCM form,SCM env,int depth)
0f2d19dd
JB
806{
807 SCM tmp;
808 int edepth = depth;
ff467021
JB
809 if (SCM_IMP(form))
810 return form;
0f2d19dd
JB
811 if (SCM_VECTORP (form))
812 {
813 long i = SCM_LENGTH (form);
814 SCM *data = SCM_VELTS (form);
815 tmp = SCM_EOL;
816 for (; --i >= 0;)
817 tmp = scm_cons (data[i], tmp);
818 return scm_vector (iqq (tmp, env, depth));
819 }
ff467021
JB
820 if (SCM_NCONSP(form))
821 return form;
0f2d19dd 822 tmp = SCM_CAR (form);
cf498326 823 if (SCM_EQ_P (scm_sym_quasiquote, tmp))
0f2d19dd
JB
824 {
825 depth++;
826 goto label;
827 }
cf498326 828 if (SCM_EQ_P (scm_sym_unquote, tmp))
0f2d19dd
JB
829 {
830 --depth;
831 label:
832 form = SCM_CDR (form);
0c95b57d
GB
833 SCM_ASSERT (SCM_ECONSP (form) && SCM_NULLP (SCM_CDR (form)),
834 form, SCM_ARG1, s_quasiquote);
0f2d19dd
JB
835 if (0 == depth)
836 return evalcar (form, env);
837 return scm_cons2 (tmp, iqq (SCM_CAR (form), env, depth), SCM_EOL);
838 }
cf498326 839 if (SCM_NIMP (tmp) && (SCM_EQ_P (scm_sym_uq_splicing, SCM_CAR (tmp))))
0f2d19dd
JB
840 {
841 tmp = SCM_CDR (tmp);
842 if (0 == --edepth)
843 return scm_append (scm_cons2 (evalcar (tmp, env), iqq (SCM_CDR (form), env, depth), SCM_EOL));
844 }
845 return scm_cons (iqq (SCM_CAR (form), env, edepth), iqq (SCM_CDR (form), env, depth));
846}
847
848/* Here are acros which return values rather than code. */
849
a570e93a
MD
850SCM_SYNTAX (s_delay, "delay", scm_makmmacro, scm_m_delay);
851SCM_GLOBAL_SYMBOL (scm_sym_delay, s_delay);
1cc91f1b 852
0f2d19dd 853SCM
6e8d25a6 854scm_m_delay (SCM xorig, SCM env)
0f2d19dd 855{
6cb702da 856 SCM_ASSYNT (scm_ilength (xorig) == 2, xorig, scm_s_expression, s_delay);
a570e93a 857 return scm_cons2 (SCM_IM_DELAY, SCM_EOL, SCM_CDR (xorig));
0f2d19dd
JB
858}
859
1cc91f1b 860
b8229a3b 861SCM_SYNTAX(s_define, "define", scm_makmmacro, scm_m_define);
2f0d1375 862SCM_GLOBAL_SYMBOL(scm_sym_define, s_define);
1cc91f1b 863
0f2d19dd 864SCM
6e8d25a6 865scm_m_define (SCM x, SCM env)
0f2d19dd
JB
866{
867 SCM proc, arg1 = x;
868 x = SCM_CDR (x);
6cb702da 869 /* SCM_ASSYNT(SCM_NULLP(env), x, "bad placement", s_define);*/
b8229a3b 870 SCM_ASSYNT (scm_ilength (x) >= 2, arg1, scm_s_expression, s_define);
0f2d19dd
JB
871 proc = SCM_CAR (x);
872 x = SCM_CDR (x);
0c95b57d 873 while (SCM_CONSP (proc))
0f2d19dd 874 { /* nested define syntax */
2f0d1375 875 x = scm_cons (scm_cons2 (scm_sym_lambda, SCM_CDR (proc), x), SCM_EOL);
0f2d19dd
JB
876 proc = SCM_CAR (proc);
877 }
0c95b57d 878 SCM_ASSYNT (SCM_SYMBOLP (proc),
b8229a3b
MS
879 arg1, scm_s_variable, s_define);
880 SCM_ASSYNT (1 == scm_ilength (x), arg1, scm_s_expression, s_define);
0f2d19dd
JB
881 if (SCM_TOP_LEVEL (env))
882 {
883 x = evalcar (x, env);
6dbd0af5 884#ifdef DEBUG_EXTENSIONS
80ea260c
MD
885 if (SCM_REC_PROCNAMES_P && SCM_NIMP (x))
886 {
887 arg1 = x;
888 proc:
889 if (SCM_CLOSUREP (arg1)
890 /* Only the first definition determines the name. */
cf498326 891 && SCM_FALSEP (scm_procedure_property (arg1, scm_sym_name)))
2f0d1375 892 scm_set_procedure_property_x (arg1, scm_sym_name, proc);
80ea260c 893 else if (SCM_TYP16 (arg1) == scm_tc16_macro
cf498326 894 && !SCM_EQ_P (SCM_CDR (arg1), arg1))
80ea260c
MD
895 {
896 arg1 = SCM_CDR (arg1);
897 goto proc;
898 }
899 }
6dbd0af5 900#endif
6cb702da 901 arg1 = scm_sym2vcell (proc, scm_env_top_level (env), SCM_BOOL_T);
0f2d19dd 902#if 0
cf7c17e9 903#ifndef SCM_RECKLESS
3201d763 904 if (SCM_NIMP (SCM_CDR (arg1)) && (SCM_SNAME (SCM_CDR (arg1)) == proc)
0f2d19dd
JB
905 && (SCM_CDR (arg1) != x))
906 scm_warn ("redefining built-in ", SCM_CHARS (proc));
907 else
908#endif
909 if (5 <= scm_verbose && SCM_UNDEFINED != SCM_CDR (arg1))
910 scm_warn ("redefining ", SCM_CHARS (proc));
0f2d19dd 911#endif
a23afe53 912 SCM_SETCDR (arg1, x);
0f2d19dd 913#ifdef SICP
2f0d1375 914 return scm_cons2 (scm_sym_quote, SCM_CAR (arg1), SCM_EOL);
0f2d19dd
JB
915#else
916 return SCM_UNSPECIFIED;
917#endif
918 }
919 return scm_cons2 (SCM_IM_DEFINE, proc, x);
920}
6dbd0af5 921
0f2d19dd
JB
922/* end of acros */
923
26d5b9b4 924static SCM
6e8d25a6 925scm_m_letrec1 (SCM op, SCM imm, SCM xorig, SCM env)
0f2d19dd
JB
926{
927 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
928 char *what = SCM_CHARS (SCM_CAR (xorig));
929 SCM x = cdrx, proc, arg1; /* structure traversers */
930 SCM vars = SCM_EOL, inits = SCM_EOL, *initloc = &inits;
931
0f2d19dd 932 proc = SCM_CAR (x);
ab66ae47 933 SCM_ASSYNT (scm_ilength (proc) >= 1, xorig, scm_s_bindings, what);
0f2d19dd
JB
934 do
935 {
936 /* vars scm_list reversed here, inits reversed at evaluation */
937 arg1 = SCM_CAR (proc);
ab66ae47
DH
938 SCM_ASSYNT (2 == scm_ilength (arg1), xorig, scm_s_bindings, what);
939 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)), xorig, scm_s_variable, what);
0f2d19dd
JB
940 vars = scm_cons (SCM_CAR (arg1), vars);
941 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 942 initloc = SCM_CDRLOC (*initloc);
0f2d19dd 943 }
ff467021 944 while (SCM_NIMP (proc = SCM_CDR (proc)));
26d5b9b4 945
3a3111a8
MD
946 return scm_cons2 (op, vars,
947 scm_cons (inits, scm_m_body (imm, SCM_CDR (x), what)));
0f2d19dd
JB
948}
949
26d5b9b4 950SCM_SYNTAX(s_letrec, "letrec", scm_makmmacro, scm_m_letrec);
2f0d1375 951SCM_GLOBAL_SYMBOL(scm_sym_letrec, s_letrec);
26d5b9b4
MD
952
953SCM
6e8d25a6 954scm_m_letrec (SCM xorig, SCM env)
26d5b9b4
MD
955{
956 SCM x = SCM_CDR (xorig);
957 SCM_ASSYNT (scm_ilength (x) >= 2, xorig, scm_s_body, s_letrec);
958
959 if (SCM_NULLP (SCM_CAR (x))) /* null binding, let* faster */
3a3111a8
MD
960 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), SCM_EOL,
961 scm_m_body (SCM_IM_LETREC,
962 SCM_CDR (x),
963 s_letrec)),
26d5b9b4
MD
964 env);
965 else
966 return scm_m_letrec1 (SCM_IM_LETREC, SCM_IM_LETREC, xorig, env);
967}
1cc91f1b 968
b8229a3b 969SCM_SYNTAX(s_let, "let", scm_makmmacro, scm_m_let);
2f0d1375 970SCM_GLOBAL_SYMBOL(scm_sym_let, s_let);
b8229a3b 971
0f2d19dd 972SCM
6e8d25a6 973scm_m_let (SCM xorig, SCM env)
0f2d19dd
JB
974{
975 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
976 SCM x = cdrx, proc, arg1, name; /* structure traversers */
977 SCM vars = SCM_EOL, inits = SCM_EOL, *varloc = &vars, *initloc = &inits;
978
b8229a3b 979 SCM_ASSYNT (scm_ilength (x) >= 2, xorig, scm_s_body, s_let);
0f2d19dd
JB
980 proc = SCM_CAR (x);
981 if (SCM_NULLP (proc)
0c95b57d 982 || (SCM_CONSP (proc)
26d5b9b4
MD
983 && SCM_CONSP (SCM_CAR (proc)) && SCM_NULLP (SCM_CDR (proc))))
984 {
985 /* null or single binding, let* is faster */
3a3111a8
MD
986 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), proc,
987 scm_m_body (SCM_IM_LET,
988 SCM_CDR (x),
989 s_let)),
26d5b9b4
MD
990 env);
991 }
992
b8229a3b 993 SCM_ASSYNT (SCM_NIMP (proc), xorig, scm_s_bindings, s_let);
26d5b9b4
MD
994 if (SCM_CONSP (proc))
995 {
996 /* plain let, proc is <bindings> */
997 return scm_m_letrec1 (SCM_IM_LET, SCM_IM_LET, xorig, env);
998 }
999
0f2d19dd 1000 if (!SCM_SYMBOLP (proc))
b8229a3b 1001 scm_wta (xorig, scm_s_bindings, s_let); /* bad let */
0f2d19dd
JB
1002 name = proc; /* named let, build equiv letrec */
1003 x = SCM_CDR (x);
b8229a3b 1004 SCM_ASSYNT (scm_ilength (x) >= 2, xorig, scm_s_body, s_let);
26d5b9b4 1005 proc = SCM_CAR (x); /* bindings list */
b8229a3b 1006 SCM_ASSYNT (scm_ilength (proc) >= 0, xorig, scm_s_bindings, s_let);
ff467021 1007 while (SCM_NIMP (proc))
0f2d19dd
JB
1008 { /* vars and inits both in order */
1009 arg1 = SCM_CAR (proc);
b8229a3b 1010 SCM_ASSYNT (2 == scm_ilength (arg1), xorig, scm_s_bindings, s_let);
0c95b57d 1011 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (arg1)),
b8229a3b 1012 xorig, scm_s_variable, s_let);
0f2d19dd 1013 *varloc = scm_cons (SCM_CAR (arg1), SCM_EOL);
a23afe53 1014 varloc = SCM_CDRLOC (*varloc);
0f2d19dd 1015 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 1016 initloc = SCM_CDRLOC (*initloc);
0f2d19dd
JB
1017 proc = SCM_CDR (proc);
1018 }
26d5b9b4 1019
2f0d1375 1020 proc = scm_cons2 (scm_sym_lambda, vars,
26d5b9b4 1021 scm_m_body (SCM_IM_LET, SCM_CDR (x), "let"));
2f0d1375 1022 proc = scm_cons2 (scm_sym_let, scm_cons (scm_cons2 (name, proc, SCM_EOL),
26d5b9b4
MD
1023 SCM_EOL),
1024 scm_acons (name, inits, SCM_EOL));
1025 return scm_m_letrec1 (SCM_IM_LETREC, SCM_IM_LET, proc, env);
0f2d19dd
JB
1026}
1027
1028
81123e6d
MD
1029SCM_SYNTAX (s_atapply,"@apply", scm_makmmacro, scm_m_apply);
1030SCM_GLOBAL_SYMBOL (scm_sym_atapply, s_atapply);
1031SCM_GLOBAL_SYMBOL (scm_sym_apply, s_atapply + 1);
1cc91f1b 1032
0f2d19dd 1033SCM
6e8d25a6 1034scm_m_apply (SCM xorig, SCM env)
0f2d19dd 1035{
6cb702da 1036 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2,
b8229a3b 1037 xorig, scm_s_expression, s_atapply);
0f2d19dd
JB
1038 return scm_cons (SCM_IM_APPLY, SCM_CDR (xorig));
1039}
1040
b8229a3b
MS
1041
1042SCM_SYNTAX(s_atcall_cc,"@call-with-current-continuation", scm_makmmacro, scm_m_cont);
2f0d1375 1043SCM_GLOBAL_SYMBOL(scm_sym_atcall_cc,s_atcall_cc);
0f2d19dd 1044
1cc91f1b 1045
0f2d19dd 1046SCM
6e8d25a6 1047scm_m_cont (SCM xorig, SCM env)
0f2d19dd 1048{
6cb702da 1049 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
b8229a3b 1050 xorig, scm_s_expression, s_atcall_cc);
3a3111a8 1051 return scm_cons (SCM_IM_CONT, SCM_CDR (xorig));
0f2d19dd
JB
1052}
1053
73b64342
MD
1054/* Multi-language support */
1055
43a912cf
MD
1056SCM scm_lisp_nil;
1057SCM scm_lisp_t;
73b64342
MD
1058
1059SCM_SYNTAX (s_nil_cond, "nil-cond", scm_makmmacro, scm_m_nil_cond);
1060
1061SCM
1062scm_m_nil_cond (SCM xorig, SCM env)
1063{
1064 int len = scm_ilength (SCM_CDR (xorig));
1065 SCM_ASSYNT (len >= 1 && (len & 1) == 1, xorig,
1066 scm_s_expression, "nil-cond");
1067 return scm_cons (SCM_IM_NIL_COND, SCM_CDR (xorig));
1068}
1069
1070SCM_SYNTAX (s_nil_ify, "nil-ify", scm_makmmacro, scm_m_nil_ify);
1071
1072SCM
1073scm_m_nil_ify (SCM xorig, SCM env)
1074{
1075 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
1076 xorig, scm_s_expression, "nil-ify");
1077 return scm_cons (SCM_IM_NIL_IFY, SCM_CDR (xorig));
1078}
1079
1080SCM_SYNTAX (s_t_ify, "t-ify", scm_makmmacro, scm_m_t_ify);
1081
1082SCM
1083scm_m_t_ify (SCM xorig, SCM env)
1084{
1085 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
1086 xorig, scm_s_expression, "t-ify");
1087 return scm_cons (SCM_IM_T_IFY, SCM_CDR (xorig));
1088}
1089
1090SCM_SYNTAX (s_0_cond, "0-cond", scm_makmmacro, scm_m_0_cond);
1091
1092SCM
1093scm_m_0_cond (SCM xorig, SCM env)
1094{
1095 int len = scm_ilength (SCM_CDR (xorig));
1096 SCM_ASSYNT (len >= 1 && (len & 1) == 1, xorig,
1097 scm_s_expression, "0-cond");
1098 return scm_cons (SCM_IM_0_COND, SCM_CDR (xorig));
1099}
1100
1101SCM_SYNTAX (s_0_ify, "0-ify", scm_makmmacro, scm_m_0_ify);
1102
1103SCM
1104scm_m_0_ify (SCM xorig, SCM env)
1105{
1106 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
1107 xorig, scm_s_expression, "0-ify");
1108 return scm_cons (SCM_IM_0_IFY, SCM_CDR (xorig));
1109}
1110
1111SCM_SYNTAX (s_1_ify, "1-ify", scm_makmmacro, scm_m_1_ify);
1112
1113SCM
1114scm_m_1_ify (SCM xorig, SCM env)
1115{
1116 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
1117 xorig, scm_s_expression, "1-ify");
1118 return scm_cons (SCM_IM_1_IFY, SCM_CDR (xorig));
1119}
1120
1121SCM_SYNTAX (s_atfop, "@fop", scm_makmmacro, scm_m_atfop);
1122
1123SCM
1124scm_m_atfop (SCM xorig, SCM env)
1125{
1126 SCM x = SCM_CDR (xorig), vcell;
1127 SCM_ASSYNT (scm_ilength (x) >= 1, xorig, scm_s_expression, "@fop");
1128 vcell = scm_symbol_fref (SCM_CAR (x));
0c95b57d 1129 SCM_ASSYNT (SCM_CONSP (vcell), x,
73b64342 1130 "Symbol's function definition is void", NULL);
3201d763 1131 SCM_SET_CELL_WORD_0 (x, SCM_UNPACK (vcell) + scm_tc3_cons_gloc);
73b64342
MD
1132 return x;
1133}
1134
1135SCM_SYNTAX (s_atbind, "@bind", scm_makmmacro, scm_m_atbind);
1136
1137SCM
1138scm_m_atbind (SCM xorig, SCM env)
1139{
1140 SCM x = SCM_CDR (xorig);
1141 SCM_ASSYNT (scm_ilength (x) > 1, xorig, scm_s_expression, "@bind");
1142
1143 if (SCM_IMP (env))
1144 env = SCM_BOOL_F;
1145 else
1146 {
1147 while (SCM_NIMP (SCM_CDR (env)))
1148 env = SCM_CDR (env);
1149 env = SCM_CAR (env);
1150 if (SCM_CONSP (env))
1151 env = SCM_BOOL_F;
1152 }
1153
1154 x = SCM_CAR (x);
1155 while (SCM_NIMP (x))
1156 {
3201d763 1157 SCM_SET_CELL_WORD_0 (x, SCM_UNPACK (scm_sym2vcell (SCM_CAR (x), env, SCM_BOOL_T)) + scm_tc3_cons_gloc);
73b64342
MD
1158 x = SCM_CDR (x);
1159 }
1160 return scm_cons (SCM_IM_BIND, SCM_CDR (xorig));
1161}
73b64342 1162
26d5b9b4
MD
1163SCM
1164scm_m_expand_body (SCM xorig, SCM env)
1165{
1166 SCM form, x = SCM_CDR (xorig), defs = SCM_EOL;
1167 char *what = SCM_ISYMCHARS (SCM_CAR (xorig)) + 2;
1168
1169 while (SCM_NIMP (x))
1170 {
1171 form = SCM_CAR (x);
1172 if (SCM_IMP (form) || SCM_NCONSP (form))
1173 break;
1174 if (SCM_IMP (SCM_CAR (form)))
1175 break;
1176 if (!SCM_SYMBOLP (SCM_CAR (form)))
1177 break;
1178
3a3111a8
MD
1179 form = scm_macroexp (scm_cons_source (form,
1180 SCM_CAR (form),
1181 SCM_CDR (form)),
1182 env);
26d5b9b4 1183
cf498326 1184 if (SCM_EQ_P (SCM_IM_DEFINE, SCM_CAR (form)))
26d5b9b4
MD
1185 {
1186 defs = scm_cons (SCM_CDR (form), defs);
1187 x = SCM_CDR(x);
1188 }
1189 else if (SCM_NIMP(defs))
1190 {
1191 break;
1192 }
cf498326 1193 else if (SCM_EQ_P (SCM_IM_BEGIN, SCM_CAR (form)))
26d5b9b4
MD
1194 {
1195 x = scm_append (scm_cons2 (SCM_CDR (form), SCM_CDR (x), SCM_EOL));
1196 }
1197 else
1198 {
1199 x = scm_cons (form, SCM_CDR(x));
1200 break;
1201 }
1202 }
1203
1204 SCM_ASSYNT (SCM_NIMP (x), SCM_CDR (xorig), scm_s_body, what);
1205 if (SCM_NIMP (defs))
1206 {
1207 x = scm_cons (scm_m_letrec1 (SCM_IM_LETREC,
1208 SCM_IM_DEFINE,
2f0d1375 1209 scm_cons2 (scm_sym_define, defs, x),
26d5b9b4
MD
1210 env),
1211 SCM_EOL);
1212 }
1213
1214 SCM_DEFER_INTS;
1215 SCM_SETCAR (xorig, SCM_CAR (x));
1216 SCM_SETCDR (xorig, SCM_CDR (x));
1217 SCM_ALLOW_INTS;
1218
1219 return xorig;
1220}
1221
1222SCM
1223scm_macroexp (SCM x, SCM env)
1224{
1225 SCM res, proc;
1226
1227 /* Don't bother to produce error messages here. We get them when we
1228 eventually execute the code for real. */
1229
1230 macro_tail:
44d3cb0d 1231 if (!SCM_SYMBOLP (SCM_CAR (x)))
26d5b9b4
MD
1232 return x;
1233
1234#ifdef USE_THREADS
1235 {
1236 SCM *proc_ptr = scm_lookupcar1 (x, env, 0);
1237 if (proc_ptr == NULL)
1238 {
1239 /* We have lost the race. */
1240 goto macro_tail;
1241 }
1242 proc = *proc_ptr;
1243 }
1244#else
1245 proc = *scm_lookupcar (x, env, 0);
1246#endif
1247
1248 /* Only handle memoizing macros. `Acros' and `macros' are really
1249 special forms and should not be evaluated here. */
1250
1251 if (SCM_IMP (proc)
1252 || scm_tc16_macro != SCM_TYP16 (proc)
445f675c 1253 || (SCM_CELL_WORD_0 (proc) >> 16) != 2)
26d5b9b4
MD
1254 return x;
1255
1256 unmemocar (x, env);
1257 res = scm_apply (SCM_CDR (proc), x, scm_cons (env, scm_listofnull));
1258
1259 if (scm_ilength (res) <= 0)
1260 res = scm_cons2 (SCM_IM_BEGIN, res, SCM_EOL);
1261
26d5b9b4
MD
1262 SCM_DEFER_INTS;
1263 SCM_SETCAR (x, SCM_CAR (res));
1264 SCM_SETCDR (x, SCM_CDR (res));
1265 SCM_ALLOW_INTS;
1266
1267 goto macro_tail;
1268}
73b64342 1269
6dbd0af5
MD
1270/* scm_unmemocopy takes a memoized expression together with its
1271 * environment and rewrites it to its original form. Thus, it is the
1272 * inversion of the rewrite rules above. The procedure is not
1273 * optimized for speed. It's used in scm_iprin1 when printing the
220ff1eb
MD
1274 * code of a closure, in scm_procedure_source, in display_frame when
1275 * generating the source for a stackframe in a backtrace, and in
1276 * display_expression.
6dbd0af5
MD
1277 */
1278
26d5b9b4
MD
1279/* We should introduce an anti-macro interface so that it is possible
1280 * to plug in transformers in both directions from other compilation
1281 * units. unmemocopy could then dispatch to anti-macro transformers.
1282 * (Those transformers could perhaps be written in slightly more
1283 * readable style... :)
1284 */
1285
f1267706 1286#define SCM_BIT8(x) (127 & SCM_UNPACK (x))
c209c88e 1287
6dbd0af5 1288static SCM
1bbd0b84 1289unmemocopy (SCM x, SCM env)
6dbd0af5
MD
1290{
1291 SCM ls, z;
1292#ifdef DEBUG_EXTENSIONS
1293 SCM p;
1294#endif
1295 if (SCM_NCELLP (x) || SCM_NECONSP (x))
1296 return x;
1297#ifdef DEBUG_EXTENSIONS
1298 p = scm_whash_lookup (scm_source_whash, x);
1299#endif
1300 switch (SCM_TYP7 (x))
1301 {
c209c88e 1302 case SCM_BIT8(SCM_IM_AND):
2f0d1375 1303 ls = z = scm_cons (scm_sym_and, SCM_UNSPECIFIED);
6dbd0af5 1304 break;
c209c88e 1305 case SCM_BIT8(SCM_IM_BEGIN):
2f0d1375 1306 ls = z = scm_cons (scm_sym_begin, SCM_UNSPECIFIED);
6dbd0af5 1307 break;
c209c88e 1308 case SCM_BIT8(SCM_IM_CASE):
2f0d1375 1309 ls = z = scm_cons (scm_sym_case, SCM_UNSPECIFIED);
6dbd0af5 1310 break;
c209c88e 1311 case SCM_BIT8(SCM_IM_COND):
2f0d1375 1312 ls = z = scm_cons (scm_sym_cond, SCM_UNSPECIFIED);
6dbd0af5 1313 break;
c209c88e 1314 case SCM_BIT8(SCM_IM_DO):
2f0d1375 1315 ls = scm_cons (scm_sym_do, SCM_UNSPECIFIED);
6dbd0af5 1316 goto transform;
c209c88e 1317 case SCM_BIT8(SCM_IM_IF):
2f0d1375 1318 ls = z = scm_cons (scm_sym_if, SCM_UNSPECIFIED);
6dbd0af5 1319 break;
c209c88e 1320 case SCM_BIT8(SCM_IM_LET):
2f0d1375 1321 ls = scm_cons (scm_sym_let, SCM_UNSPECIFIED);
6dbd0af5 1322 goto transform;
c209c88e 1323 case SCM_BIT8(SCM_IM_LETREC):
6dbd0af5
MD
1324 {
1325 SCM f, v, e, s;
2f0d1375 1326 ls = scm_cons (scm_sym_letrec, SCM_UNSPECIFIED);
6dbd0af5
MD
1327 transform:
1328 x = SCM_CDR (x);
26d5b9b4 1329 /* binding names */
6dbd0af5
MD
1330 f = v = SCM_CAR (x);
1331 x = SCM_CDR (x);
e2806c10 1332 z = EXTEND_ENV (f, SCM_EOL, env);
26d5b9b4 1333 /* inits */
6dbd0af5 1334 e = scm_reverse (unmemocopy (SCM_CAR (x),
cf498326 1335 SCM_EQ_P (SCM_CAR (ls), scm_sym_letrec) ? z : env));
6dbd0af5 1336 env = z;
26d5b9b4 1337 /* increments */
cf498326 1338 s = SCM_EQ_P (SCM_CAR (ls), scm_sym_do)
6dbd0af5
MD
1339 ? scm_reverse (unmemocopy (SCM_CDR (SCM_CDR (SCM_CDR (x))), env))
1340 : f;
26d5b9b4 1341 /* build transformed binding list */
6dbd0af5
MD
1342 z = SCM_EOL;
1343 do
1344 {
1345 z = scm_acons (SCM_CAR (v),
1346 scm_cons (SCM_CAR (e),
cf498326 1347 SCM_EQ_P (SCM_CAR (s), SCM_CAR (v))
6dbd0af5
MD
1348 ? SCM_EOL
1349 : scm_cons (SCM_CAR (s), SCM_EOL)),
1350 z);
1351 v = SCM_CDR (v);
1352 e = SCM_CDR (e);
1353 s = SCM_CDR (s);
1354 }
ff467021 1355 while (SCM_NIMP (v));
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));
6dbd0af5 2645#ifdef CCLO
0f2d19dd
JB
2646 case scm_tc7_cclo:
2647 t.arg1 = proc;
2648 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2649#ifdef DEVAL
2650 debug.info->a.proc = proc;
2651 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2652#endif
0f2d19dd 2653 goto evap1;
6dbd0af5 2654#endif
89efbff4
MD
2655 case scm_tc7_pws:
2656 proc = SCM_PROCEDURE (proc);
2657#ifdef DEVAL
2658 debug.info->a.proc = proc;
2659#endif
002f1a5d
MD
2660 if (!SCM_CLOSUREP (proc))
2661 goto evap0;
2662 if (scm_badformalsp (proc, 0))
2663 goto umwrongnumargs;
0f2d19dd
JB
2664 case scm_tcs_closures:
2665 x = SCM_CODE (proc);
e2806c10 2666 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, SCM_ENV (proc));
0f2d19dd 2667 goto cdrxbegin;
da7f71d7 2668 case scm_tcs_cons_gloc:
195847fa
MD
2669 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2670 {
2671 x = SCM_ENTITY_PROCEDURE (proc);
2672 arg2 = SCM_EOL;
2673 goto type_dispatch;
2674 }
2675 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2676 goto badfun;
2677 else
da7f71d7 2678 {
195847fa
MD
2679 t.arg1 = proc;
2680 proc = (SCM_I_ENTITYP (proc)
2681 ? SCM_ENTITY_PROCEDURE (proc)
2682 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7 2683#ifdef DEVAL
195847fa
MD
2684 debug.info->a.proc = proc;
2685 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
da7f71d7 2686#endif
195847fa
MD
2687 if (SCM_NIMP (proc))
2688 goto evap1;
2689 else
2690 goto badfun;
da7f71d7 2691 }
0f2d19dd
JB
2692 case scm_tc7_contin:
2693 case scm_tc7_subr_1:
2694 case scm_tc7_subr_2:
2695 case scm_tc7_subr_2o:
2696 case scm_tc7_cxr:
2697 case scm_tc7_subr_3:
2698 case scm_tc7_lsubr_2:
2699 umwrongnumargs:
2700 unmemocar (x, env);
2701 wrongnumargs:
f5bf2977
GH
2702 /* scm_everr (x, env,...) */
2703 scm_wrong_num_args (proc);
0f2d19dd
JB
2704 default:
2705 /* handle macros here */
2706 goto badfun;
2707 }
6dbd0af5 2708 }
0f2d19dd
JB
2709
2710 /* must handle macros by here */
2711 x = SCM_CDR (x);
cf7c17e9 2712#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2713 if (SCM_IMP (x))
2714 goto wrongnumargs;
680ed4a8
MD
2715 else if (SCM_CONSP (x))
2716 {
2717 if (SCM_IMP (SCM_CAR (x)))
6cb702da 2718 t.arg1 = SCM_EVALIM (SCM_CAR (x), env);
680ed4a8
MD
2719 else
2720 t.arg1 = EVALCELLCAR (x, env);
2721 }
3201d763 2722 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
680ed4a8 2723 {
3201d763
DH
2724 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2725 if (vcell == 0)
680ed4a8 2726 t.arg1 = SCM_CAR (x); /* struct planted in code */
3201d763
DH
2727 else
2728 t.arg1 = SCM_PACK (vcell);
680ed4a8
MD
2729 }
2730 else
2731 goto wrongnumargs;
2732#else
0f2d19dd 2733 t.arg1 = EVALCAR (x, env);
680ed4a8 2734#endif
6dbd0af5
MD
2735#ifdef DEVAL
2736 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2737#endif
0f2d19dd
JB
2738 x = SCM_CDR (x);
2739 if (SCM_NULLP (x))
2740 {
6dbd0af5 2741 ENTER_APPLY;
0f2d19dd
JB
2742 evap1:
2743 switch (SCM_TYP7 (proc))
6dbd0af5 2744 { /* have one argument in t.arg1 */
0f2d19dd
JB
2745 case scm_tc7_subr_2o:
2746 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2747 case scm_tc7_subr_1:
2748 case scm_tc7_subr_1o:
2749 RETURN (SCM_SUBRF (proc) (t.arg1));
2750 case scm_tc7_cxr:
0f2d19dd
JB
2751 if (SCM_SUBRF (proc))
2752 {
2753 if (SCM_INUMP (t.arg1))
2754 {
f8de44c1 2755 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (t.arg1))));
0f2d19dd
JB
2756 }
2757 SCM_ASRTGO (SCM_NIMP (t.arg1), floerr);
2758 if (SCM_REALP (t.arg1))
2759 {
eb42e2f0 2760 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (t.arg1))));
0f2d19dd
JB
2761 }
2762#ifdef SCM_BIGDIG
2763 if (SCM_BIGP (t.arg1))
2764 {
f8de44c1 2765 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_big2dbl (t.arg1))));
0f2d19dd
JB
2766 }
2767#endif
2768 floerr:
9de33deb
MD
2769 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), t.arg1,
2770 SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
0f2d19dd 2771 }
3201d763 2772 proc = SCM_SNAME (proc);
0f2d19dd
JB
2773 {
2774 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
2775 while ('c' != *--chrs)
2776 {
0c95b57d 2777 SCM_ASSERT (SCM_CONSP (t.arg1),
0f2d19dd
JB
2778 t.arg1, SCM_ARG1, SCM_CHARS (proc));
2779 t.arg1 = ('a' == *chrs) ? SCM_CAR (t.arg1) : SCM_CDR (t.arg1);
2780 }
2781 RETURN (t.arg1);
2782 }
2783 case scm_tc7_rpsubr:
2784 RETURN (SCM_BOOL_T);
2785 case scm_tc7_asubr:
2786 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2787 case scm_tc7_lsubr:
2788#ifdef DEVAL
6dbd0af5 2789 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd
JB
2790#else
2791 RETURN (SCM_SUBRF (proc) (scm_cons (t.arg1, SCM_EOL)));
2792#endif
6dbd0af5 2793#ifdef CCLO
0f2d19dd
JB
2794 case scm_tc7_cclo:
2795 arg2 = t.arg1;
2796 t.arg1 = proc;
2797 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2798#ifdef DEVAL
2799 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2800 debug.info->a.proc = proc;
2801#endif
0f2d19dd 2802 goto evap2;
6dbd0af5 2803#endif
89efbff4
MD
2804 case scm_tc7_pws:
2805 proc = SCM_PROCEDURE (proc);
2806#ifdef DEVAL
2807 debug.info->a.proc = proc;
2808#endif
002f1a5d
MD
2809 if (!SCM_CLOSUREP (proc))
2810 goto evap1;
2811 if (scm_badformalsp (proc, 1))
2812 goto umwrongnumargs;
0f2d19dd 2813 case scm_tcs_closures:
195847fa 2814 /* clos1: */
0f2d19dd
JB
2815 x = SCM_CODE (proc);
2816#ifdef DEVAL
e2806c10 2817 env = EXTEND_ENV (SCM_CAR (x), debug.info->a.args, SCM_ENV (proc));
0f2d19dd 2818#else
e2806c10 2819 env = EXTEND_ENV (SCM_CAR (x), scm_cons (t.arg1, SCM_EOL), SCM_ENV (proc));
0f2d19dd
JB
2820#endif
2821 goto cdrxbegin;
65e41721
MD
2822 case scm_tc7_contin:
2823 scm_call_continuation (proc, t.arg1);
0c32d76c 2824 case scm_tcs_cons_gloc:
f3d2630a
MD
2825 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2826 {
195847fa 2827 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a
MD
2828#ifdef DEVAL
2829 arg2 = debug.info->a.args;
2830#else
2831 arg2 = scm_cons (t.arg1, SCM_EOL);
2832#endif
f3d2630a
MD
2833 goto type_dispatch;
2834 }
2835 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2836 goto badfun;
2837 else
0c32d76c 2838 {
195847fa
MD
2839 arg2 = t.arg1;
2840 t.arg1 = proc;
2841 proc = (SCM_I_ENTITYP (proc)
2842 ? SCM_ENTITY_PROCEDURE (proc)
2843 : SCM_OPERATOR_PROCEDURE (proc));
0c32d76c 2844#ifdef DEVAL
195847fa
MD
2845 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2846 debug.info->a.proc = proc;
0c32d76c 2847#endif
195847fa
MD
2848 if (SCM_NIMP (proc))
2849 goto evap2;
2850 else
2851 goto badfun;
0c32d76c 2852 }
0f2d19dd
JB
2853 case scm_tc7_subr_2:
2854 case scm_tc7_subr_0:
2855 case scm_tc7_subr_3:
2856 case scm_tc7_lsubr_2:
2857 goto wrongnumargs;
2858 default:
2859 goto badfun;
2860 }
2861 }
cf7c17e9 2862#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2863 if (SCM_IMP (x))
2864 goto wrongnumargs;
680ed4a8
MD
2865 else if (SCM_CONSP (x))
2866 {
2867 if (SCM_IMP (SCM_CAR (x)))
6cb702da 2868 arg2 = SCM_EVALIM (SCM_CAR (x), env);
680ed4a8
MD
2869 else
2870 arg2 = EVALCELLCAR (x, env);
2871 }
3201d763 2872 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
680ed4a8 2873 {
3201d763
DH
2874 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2875 if (vcell == 0)
680ed4a8 2876 arg2 = SCM_CAR (x); /* struct planted in code */
3201d763
DH
2877 else
2878 arg2 = SCM_PACK (vcell);
680ed4a8
MD
2879 }
2880 else
2881 goto wrongnumargs;
2882#else
2883 arg2 = EVALCAR (x, env);
0f2d19dd
JB
2884#endif
2885 { /* have two or more arguments */
6dbd0af5
MD
2886#ifdef DEVAL
2887 debug.info->a.args = scm_cons2 (t.arg1, arg2, SCM_EOL);
2888#endif
0f2d19dd
JB
2889 x = SCM_CDR (x);
2890 if (SCM_NULLP (x)) {
6dbd0af5 2891 ENTER_APPLY;
0f2d19dd
JB
2892#ifdef CCLO
2893 evap2:
2894#endif
6dbd0af5
MD
2895 switch (SCM_TYP7 (proc))
2896 { /* have two arguments */
2897 case scm_tc7_subr_2:
2898 case scm_tc7_subr_2o:
2899 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2900 case scm_tc7_lsubr:
0f2d19dd 2901#ifdef DEVAL
6dbd0af5
MD
2902 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2903#else
2904 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, SCM_EOL)));
0f2d19dd 2905#endif
6dbd0af5
MD
2906 case scm_tc7_lsubr_2:
2907 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_EOL));
2908 case scm_tc7_rpsubr:
2909 case scm_tc7_asubr:
2910 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2911#ifdef CCLO
2912 cclon:
2913 case scm_tc7_cclo:
0f2d19dd 2914#ifdef DEVAL
195847fa
MD
2915 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2916 scm_cons (proc, debug.info->a.args),
2917 SCM_EOL));
0f2d19dd 2918#else
195847fa
MD
2919 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2920 scm_cons2 (proc, t.arg1,
2921 scm_cons (arg2,
2922 scm_eval_args (x,
2923 env,
2924 proc))),
2925 SCM_EOL));
0f2d19dd 2926#endif
6dbd0af5
MD
2927 /* case scm_tc7_cclo:
2928 x = scm_cons(arg2, scm_eval_args(x, env));
2929 arg2 = t.arg1;
2930 t.arg1 = proc;
2931 proc = SCM_CCLO_SUBR(proc);
2932 goto evap3; */
2933#endif
0c32d76c 2934 case scm_tcs_cons_gloc:
f3d2630a
MD
2935 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2936 {
195847fa 2937 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a
MD
2938#ifdef DEVAL
2939 arg2 = debug.info->a.args;
2940#else
2941 arg2 = scm_cons2 (t.arg1, arg2, SCM_EOL);
2942#endif
f3d2630a
MD
2943 goto type_dispatch;
2944 }
2945 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2946 goto badfun;
2947 else
0c32d76c 2948 {
195847fa 2949 operatorn:
0c32d76c 2950#ifdef DEVAL
195847fa
MD
2951 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2952 ? SCM_ENTITY_PROCEDURE (proc)
2953 : SCM_OPERATOR_PROCEDURE (proc),
2954 scm_cons (proc, debug.info->a.args),
2955 SCM_EOL));
2956#else
2957 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2958 ? SCM_ENTITY_PROCEDURE (proc)
2959 : SCM_OPERATOR_PROCEDURE (proc),
2960 scm_cons2 (proc, t.arg1,
2961 scm_cons (arg2,
2962 scm_eval_args (x,
2963 env,
2964 proc))),
2965 SCM_EOL));
2966#endif
0c32d76c 2967 }
6dbd0af5
MD
2968 case scm_tc7_subr_0:
2969 case scm_tc7_cxr:
2970 case scm_tc7_subr_1o:
2971 case scm_tc7_subr_1:
2972 case scm_tc7_subr_3:
2973 case scm_tc7_contin:
2974 goto wrongnumargs;
2975 default:
2976 goto badfun;
002f1a5d
MD
2977 case scm_tc7_pws:
2978 proc = SCM_PROCEDURE (proc);
2979#ifdef DEVAL
2980 debug.info->a.proc = proc;
2981#endif
2982 if (!SCM_CLOSUREP (proc))
2983 goto evap2;
2984 if (scm_badformalsp (proc, 2))
2985 goto umwrongnumargs;
6dbd0af5 2986 case scm_tcs_closures:
195847fa 2987 /* clos2: */
0f2d19dd 2988#ifdef DEVAL
da7f71d7
MD
2989 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
2990 debug.info->a.args,
2991 SCM_ENV (proc));
0f2d19dd 2992#else
da7f71d7
MD
2993 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
2994 scm_cons2 (t.arg1, arg2, SCM_EOL), SCM_ENV (proc));
0f2d19dd 2995#endif
6dbd0af5
MD
2996 x = SCM_CODE (proc);
2997 goto cdrxbegin;
2998 }
0f2d19dd 2999 }
cf7c17e9 3000#ifdef SCM_CAUTIOUS
680ed4a8
MD
3001 if (SCM_IMP (x) || SCM_NECONSP (x))
3002 goto wrongnumargs;
3003#endif
0f2d19dd 3004#ifdef DEVAL
6dbd0af5 3005 debug.info->a.args = scm_cons2 (t.arg1, arg2,
680ed4a8
MD
3006 scm_deval_args (x, env, proc,
3007 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
0f2d19dd 3008#endif
6dbd0af5 3009 ENTER_APPLY;
89efbff4 3010 evap3:
6dbd0af5
MD
3011 switch (SCM_TYP7 (proc))
3012 { /* have 3 or more arguments */
0f2d19dd 3013#ifdef DEVAL
6dbd0af5
MD
3014 case scm_tc7_subr_3:
3015 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
da7f71d7
MD
3016 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
3017 SCM_CADDR (debug.info->a.args)));
6dbd0af5 3018 case scm_tc7_asubr:
399dedcc
MD
3019#ifdef BUILTIN_RPASUBR
3020 t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
3021 arg2 = SCM_CDR (SCM_CDR (debug.info->a.args));
da7f71d7
MD
3022 do
3023 {
3024 t.arg1 = SCM_SUBRF(proc)(t.arg1, SCM_CAR (arg2));
3025 arg2 = SCM_CDR (arg2);
3026 }
3027 while (SCM_NIMP (arg2));
399dedcc
MD
3028 RETURN (t.arg1)
3029#endif /* BUILTIN_RPASUBR */
6dbd0af5 3030 case scm_tc7_rpsubr:
71d3aa6d
MD
3031#ifdef BUILTIN_RPASUBR
3032 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
3033 RETURN (SCM_BOOL_F)
3034 t.arg1 = SCM_CDR (SCM_CDR (debug.info->a.args));
da7f71d7
MD
3035 do
3036 {
3037 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, SCM_CAR (t.arg1))))
3038 RETURN (SCM_BOOL_F)
3039 arg2 = SCM_CAR (t.arg1);
3040 t.arg1 = SCM_CDR (t.arg1);
3041 }
3042 while (SCM_NIMP (t.arg1));
71d3aa6d
MD
3043 RETURN (SCM_BOOL_T)
3044#else /* BUILTIN_RPASUBR */
da7f71d7
MD
3045 RETURN (SCM_APPLY (proc, t.arg1,
3046 scm_acons (arg2,
3047 SCM_CDR (SCM_CDR (debug.info->a.args)),
3048 SCM_EOL)))
71d3aa6d 3049#endif /* BUILTIN_RPASUBR */
399dedcc 3050 case scm_tc7_lsubr_2:
da7f71d7
MD
3051 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
3052 SCM_CDR (SCM_CDR (debug.info->a.args))))
399dedcc
MD
3053 case scm_tc7_lsubr:
3054 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd 3055#ifdef CCLO
6dbd0af5
MD
3056 case scm_tc7_cclo:
3057 goto cclon;
0f2d19dd 3058#endif
89efbff4
MD
3059 case scm_tc7_pws:
3060 proc = SCM_PROCEDURE (proc);
3061 debug.info->a.proc = proc;
002f1a5d
MD
3062 if (!SCM_CLOSUREP (proc))
3063 goto evap3;
3064 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), debug.info->a.args))
3065 goto umwrongnumargs;
6dbd0af5 3066 case scm_tcs_closures:
b7ff98dd 3067 SCM_SET_ARGSREADY (debug);
e2806c10 3068 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
6dbd0af5
MD
3069 debug.info->a.args,
3070 SCM_ENV (proc));
3071 x = SCM_CODE (proc);
3072 goto cdrxbegin;
3073#else /* DEVAL */
3074 case scm_tc7_subr_3:
3075 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
3076 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, EVALCAR (x, env)));
3077 case scm_tc7_asubr:
399dedcc 3078#ifdef BUILTIN_RPASUBR
da7f71d7
MD
3079 t.arg1 = SCM_SUBRF (proc) (t.arg1, arg2);
3080 do
3081 {
3082 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
3083 x = SCM_CDR(x);
3084 }
3085 while (SCM_NIMP (x));
399dedcc
MD
3086 RETURN (t.arg1)
3087#endif /* BUILTIN_RPASUBR */
6dbd0af5 3088 case scm_tc7_rpsubr:
71d3aa6d
MD
3089#ifdef BUILTIN_RPASUBR
3090 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
3091 RETURN (SCM_BOOL_F)
da7f71d7
MD
3092 do
3093 {
3094 t.arg1 = EVALCAR (x, env);
3095 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, t.arg1)))
3096 RETURN (SCM_BOOL_F)
3097 arg2 = t.arg1;
3098 x = SCM_CDR (x);
3099 }
3100 while (SCM_NIMP (x));
71d3aa6d
MD
3101 RETURN (SCM_BOOL_T)
3102#else /* BUILTIN_RPASUBR */
da7f71d7 3103 RETURN (SCM_APPLY (proc, t.arg1,
680ed4a8
MD
3104 scm_acons (arg2,
3105 scm_eval_args (x, env, proc),
3106 SCM_EOL)));
71d3aa6d 3107#endif /* BUILTIN_RPASUBR */
6dbd0af5 3108 case scm_tc7_lsubr_2:
680ed4a8 3109 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, scm_eval_args (x, env, proc)));
6dbd0af5 3110 case scm_tc7_lsubr:
680ed4a8
MD
3111 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1,
3112 arg2,
3113 scm_eval_args (x, env, proc))));
0f2d19dd 3114#ifdef CCLO
6dbd0af5
MD
3115 case scm_tc7_cclo:
3116 goto cclon;
0f2d19dd 3117#endif
89efbff4
MD
3118 case scm_tc7_pws:
3119 proc = SCM_PROCEDURE (proc);
002f1a5d
MD
3120 if (!SCM_CLOSUREP (proc))
3121 goto evap3;
3122 {
3123 SCM formals = SCM_CAR (SCM_CODE (proc));
3124 if (SCM_NULLP (formals)
3125 || (SCM_CONSP (formals)
3126 && (SCM_NULLP (SCM_CDR (formals))
3127 || (SCM_CONSP (SCM_CDR (formals))
3128 && scm_badargsp (SCM_CDDR (formals), x)))))
3129 goto umwrongnumargs;
3130 }
6dbd0af5
MD
3131 case scm_tcs_closures:
3132#ifdef DEVAL
b7ff98dd 3133 SCM_SET_ARGSREADY (debug);
6dbd0af5 3134#endif
e2806c10 3135 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
680ed4a8
MD
3136 scm_cons2 (t.arg1,
3137 arg2,
3138 scm_eval_args (x, env, proc)),
6dbd0af5
MD
3139 SCM_ENV (proc));
3140 x = SCM_CODE (proc);
3141 goto cdrxbegin;
0f2d19dd 3142#endif /* DEVAL */
0c32d76c 3143 case scm_tcs_cons_gloc:
f3d2630a
MD
3144 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3145 {
3146#ifdef DEVAL
3147 arg2 = debug.info->a.args;
3148#else
3149 arg2 = scm_cons2 (t.arg1, arg2, scm_eval_args (x, env, proc));
3150#endif
195847fa 3151 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a
MD
3152 goto type_dispatch;
3153 }
3154 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
3155 goto badfun;
3156 else
195847fa 3157 goto operatorn;
6dbd0af5
MD
3158 case scm_tc7_subr_2:
3159 case scm_tc7_subr_1o:
3160 case scm_tc7_subr_2o:
3161 case scm_tc7_subr_0:
3162 case scm_tc7_cxr:
3163 case scm_tc7_subr_1:
3164 case scm_tc7_contin:
3165 goto wrongnumargs;
3166 default:
3167 goto badfun;
3168 }
0f2d19dd
JB
3169 }
3170#ifdef DEVAL
6dbd0af5 3171exit:
b6d75948 3172 if (CHECK_EXIT && SCM_TRAPS_P)
b7ff98dd 3173 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3174 {
b7ff98dd
MD
3175 SCM_CLEAR_TRACED_FRAME (debug);
3176 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3177 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3178 else
3179 {
3180 scm_make_cont (&t.arg1);
ca6ef71a 3181 if (setjmp (SCM_JMPBUF (t.arg1)))
6dbd0af5
MD
3182 {
3183 proc = SCM_THROW_VALUE (t.arg1);
3184 goto ret;
3185 }
3186 }
2f0d1375 3187 scm_ithrow (scm_sym_exit_frame, scm_cons2 (t.arg1, proc, SCM_EOL), 0);
6dbd0af5
MD
3188 }
3189ret:
1646d37b 3190 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3191 return proc;
3192#endif
3193}
3194
6dbd0af5
MD
3195
3196/* SECTION: This code is compiled once.
3197 */
3198
0f2d19dd
JB
3199#ifndef DEVAL
3200
82a2622a 3201/* This code processes the arguments to apply:
b145c172
JB
3202
3203 (apply PROC ARG1 ... ARGS)
3204
82a2622a
JB
3205 Given a list (ARG1 ... ARGS), this function conses the ARG1
3206 ... arguments onto the front of ARGS, and returns the resulting
3207 list. Note that ARGS is a list; thus, the argument to this
3208 function is a list whose last element is a list.
3209
3210 Apply calls this function, and applies PROC to the elements of the
b145c172
JB
3211 result. apply:nconc2last takes care of building the list of
3212 arguments, given (ARG1 ... ARGS).
3213
82a2622a
JB
3214 Rather than do new consing, apply:nconc2last destroys its argument.
3215 On that topic, this code came into my care with the following
3216 beautifully cryptic comment on that topic: "This will only screw
3217 you if you do (scm_apply scm_apply '( ... ))" If you know what
3218 they're referring to, send me a patch to this comment. */
b145c172 3219
3b3b36dd 3220SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
1bbd0b84 3221 (SCM lst),
b380b885 3222 "")
1bbd0b84 3223#define FUNC_NAME s_scm_nconc2last
0f2d19dd
JB
3224{
3225 SCM *lloc;
c1bfcf60 3226 SCM_VALIDATE_NONEMPTYLIST (1,lst);
0f2d19dd
JB
3227 lloc = &lst;
3228 while (SCM_NNULLP (SCM_CDR (*lloc)))
a23afe53 3229 lloc = SCM_CDRLOC (*lloc);
1bbd0b84 3230 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
0f2d19dd
JB
3231 *lloc = SCM_CAR (*lloc);
3232 return lst;
3233}
1bbd0b84 3234#undef FUNC_NAME
0f2d19dd
JB
3235
3236#endif /* !DEVAL */
3237
6dbd0af5
MD
3238
3239/* SECTION: When DEVAL is defined this code yields scm_dapply.
3240 * It is compiled twice.
3241 */
3242
0f2d19dd 3243#if 0
1cc91f1b 3244
0f2d19dd 3245SCM
6e8d25a6 3246scm_apply (SCM proc, SCM arg1, SCM args)
0f2d19dd
JB
3247{}
3248#endif
3249
3250#if 0
1cc91f1b 3251
0f2d19dd 3252SCM
6e8d25a6
GB
3253scm_dapply (SCM proc, SCM arg1, SCM args)
3254{ /* empty */ }
0f2d19dd
JB
3255#endif
3256
1cc91f1b 3257
82a2622a
JB
3258/* Apply a function to a list of arguments.
3259
3260 This function is exported to the Scheme level as taking two
3261 required arguments and a tail argument, as if it were:
3262 (lambda (proc arg1 . args) ...)
3263 Thus, if you just have a list of arguments to pass to a procedure,
3264 pass the list as ARG1, and '() for ARGS. If you have some fixed
3265 args, pass the first as ARG1, then cons any remaining fixed args
3266 onto the front of your argument list, and pass that as ARGS. */
3267
0f2d19dd 3268SCM
1bbd0b84 3269SCM_APPLY (SCM proc, SCM arg1, SCM args)
0f2d19dd
JB
3270{
3271#ifdef DEBUG_EXTENSIONS
3272#ifdef DEVAL
6dbd0af5 3273 scm_debug_frame debug;
c0ab1b8d 3274 scm_debug_info debug_vect_body;
1646d37b 3275 debug.prev = scm_last_debug_frame;
b7ff98dd 3276 debug.status = SCM_APPLYFRAME;
c0ab1b8d 3277 debug.vect = &debug_vect_body;
6dbd0af5
MD
3278 debug.vect[0].a.proc = proc;
3279 debug.vect[0].a.args = SCM_EOL;
1646d37b 3280 scm_last_debug_frame = &debug;
0f2d19dd 3281#else
b7ff98dd 3282 if (SCM_DEBUGGINGP)
0f2d19dd
JB
3283 return scm_dapply (proc, arg1, args);
3284#endif
3285#endif
3286
3287 SCM_ASRTGO (SCM_NIMP (proc), badproc);
82a2622a
JB
3288
3289 /* If ARGS is the empty list, then we're calling apply with only two
3290 arguments --- ARG1 is the list of arguments for PROC. Whatever
3291 the case, futz with things so that ARG1 is the first argument to
3292 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
30000774
JB
3293 rest.
3294
3295 Setting the debug apply frame args this way is pretty messy.
3296 Perhaps we should store arg1 and args directly in the frame as
3297 received, and let scm_frame_arguments unpack them, because that's
3298 a relatively rare operation. This works for now; if the Guile
3299 developer archives are still around, see Mikael's post of
3300 11-Apr-97. */
0f2d19dd
JB
3301 if (SCM_NULLP (args))
3302 {
3303 if (SCM_NULLP (arg1))
30000774
JB
3304 {
3305 arg1 = SCM_UNDEFINED;
3306#ifdef DEVAL
3307 debug.vect[0].a.args = SCM_EOL;
3308#endif
3309 }
0f2d19dd
JB
3310 else
3311 {
30000774
JB
3312#ifdef DEVAL
3313 debug.vect[0].a.args = arg1;
3314#endif
0f2d19dd
JB
3315 args = SCM_CDR (arg1);
3316 arg1 = SCM_CAR (arg1);
3317 }
3318 }
3319 else
3320 {
0c95b57d 3321 /* SCM_ASRTGO(SCM_CONSP(args), wrongnumargs); */
0f2d19dd 3322 args = scm_nconc2last (args);
30000774
JB
3323#ifdef DEVAL
3324 debug.vect[0].a.args = scm_cons (arg1, args);
3325#endif
0f2d19dd 3326 }
0f2d19dd 3327#ifdef DEVAL
b6d75948 3328 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
6dbd0af5
MD
3329 {
3330 SCM tmp;
b7ff98dd 3331 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3332 tmp = scm_make_debugobj (&debug);
6dbd0af5
MD
3333 else
3334 {
3335 scm_make_cont (&tmp);
ca6ef71a 3336 if (setjmp (SCM_JMPBUF (tmp)))
6dbd0af5
MD
3337 goto entap;
3338 }
2f0d1375 3339 scm_ithrow (scm_sym_enter_frame, scm_cons (tmp, SCM_EOL), 0);
6dbd0af5
MD
3340 }
3341entap:
3342 ENTER_APPLY;
3343#endif
3344#ifdef CCLO
3345tail:
0f2d19dd
JB
3346#endif
3347 switch (SCM_TYP7 (proc))
3348 {
3349 case scm_tc7_subr_2o:
3350 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
3351 RETURN (SCM_SUBRF (proc) (arg1, args))
3352 case scm_tc7_subr_2:
269861c7
MD
3353 SCM_ASRTGO (SCM_NNULLP (args) && SCM_NULLP (SCM_CDR (args)),
3354 wrongnumargs);
0f2d19dd
JB
3355 args = SCM_CAR (args);
3356 RETURN (SCM_SUBRF (proc) (arg1, args))
3357 case scm_tc7_subr_0:
3358 SCM_ASRTGO (SCM_UNBNDP (arg1), wrongnumargs);
3359 RETURN (SCM_SUBRF (proc) ())
3360 case scm_tc7_subr_1:
3361 case scm_tc7_subr_1o:
3362 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
3363 RETURN (SCM_SUBRF (proc) (arg1))
3364 case scm_tc7_cxr:
3365 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
0f2d19dd
JB
3366 if (SCM_SUBRF (proc))
3367 {
6dbd0af5
MD
3368 if (SCM_INUMP (arg1))
3369 {
f8de44c1 3370 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
6dbd0af5 3371 }
0f2d19dd 3372 SCM_ASRTGO (SCM_NIMP (arg1), floerr);
6dbd0af5
MD
3373 if (SCM_REALP (arg1))
3374 {
eb42e2f0 3375 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
6dbd0af5 3376 }
0f2d19dd 3377#ifdef SCM_BIGDIG
26d5b9b4 3378 if (SCM_BIGP (arg1))
f8de44c1 3379 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_big2dbl (arg1))))
0f2d19dd
JB
3380#endif
3381 floerr:
9de33deb
MD
3382 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3383 SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
0f2d19dd 3384 }
3201d763 3385 proc = SCM_SNAME (proc);
0f2d19dd
JB
3386 {
3387 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
3388 while ('c' != *--chrs)
3389 {
0c95b57d 3390 SCM_ASSERT (SCM_CONSP (arg1),
0f2d19dd
JB
3391 arg1, SCM_ARG1, SCM_CHARS (proc));
3392 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3393 }
3394 RETURN (arg1)
3395 }
3396 case scm_tc7_subr_3:
3397 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CAR (SCM_CDR (args))))
3398 case scm_tc7_lsubr:
3399#ifdef DEVAL
6dbd0af5 3400 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args))
0f2d19dd
JB
3401#else
3402 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)))
3403#endif
3404 case scm_tc7_lsubr_2:
0c95b57d 3405 SCM_ASRTGO (SCM_CONSP (args), wrongnumargs);
0f2d19dd
JB
3406 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)))
3407 case scm_tc7_asubr:
3408 if (SCM_NULLP (args))
3409 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED))
3410 while (SCM_NIMP (args))
3411 {
3412 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3413 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
3414 args = SCM_CDR (args);
3415 }
3416 RETURN (arg1);
3417 case scm_tc7_rpsubr:
3418 if (SCM_NULLP (args))
3419 RETURN (SCM_BOOL_T);
3420 while (SCM_NIMP (args))
3421 {
3422 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3423 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
3424 RETURN (SCM_BOOL_F);
3425 arg1 = SCM_CAR (args);
3426 args = SCM_CDR (args);
3427 }
3428 RETURN (SCM_BOOL_T);
3429 case scm_tcs_closures:
3430#ifdef DEVAL
6dbd0af5 3431 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
0f2d19dd
JB
3432#else
3433 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
3434#endif
cf7c17e9 3435#ifndef SCM_RECKLESS
0f2d19dd
JB
3436 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), arg1))
3437 goto wrongnumargs;
3438#endif
1609038c
MD
3439
3440 /* Copy argument list */
3441 if (SCM_IMP (arg1))
3442 args = arg1;
3443 else
3444 {
3445 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
cabe682c 3446 while (arg1 = SCM_CDR (arg1), SCM_CONSP (arg1))
1609038c
MD
3447 {
3448 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1),
3449 SCM_UNSPECIFIED));
3450 tl = SCM_CDR (tl);
3451 }
3452 SCM_SETCDR (tl, arg1);
3453 }
3454
3455 args = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), args, SCM_ENV (proc));
2ddb0920 3456 proc = SCM_CDR (SCM_CODE (proc));
e791c18f
MD
3457 again:
3458 arg1 = proc;
3459 while (SCM_NNULLP (arg1 = SCM_CDR (arg1)))
2ddb0920
MD
3460 {
3461 if (SCM_IMP (SCM_CAR (proc)))
3462 {
3463 if (SCM_ISYMP (SCM_CAR (proc)))
3464 {
3465 proc = scm_m_expand_body (proc, args);
e791c18f 3466 goto again;
2ddb0920 3467 }
2ddb0920
MD
3468 }
3469 else
e791c18f
MD
3470 SCM_CEVAL (SCM_CAR (proc), args);
3471 proc = arg1;
2ddb0920 3472 }
e791c18f 3473 RETURN (EVALCAR (proc, args));
0f2d19dd
JB
3474 case scm_tc7_contin:
3475 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
3476 scm_call_continuation (proc, arg1);
3477#ifdef CCLO
3478 case scm_tc7_cclo:
3479#ifdef DEVAL
6dbd0af5
MD
3480 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3481 arg1 = proc;
3482 proc = SCM_CCLO_SUBR (proc);
3483 debug.vect[0].a.proc = proc;
3484 debug.vect[0].a.args = scm_cons (arg1, args);
0f2d19dd
JB
3485#else
3486 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
0f2d19dd
JB
3487 arg1 = proc;
3488 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 3489#endif
0f2d19dd
JB
3490 goto tail;
3491#endif
89efbff4
MD
3492 case scm_tc7_pws:
3493 proc = SCM_PROCEDURE (proc);
3494#ifdef DEVAL
3495 debug.vect[0].a.proc = proc;
3496#endif
3497 goto tail;
0c32d76c 3498 case scm_tcs_cons_gloc:
f3d2630a
MD
3499 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3500 {
3501#ifdef DEVAL
3502 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3503#else
3504 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3505#endif
195847fa 3506 RETURN (scm_apply_generic (proc, args));
f3d2630a
MD
3507 }
3508 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
3509 goto badproc;
3510 else
da7f71d7
MD
3511 {
3512#ifdef DEVAL
3513 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3514#else
3515 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3516#endif
3517 arg1 = proc;
195847fa
MD
3518 proc = (SCM_I_ENTITYP (proc)
3519 ? SCM_ENTITY_PROCEDURE (proc)
3520 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7
MD
3521#ifdef DEVAL
3522 debug.vect[0].a.proc = proc;
3523 debug.vect[0].a.args = scm_cons (arg1, args);
3524#endif
195847fa
MD
3525 if (SCM_NIMP (proc))
3526 goto tail;
3527 else
3528 goto badproc;
da7f71d7 3529 }
0f2d19dd 3530 wrongnumargs:
f5bf2977 3531 scm_wrong_num_args (proc);
0f2d19dd
JB
3532 default:
3533 badproc:
3534 scm_wta (proc, (char *) SCM_ARG1, "apply");
3535 RETURN (arg1);
3536 }
3537#ifdef DEVAL
6dbd0af5 3538exit:
b6d75948 3539 if (CHECK_EXIT && SCM_TRAPS_P)
b7ff98dd 3540 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3541 {
b7ff98dd
MD
3542 SCM_CLEAR_TRACED_FRAME (debug);
3543 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3544 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3545 else
3546 {
3547 scm_make_cont (&arg1);
ca6ef71a 3548 if (setjmp (SCM_JMPBUF (arg1)))
6dbd0af5
MD
3549 {
3550 proc = SCM_THROW_VALUE (arg1);
3551 goto ret;
3552 }
3553 }
2f0d1375 3554 scm_ithrow (scm_sym_exit_frame, scm_cons2 (arg1, proc, SCM_EOL), 0);
6dbd0af5
MD
3555 }
3556ret:
1646d37b 3557 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3558 return proc;
3559#endif
3560}
3561
6dbd0af5
MD
3562
3563/* SECTION: The rest of this file is only read once.
3564 */
3565
0f2d19dd
JB
3566#ifndef DEVAL
3567
d9c393f5
JB
3568/* Typechecking for multi-argument MAP and FOR-EACH.
3569
47c3f06d 3570 Verify that each element of the vector ARGV, except for the first,
d9c393f5 3571 is a proper list whose length is LEN. Attribute errors to WHO,
47c3f06d 3572 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
d9c393f5 3573static inline void
47c3f06d
MD
3574check_map_args (SCM argv,
3575 long len,
3576 SCM gf,
3577 SCM proc,
3578 SCM args,
3579 const char *who)
d9c393f5 3580{
47c3f06d 3581 SCM *ve = SCM_VELTS (argv);
d9c393f5
JB
3582 int i;
3583
47c3f06d 3584 for (i = SCM_LENGTH (argv) - 1; i >= 1; i--)
d9c393f5
JB
3585 {
3586 int elt_len = scm_ilength (ve[i]);
3587
3588 if (elt_len < 0)
47c3f06d
MD
3589 {
3590 if (gf)
3591 scm_apply_generic (gf, scm_cons (proc, args));
3592 else
3593 scm_wrong_type_arg (who, i + 2, ve[i]);
3594 }
d9c393f5
JB
3595
3596 if (elt_len != len)
3597 scm_out_of_range (who, ve[i]);
3598 }
3599
47c3f06d 3600 scm_remember (&argv);
d9c393f5
JB
3601}
3602
3603
47c3f06d 3604SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
1cc91f1b 3605
368bf056
MD
3606/* Note: Currently, scm_map applies PROC to the argument list(s)
3607 sequentially, starting with the first element(s). This is used in
8878f040 3608 evalext.c where the Scheme procedure `map-in-order', which guarantees
368bf056 3609 sequential behaviour, is implemented using scm_map. If the
8878f040 3610 behaviour changes, we need to update `map-in-order'.
368bf056
MD
3611*/
3612
0f2d19dd 3613SCM
1bbd0b84 3614scm_map (SCM proc, SCM arg1, SCM args)
af45e3b0 3615#define FUNC_NAME s_map
0f2d19dd 3616{
d9c393f5 3617 long i, len;
0f2d19dd
JB
3618 SCM res = SCM_EOL;
3619 SCM *pres = &res;
3620 SCM *ve = &args; /* Keep args from being optimized away. */
3621
d9c393f5 3622 len = scm_ilength (arg1);
47c3f06d
MD
3623 SCM_GASSERTn (len >= 0,
3624 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
af45e3b0 3625 SCM_VALIDATE_REST_ARGUMENT (args);
0f2d19dd
JB
3626 if (SCM_NULLP (args))
3627 {
3628 while (SCM_NIMP (arg1))
3629 {
47c3f06d
MD
3630 *pres = scm_cons (scm_apply (proc, SCM_CAR (arg1), scm_listofnull),
3631 SCM_EOL);
a23afe53 3632 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
3633 arg1 = SCM_CDR (arg1);
3634 }
3635 return res;
3636 }
47c3f06d 3637 args = scm_vector (arg1 = scm_cons (arg1, args));
0f2d19dd 3638 ve = SCM_VELTS (args);
cf7c17e9 3639#ifndef SCM_RECKLESS
47c3f06d 3640 check_map_args (args, len, g_map, proc, arg1, s_map);
0f2d19dd
JB
3641#endif
3642 while (1)
3643 {
3644 arg1 = SCM_EOL;
3645 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
3646 {
d9c393f5
JB
3647 if (SCM_IMP (ve[i]))
3648 return res;
0f2d19dd
JB
3649 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3650 ve[i] = SCM_CDR (ve[i]);
3651 }
3652 *pres = scm_cons (scm_apply (proc, arg1, SCM_EOL), SCM_EOL);
a23afe53 3653 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
3654 }
3655}
af45e3b0 3656#undef FUNC_NAME
0f2d19dd
JB
3657
3658
47c3f06d 3659SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
1cc91f1b 3660
0f2d19dd 3661SCM
1bbd0b84 3662scm_for_each (SCM proc, SCM arg1, SCM args)
af45e3b0 3663#define FUNC_NAME s_for_each
0f2d19dd
JB
3664{
3665 SCM *ve = &args; /* Keep args from being optimized away. */
d9c393f5 3666 long i, len;
d9c393f5 3667 len = scm_ilength (arg1);
47c3f06d
MD
3668 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
3669 SCM_ARG2, s_for_each);
af45e3b0 3670 SCM_VALIDATE_REST_ARGUMENT (args);
0f2d19dd
JB
3671 if SCM_NULLP (args)
3672 {
3673 while SCM_NIMP (arg1)
3674 {
0f2d19dd
JB
3675 scm_apply (proc, SCM_CAR (arg1), scm_listofnull);
3676 arg1 = SCM_CDR (arg1);
3677 }
3678 return SCM_UNSPECIFIED;
3679 }
47c3f06d 3680 args = scm_vector (arg1 = scm_cons (arg1, args));
0f2d19dd 3681 ve = SCM_VELTS (args);
cf7c17e9 3682#ifndef SCM_RECKLESS
47c3f06d 3683 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
0f2d19dd
JB
3684#endif
3685 while (1)
3686 {
3687 arg1 = SCM_EOL;
3688 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
3689 {
3690 if SCM_IMP
3691 (ve[i]) return SCM_UNSPECIFIED;
3692 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3693 ve[i] = SCM_CDR (ve[i]);
3694 }
3695 scm_apply (proc, arg1, SCM_EOL);
3696 }
3697}
af45e3b0 3698#undef FUNC_NAME
0f2d19dd 3699
1cc91f1b 3700
0f2d19dd 3701SCM
6e8d25a6 3702scm_closure (SCM code, SCM env)
0f2d19dd
JB
3703{
3704 register SCM z;
3705 SCM_NEWCELL (z);
3706 SCM_SETCODE (z, code);
a23afe53 3707 SCM_SETENV (z, env);
0f2d19dd
JB
3708 return z;
3709}
3710
3711
3712long scm_tc16_promise;
1cc91f1b 3713
0f2d19dd 3714SCM
6e8d25a6 3715scm_makprom (SCM code)
0f2d19dd 3716{
cf498326 3717 SCM_RETURN_NEWSMOB (scm_tc16_promise, SCM_UNPACK (code));
0f2d19dd
JB
3718}
3719
3720
1cc91f1b 3721
0f2d19dd 3722static int
1bbd0b84 3723prinprom (SCM exp,SCM port,scm_print_state *pstate)
0f2d19dd 3724{
19402679 3725 int writingp = SCM_WRITINGP (pstate);
b7f3516f 3726 scm_puts ("#<promise ", port);
19402679
MD
3727 SCM_SET_WRITINGP (pstate, 1);
3728 scm_iprin1 (SCM_CDR (exp), port, pstate);
3729 SCM_SET_WRITINGP (pstate, writingp);
b7f3516f 3730 scm_putc ('>', port);
0f2d19dd
JB
3731 return !0;
3732}
3733
3734
3b3b36dd 3735SCM_DEFINE (scm_force, "force", 1, 0, 0,
1bbd0b84 3736 (SCM x),
445f675c
DH
3737 "If the promise X has not been computed yet, compute and return\n"
3738 "X, otherwise just return the previously computed value.")
1bbd0b84 3739#define FUNC_NAME s_scm_force
0f2d19dd 3740{
445f675c
DH
3741 SCM_VALIDATE_SMOB (1, x, promise);
3742 if (!((1L << 16) & SCM_CELL_WORD_0 (x)))
0f2d19dd 3743 {
445f675c
DH
3744 SCM ans = scm_apply (SCM_CELL_OBJECT_1 (x), SCM_EOL, SCM_EOL);
3745 if (!((1L << 16) & SCM_CELL_WORD_0 (x)))
0f2d19dd
JB
3746 {
3747 SCM_DEFER_INTS;
445f675c
DH
3748 SCM_SET_CELL_OBJECT_1 (x, ans);
3749 SCM_SET_CELL_WORD_0 (x, SCM_CELL_WORD_0 (x) | (1L << 16));
0f2d19dd
JB
3750 SCM_ALLOW_INTS;
3751 }
3752 }
445f675c 3753 return SCM_CELL_OBJECT_1 (x);
0f2d19dd 3754}
1bbd0b84 3755#undef FUNC_NAME
0f2d19dd 3756
445f675c 3757
a1ec6916 3758SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
1bbd0b84 3759 (SCM x),
b380b885
MD
3760 "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
3761 "(@pxref{Delayed evaluation,,,r4rs.info,The Revised^4 Report on Scheme}).")
1bbd0b84 3762#define FUNC_NAME s_scm_promise_p
0f2d19dd 3763{
445f675c 3764 return SCM_BOOL (SCM_SMOB_PREDICATE (scm_tc16_promise, x));
0f2d19dd 3765}
1bbd0b84 3766#undef FUNC_NAME
0f2d19dd 3767
445f675c 3768
a1ec6916 3769SCM_DEFINE (scm_cons_source, "cons-source", 3, 0, 0,
1bbd0b84 3770 (SCM xorig, SCM x, SCM y),
b380b885 3771 "")
1bbd0b84 3772#define FUNC_NAME s_scm_cons_source
26d5b9b4
MD
3773{
3774 SCM p, z;
3775 SCM_NEWCELL (z);
445f675c
DH
3776 SCM_SET_CELL_OBJECT_0 (z, x);
3777 SCM_SET_CELL_OBJECT_1 (z, y);
26d5b9b4
MD
3778 /* Copy source properties possibly associated with xorig. */
3779 p = scm_whash_lookup (scm_source_whash, xorig);
445f675c 3780 if (!SCM_IMP (p))
26d5b9b4
MD
3781 scm_whash_insert (scm_source_whash, z, p);
3782 return z;
3783}
1bbd0b84 3784#undef FUNC_NAME
26d5b9b4 3785
445f675c 3786
a1ec6916 3787SCM_DEFINE (scm_copy_tree, "copy-tree", 1, 0, 0,
1bbd0b84 3788 (SCM obj),
b380b885
MD
3789 "Recursively copy the data tree that is bound to @var{obj}, and return a\n"
3790 "pointer to the new data structure. @code{copy-tree} recurses down the\n"
3791 "contents of both pairs and vectors (since both cons cells and vector\n"
3792 "cells may point to arbitrary objects), and stops recursing when it hits\n"
3793 "any other object.")
1bbd0b84 3794#define FUNC_NAME s_scm_copy_tree
0f2d19dd
JB
3795{
3796 SCM ans, tl;
26d5b9b4 3797 if (SCM_IMP (obj))
ff467021 3798 return obj;
3910272e
MD
3799 if (SCM_VECTORP (obj))
3800 {
3801 scm_sizet i = SCM_LENGTH (obj);
3802 ans = scm_make_vector (SCM_MAKINUM (i), SCM_UNSPECIFIED);
3803 while (i--)
3804 SCM_VELTS (ans)[i] = scm_copy_tree (SCM_VELTS (obj)[i]);
3805 return ans;
3806 }
ff467021 3807 if (SCM_NCONSP (obj))
0f2d19dd
JB
3808 return obj;
3809/* return scm_cons(scm_copy_tree(SCM_CAR(obj)), scm_copy_tree(SCM_CDR(obj))); */
26d5b9b4
MD
3810 ans = tl = scm_cons_source (obj,
3811 scm_copy_tree (SCM_CAR (obj)),
3812 SCM_UNSPECIFIED);
cabe682c 3813 while (obj = SCM_CDR (obj), SCM_CONSP (obj))
a23afe53
MD
3814 {
3815 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
3816 SCM_UNSPECIFIED));
3817 tl = SCM_CDR (tl);
3818 }
3819 SCM_SETCDR (tl, obj);
0f2d19dd
JB
3820 return ans;
3821}
1bbd0b84 3822#undef FUNC_NAME
0f2d19dd 3823
1cc91f1b 3824
0f2d19dd 3825SCM
1bbd0b84 3826scm_eval_3 (SCM obj, int copyp, SCM env)
0f2d19dd
JB
3827{
3828 if (SCM_NIMP (SCM_CDR (scm_system_transformer)))
3829 obj = scm_apply (SCM_CDR (scm_system_transformer), obj, scm_listofnull);
3830 else if (copyp)
3831 obj = scm_copy_tree (obj);
6cb702da 3832 return SCM_XEVAL (obj, env);
0f2d19dd
JB
3833}
3834
3b3b36dd 3835SCM_DEFINE (scm_eval2, "eval2", 2, 0, 0,
1bbd0b84 3836 (SCM obj, SCM env_thunk),
b380b885
MD
3837 "Evaluate @var{exp}, a Scheme expression, in the environment designated\n"
3838 "by @var{lookup}, a symbol-lookup function. @code{(eval exp)} is\n"
3839 "equivalent to @code{(eval2 exp *top-level-lookup-closure*)}.")
1bbd0b84 3840#define FUNC_NAME s_scm_eval2
0f2d19dd 3841{
6bcb0868 3842 return scm_eval_3 (obj, 1, scm_top_level_env (env_thunk));
0f2d19dd 3843}
1bbd0b84 3844#undef FUNC_NAME
0f2d19dd 3845
3b3b36dd 3846SCM_DEFINE (scm_eval, "eval", 1, 0, 0,
1bbd0b84 3847 (SCM obj),
b380b885
MD
3848 "Evaluate @var{exp}, a list representing a Scheme expression, in the\n"
3849 "top-level environment.")
1bbd0b84 3850#define FUNC_NAME s_scm_eval
0f2d19dd 3851{
6bcb0868
MD
3852 return scm_eval_3 (obj,
3853 1,
3854 scm_top_level_env
3855 (SCM_CDR (scm_top_level_lookup_closure_var)));
0f2d19dd 3856}
1bbd0b84 3857#undef FUNC_NAME
0f2d19dd 3858
1bbd0b84
GB
3859/*
3860SCM_REGISTER_PROC(s_eval_x, "eval!", 1, 0, 0, scm_eval_x);
3861*/
1cc91f1b 3862
0f2d19dd 3863SCM
1bbd0b84 3864scm_eval_x (SCM obj)
0f2d19dd 3865{
6bcb0868
MD
3866 return scm_eval_3 (obj,
3867 0,
3868 scm_top_level_env
3869 (SCM_CDR (scm_top_level_lookup_closure_var)));
0f2d19dd
JB
3870}
3871
6dbd0af5
MD
3872
3873/* At this point, scm_deval and scm_dapply are generated.
3874 */
3875
0f2d19dd 3876#ifdef DEBUG_EXTENSIONS
6dbd0af5
MD
3877# define DEVAL
3878# include "eval.c"
0f2d19dd
JB
3879#endif
3880
3881
1cc91f1b 3882
0f2d19dd
JB
3883void
3884scm_init_eval ()
0f2d19dd 3885{
33b97402
MD
3886 scm_init_opts (scm_evaluator_traps,
3887 scm_evaluator_trap_table,
3888 SCM_N_EVALUATOR_TRAPS);
3889 scm_init_opts (scm_eval_options_interface,
3890 scm_eval_opts,
3891 SCM_N_EVAL_OPTIONS);
3892
f99c9c28
MD
3893 scm_tc16_promise = scm_make_smob_type ("promise", 0);
3894 scm_set_smob_mark (scm_tc16_promise, scm_markcdr);
3895 scm_set_smob_print (scm_tc16_promise, prinprom);
b8229a3b 3896
81123e6d 3897 scm_f_apply = scm_make_subr ("apply", scm_tc7_lsubr_2, scm_apply);
0f2d19dd 3898 scm_system_transformer = scm_sysintern ("scm:eval-transformer", SCM_UNDEFINED);
2f0d1375
MD
3899 scm_sym_dot = SCM_CAR (scm_sysintern (".", SCM_UNDEFINED));
3900 scm_sym_arrow = SCM_CAR (scm_sysintern ("=>", SCM_UNDEFINED));
3901 scm_sym_else = SCM_CAR (scm_sysintern ("else", SCM_UNDEFINED));
3902 scm_sym_unquote = SCM_CAR (scm_sysintern ("unquote", SCM_UNDEFINED));
3903 scm_sym_uq_splicing = SCM_CAR (scm_sysintern ("unquote-splicing", SCM_UNDEFINED));
0f2d19dd 3904
43a912cf
MD
3905 scm_lisp_nil = scm_sysintern ("nil", SCM_UNDEFINED);
3906 SCM_SETCDR (scm_lisp_nil, SCM_CAR (scm_lisp_nil));
3907 scm_lisp_nil = SCM_CAR (scm_lisp_nil);
3908 scm_lisp_t = scm_sysintern ("t", SCM_UNDEFINED);
3909 SCM_SETCDR (scm_lisp_t, SCM_CAR (scm_lisp_t));
3910 scm_lisp_t = SCM_CAR (scm_lisp_t);
73b64342 3911
0f2d19dd 3912 /* acros */
0f2d19dd
JB
3913 /* end of acros */
3914
dc19d1d2
JB
3915 scm_top_level_lookup_closure_var =
3916 scm_sysintern("*top-level-lookup-closure*", SCM_BOOL_F);
9b8d3288 3917 scm_can_use_top_level_lookup_closure_var = 1;
0f2d19dd 3918
6dbd0af5 3919#ifdef DEBUG_EXTENSIONS
2f0d1375
MD
3920 scm_sym_enter_frame = SCM_CAR (scm_sysintern ("enter-frame", SCM_UNDEFINED));
3921 scm_sym_apply_frame = SCM_CAR (scm_sysintern ("apply-frame", SCM_UNDEFINED));
3922 scm_sym_exit_frame = SCM_CAR (scm_sysintern ("exit-frame", SCM_UNDEFINED));
3923 scm_sym_trace = SCM_CAR (scm_sysintern ("trace", SCM_UNDEFINED));
6dbd0af5
MD
3924#endif
3925
a0599745 3926#include "libguile/eval.x"
25eaf21a
MD
3927
3928 scm_add_feature ("delay");
0f2d19dd 3929}
0f2d19dd 3930
6dbd0af5 3931#endif /* !DEVAL */
89e00824
ML
3932
3933/*
3934 Local Variables:
3935 c-file-style: "gnu"
3936 End:
3937*/