* Deprecated some unused SCM_NxxxP macros.
[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 {
cf498326 276 if (SCM_TRUE_P (scm_procedure_p (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;
326 if (SCM_NIMP(env))
327 {
328 top_thunk = SCM_CAR(env); /* env now refers to a top level env thunk */
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)
f1267706 1253 || (int) (SCM_UNPACK_CAR (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
1509
1510\f
6dbd0af5 1511SCM
6e8d25a6 1512scm_eval_args (SCM l, SCM env, SCM proc)
6dbd0af5 1513{
680ed4a8 1514 SCM results = SCM_EOL, *lloc = &results, res;
6dbd0af5
MD
1515 while (SCM_NIMP (l))
1516 {
cf7c17e9 1517#ifdef SCM_CAUTIOUS
44d3cb0d 1518 if (SCM_CONSP (l))
680ed4a8
MD
1519 {
1520 if (SCM_IMP (SCM_CAR (l)))
6cb702da 1521 res = SCM_EVALIM (SCM_CAR (l), env);
680ed4a8
MD
1522 else
1523 res = EVALCELLCAR (l, env);
1524 }
3201d763 1525 else if (SCM_TYP3 (l) == scm_tc3_cons_gloc)
680ed4a8 1526 {
3201d763
DH
1527 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (l) [scm_vtable_index_vcell];
1528 if (vcell == 0)
680ed4a8 1529 res = SCM_CAR (l); /* struct planted in code */
3201d763
DH
1530 else
1531 res = SCM_PACK (vcell);
680ed4a8
MD
1532 }
1533 else
1534 goto wrongnumargs;
1535#else
1536 res = EVALCAR (l, env);
1537#endif
1538 *lloc = scm_cons (res, SCM_EOL);
a23afe53 1539 lloc = SCM_CDRLOC (*lloc);
6dbd0af5
MD
1540 l = SCM_CDR (l);
1541 }
cf7c17e9 1542#ifdef SCM_CAUTIOUS
680ed4a8
MD
1543 if (SCM_NNULLP (l))
1544 {
1545 wrongnumargs:
1546 scm_wrong_num_args (proc);
1547 }
1548#endif
1549 return results;
6dbd0af5 1550}
c4ac4d88 1551
9de33deb
MD
1552SCM
1553scm_eval_body (SCM code, SCM env)
1554{
1555 SCM next;
1556 again:
1557 next = code;
1558 while (SCM_NNULLP (next = SCM_CDR (next)))
1559 {
1560 if (SCM_IMP (SCM_CAR (code)))
1561 {
1562 if (SCM_ISYMP (SCM_CAR (code)))
1563 {
1564 code = scm_m_expand_body (code, env);
1565 goto again;
1566 }
1567 }
1568 else
1569 SCM_XEVAL (SCM_CAR (code), env);
1570 code = next;
1571 }
1572 return SCM_XEVALCAR (code, env);
1573}
1574
c4ac4d88 1575
0f2d19dd
JB
1576#endif /* !DEVAL */
1577
6dbd0af5
MD
1578
1579/* SECTION: This code is specific for the debugging support. One
1580 * branch is read when DEVAL isn't defined, the other when DEVAL is
1581 * defined.
1582 */
1583
1584#ifndef DEVAL
1585
1586#define SCM_APPLY scm_apply
1587#define PREP_APPLY(proc, args)
1588#define ENTER_APPLY
1589#define RETURN(x) return x;
b7ff98dd
MD
1590#ifdef STACK_CHECKING
1591#ifndef NO_CEVAL_STACK_CHECKING
1592#define EVAL_STACK_CHECKING
1593#endif
6dbd0af5
MD
1594#endif
1595
1596#else /* !DEVAL */
1597
0f2d19dd
JB
1598#undef SCM_CEVAL
1599#define SCM_CEVAL scm_deval /* Substitute all uses of scm_ceval */
1600#undef SCM_APPLY
1601#define SCM_APPLY scm_dapply
6dbd0af5
MD
1602#undef PREP_APPLY
1603#define PREP_APPLY(p, l) \
1604{ ++debug.info; debug.info->a.proc = p; debug.info->a.args = l; }
1605#undef ENTER_APPLY
1606#define ENTER_APPLY \
d3a6bc94 1607do { \
b7ff98dd 1608 SCM_SET_ARGSREADY (debug);\
b6d75948 1609 if (CHECK_APPLY && SCM_TRAPS_P)\
b7ff98dd 1610 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && PROCTRACEP (proc)))\
6dbd0af5 1611 {\
156dcb09 1612 SCM tmp, tail = SCM_BOOL(SCM_TRACED_FRAME_P (debug)); \
c6a4fbce 1613 SCM_SET_TRACED_FRAME (debug); \
b7ff98dd 1614 if (SCM_CHEAPTRAPS_P)\
6dbd0af5 1615 {\
c0ab1b8d 1616 tmp = scm_make_debugobj (&debug);\
2f0d1375 1617 scm_ithrow (scm_sym_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
b6d75948 1618 }\
6dbd0af5
MD
1619 else\
1620 {\
1621 scm_make_cont (&tmp);\
ca6ef71a 1622 if (!setjmp (SCM_JMPBUF (tmp)))\
2f0d1375 1623 scm_ithrow (scm_sym_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
6dbd0af5
MD
1624 }\
1625 }\
d3a6bc94 1626} while (0)
0f2d19dd
JB
1627#undef RETURN
1628#define RETURN(e) {proc = (e); goto exit;}
b7ff98dd
MD
1629#ifdef STACK_CHECKING
1630#ifndef EVAL_STACK_CHECKING
1631#define EVAL_STACK_CHECKING
1632#endif
6dbd0af5
MD
1633#endif
1634
1635/* scm_ceval_ptr points to the currently selected evaluator.
1636 * *fixme*: Although efficiency is important here, this state variable
1637 * should probably not be a global. It should be related to the
1638 * current repl.
1639 */
1640
1cc91f1b 1641
1bbd0b84 1642SCM (*scm_ceval_ptr) (SCM x, SCM env);
0f2d19dd 1643
1646d37b 1644/* scm_last_debug_frame contains a pointer to the last debugging
6dbd0af5
MD
1645 * information stack frame. It is accessed very often from the
1646 * debugging evaluator, so it should probably not be indirectly
1647 * addressed. Better to save and restore it from the current root at
1648 * any stack swaps.
1649 */
1650
1646d37b
MD
1651#ifndef USE_THREADS
1652scm_debug_frame *scm_last_debug_frame;
1653#endif
6dbd0af5
MD
1654
1655/* scm_debug_eframe_size is the number of slots available for pseudo
1656 * stack frames at each real stack frame.
1657 */
1658
1659int scm_debug_eframe_size;
1660
b7ff98dd 1661int scm_debug_mode, scm_check_entry_p, scm_check_apply_p, scm_check_exit_p;
6dbd0af5 1662
a74145b8
MD
1663int scm_eval_stack;
1664
33b97402 1665scm_option scm_eval_opts[] = {
a74145b8 1666 { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." }
33b97402
MD
1667};
1668
6dbd0af5 1669scm_option scm_debug_opts[] = {
b7ff98dd
MD
1670 { SCM_OPTION_BOOLEAN, "cheap", 1,
1671 "*Flyweight representation of the stack at traps." },
1672 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
1673 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
1674 { SCM_OPTION_BOOLEAN, "procnames", 1,
1675 "Record procedure names at definition." },
1676 { SCM_OPTION_BOOLEAN, "backwards", 0,
1677 "Display backtrace in anti-chronological order." },
274dc5fd 1678 { SCM_OPTION_INTEGER, "width", 79, "Maximal width of backtrace." },
4e646a03
MD
1679 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
1680 { SCM_OPTION_INTEGER, "frames", 3,
b7ff98dd 1681 "Maximum number of tail-recursive frames in backtrace." },
4e646a03
MD
1682 { SCM_OPTION_INTEGER, "maxdepth", 1000,
1683 "Maximal number of stored backtrace frames." },
1684 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
11f77bfc
MD
1685 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
1686 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
a74145b8 1687 { SCM_OPTION_INTEGER, "stack", 20000, "Stack size limit (measured in words; 0 = no check)." }
6dbd0af5
MD
1688};
1689
1690scm_option scm_evaluator_trap_table[] = {
b6d75948 1691 { SCM_OPTION_BOOLEAN, "traps", 0, "Enable evaluator traps." },
b7ff98dd
MD
1692 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
1693 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
1694 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." }
6dbd0af5
MD
1695};
1696
a1ec6916 1697SCM_DEFINE (scm_eval_options_interface, "eval-options-interface", 0, 1, 0,
1bbd0b84 1698 (SCM setting),
b380b885 1699 "")
1bbd0b84 1700#define FUNC_NAME s_scm_eval_options_interface
33b97402
MD
1701{
1702 SCM ans;
1703 SCM_DEFER_INTS;
1704 ans = scm_options (setting,
1705 scm_eval_opts,
1706 SCM_N_EVAL_OPTIONS,
1bbd0b84 1707 FUNC_NAME);
a74145b8 1708 scm_eval_stack = SCM_EVAL_STACK * sizeof (void *);
33b97402
MD
1709 SCM_ALLOW_INTS;
1710 return ans;
1711}
1bbd0b84 1712#undef FUNC_NAME
33b97402 1713
a1ec6916 1714SCM_DEFINE (scm_evaluator_traps, "evaluator-traps-interface", 0, 1, 0,
1bbd0b84 1715 (SCM setting),
b380b885 1716 "")
1bbd0b84 1717#define FUNC_NAME s_scm_evaluator_traps
33b97402
MD
1718{
1719 SCM ans;
1720 SCM_DEFER_INTS;
1721 ans = scm_options (setting,
1722 scm_evaluator_trap_table,
1723 SCM_N_EVALUATOR_TRAPS,
1bbd0b84 1724 FUNC_NAME);
33b97402 1725 SCM_RESET_DEBUG_MODE;
bfc69694 1726 SCM_ALLOW_INTS;
33b97402
MD
1727 return ans;
1728}
1bbd0b84 1729#undef FUNC_NAME
33b97402 1730
6dbd0af5 1731SCM
6e8d25a6 1732scm_deval_args (SCM l, SCM env, SCM proc, SCM *lloc)
0f2d19dd 1733{
680ed4a8 1734 SCM *results = lloc, res;
0f2d19dd
JB
1735 while (SCM_NIMP (l))
1736 {
cf7c17e9 1737#ifdef SCM_CAUTIOUS
44d3cb0d 1738 if (SCM_CONSP (l))
680ed4a8
MD
1739 {
1740 if (SCM_IMP (SCM_CAR (l)))
6cb702da 1741 res = SCM_EVALIM (SCM_CAR (l), env);
680ed4a8
MD
1742 else
1743 res = EVALCELLCAR (l, env);
1744 }
3201d763 1745 else if (SCM_TYP3 (l) == scm_tc3_cons_gloc)
680ed4a8 1746 {
3201d763
DH
1747 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (l) [scm_vtable_index_vcell];
1748 if (vcell == 0)
680ed4a8 1749 res = SCM_CAR (l); /* struct planted in code */
3201d763
DH
1750 else
1751 res = SCM_PACK (vcell);
680ed4a8
MD
1752 }
1753 else
1754 goto wrongnumargs;
1755#else
1756 res = EVALCAR (l, env);
1757#endif
1758 *lloc = scm_cons (res, SCM_EOL);
a23afe53 1759 lloc = SCM_CDRLOC (*lloc);
0f2d19dd
JB
1760 l = SCM_CDR (l);
1761 }
cf7c17e9 1762#ifdef SCM_CAUTIOUS
680ed4a8
MD
1763 if (SCM_NNULLP (l))
1764 {
1765 wrongnumargs:
1766 scm_wrong_num_args (proc);
1767 }
1768#endif
1769 return *results;
0f2d19dd
JB
1770}
1771
6dbd0af5
MD
1772#endif /* !DEVAL */
1773
1774
1775/* SECTION: Some local definitions for the evaluator.
1776 */
1777
1778#ifndef DEVAL
3201d763 1779#define CHECK_EQVISH(A,B) (SCM_EQ_P ((A), (B)) || (SCM_NFALSEP (scm_eqv_p ((A), (B)))))
6dbd0af5
MD
1780#endif /* DEVAL */
1781
399dedcc 1782#define BUILTIN_RPASUBR /* Handle rpsubrs and asubrs without calling apply */
6dbd0af5
MD
1783
1784/* SECTION: This is the evaluator. Like any real monster, it has
1785 * three heads. This code is compiled twice.
1786 */
1787
0f2d19dd 1788#if 0
1cc91f1b 1789
0f2d19dd 1790SCM
1bbd0b84 1791scm_ceval (SCM x, SCM env)
0f2d19dd
JB
1792{}
1793#endif
1794#if 0
1cc91f1b 1795
0f2d19dd 1796SCM
1bbd0b84 1797scm_deval (SCM x, SCM env)
0f2d19dd
JB
1798{}
1799#endif
1800
6dbd0af5 1801SCM
1bbd0b84 1802SCM_CEVAL (SCM x, SCM env)
0f2d19dd
JB
1803{
1804 union
1805 {
1806 SCM *lloc;
1807 SCM arg1;
f8769b1d 1808 } t;
6dbd0af5
MD
1809 SCM proc, arg2;
1810#ifdef DEVAL
c0ab1b8d
JB
1811 scm_debug_frame debug;
1812 scm_debug_info *debug_info_end;
1646d37b 1813 debug.prev = scm_last_debug_frame;
6dbd0af5 1814 debug.status = scm_debug_eframe_size;
04b6c081
MD
1815 /*
1816 * The debug.vect contains twice as much scm_debug_info frames as the
1817 * user has specified with (debug-set! frames <n>).
1818 *
1819 * Even frames are eval frames, odd frames are apply frames.
1820 */
c0ab1b8d
JB
1821 debug.vect = (scm_debug_info *) alloca (scm_debug_eframe_size
1822 * sizeof (debug.vect[0]));
1823 debug.info = debug.vect;
1824 debug_info_end = debug.vect + scm_debug_eframe_size;
1825 scm_last_debug_frame = &debug;
6dbd0af5 1826#endif
b7ff98dd 1827#ifdef EVAL_STACK_CHECKING
6f13f9cb
MD
1828 if (scm_stack_checking_enabled_p
1829 && SCM_STACK_OVERFLOW_P ((SCM_STACKITEM *) &proc))
6dbd0af5 1830 {
b7ff98dd 1831#ifdef DEVAL
6dbd0af5
MD
1832 debug.info->e.exp = x;
1833 debug.info->e.env = env;
b7ff98dd 1834#endif
6dbd0af5
MD
1835 scm_report_stack_overflow ();
1836 }
1837#endif
1838#ifdef DEVAL
1839 goto start;
1840#endif
1841loopnoap:
1842 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1843loop:
1844#ifdef DEVAL
b7ff98dd
MD
1845 SCM_CLEAR_ARGSREADY (debug);
1846 if (SCM_OVERFLOWP (debug))
6dbd0af5 1847 --debug.info;
04b6c081
MD
1848 /*
1849 * In theory, this should be the only place where it is necessary to
1850 * check for space in debug.vect since both eval frames and
1851 * available space are even.
1852 *
1853 * For this to be the case, however, it is necessary that primitive
1854 * special forms which jump back to `loop', `begin' or some similar
1855 * label call PREP_APPLY. A convenient way to do this is to jump to
1856 * `loopnoap' or `cdrxnoap'.
1857 */
c0ab1b8d 1858 else if (++debug.info >= debug_info_end)
6dbd0af5 1859 {
b7ff98dd 1860 SCM_SET_OVERFLOW (debug);
6dbd0af5
MD
1861 debug.info -= 2;
1862 }
1863start:
1864 debug.info->e.exp = x;
1865 debug.info->e.env = env;
b6d75948 1866 if (CHECK_ENTRY && SCM_TRAPS_P)
b7ff98dd 1867 if (SCM_ENTER_FRAME_P || (SCM_BREAKPOINTS_P && SRCBRKP (x)))
6dbd0af5 1868 {
156dcb09 1869 SCM tail = SCM_BOOL(SCM_TAILRECP (debug));
b7ff98dd 1870 SCM_SET_TAILREC (debug);
b7ff98dd 1871 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 1872 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
1873 else
1874 {
1875 scm_make_cont (&t.arg1);
ca6ef71a 1876 if (setjmp (SCM_JMPBUF (t.arg1)))
6dbd0af5
MD
1877 {
1878 x = SCM_THROW_VALUE (t.arg1);
1879 if (SCM_IMP (x))
1880 {
1881 RETURN (x);
1882 }
1883 else
1884 /* This gives the possibility for the debugger to
1885 modify the source expression before evaluation. */
1886 goto dispatch;
1887 }
1888 }
2f0d1375 1889 scm_ithrow (scm_sym_enter_frame,
6dbd0af5
MD
1890 scm_cons2 (t.arg1, tail,
1891 scm_cons (scm_unmemocopy (x, env), SCM_EOL)),
1892 0);
1893 }
6dbd0af5 1894#endif
e3173f93 1895#if defined (USE_THREADS) || defined (DEVAL)
f8769b1d 1896dispatch:
e3173f93 1897#endif
9cb5124f 1898 SCM_TICK;
0f2d19dd
JB
1899 switch (SCM_TYP7 (x))
1900 {
1901 case scm_tcs_symbols:
1902 /* Only happens when called at top level.
1903 */
1904 x = scm_cons (x, SCM_UNDEFINED);
1905 goto retval;
1906
c209c88e 1907 case SCM_BIT8(SCM_IM_AND):
0f2d19dd
JB
1908 x = SCM_CDR (x);
1909 t.arg1 = x;
1910 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1911 if (SCM_FALSEP (EVALCAR (x, env)))
1912 {
1913 RETURN (SCM_BOOL_F);
1914 }
1915 else
1916 x = t.arg1;
6dbd0af5 1917 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1918 goto carloop;
1919
c209c88e 1920 case SCM_BIT8(SCM_IM_BEGIN):
6dbd0af5
MD
1921 cdrxnoap:
1922 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1923 cdrxbegin:
1924 x = SCM_CDR (x);
1925
1926 begin:
1927 t.arg1 = x;
1928 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1929 {
26d5b9b4
MD
1930 if (SCM_IMP (SCM_CAR (x)))
1931 {
1932 if (SCM_ISYMP (SCM_CAR (x)))
1933 {
1934 x = scm_m_expand_body (x, env);
1935 goto begin;
1936 }
1937 }
1938 else
1939 SCM_CEVAL (SCM_CAR (x), env);
0f2d19dd
JB
1940 x = t.arg1;
1941 }
1942
1943 carloop: /* scm_eval car of last form in list */
1944 if (SCM_NCELLP (SCM_CAR (x)))
1945 {
1946 x = SCM_CAR (x);
6cb702da 1947 RETURN (SCM_IMP (x) ? SCM_EVALIM (x, env) : SCM_GLOC_VAL (x))
0f2d19dd
JB
1948 }
1949
1950 if (SCM_SYMBOLP (SCM_CAR (x)))
1951 {
1952 retval:
26d5b9b4 1953 RETURN (*scm_lookupcar (x, env, 1))
0f2d19dd
JB
1954 }
1955
1956 x = SCM_CAR (x);
1957 goto loop; /* tail recurse */
1958
1959
c209c88e 1960 case SCM_BIT8(SCM_IM_CASE):
0f2d19dd
JB
1961 x = SCM_CDR (x);
1962 t.arg1 = EVALCAR (x, env);
1963 while (SCM_NIMP (x = SCM_CDR (x)))
1964 {
1965 proc = SCM_CAR (x);
cf498326 1966 if (SCM_EQ_P (scm_sym_else, SCM_CAR (proc)))
0f2d19dd
JB
1967 {
1968 x = SCM_CDR (proc);
6dbd0af5 1969 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1970 goto begin;
1971 }
1972 proc = SCM_CAR (proc);
1973 while (SCM_NIMP (proc))
1974 {
1975 if (CHECK_EQVISH (SCM_CAR (proc), t.arg1))
1976 {
1977 x = SCM_CDR (SCM_CAR (x));
6dbd0af5 1978 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1979 goto begin;
1980 }
1981 proc = SCM_CDR (proc);
1982 }
1983 }
6dbd0af5 1984 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1985
1986
c209c88e 1987 case SCM_BIT8(SCM_IM_COND):
0f2d19dd
JB
1988 while (SCM_NIMP (x = SCM_CDR (x)))
1989 {
1990 proc = SCM_CAR (x);
1991 t.arg1 = EVALCAR (proc, env);
1992 if (SCM_NFALSEP (t.arg1))
1993 {
1994 x = SCM_CDR (proc);
6dbd0af5 1995 if SCM_NULLP (x)
0f2d19dd 1996 {
6dbd0af5 1997 RETURN (t.arg1)
0f2d19dd 1998 }
cf498326 1999 if (! SCM_EQ_P (scm_sym_arrow, SCM_CAR (x)))
6dbd0af5
MD
2000 {
2001 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2002 goto begin;
2003 }
0f2d19dd
JB
2004 proc = SCM_CDR (x);
2005 proc = EVALCAR (proc, env);
2006 SCM_ASRTGO (SCM_NIMP (proc), badfun);
6dbd0af5
MD
2007 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
2008 ENTER_APPLY;
0f2d19dd
JB
2009 goto evap1;
2010 }
2011 }
6dbd0af5 2012 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
2013
2014
c209c88e 2015 case SCM_BIT8(SCM_IM_DO):
0f2d19dd
JB
2016 x = SCM_CDR (x);
2017 proc = SCM_CAR (SCM_CDR (x)); /* inits */
2018 t.arg1 = SCM_EOL; /* values */
2019 while (SCM_NIMP (proc))
2020 {
2021 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
2022 proc = SCM_CDR (proc);
2023 }
e2806c10 2024 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
0f2d19dd
JB
2025 x = SCM_CDR (SCM_CDR (x));
2026 while (proc = SCM_CAR (x), SCM_FALSEP (EVALCAR (proc, env)))
2027 {
f3d2630a 2028 for (proc = SCM_CADR (x); SCM_NIMP (proc); proc = SCM_CDR (proc))
0f2d19dd
JB
2029 {
2030 t.arg1 = SCM_CAR (proc); /* body */
2031 SIDEVAL (t.arg1, env);
2032 }
f3d2630a
MD
2033 for (t.arg1 = SCM_EOL, proc = SCM_CDDR (x);
2034 SCM_NIMP (proc);
2035 proc = SCM_CDR (proc))
0f2d19dd 2036 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1); /* steps */
e2806c10 2037 env = EXTEND_ENV (SCM_CAR (SCM_CAR (env)), t.arg1, SCM_CDR (env));
0f2d19dd
JB
2038 }
2039 x = SCM_CDR (proc);
2040 if (SCM_NULLP (x))
6dbd0af5
MD
2041 RETURN (SCM_UNSPECIFIED);
2042 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2043 goto begin;
2044
2045
c209c88e 2046 case SCM_BIT8(SCM_IM_IF):
0f2d19dd
JB
2047 x = SCM_CDR (x);
2048 if (SCM_NFALSEP (EVALCAR (x, env)))
2049 x = SCM_CDR (x);
2050 else if (SCM_IMP (x = SCM_CDR (SCM_CDR (x))))
2051 {
2052 RETURN (SCM_UNSPECIFIED);
2053 }
6dbd0af5 2054 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2055 goto carloop;
2056
2057
c209c88e 2058 case SCM_BIT8(SCM_IM_LET):
0f2d19dd
JB
2059 x = SCM_CDR (x);
2060 proc = SCM_CAR (SCM_CDR (x));
2061 t.arg1 = SCM_EOL;
2062 do
2063 {
2064 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
2065 }
2066 while (SCM_NIMP (proc = SCM_CDR (proc)));
e2806c10 2067 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
0f2d19dd 2068 x = SCM_CDR (x);
6dbd0af5 2069 goto cdrxnoap;
0f2d19dd
JB
2070
2071
c209c88e 2072 case SCM_BIT8(SCM_IM_LETREC):
0f2d19dd 2073 x = SCM_CDR (x);
e2806c10 2074 env = EXTEND_ENV (SCM_CAR (x), scm_undefineds, env);
0f2d19dd
JB
2075 x = SCM_CDR (x);
2076 proc = SCM_CAR (x);
2077 t.arg1 = SCM_EOL;
2078 do
2079 {
2080 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
2081 }
2082 while (SCM_NIMP (proc = SCM_CDR (proc)));
a23afe53 2083 SCM_SETCDR (SCM_CAR (env), t.arg1);
6dbd0af5 2084 goto cdrxnoap;
0f2d19dd
JB
2085
2086
c209c88e 2087 case SCM_BIT8(SCM_IM_LETSTAR):
0f2d19dd
JB
2088 x = SCM_CDR (x);
2089 proc = SCM_CAR (x);
2090 if (SCM_IMP (proc))
2091 {
e2806c10 2092 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5 2093 goto cdrxnoap;
0f2d19dd
JB
2094 }
2095 do
2096 {
2097 t.arg1 = SCM_CAR (proc);
2098 proc = SCM_CDR (proc);
e2806c10 2099 env = EXTEND_ENV (t.arg1, EVALCAR (proc, env), env);
0f2d19dd
JB
2100 }
2101 while (SCM_NIMP (proc = SCM_CDR (proc)));
6dbd0af5 2102 goto cdrxnoap;
0f2d19dd 2103
c209c88e 2104 case SCM_BIT8(SCM_IM_OR):
0f2d19dd
JB
2105 x = SCM_CDR (x);
2106 t.arg1 = x;
2107 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
2108 {
2109 x = EVALCAR (x, env);
2110 if (SCM_NFALSEP (x))
2111 {
2112 RETURN (x);
2113 }
2114 x = t.arg1;
2115 }
6dbd0af5 2116 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2117 goto carloop;
2118
2119
c209c88e 2120 case SCM_BIT8(SCM_IM_LAMBDA):
0f2d19dd
JB
2121 RETURN (scm_closure (SCM_CDR (x), env));
2122
2123
c209c88e 2124 case SCM_BIT8(SCM_IM_QUOTE):
0f2d19dd
JB
2125 RETURN (SCM_CAR (SCM_CDR (x)));
2126
2127
c209c88e 2128 case SCM_BIT8(SCM_IM_SET_X):
0f2d19dd
JB
2129 x = SCM_CDR (x);
2130 proc = SCM_CAR (x);
3201d763 2131 switch (SCM_ITAG3 (proc))
0f2d19dd 2132 {
3201d763 2133 case scm_tc3_cons:
26d5b9b4 2134 t.lloc = scm_lookupcar (x, env, 1);
0f2d19dd 2135 break;
3201d763 2136 case scm_tc3_cons_gloc:
a23afe53 2137 t.lloc = SCM_GLOC_VAL_LOC (proc);
0f2d19dd
JB
2138 break;
2139#ifdef MEMOIZE_LOCALS
3201d763 2140 case scm_tc3_imm24:
0f2d19dd
JB
2141 t.lloc = scm_ilookup (proc, env);
2142 break;
2143#endif
2144 }
2145 x = SCM_CDR (x);
2146 *t.lloc = EVALCAR (x, env);
0f2d19dd
JB
2147#ifdef SICP
2148 RETURN (*t.lloc);
2149#else
2150 RETURN (SCM_UNSPECIFIED);
2151#endif
2152
2153
c209c88e 2154 case SCM_BIT8(SCM_IM_DEFINE): /* only for internal defines */
26d5b9b4
MD
2155 scm_misc_error (NULL, "Bad define placement", SCM_EOL);
2156
0f2d19dd 2157 /* new syntactic forms go here. */
c209c88e 2158 case SCM_BIT8(SCM_MAKISYM (0)):
0f2d19dd
JB
2159 proc = SCM_CAR (x);
2160 SCM_ASRTGO (SCM_ISYMP (proc), badfun);
2161 switch SCM_ISYMNUM (proc)
2162 {
2163#if 0
2164 case (SCM_ISYMNUM (IM_VREF)):
2165 {
2166 SCM var;
2167 var = SCM_CAR (SCM_CDR (x));
2168 RETURN (SCM_CDR(var));
2169 }
2170 case (SCM_ISYMNUM (IM_VSET)):
2171 SCM_CDR (SCM_CAR ( SCM_CDR (x))) = EVALCAR( SCM_CDR ( SCM_CDR (x)), env);
2172 SCM_CAR (SCM_CAR ( SCM_CDR (x))) = scm_tc16_variable;
6dbd0af5 2173 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
2174#endif
2175
2176 case (SCM_ISYMNUM (SCM_IM_APPLY)):
2177 proc = SCM_CDR (x);
2178 proc = EVALCAR (proc, env);
2179 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2180 if (SCM_CLOSUREP (proc))
2181 {
1609038c 2182 SCM argl, tl;
6dbd0af5 2183 PREP_APPLY (proc, SCM_EOL);
0f2d19dd
JB
2184 t.arg1 = SCM_CDR (SCM_CDR (x));
2185 t.arg1 = EVALCAR (t.arg1, env);
6dbd0af5
MD
2186#ifdef DEVAL
2187 debug.info->a.args = t.arg1;
2188#endif
cf7c17e9 2189#ifndef SCM_RECKLESS
0f2d19dd
JB
2190 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), t.arg1))
2191 goto wrongnumargs;
2192#endif
c79450dd 2193 ENTER_APPLY;
1609038c
MD
2194 /* Copy argument list */
2195 if (SCM_IMP (t.arg1))
2196 argl = t.arg1;
2197 else
2198 {
2199 argl = tl = scm_cons (SCM_CAR (t.arg1), SCM_UNSPECIFIED);
2200 while (SCM_NIMP (t.arg1 = SCM_CDR (t.arg1))
2201 && SCM_CONSP (t.arg1))
2202 {
2203 SCM_SETCDR (tl, scm_cons (SCM_CAR (t.arg1),
2204 SCM_UNSPECIFIED));
2205 tl = SCM_CDR (tl);
2206 }
2207 SCM_SETCDR (tl, t.arg1);
2208 }
2209
2210 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), argl, SCM_ENV (proc));
0f2d19dd
JB
2211 x = SCM_CODE (proc);
2212 goto cdrxbegin;
2213 }
81123e6d 2214 proc = scm_f_apply;
0f2d19dd
JB
2215 goto evapply;
2216
2217 case (SCM_ISYMNUM (SCM_IM_CONT)):
2218 scm_make_cont (&t.arg1);
ca6ef71a 2219 if (setjmp (SCM_JMPBUF (t.arg1)))
0f2d19dd
JB
2220 {
2221 SCM val;
2222 val = SCM_THROW_VALUE (t.arg1);
a570e93a 2223 RETURN (val)
0f2d19dd
JB
2224 }
2225 proc = SCM_CDR (x);
2226 proc = evalcar (proc, env);
2227 SCM_ASRTGO (SCM_NIMP (proc), badfun);
6dbd0af5
MD
2228 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
2229 ENTER_APPLY;
0f2d19dd
JB
2230 goto evap1;
2231
a570e93a
MD
2232 case (SCM_ISYMNUM (SCM_IM_DELAY)):
2233 RETURN (scm_makprom (scm_closure (SCM_CDR (x), env)))
2234
89efbff4 2235 case (SCM_ISYMNUM (SCM_IM_DISPATCH)):
195847fa
MD
2236 proc = SCM_CADR (x); /* unevaluated operands */
2237 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2238 if (SCM_IMP (proc))
2239 arg2 = *scm_ilookup (proc, env);
2240 else if (SCM_NCONSP (proc))
2241 {
2242 if (SCM_NCELLP (proc))
2243 arg2 = SCM_GLOC_VAL (proc);
2244 else
2245 arg2 = *scm_lookupcar (SCM_CDR (x), env, 1);
2246 }
2247 else
2248 {
2249 arg2 = scm_cons (EVALCAR (proc, env), SCM_EOL);
2250 t.lloc = SCM_CDRLOC (arg2);
2251 while (SCM_NIMP (proc = SCM_CDR (proc)))
2252 {
2253 *t.lloc = scm_cons (EVALCAR (proc, env), SCM_EOL);
2254 t.lloc = SCM_CDRLOC (*t.lloc);
2255 }
2256 }
2257
2258 type_dispatch:
61364ba6
MD
2259 /* The type dispatch code is duplicated here
2260 * (c.f. objects.c:scm_mcache_compute_cmethod) since that
2261 * cuts down execution time for type dispatch to 50%.
2262 */
2263 {
2264 int i, n, end, mask;
2265 SCM z = SCM_CDDR (x);
2266 n = SCM_INUM (SCM_CAR (z)); /* maximum number of specializers */
2267 proc = SCM_CADR (z);
2268
2269 if (SCM_NIMP (proc))
2270 {
2271 /* Prepare for linear search */
2272 mask = -1;
2273 i = 0;
2274 end = SCM_LENGTH (proc);
2275 }
2276 else
2277 {
2278 /* Compute a hash value */
2279 int hashset = SCM_INUM (proc);
2280 int j = n;
2281 mask = SCM_INUM (SCM_CAR (z = SCM_CDDR (z)));
2282 proc = SCM_CADR (z);
2283 i = 0;
2284 t.arg1 = arg2;
2285 if (SCM_NIMP (t.arg1))
2286 do
2287 {
d8c40b9f
DH
2288 i += SCM_STRUCT_DATA (scm_class_of (SCM_CAR (t.arg1)))
2289 [scm_si_hashsets + hashset];
61364ba6
MD
2290 t.arg1 = SCM_CDR (t.arg1);
2291 }
2292 while (--j && SCM_NIMP (t.arg1));
2293 i &= mask;
2294 end = i;
2295 }
2296
2297 /* Search for match */
2298 do
2299 {
2300 int j = n;
2301 z = SCM_VELTS (proc)[i];
2302 t.arg1 = arg2; /* list of arguments */
2303 if (SCM_NIMP (t.arg1))
2304 do
2305 {
2306 /* More arguments than specifiers => CLASS != ENV */
cf498326 2307 if (! SCM_EQ_P (scm_class_of (SCM_CAR (t.arg1)), SCM_CAR (z)))
61364ba6
MD
2308 goto next_method;
2309 t.arg1 = SCM_CDR (t.arg1);
2310 z = SCM_CDR (z);
2311 }
2312 while (--j && SCM_NIMP (t.arg1));
2313 /* Fewer arguments than specifiers => CAR != ENV */
2314 if (!(SCM_IMP (SCM_CAR (z)) || SCM_CONSP (SCM_CAR (z))))
2315 goto next_method;
2316 apply_cmethod:
2317 env = EXTEND_ENV (SCM_CAR (SCM_CMETHOD_CODE (z)),
2318 arg2,
2319 SCM_CMETHOD_ENV (z));
2320 x = SCM_CMETHOD_CODE (z);
2321 goto cdrxbegin;
2322 next_method:
2323 i = (i + 1) & mask;
2324 } while (i != end);
2325
2326 z = scm_memoize_method (x, arg2);
2327 goto apply_cmethod;
2328 }
73b64342 2329
ca4be6ea
MD
2330 case (SCM_ISYMNUM (SCM_IM_SLOT_REF)):
2331 x = SCM_CDR (x);
2332 t.arg1 = EVALCAR (x, env);
d8c40b9f 2333 RETURN (SCM_PACK (SCM_STRUCT_DATA (t.arg1) [SCM_INUM (SCM_CADR (x))]))
ca4be6ea
MD
2334
2335 case (SCM_ISYMNUM (SCM_IM_SLOT_SET_X)):
2336 x = SCM_CDR (x);
2337 t.arg1 = EVALCAR (x, env);
2338 x = SCM_CDR (x);
2339 proc = SCM_CDR (x);
d8c40b9f
DH
2340 SCM_STRUCT_DATA (t.arg1) [SCM_INUM (SCM_CAR (x))]
2341 = SCM_UNPACK (EVALCAR (proc, env));
5623a9b4 2342 RETURN (SCM_UNSPECIFIED)
ca4be6ea 2343
73b64342
MD
2344 case (SCM_ISYMNUM (SCM_IM_NIL_COND)):
2345 proc = SCM_CDR (x);
2346 while (SCM_NIMP (x = SCM_CDR (proc)))
2347 {
2348 if (!(SCM_FALSEP (t.arg1 = EVALCAR (proc, env))
3201d763 2349 || SCM_EQ_P (t.arg1, scm_lisp_nil)))
73b64342 2350 {
cf498326 2351 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
73b64342
MD
2352 RETURN (t.arg1);
2353 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2354 goto carloop;
2355 }
2356 proc = SCM_CDR (x);
2357 }
2358 x = proc;
2359 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2360 goto carloop;
2361
2362 case (SCM_ISYMNUM (SCM_IM_NIL_IFY)):
2363 x = SCM_CDR (x);
2364 RETURN ((SCM_FALSEP (proc = EVALCAR (x, env)) || SCM_NULLP (proc))
43a912cf 2365 ? scm_lisp_nil
73b64342
MD
2366 : proc)
2367
2368 case (SCM_ISYMNUM (SCM_IM_T_IFY)):
2369 x = SCM_CDR (x);
43a912cf 2370 RETURN (SCM_NFALSEP (EVALCAR (x, env)) ? scm_lisp_t : scm_lisp_nil)
73b64342
MD
2371
2372 case (SCM_ISYMNUM (SCM_IM_0_COND)):
2373 proc = SCM_CDR (x);
2374 while (SCM_NIMP (x = SCM_CDR (proc)))
2375 {
2376 if (!(SCM_FALSEP (t.arg1 = EVALCAR (proc, env))
3201d763 2377 || SCM_EQ_P (t.arg1, SCM_INUM0)))
73b64342 2378 {
cf498326 2379 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
73b64342
MD
2380 RETURN (t.arg1);
2381 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2382 goto carloop;
2383 }
2384 proc = SCM_CDR (x);
2385 }
2386 x = proc;
2387 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2388 goto carloop;
2389
2390 case (SCM_ISYMNUM (SCM_IM_0_IFY)):
2391 x = SCM_CDR (x);
2392 RETURN (SCM_FALSEP (proc = EVALCAR (x, env))
2393 ? SCM_INUM0
2394 : proc)
2395
2396 case (SCM_ISYMNUM (SCM_IM_1_IFY)):
2397 x = SCM_CDR (x);
2398 RETURN (SCM_NFALSEP (EVALCAR (x, env))
2399 ? SCM_MAKINUM (1)
2400 : SCM_INUM0)
2401
2402 case (SCM_ISYMNUM (SCM_IM_BIND)):
2403 x = SCM_CDR (x);
2404
2405 t.arg1 = SCM_CAR (x);
2406 arg2 = SCM_CDAR (env);
2407 while (SCM_NIMP (arg2))
2408 {
2409 proc = SCM_GLOC_VAL (SCM_CAR (t.arg1));
a963f787
MD
2410 SCM_SETCDR (SCM_PACK (SCM_UNPACK (SCM_CAR (t.arg1)) - 1L),
2411 SCM_CAR (arg2));
73b64342
MD
2412 SCM_SETCAR (arg2, proc);
2413 t.arg1 = SCM_CDR (t.arg1);
2414 arg2 = SCM_CDR (arg2);
2415 }
2416 t.arg1 = SCM_CAR (x);
2417 scm_dynwinds = scm_acons (t.arg1, SCM_CDAR (env), scm_dynwinds);
89efbff4 2418
73b64342
MD
2419 arg2 = x = SCM_CDR (x);
2420 while (SCM_NNULLP (arg2 = SCM_CDR (arg2)))
2421 {
2422 SIDEVAL (SCM_CAR (x), env);
2423 x = arg2;
2424 }
2425 proc = EVALCAR (x, env);
2426
2427 scm_dynwinds = SCM_CDR (scm_dynwinds);
2428 arg2 = SCM_CDAR (env);
2429 while (SCM_NIMP (arg2))
2430 {
a963f787
MD
2431 SCM_SETCDR (SCM_PACK (SCM_UNPACK (SCM_CAR (t.arg1)) - 1L),
2432 SCM_CAR (arg2));
73b64342
MD
2433 t.arg1 = SCM_CDR (t.arg1);
2434 arg2 = SCM_CDR (arg2);
2435 }
2436
2437 RETURN (proc)
2438
0f2d19dd
JB
2439 default:
2440 goto badfun;
2441 }
2442
2443 default:
2444 proc = x;
2445 badfun:
f5bf2977 2446 /* scm_everr (x, env,...) */
523f5266 2447 scm_misc_error (NULL,
70d63753 2448 "Wrong type to apply: ~S",
523f5266 2449 scm_listify (proc, SCM_UNDEFINED));
0f2d19dd
JB
2450 case scm_tc7_vector:
2451 case scm_tc7_wvect:
afe5177e 2452#ifdef HAVE_ARRAYS
0f2d19dd
JB
2453 case scm_tc7_bvect:
2454 case scm_tc7_byvect:
2455 case scm_tc7_svect:
2456 case scm_tc7_ivect:
2457 case scm_tc7_uvect:
2458 case scm_tc7_fvect:
2459 case scm_tc7_dvect:
2460 case scm_tc7_cvect:
5c11cc9d 2461#ifdef HAVE_LONG_LONGS
0f2d19dd 2462 case scm_tc7_llvect:
afe5177e 2463#endif
0f2d19dd
JB
2464#endif
2465 case scm_tc7_string:
0f2d19dd 2466 case scm_tc7_substring:
0f2d19dd
JB
2467 case scm_tc7_smob:
2468 case scm_tcs_closures:
224822be
MD
2469#ifdef CCLO
2470 case scm_tc7_cclo:
2471#endif
89efbff4 2472 case scm_tc7_pws:
0f2d19dd
JB
2473 case scm_tcs_subrs:
2474 RETURN (x);
2475
2476#ifdef MEMOIZE_LOCALS
c209c88e 2477 case SCM_BIT8(SCM_ILOC00):
0f2d19dd
JB
2478 proc = *scm_ilookup (SCM_CAR (x), env);
2479 SCM_ASRTGO (SCM_NIMP (proc), badfun);
cf7c17e9
JB
2480#ifndef SCM_RECKLESS
2481#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2482 goto checkargs;
2483#endif
2484#endif
2485 break;
2486#endif /* ifdef MEMOIZE_LOCALS */
2487
2488
3201d763
DH
2489 case scm_tcs_cons_gloc: {
2490 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2491 if (vcell == 0) {
aa00bd1e
MD
2492 /* This is a struct implanted in the code, not a gloc. */
2493 RETURN (x);
3201d763
DH
2494 } else {
2495 proc = SCM_PACK (vcell);
2496 SCM_ASRTGO (SCM_NIMP (proc), badfun);
cf7c17e9
JB
2497#ifndef SCM_RECKLESS
2498#ifdef SCM_CAUTIOUS
3201d763 2499 goto checkargs;
0f2d19dd
JB
2500#endif
2501#endif
3201d763 2502 }
0f2d19dd 2503 break;
3201d763 2504 }
0f2d19dd
JB
2505
2506 case scm_tcs_cons_nimcar:
2507 if (SCM_SYMBOLP (SCM_CAR (x)))
2508 {
f8769b1d 2509#ifdef USE_THREADS
26d5b9b4 2510 t.lloc = scm_lookupcar1 (x, env, 1);
f8769b1d
MV
2511 if (t.lloc == NULL)
2512 {
2513 /* we have lost the race, start again. */
2514 goto dispatch;
2515 }
2516 proc = *t.lloc;
2517#else
26d5b9b4 2518 proc = *scm_lookupcar (x, env, 1);
f8769b1d
MV
2519#endif
2520
0f2d19dd
JB
2521 if (SCM_IMP (proc))
2522 {
2523 unmemocar (x, env);
2524 goto badfun;
2525 }
2526 if (scm_tc16_macro == SCM_TYP16 (proc))
2527 {
2528 unmemocar (x, env);
2529
2530 handle_a_macro:
368bf056 2531#ifdef DEVAL
7c354052
MD
2532 /* Set a flag during macro expansion so that macro
2533 application frames can be deleted from the backtrace. */
2534 SCM_SET_MACROEXP (debug);
368bf056 2535#endif
f8769b1d
MV
2536 t.arg1 = SCM_APPLY (SCM_CDR (proc), x,
2537 scm_cons (env, scm_listofnull));
2538
7c354052
MD
2539#ifdef DEVAL
2540 SCM_CLEAR_MACROEXP (debug);
2541#endif
f1267706 2542 switch ((int) (SCM_UNPACK_CAR (proc) >> 16))
0f2d19dd
JB
2543 {
2544 case 2:
2545 if (scm_ilength (t.arg1) <= 0)
2546 t.arg1 = scm_cons2 (SCM_IM_BEGIN, t.arg1, SCM_EOL);
6dbd0af5
MD
2547#ifdef DEVAL
2548 if (!SCM_CLOSUREP (SCM_CDR (proc)))
2549 {
f8769b1d 2550
6dbd0af5
MD
2551#if 0 /* Top-level defines doesn't very often occur in backtraces */
2552 if (scm_m_define == SCM_SUBRF (SCM_CDR (proc)) && SCM_TOP_LEVEL (env))
2553 /* Prevent memoizing result of define macro */
2554 {
2555 debug.info->e.exp = scm_cons (SCM_CAR (x), SCM_CDR (x));
2556 scm_set_source_properties_x (debug.info->e.exp,
2557 scm_source_properties (x));
2558 }
2559#endif
2560 SCM_DEFER_INTS;
a23afe53
MD
2561 SCM_SETCAR (x, SCM_CAR (t.arg1));
2562 SCM_SETCDR (x, SCM_CDR (t.arg1));
6dbd0af5
MD
2563 SCM_ALLOW_INTS;
2564 goto dispatch;
2565 }
2566 /* Prevent memoizing of debug info expression. */
6203706f
MD
2567 debug.info->e.exp = scm_cons_source (debug.info->e.exp,
2568 SCM_CAR (x),
2569 SCM_CDR (x));
6dbd0af5 2570#endif
0f2d19dd 2571 SCM_DEFER_INTS;
a23afe53
MD
2572 SCM_SETCAR (x, SCM_CAR (t.arg1));
2573 SCM_SETCDR (x, SCM_CDR (t.arg1));
0f2d19dd 2574 SCM_ALLOW_INTS;
6dbd0af5 2575 goto loopnoap;
0f2d19dd
JB
2576 case 1:
2577 if (SCM_NIMP (x = t.arg1))
6dbd0af5 2578 goto loopnoap;
0f2d19dd
JB
2579 case 0:
2580 RETURN (t.arg1);
2581 }
2582 }
2583 }
2584 else
2585 proc = SCM_CEVAL (SCM_CAR (x), env);
2586 SCM_ASRTGO (SCM_NIMP (proc), badfun);
cf7c17e9
JB
2587#ifndef SCM_RECKLESS
2588#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2589 checkargs:
2590#endif
2591 if (SCM_CLOSUREP (proc))
2592 {
2593 arg2 = SCM_CAR (SCM_CODE (proc));
2594 t.arg1 = SCM_CDR (x);
2595 while (SCM_NIMP (arg2))
2596 {
2597 if (SCM_NCONSP (arg2))
2598 goto evapply;
2599 if (SCM_IMP (t.arg1))
2600 goto umwrongnumargs;
2601 arg2 = SCM_CDR (arg2);
2602 t.arg1 = SCM_CDR (t.arg1);
2603 }
2604 if (SCM_NNULLP (t.arg1))
2605 goto umwrongnumargs;
2606 }
2607 else if (scm_tc16_macro == SCM_TYP16 (proc))
2608 goto handle_a_macro;
2609#endif
2610 }
2611
2612
6dbd0af5
MD
2613evapply:
2614 PREP_APPLY (proc, SCM_EOL);
2615 if (SCM_NULLP (SCM_CDR (x))) {
2616 ENTER_APPLY;
89efbff4 2617 evap0:
0f2d19dd
JB
2618 switch (SCM_TYP7 (proc))
2619 { /* no arguments given */
2620 case scm_tc7_subr_0:
2621 RETURN (SCM_SUBRF (proc) ());
2622 case scm_tc7_subr_1o:
2623 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
2624 case scm_tc7_lsubr:
2625 RETURN (SCM_SUBRF (proc) (SCM_EOL));
2626 case scm_tc7_rpsubr:
2627 RETURN (SCM_BOOL_T);
2628 case scm_tc7_asubr:
2629 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
6dbd0af5 2630#ifdef CCLO
0f2d19dd
JB
2631 case scm_tc7_cclo:
2632 t.arg1 = proc;
2633 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2634#ifdef DEVAL
2635 debug.info->a.proc = proc;
2636 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2637#endif
0f2d19dd 2638 goto evap1;
6dbd0af5 2639#endif
89efbff4
MD
2640 case scm_tc7_pws:
2641 proc = SCM_PROCEDURE (proc);
2642#ifdef DEVAL
2643 debug.info->a.proc = proc;
2644#endif
2645 goto evap0;
0f2d19dd
JB
2646 case scm_tcs_closures:
2647 x = SCM_CODE (proc);
e2806c10 2648 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, SCM_ENV (proc));
0f2d19dd 2649 goto cdrxbegin;
da7f71d7 2650 case scm_tcs_cons_gloc:
195847fa
MD
2651 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2652 {
2653 x = SCM_ENTITY_PROCEDURE (proc);
2654 arg2 = SCM_EOL;
2655 goto type_dispatch;
2656 }
2657 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2658 goto badfun;
2659 else
da7f71d7 2660 {
195847fa
MD
2661 t.arg1 = proc;
2662 proc = (SCM_I_ENTITYP (proc)
2663 ? SCM_ENTITY_PROCEDURE (proc)
2664 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7 2665#ifdef DEVAL
195847fa
MD
2666 debug.info->a.proc = proc;
2667 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
da7f71d7 2668#endif
195847fa
MD
2669 if (SCM_NIMP (proc))
2670 goto evap1;
2671 else
2672 goto badfun;
da7f71d7 2673 }
0f2d19dd
JB
2674 case scm_tc7_contin:
2675 case scm_tc7_subr_1:
2676 case scm_tc7_subr_2:
2677 case scm_tc7_subr_2o:
2678 case scm_tc7_cxr:
2679 case scm_tc7_subr_3:
2680 case scm_tc7_lsubr_2:
2681 umwrongnumargs:
2682 unmemocar (x, env);
2683 wrongnumargs:
f5bf2977
GH
2684 /* scm_everr (x, env,...) */
2685 scm_wrong_num_args (proc);
0f2d19dd
JB
2686 default:
2687 /* handle macros here */
2688 goto badfun;
2689 }
6dbd0af5 2690 }
0f2d19dd
JB
2691
2692 /* must handle macros by here */
2693 x = SCM_CDR (x);
cf7c17e9 2694#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2695 if (SCM_IMP (x))
2696 goto wrongnumargs;
680ed4a8
MD
2697 else if (SCM_CONSP (x))
2698 {
2699 if (SCM_IMP (SCM_CAR (x)))
6cb702da 2700 t.arg1 = SCM_EVALIM (SCM_CAR (x), env);
680ed4a8
MD
2701 else
2702 t.arg1 = EVALCELLCAR (x, env);
2703 }
3201d763 2704 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
680ed4a8 2705 {
3201d763
DH
2706 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2707 if (vcell == 0)
680ed4a8 2708 t.arg1 = SCM_CAR (x); /* struct planted in code */
3201d763
DH
2709 else
2710 t.arg1 = SCM_PACK (vcell);
680ed4a8
MD
2711 }
2712 else
2713 goto wrongnumargs;
2714#else
0f2d19dd 2715 t.arg1 = EVALCAR (x, env);
680ed4a8 2716#endif
6dbd0af5
MD
2717#ifdef DEVAL
2718 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2719#endif
0f2d19dd
JB
2720 x = SCM_CDR (x);
2721 if (SCM_NULLP (x))
2722 {
6dbd0af5 2723 ENTER_APPLY;
0f2d19dd
JB
2724 evap1:
2725 switch (SCM_TYP7 (proc))
6dbd0af5 2726 { /* have one argument in t.arg1 */
0f2d19dd
JB
2727 case scm_tc7_subr_2o:
2728 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2729 case scm_tc7_subr_1:
2730 case scm_tc7_subr_1o:
2731 RETURN (SCM_SUBRF (proc) (t.arg1));
2732 case scm_tc7_cxr:
0f2d19dd
JB
2733 if (SCM_SUBRF (proc))
2734 {
2735 if (SCM_INUMP (t.arg1))
2736 {
f8de44c1 2737 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (t.arg1))));
0f2d19dd
JB
2738 }
2739 SCM_ASRTGO (SCM_NIMP (t.arg1), floerr);
2740 if (SCM_REALP (t.arg1))
2741 {
eb42e2f0 2742 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (t.arg1))));
0f2d19dd
JB
2743 }
2744#ifdef SCM_BIGDIG
2745 if (SCM_BIGP (t.arg1))
2746 {
f8de44c1 2747 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_big2dbl (t.arg1))));
0f2d19dd
JB
2748 }
2749#endif
2750 floerr:
9de33deb
MD
2751 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), t.arg1,
2752 SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
0f2d19dd 2753 }
3201d763 2754 proc = SCM_SNAME (proc);
0f2d19dd
JB
2755 {
2756 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
2757 while ('c' != *--chrs)
2758 {
0c95b57d 2759 SCM_ASSERT (SCM_CONSP (t.arg1),
0f2d19dd
JB
2760 t.arg1, SCM_ARG1, SCM_CHARS (proc));
2761 t.arg1 = ('a' == *chrs) ? SCM_CAR (t.arg1) : SCM_CDR (t.arg1);
2762 }
2763 RETURN (t.arg1);
2764 }
2765 case scm_tc7_rpsubr:
2766 RETURN (SCM_BOOL_T);
2767 case scm_tc7_asubr:
2768 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2769 case scm_tc7_lsubr:
2770#ifdef DEVAL
6dbd0af5 2771 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd
JB
2772#else
2773 RETURN (SCM_SUBRF (proc) (scm_cons (t.arg1, SCM_EOL)));
2774#endif
6dbd0af5 2775#ifdef CCLO
0f2d19dd
JB
2776 case scm_tc7_cclo:
2777 arg2 = t.arg1;
2778 t.arg1 = proc;
2779 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2780#ifdef DEVAL
2781 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2782 debug.info->a.proc = proc;
2783#endif
0f2d19dd 2784 goto evap2;
6dbd0af5 2785#endif
89efbff4
MD
2786 case scm_tc7_pws:
2787 proc = SCM_PROCEDURE (proc);
2788#ifdef DEVAL
2789 debug.info->a.proc = proc;
2790#endif
2791 goto evap1;
0f2d19dd 2792 case scm_tcs_closures:
195847fa 2793 /* clos1: */
0f2d19dd
JB
2794 x = SCM_CODE (proc);
2795#ifdef DEVAL
e2806c10 2796 env = EXTEND_ENV (SCM_CAR (x), debug.info->a.args, SCM_ENV (proc));
0f2d19dd 2797#else
e2806c10 2798 env = EXTEND_ENV (SCM_CAR (x), scm_cons (t.arg1, SCM_EOL), SCM_ENV (proc));
0f2d19dd
JB
2799#endif
2800 goto cdrxbegin;
65e41721
MD
2801 case scm_tc7_contin:
2802 scm_call_continuation (proc, t.arg1);
0c32d76c 2803 case scm_tcs_cons_gloc:
f3d2630a
MD
2804 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2805 {
195847fa 2806 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a
MD
2807#ifdef DEVAL
2808 arg2 = debug.info->a.args;
2809#else
2810 arg2 = scm_cons (t.arg1, SCM_EOL);
2811#endif
f3d2630a
MD
2812 goto type_dispatch;
2813 }
2814 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2815 goto badfun;
2816 else
0c32d76c 2817 {
195847fa
MD
2818 arg2 = t.arg1;
2819 t.arg1 = proc;
2820 proc = (SCM_I_ENTITYP (proc)
2821 ? SCM_ENTITY_PROCEDURE (proc)
2822 : SCM_OPERATOR_PROCEDURE (proc));
0c32d76c 2823#ifdef DEVAL
195847fa
MD
2824 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2825 debug.info->a.proc = proc;
0c32d76c 2826#endif
195847fa
MD
2827 if (SCM_NIMP (proc))
2828 goto evap2;
2829 else
2830 goto badfun;
0c32d76c 2831 }
0f2d19dd
JB
2832 case scm_tc7_subr_2:
2833 case scm_tc7_subr_0:
2834 case scm_tc7_subr_3:
2835 case scm_tc7_lsubr_2:
2836 goto wrongnumargs;
2837 default:
2838 goto badfun;
2839 }
2840 }
cf7c17e9 2841#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2842 if (SCM_IMP (x))
2843 goto wrongnumargs;
680ed4a8
MD
2844 else if (SCM_CONSP (x))
2845 {
2846 if (SCM_IMP (SCM_CAR (x)))
6cb702da 2847 arg2 = SCM_EVALIM (SCM_CAR (x), env);
680ed4a8
MD
2848 else
2849 arg2 = EVALCELLCAR (x, env);
2850 }
3201d763 2851 else if (SCM_TYP3 (x) == scm_tc3_cons_gloc)
680ed4a8 2852 {
3201d763
DH
2853 scm_bits_t vcell = SCM_STRUCT_VTABLE_DATA (x) [scm_vtable_index_vcell];
2854 if (vcell == 0)
680ed4a8 2855 arg2 = SCM_CAR (x); /* struct planted in code */
3201d763
DH
2856 else
2857 arg2 = SCM_PACK (vcell);
680ed4a8
MD
2858 }
2859 else
2860 goto wrongnumargs;
2861#else
2862 arg2 = EVALCAR (x, env);
0f2d19dd
JB
2863#endif
2864 { /* have two or more arguments */
6dbd0af5
MD
2865#ifdef DEVAL
2866 debug.info->a.args = scm_cons2 (t.arg1, arg2, SCM_EOL);
2867#endif
0f2d19dd
JB
2868 x = SCM_CDR (x);
2869 if (SCM_NULLP (x)) {
6dbd0af5 2870 ENTER_APPLY;
0f2d19dd
JB
2871#ifdef CCLO
2872 evap2:
2873#endif
6dbd0af5
MD
2874 switch (SCM_TYP7 (proc))
2875 { /* have two arguments */
2876 case scm_tc7_subr_2:
2877 case scm_tc7_subr_2o:
2878 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2879 case scm_tc7_lsubr:
0f2d19dd 2880#ifdef DEVAL
6dbd0af5
MD
2881 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2882#else
2883 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, SCM_EOL)));
0f2d19dd 2884#endif
6dbd0af5
MD
2885 case scm_tc7_lsubr_2:
2886 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_EOL));
2887 case scm_tc7_rpsubr:
2888 case scm_tc7_asubr:
2889 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2890#ifdef CCLO
2891 cclon:
2892 case scm_tc7_cclo:
0f2d19dd 2893#ifdef DEVAL
195847fa
MD
2894 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2895 scm_cons (proc, debug.info->a.args),
2896 SCM_EOL));
0f2d19dd 2897#else
195847fa
MD
2898 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
2899 scm_cons2 (proc, t.arg1,
2900 scm_cons (arg2,
2901 scm_eval_args (x,
2902 env,
2903 proc))),
2904 SCM_EOL));
0f2d19dd 2905#endif
6dbd0af5
MD
2906 /* case scm_tc7_cclo:
2907 x = scm_cons(arg2, scm_eval_args(x, env));
2908 arg2 = t.arg1;
2909 t.arg1 = proc;
2910 proc = SCM_CCLO_SUBR(proc);
2911 goto evap3; */
2912#endif
89efbff4
MD
2913 case scm_tc7_pws:
2914 proc = SCM_PROCEDURE (proc);
2915#ifdef DEVAL
2916 debug.info->a.proc = proc;
2917#endif
2918 goto evap2;
0c32d76c 2919 case scm_tcs_cons_gloc:
f3d2630a
MD
2920 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2921 {
195847fa 2922 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a
MD
2923#ifdef DEVAL
2924 arg2 = debug.info->a.args;
2925#else
2926 arg2 = scm_cons2 (t.arg1, arg2, SCM_EOL);
2927#endif
f3d2630a
MD
2928 goto type_dispatch;
2929 }
2930 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2931 goto badfun;
2932 else
0c32d76c 2933 {
195847fa 2934 operatorn:
0c32d76c 2935#ifdef DEVAL
195847fa
MD
2936 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2937 ? SCM_ENTITY_PROCEDURE (proc)
2938 : SCM_OPERATOR_PROCEDURE (proc),
2939 scm_cons (proc, debug.info->a.args),
2940 SCM_EOL));
2941#else
2942 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
2943 ? SCM_ENTITY_PROCEDURE (proc)
2944 : SCM_OPERATOR_PROCEDURE (proc),
2945 scm_cons2 (proc, t.arg1,
2946 scm_cons (arg2,
2947 scm_eval_args (x,
2948 env,
2949 proc))),
2950 SCM_EOL));
2951#endif
0c32d76c 2952 }
6dbd0af5
MD
2953 case scm_tc7_subr_0:
2954 case scm_tc7_cxr:
2955 case scm_tc7_subr_1o:
2956 case scm_tc7_subr_1:
2957 case scm_tc7_subr_3:
2958 case scm_tc7_contin:
2959 goto wrongnumargs;
2960 default:
2961 goto badfun;
2962 case scm_tcs_closures:
195847fa 2963 /* clos2: */
0f2d19dd 2964#ifdef DEVAL
da7f71d7
MD
2965 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
2966 debug.info->a.args,
2967 SCM_ENV (proc));
0f2d19dd 2968#else
da7f71d7
MD
2969 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
2970 scm_cons2 (t.arg1, arg2, SCM_EOL), SCM_ENV (proc));
0f2d19dd 2971#endif
6dbd0af5
MD
2972 x = SCM_CODE (proc);
2973 goto cdrxbegin;
2974 }
0f2d19dd 2975 }
cf7c17e9 2976#ifdef SCM_CAUTIOUS
680ed4a8
MD
2977 if (SCM_IMP (x) || SCM_NECONSP (x))
2978 goto wrongnumargs;
2979#endif
0f2d19dd 2980#ifdef DEVAL
6dbd0af5 2981 debug.info->a.args = scm_cons2 (t.arg1, arg2,
680ed4a8
MD
2982 scm_deval_args (x, env, proc,
2983 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
0f2d19dd 2984#endif
6dbd0af5 2985 ENTER_APPLY;
89efbff4 2986 evap3:
6dbd0af5
MD
2987 switch (SCM_TYP7 (proc))
2988 { /* have 3 or more arguments */
0f2d19dd 2989#ifdef DEVAL
6dbd0af5
MD
2990 case scm_tc7_subr_3:
2991 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
da7f71d7
MD
2992 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
2993 SCM_CADDR (debug.info->a.args)));
6dbd0af5 2994 case scm_tc7_asubr:
399dedcc
MD
2995#ifdef BUILTIN_RPASUBR
2996 t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
2997 arg2 = SCM_CDR (SCM_CDR (debug.info->a.args));
da7f71d7
MD
2998 do
2999 {
3000 t.arg1 = SCM_SUBRF(proc)(t.arg1, SCM_CAR (arg2));
3001 arg2 = SCM_CDR (arg2);
3002 }
3003 while (SCM_NIMP (arg2));
399dedcc
MD
3004 RETURN (t.arg1)
3005#endif /* BUILTIN_RPASUBR */
6dbd0af5 3006 case scm_tc7_rpsubr:
71d3aa6d
MD
3007#ifdef BUILTIN_RPASUBR
3008 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
3009 RETURN (SCM_BOOL_F)
3010 t.arg1 = SCM_CDR (SCM_CDR (debug.info->a.args));
da7f71d7
MD
3011 do
3012 {
3013 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, SCM_CAR (t.arg1))))
3014 RETURN (SCM_BOOL_F)
3015 arg2 = SCM_CAR (t.arg1);
3016 t.arg1 = SCM_CDR (t.arg1);
3017 }
3018 while (SCM_NIMP (t.arg1));
71d3aa6d
MD
3019 RETURN (SCM_BOOL_T)
3020#else /* BUILTIN_RPASUBR */
da7f71d7
MD
3021 RETURN (SCM_APPLY (proc, t.arg1,
3022 scm_acons (arg2,
3023 SCM_CDR (SCM_CDR (debug.info->a.args)),
3024 SCM_EOL)))
71d3aa6d 3025#endif /* BUILTIN_RPASUBR */
399dedcc 3026 case scm_tc7_lsubr_2:
da7f71d7
MD
3027 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
3028 SCM_CDR (SCM_CDR (debug.info->a.args))))
399dedcc
MD
3029 case scm_tc7_lsubr:
3030 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd 3031#ifdef CCLO
6dbd0af5
MD
3032 case scm_tc7_cclo:
3033 goto cclon;
0f2d19dd 3034#endif
89efbff4
MD
3035 case scm_tc7_pws:
3036 proc = SCM_PROCEDURE (proc);
3037 debug.info->a.proc = proc;
3038 goto evap3;
6dbd0af5 3039 case scm_tcs_closures:
b7ff98dd 3040 SCM_SET_ARGSREADY (debug);
e2806c10 3041 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
6dbd0af5
MD
3042 debug.info->a.args,
3043 SCM_ENV (proc));
3044 x = SCM_CODE (proc);
3045 goto cdrxbegin;
3046#else /* DEVAL */
3047 case scm_tc7_subr_3:
3048 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
3049 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, EVALCAR (x, env)));
3050 case scm_tc7_asubr:
399dedcc 3051#ifdef BUILTIN_RPASUBR
da7f71d7
MD
3052 t.arg1 = SCM_SUBRF (proc) (t.arg1, arg2);
3053 do
3054 {
3055 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
3056 x = SCM_CDR(x);
3057 }
3058 while (SCM_NIMP (x));
399dedcc
MD
3059 RETURN (t.arg1)
3060#endif /* BUILTIN_RPASUBR */
6dbd0af5 3061 case scm_tc7_rpsubr:
71d3aa6d
MD
3062#ifdef BUILTIN_RPASUBR
3063 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
3064 RETURN (SCM_BOOL_F)
da7f71d7
MD
3065 do
3066 {
3067 t.arg1 = EVALCAR (x, env);
3068 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, t.arg1)))
3069 RETURN (SCM_BOOL_F)
3070 arg2 = t.arg1;
3071 x = SCM_CDR (x);
3072 }
3073 while (SCM_NIMP (x));
71d3aa6d
MD
3074 RETURN (SCM_BOOL_T)
3075#else /* BUILTIN_RPASUBR */
da7f71d7 3076 RETURN (SCM_APPLY (proc, t.arg1,
680ed4a8
MD
3077 scm_acons (arg2,
3078 scm_eval_args (x, env, proc),
3079 SCM_EOL)));
71d3aa6d 3080#endif /* BUILTIN_RPASUBR */
6dbd0af5 3081 case scm_tc7_lsubr_2:
680ed4a8 3082 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, scm_eval_args (x, env, proc)));
6dbd0af5 3083 case scm_tc7_lsubr:
680ed4a8
MD
3084 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1,
3085 arg2,
3086 scm_eval_args (x, env, proc))));
0f2d19dd 3087#ifdef CCLO
6dbd0af5
MD
3088 case scm_tc7_cclo:
3089 goto cclon;
0f2d19dd 3090#endif
89efbff4
MD
3091 case scm_tc7_pws:
3092 proc = SCM_PROCEDURE (proc);
3093 goto evap3;
6dbd0af5
MD
3094 case scm_tcs_closures:
3095#ifdef DEVAL
b7ff98dd 3096 SCM_SET_ARGSREADY (debug);
6dbd0af5 3097#endif
e2806c10 3098 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
680ed4a8
MD
3099 scm_cons2 (t.arg1,
3100 arg2,
3101 scm_eval_args (x, env, proc)),
6dbd0af5
MD
3102 SCM_ENV (proc));
3103 x = SCM_CODE (proc);
3104 goto cdrxbegin;
0f2d19dd 3105#endif /* DEVAL */
0c32d76c 3106 case scm_tcs_cons_gloc:
f3d2630a
MD
3107 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3108 {
3109#ifdef DEVAL
3110 arg2 = debug.info->a.args;
3111#else
3112 arg2 = scm_cons2 (t.arg1, arg2, scm_eval_args (x, env, proc));
3113#endif
195847fa 3114 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a
MD
3115 goto type_dispatch;
3116 }
3117 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
3118 goto badfun;
3119 else
195847fa 3120 goto operatorn;
6dbd0af5
MD
3121 case scm_tc7_subr_2:
3122 case scm_tc7_subr_1o:
3123 case scm_tc7_subr_2o:
3124 case scm_tc7_subr_0:
3125 case scm_tc7_cxr:
3126 case scm_tc7_subr_1:
3127 case scm_tc7_contin:
3128 goto wrongnumargs;
3129 default:
3130 goto badfun;
3131 }
0f2d19dd
JB
3132 }
3133#ifdef DEVAL
6dbd0af5 3134exit:
b6d75948 3135 if (CHECK_EXIT && SCM_TRAPS_P)
b7ff98dd 3136 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3137 {
b7ff98dd
MD
3138 SCM_CLEAR_TRACED_FRAME (debug);
3139 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3140 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3141 else
3142 {
3143 scm_make_cont (&t.arg1);
ca6ef71a 3144 if (setjmp (SCM_JMPBUF (t.arg1)))
6dbd0af5
MD
3145 {
3146 proc = SCM_THROW_VALUE (t.arg1);
3147 goto ret;
3148 }
3149 }
2f0d1375 3150 scm_ithrow (scm_sym_exit_frame, scm_cons2 (t.arg1, proc, SCM_EOL), 0);
6dbd0af5
MD
3151 }
3152ret:
1646d37b 3153 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3154 return proc;
3155#endif
3156}
3157
6dbd0af5
MD
3158
3159/* SECTION: This code is compiled once.
3160 */
3161
0f2d19dd
JB
3162#ifndef DEVAL
3163
82a2622a 3164/* This code processes the arguments to apply:
b145c172
JB
3165
3166 (apply PROC ARG1 ... ARGS)
3167
82a2622a
JB
3168 Given a list (ARG1 ... ARGS), this function conses the ARG1
3169 ... arguments onto the front of ARGS, and returns the resulting
3170 list. Note that ARGS is a list; thus, the argument to this
3171 function is a list whose last element is a list.
3172
3173 Apply calls this function, and applies PROC to the elements of the
b145c172
JB
3174 result. apply:nconc2last takes care of building the list of
3175 arguments, given (ARG1 ... ARGS).
3176
82a2622a
JB
3177 Rather than do new consing, apply:nconc2last destroys its argument.
3178 On that topic, this code came into my care with the following
3179 beautifully cryptic comment on that topic: "This will only screw
3180 you if you do (scm_apply scm_apply '( ... ))" If you know what
3181 they're referring to, send me a patch to this comment. */
b145c172 3182
3b3b36dd 3183SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
1bbd0b84 3184 (SCM lst),
b380b885 3185 "")
1bbd0b84 3186#define FUNC_NAME s_scm_nconc2last
0f2d19dd
JB
3187{
3188 SCM *lloc;
c1bfcf60 3189 SCM_VALIDATE_NONEMPTYLIST (1,lst);
0f2d19dd
JB
3190 lloc = &lst;
3191 while (SCM_NNULLP (SCM_CDR (*lloc)))
a23afe53 3192 lloc = SCM_CDRLOC (*lloc);
1bbd0b84 3193 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
0f2d19dd
JB
3194 *lloc = SCM_CAR (*lloc);
3195 return lst;
3196}
1bbd0b84 3197#undef FUNC_NAME
0f2d19dd
JB
3198
3199#endif /* !DEVAL */
3200
6dbd0af5
MD
3201
3202/* SECTION: When DEVAL is defined this code yields scm_dapply.
3203 * It is compiled twice.
3204 */
3205
0f2d19dd 3206#if 0
1cc91f1b 3207
0f2d19dd 3208SCM
6e8d25a6 3209scm_apply (SCM proc, SCM arg1, SCM args)
0f2d19dd
JB
3210{}
3211#endif
3212
3213#if 0
1cc91f1b 3214
0f2d19dd 3215SCM
6e8d25a6
GB
3216scm_dapply (SCM proc, SCM arg1, SCM args)
3217{ /* empty */ }
0f2d19dd
JB
3218#endif
3219
1cc91f1b 3220
82a2622a
JB
3221/* Apply a function to a list of arguments.
3222
3223 This function is exported to the Scheme level as taking two
3224 required arguments and a tail argument, as if it were:
3225 (lambda (proc arg1 . args) ...)
3226 Thus, if you just have a list of arguments to pass to a procedure,
3227 pass the list as ARG1, and '() for ARGS. If you have some fixed
3228 args, pass the first as ARG1, then cons any remaining fixed args
3229 onto the front of your argument list, and pass that as ARGS. */
3230
0f2d19dd 3231SCM
1bbd0b84 3232SCM_APPLY (SCM proc, SCM arg1, SCM args)
0f2d19dd
JB
3233{
3234#ifdef DEBUG_EXTENSIONS
3235#ifdef DEVAL
6dbd0af5 3236 scm_debug_frame debug;
c0ab1b8d 3237 scm_debug_info debug_vect_body;
1646d37b 3238 debug.prev = scm_last_debug_frame;
b7ff98dd 3239 debug.status = SCM_APPLYFRAME;
c0ab1b8d 3240 debug.vect = &debug_vect_body;
6dbd0af5
MD
3241 debug.vect[0].a.proc = proc;
3242 debug.vect[0].a.args = SCM_EOL;
1646d37b 3243 scm_last_debug_frame = &debug;
0f2d19dd 3244#else
b7ff98dd 3245 if (SCM_DEBUGGINGP)
0f2d19dd
JB
3246 return scm_dapply (proc, arg1, args);
3247#endif
3248#endif
3249
3250 SCM_ASRTGO (SCM_NIMP (proc), badproc);
82a2622a
JB
3251
3252 /* If ARGS is the empty list, then we're calling apply with only two
3253 arguments --- ARG1 is the list of arguments for PROC. Whatever
3254 the case, futz with things so that ARG1 is the first argument to
3255 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
30000774
JB
3256 rest.
3257
3258 Setting the debug apply frame args this way is pretty messy.
3259 Perhaps we should store arg1 and args directly in the frame as
3260 received, and let scm_frame_arguments unpack them, because that's
3261 a relatively rare operation. This works for now; if the Guile
3262 developer archives are still around, see Mikael's post of
3263 11-Apr-97. */
0f2d19dd
JB
3264 if (SCM_NULLP (args))
3265 {
3266 if (SCM_NULLP (arg1))
30000774
JB
3267 {
3268 arg1 = SCM_UNDEFINED;
3269#ifdef DEVAL
3270 debug.vect[0].a.args = SCM_EOL;
3271#endif
3272 }
0f2d19dd
JB
3273 else
3274 {
30000774
JB
3275#ifdef DEVAL
3276 debug.vect[0].a.args = arg1;
3277#endif
0f2d19dd
JB
3278 args = SCM_CDR (arg1);
3279 arg1 = SCM_CAR (arg1);
3280 }
3281 }
3282 else
3283 {
0c95b57d 3284 /* SCM_ASRTGO(SCM_CONSP(args), wrongnumargs); */
0f2d19dd 3285 args = scm_nconc2last (args);
30000774
JB
3286#ifdef DEVAL
3287 debug.vect[0].a.args = scm_cons (arg1, args);
3288#endif
0f2d19dd 3289 }
0f2d19dd 3290#ifdef DEVAL
b6d75948 3291 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
6dbd0af5
MD
3292 {
3293 SCM tmp;
b7ff98dd 3294 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3295 tmp = scm_make_debugobj (&debug);
6dbd0af5
MD
3296 else
3297 {
3298 scm_make_cont (&tmp);
ca6ef71a 3299 if (setjmp (SCM_JMPBUF (tmp)))
6dbd0af5
MD
3300 goto entap;
3301 }
2f0d1375 3302 scm_ithrow (scm_sym_enter_frame, scm_cons (tmp, SCM_EOL), 0);
6dbd0af5
MD
3303 }
3304entap:
3305 ENTER_APPLY;
3306#endif
3307#ifdef CCLO
3308tail:
0f2d19dd
JB
3309#endif
3310 switch (SCM_TYP7 (proc))
3311 {
3312 case scm_tc7_subr_2o:
3313 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
3314 RETURN (SCM_SUBRF (proc) (arg1, args))
3315 case scm_tc7_subr_2:
269861c7
MD
3316 SCM_ASRTGO (SCM_NNULLP (args) && SCM_NULLP (SCM_CDR (args)),
3317 wrongnumargs);
0f2d19dd
JB
3318 args = SCM_CAR (args);
3319 RETURN (SCM_SUBRF (proc) (arg1, args))
3320 case scm_tc7_subr_0:
3321 SCM_ASRTGO (SCM_UNBNDP (arg1), wrongnumargs);
3322 RETURN (SCM_SUBRF (proc) ())
3323 case scm_tc7_subr_1:
3324 case scm_tc7_subr_1o:
3325 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
3326 RETURN (SCM_SUBRF (proc) (arg1))
3327 case scm_tc7_cxr:
3328 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
0f2d19dd
JB
3329 if (SCM_SUBRF (proc))
3330 {
6dbd0af5
MD
3331 if (SCM_INUMP (arg1))
3332 {
f8de44c1 3333 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
6dbd0af5 3334 }
0f2d19dd 3335 SCM_ASRTGO (SCM_NIMP (arg1), floerr);
6dbd0af5
MD
3336 if (SCM_REALP (arg1))
3337 {
eb42e2f0 3338 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
6dbd0af5 3339 }
0f2d19dd 3340#ifdef SCM_BIGDIG
26d5b9b4 3341 if (SCM_BIGP (arg1))
f8de44c1 3342 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_big2dbl (arg1))))
0f2d19dd
JB
3343#endif
3344 floerr:
9de33deb
MD
3345 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3346 SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
0f2d19dd 3347 }
3201d763 3348 proc = SCM_SNAME (proc);
0f2d19dd
JB
3349 {
3350 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
3351 while ('c' != *--chrs)
3352 {
0c95b57d 3353 SCM_ASSERT (SCM_CONSP (arg1),
0f2d19dd
JB
3354 arg1, SCM_ARG1, SCM_CHARS (proc));
3355 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3356 }
3357 RETURN (arg1)
3358 }
3359 case scm_tc7_subr_3:
3360 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CAR (SCM_CDR (args))))
3361 case scm_tc7_lsubr:
3362#ifdef DEVAL
6dbd0af5 3363 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args))
0f2d19dd
JB
3364#else
3365 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)))
3366#endif
3367 case scm_tc7_lsubr_2:
0c95b57d 3368 SCM_ASRTGO (SCM_CONSP (args), wrongnumargs);
0f2d19dd
JB
3369 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)))
3370 case scm_tc7_asubr:
3371 if (SCM_NULLP (args))
3372 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED))
3373 while (SCM_NIMP (args))
3374 {
3375 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3376 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
3377 args = SCM_CDR (args);
3378 }
3379 RETURN (arg1);
3380 case scm_tc7_rpsubr:
3381 if (SCM_NULLP (args))
3382 RETURN (SCM_BOOL_T);
3383 while (SCM_NIMP (args))
3384 {
3385 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3386 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
3387 RETURN (SCM_BOOL_F);
3388 arg1 = SCM_CAR (args);
3389 args = SCM_CDR (args);
3390 }
3391 RETURN (SCM_BOOL_T);
3392 case scm_tcs_closures:
3393#ifdef DEVAL
6dbd0af5 3394 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
0f2d19dd
JB
3395#else
3396 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
3397#endif
cf7c17e9 3398#ifndef SCM_RECKLESS
0f2d19dd
JB
3399 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), arg1))
3400 goto wrongnumargs;
3401#endif
1609038c
MD
3402
3403 /* Copy argument list */
3404 if (SCM_IMP (arg1))
3405 args = arg1;
3406 else
3407 {
3408 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
cabe682c 3409 while (arg1 = SCM_CDR (arg1), SCM_CONSP (arg1))
1609038c
MD
3410 {
3411 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1),
3412 SCM_UNSPECIFIED));
3413 tl = SCM_CDR (tl);
3414 }
3415 SCM_SETCDR (tl, arg1);
3416 }
3417
3418 args = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), args, SCM_ENV (proc));
2ddb0920 3419 proc = SCM_CDR (SCM_CODE (proc));
e791c18f
MD
3420 again:
3421 arg1 = proc;
3422 while (SCM_NNULLP (arg1 = SCM_CDR (arg1)))
2ddb0920
MD
3423 {
3424 if (SCM_IMP (SCM_CAR (proc)))
3425 {
3426 if (SCM_ISYMP (SCM_CAR (proc)))
3427 {
3428 proc = scm_m_expand_body (proc, args);
e791c18f 3429 goto again;
2ddb0920 3430 }
2ddb0920
MD
3431 }
3432 else
e791c18f
MD
3433 SCM_CEVAL (SCM_CAR (proc), args);
3434 proc = arg1;
2ddb0920 3435 }
e791c18f 3436 RETURN (EVALCAR (proc, args));
0f2d19dd
JB
3437 case scm_tc7_contin:
3438 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
3439 scm_call_continuation (proc, arg1);
3440#ifdef CCLO
3441 case scm_tc7_cclo:
3442#ifdef DEVAL
6dbd0af5
MD
3443 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3444 arg1 = proc;
3445 proc = SCM_CCLO_SUBR (proc);
3446 debug.vect[0].a.proc = proc;
3447 debug.vect[0].a.args = scm_cons (arg1, args);
0f2d19dd
JB
3448#else
3449 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
0f2d19dd
JB
3450 arg1 = proc;
3451 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 3452#endif
0f2d19dd
JB
3453 goto tail;
3454#endif
89efbff4
MD
3455 case scm_tc7_pws:
3456 proc = SCM_PROCEDURE (proc);
3457#ifdef DEVAL
3458 debug.vect[0].a.proc = proc;
3459#endif
3460 goto tail;
0c32d76c 3461 case scm_tcs_cons_gloc:
f3d2630a
MD
3462 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3463 {
3464#ifdef DEVAL
3465 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3466#else
3467 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3468#endif
195847fa 3469 RETURN (scm_apply_generic (proc, args));
f3d2630a
MD
3470 }
3471 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
3472 goto badproc;
3473 else
da7f71d7
MD
3474 {
3475#ifdef DEVAL
3476 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3477#else
3478 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3479#endif
3480 arg1 = proc;
195847fa
MD
3481 proc = (SCM_I_ENTITYP (proc)
3482 ? SCM_ENTITY_PROCEDURE (proc)
3483 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7
MD
3484#ifdef DEVAL
3485 debug.vect[0].a.proc = proc;
3486 debug.vect[0].a.args = scm_cons (arg1, args);
3487#endif
195847fa
MD
3488 if (SCM_NIMP (proc))
3489 goto tail;
3490 else
3491 goto badproc;
da7f71d7 3492 }
0f2d19dd 3493 wrongnumargs:
f5bf2977 3494 scm_wrong_num_args (proc);
0f2d19dd
JB
3495 default:
3496 badproc:
3497 scm_wta (proc, (char *) SCM_ARG1, "apply");
3498 RETURN (arg1);
3499 }
3500#ifdef DEVAL
6dbd0af5 3501exit:
b6d75948 3502 if (CHECK_EXIT && SCM_TRAPS_P)
b7ff98dd 3503 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3504 {
b7ff98dd
MD
3505 SCM_CLEAR_TRACED_FRAME (debug);
3506 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3507 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3508 else
3509 {
3510 scm_make_cont (&arg1);
ca6ef71a 3511 if (setjmp (SCM_JMPBUF (arg1)))
6dbd0af5
MD
3512 {
3513 proc = SCM_THROW_VALUE (arg1);
3514 goto ret;
3515 }
3516 }
2f0d1375 3517 scm_ithrow (scm_sym_exit_frame, scm_cons2 (arg1, proc, SCM_EOL), 0);
6dbd0af5
MD
3518 }
3519ret:
1646d37b 3520 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3521 return proc;
3522#endif
3523}
3524
6dbd0af5
MD
3525
3526/* SECTION: The rest of this file is only read once.
3527 */
3528
0f2d19dd
JB
3529#ifndef DEVAL
3530
d9c393f5
JB
3531/* Typechecking for multi-argument MAP and FOR-EACH.
3532
47c3f06d 3533 Verify that each element of the vector ARGV, except for the first,
d9c393f5 3534 is a proper list whose length is LEN. Attribute errors to WHO,
47c3f06d 3535 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
d9c393f5 3536static inline void
47c3f06d
MD
3537check_map_args (SCM argv,
3538 long len,
3539 SCM gf,
3540 SCM proc,
3541 SCM args,
3542 const char *who)
d9c393f5 3543{
47c3f06d 3544 SCM *ve = SCM_VELTS (argv);
d9c393f5
JB
3545 int i;
3546
47c3f06d 3547 for (i = SCM_LENGTH (argv) - 1; i >= 1; i--)
d9c393f5
JB
3548 {
3549 int elt_len = scm_ilength (ve[i]);
3550
3551 if (elt_len < 0)
47c3f06d
MD
3552 {
3553 if (gf)
3554 scm_apply_generic (gf, scm_cons (proc, args));
3555 else
3556 scm_wrong_type_arg (who, i + 2, ve[i]);
3557 }
d9c393f5
JB
3558
3559 if (elt_len != len)
3560 scm_out_of_range (who, ve[i]);
3561 }
3562
47c3f06d 3563 scm_remember (&argv);
d9c393f5
JB
3564}
3565
3566
47c3f06d 3567SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
1cc91f1b 3568
368bf056
MD
3569/* Note: Currently, scm_map applies PROC to the argument list(s)
3570 sequentially, starting with the first element(s). This is used in
3571 evalext.c where the Scheme procedure `serial-map', which guarantees
3572 sequential behaviour, is implemented using scm_map. If the
3573 behaviour changes, we need to update `serial-map'.
3574*/
3575
0f2d19dd 3576SCM
1bbd0b84 3577scm_map (SCM proc, SCM arg1, SCM args)
af45e3b0 3578#define FUNC_NAME s_map
0f2d19dd 3579{
d9c393f5 3580 long i, len;
0f2d19dd
JB
3581 SCM res = SCM_EOL;
3582 SCM *pres = &res;
3583 SCM *ve = &args; /* Keep args from being optimized away. */
3584
d9c393f5 3585 len = scm_ilength (arg1);
47c3f06d
MD
3586 SCM_GASSERTn (len >= 0,
3587 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
af45e3b0 3588 SCM_VALIDATE_REST_ARGUMENT (args);
0f2d19dd
JB
3589 if (SCM_NULLP (args))
3590 {
3591 while (SCM_NIMP (arg1))
3592 {
47c3f06d
MD
3593 *pres = scm_cons (scm_apply (proc, SCM_CAR (arg1), scm_listofnull),
3594 SCM_EOL);
a23afe53 3595 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
3596 arg1 = SCM_CDR (arg1);
3597 }
3598 return res;
3599 }
47c3f06d 3600 args = scm_vector (arg1 = scm_cons (arg1, args));
0f2d19dd 3601 ve = SCM_VELTS (args);
cf7c17e9 3602#ifndef SCM_RECKLESS
47c3f06d 3603 check_map_args (args, len, g_map, proc, arg1, s_map);
0f2d19dd
JB
3604#endif
3605 while (1)
3606 {
3607 arg1 = SCM_EOL;
3608 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
3609 {
d9c393f5
JB
3610 if (SCM_IMP (ve[i]))
3611 return res;
0f2d19dd
JB
3612 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3613 ve[i] = SCM_CDR (ve[i]);
3614 }
3615 *pres = scm_cons (scm_apply (proc, arg1, SCM_EOL), SCM_EOL);
a23afe53 3616 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
3617 }
3618}
af45e3b0 3619#undef FUNC_NAME
0f2d19dd
JB
3620
3621
47c3f06d 3622SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
1cc91f1b 3623
0f2d19dd 3624SCM
1bbd0b84 3625scm_for_each (SCM proc, SCM arg1, SCM args)
af45e3b0 3626#define FUNC_NAME s_for_each
0f2d19dd
JB
3627{
3628 SCM *ve = &args; /* Keep args from being optimized away. */
d9c393f5 3629 long i, len;
d9c393f5 3630 len = scm_ilength (arg1);
47c3f06d
MD
3631 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
3632 SCM_ARG2, s_for_each);
af45e3b0 3633 SCM_VALIDATE_REST_ARGUMENT (args);
0f2d19dd
JB
3634 if SCM_NULLP (args)
3635 {
3636 while SCM_NIMP (arg1)
3637 {
0f2d19dd
JB
3638 scm_apply (proc, SCM_CAR (arg1), scm_listofnull);
3639 arg1 = SCM_CDR (arg1);
3640 }
3641 return SCM_UNSPECIFIED;
3642 }
47c3f06d 3643 args = scm_vector (arg1 = scm_cons (arg1, args));
0f2d19dd 3644 ve = SCM_VELTS (args);
cf7c17e9 3645#ifndef SCM_RECKLESS
47c3f06d 3646 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
0f2d19dd
JB
3647#endif
3648 while (1)
3649 {
3650 arg1 = SCM_EOL;
3651 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
3652 {
3653 if SCM_IMP
3654 (ve[i]) return SCM_UNSPECIFIED;
3655 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3656 ve[i] = SCM_CDR (ve[i]);
3657 }
3658 scm_apply (proc, arg1, SCM_EOL);
3659 }
3660}
af45e3b0 3661#undef FUNC_NAME
0f2d19dd 3662
1cc91f1b 3663
0f2d19dd 3664SCM
6e8d25a6 3665scm_closure (SCM code, SCM env)
0f2d19dd
JB
3666{
3667 register SCM z;
3668 SCM_NEWCELL (z);
3669 SCM_SETCODE (z, code);
a23afe53 3670 SCM_SETENV (z, env);
0f2d19dd
JB
3671 return z;
3672}
3673
3674
3675long scm_tc16_promise;
1cc91f1b 3676
0f2d19dd 3677SCM
6e8d25a6 3678scm_makprom (SCM code)
0f2d19dd 3679{
cf498326 3680 SCM_RETURN_NEWSMOB (scm_tc16_promise, SCM_UNPACK (code));
0f2d19dd
JB
3681}
3682
3683
1cc91f1b 3684
0f2d19dd 3685static int
1bbd0b84 3686prinprom (SCM exp,SCM port,scm_print_state *pstate)
0f2d19dd 3687{
19402679 3688 int writingp = SCM_WRITINGP (pstate);
b7f3516f 3689 scm_puts ("#<promise ", port);
19402679
MD
3690 SCM_SET_WRITINGP (pstate, 1);
3691 scm_iprin1 (SCM_CDR (exp), port, pstate);
3692 SCM_SET_WRITINGP (pstate, writingp);
b7f3516f 3693 scm_putc ('>', port);
0f2d19dd
JB
3694 return !0;
3695}
3696
3697
3b3b36dd 3698SCM_DEFINE (scm_force, "force", 1, 0, 0,
1bbd0b84 3699 (SCM x),
b380b885 3700 "")
1bbd0b84 3701#define FUNC_NAME s_scm_force
0f2d19dd 3702{
3b3b36dd 3703 SCM_VALIDATE_SMOB (1,x,promise);
f1267706 3704 if (!((1L << 16) & SCM_UNPACK_CAR (x)))
0f2d19dd
JB
3705 {
3706 SCM ans = scm_apply (SCM_CDR (x), SCM_EOL, SCM_EOL);
f1267706 3707 if (!((1L << 16) & SCM_UNPACK_CAR (x)))
0f2d19dd
JB
3708 {
3709 SCM_DEFER_INTS;
a23afe53
MD
3710 SCM_SETCDR (x, ans);
3711 SCM_SETOR_CAR (x, (1L << 16));
0f2d19dd
JB
3712 SCM_ALLOW_INTS;
3713 }
3714 }
3715 return SCM_CDR (x);
3716}
1bbd0b84 3717#undef FUNC_NAME
0f2d19dd 3718
a1ec6916 3719SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
1bbd0b84 3720 (SCM x),
b380b885
MD
3721 "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
3722 "(@pxref{Delayed evaluation,,,r4rs.info,The Revised^4 Report on Scheme}).")
1bbd0b84 3723#define FUNC_NAME s_scm_promise_p
0f2d19dd 3724{
1bbd0b84 3725 return SCM_BOOL(SCM_NIMP (x) && (SCM_TYP16 (x) == scm_tc16_promise));
0f2d19dd 3726}
1bbd0b84 3727#undef FUNC_NAME
0f2d19dd 3728
a1ec6916 3729SCM_DEFINE (scm_cons_source, "cons-source", 3, 0, 0,
1bbd0b84 3730 (SCM xorig, SCM x, SCM y),
b380b885 3731 "")
1bbd0b84 3732#define FUNC_NAME s_scm_cons_source
26d5b9b4
MD
3733{
3734 SCM p, z;
3735 SCM_NEWCELL (z);
3736 SCM_SETCAR (z, x);
3737 SCM_SETCDR (z, y);
3738 /* Copy source properties possibly associated with xorig. */
3739 p = scm_whash_lookup (scm_source_whash, xorig);
3740 if (SCM_NIMP (p))
3741 scm_whash_insert (scm_source_whash, z, p);
3742 return z;
3743}
1bbd0b84 3744#undef FUNC_NAME
26d5b9b4 3745
a1ec6916 3746SCM_DEFINE (scm_copy_tree, "copy-tree", 1, 0, 0,
1bbd0b84 3747 (SCM obj),
b380b885
MD
3748 "Recursively copy the data tree that is bound to @var{obj}, and return a\n"
3749 "pointer to the new data structure. @code{copy-tree} recurses down the\n"
3750 "contents of both pairs and vectors (since both cons cells and vector\n"
3751 "cells may point to arbitrary objects), and stops recursing when it hits\n"
3752 "any other object.")
1bbd0b84 3753#define FUNC_NAME s_scm_copy_tree
0f2d19dd
JB
3754{
3755 SCM ans, tl;
26d5b9b4 3756 if (SCM_IMP (obj))
ff467021 3757 return obj;
3910272e
MD
3758 if (SCM_VECTORP (obj))
3759 {
3760 scm_sizet i = SCM_LENGTH (obj);
3761 ans = scm_make_vector (SCM_MAKINUM (i), SCM_UNSPECIFIED);
3762 while (i--)
3763 SCM_VELTS (ans)[i] = scm_copy_tree (SCM_VELTS (obj)[i]);
3764 return ans;
3765 }
ff467021 3766 if (SCM_NCONSP (obj))
0f2d19dd
JB
3767 return obj;
3768/* return scm_cons(scm_copy_tree(SCM_CAR(obj)), scm_copy_tree(SCM_CDR(obj))); */
26d5b9b4
MD
3769 ans = tl = scm_cons_source (obj,
3770 scm_copy_tree (SCM_CAR (obj)),
3771 SCM_UNSPECIFIED);
cabe682c 3772 while (obj = SCM_CDR (obj), SCM_CONSP (obj))
a23afe53
MD
3773 {
3774 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
3775 SCM_UNSPECIFIED));
3776 tl = SCM_CDR (tl);
3777 }
3778 SCM_SETCDR (tl, obj);
0f2d19dd
JB
3779 return ans;
3780}
1bbd0b84 3781#undef FUNC_NAME
0f2d19dd 3782
1cc91f1b 3783
0f2d19dd 3784SCM
1bbd0b84 3785scm_eval_3 (SCM obj, int copyp, SCM env)
0f2d19dd
JB
3786{
3787 if (SCM_NIMP (SCM_CDR (scm_system_transformer)))
3788 obj = scm_apply (SCM_CDR (scm_system_transformer), obj, scm_listofnull);
3789 else if (copyp)
3790 obj = scm_copy_tree (obj);
6cb702da 3791 return SCM_XEVAL (obj, env);
0f2d19dd
JB
3792}
3793
3b3b36dd 3794SCM_DEFINE (scm_eval2, "eval2", 2, 0, 0,
1bbd0b84 3795 (SCM obj, SCM env_thunk),
b380b885
MD
3796 "Evaluate @var{exp}, a Scheme expression, in the environment designated\n"
3797 "by @var{lookup}, a symbol-lookup function. @code{(eval exp)} is\n"
3798 "equivalent to @code{(eval2 exp *top-level-lookup-closure*)}.")
1bbd0b84 3799#define FUNC_NAME s_scm_eval2
0f2d19dd 3800{
6bcb0868 3801 return scm_eval_3 (obj, 1, scm_top_level_env (env_thunk));
0f2d19dd 3802}
1bbd0b84 3803#undef FUNC_NAME
0f2d19dd 3804
3b3b36dd 3805SCM_DEFINE (scm_eval, "eval", 1, 0, 0,
1bbd0b84 3806 (SCM obj),
b380b885
MD
3807 "Evaluate @var{exp}, a list representing a Scheme expression, in the\n"
3808 "top-level environment.")
1bbd0b84 3809#define FUNC_NAME s_scm_eval
0f2d19dd 3810{
6bcb0868
MD
3811 return scm_eval_3 (obj,
3812 1,
3813 scm_top_level_env
3814 (SCM_CDR (scm_top_level_lookup_closure_var)));
0f2d19dd 3815}
1bbd0b84 3816#undef FUNC_NAME
0f2d19dd 3817
1bbd0b84
GB
3818/*
3819SCM_REGISTER_PROC(s_eval_x, "eval!", 1, 0, 0, scm_eval_x);
3820*/
1cc91f1b 3821
0f2d19dd 3822SCM
1bbd0b84 3823scm_eval_x (SCM obj)
0f2d19dd 3824{
6bcb0868
MD
3825 return scm_eval_3 (obj,
3826 0,
3827 scm_top_level_env
3828 (SCM_CDR (scm_top_level_lookup_closure_var)));
0f2d19dd
JB
3829}
3830
6dbd0af5
MD
3831
3832/* At this point, scm_deval and scm_dapply are generated.
3833 */
3834
0f2d19dd 3835#ifdef DEBUG_EXTENSIONS
6dbd0af5
MD
3836# define DEVAL
3837# include "eval.c"
0f2d19dd
JB
3838#endif
3839
3840
1cc91f1b 3841
0f2d19dd
JB
3842void
3843scm_init_eval ()
0f2d19dd 3844{
33b97402
MD
3845 scm_init_opts (scm_evaluator_traps,
3846 scm_evaluator_trap_table,
3847 SCM_N_EVALUATOR_TRAPS);
3848 scm_init_opts (scm_eval_options_interface,
3849 scm_eval_opts,
3850 SCM_N_EVAL_OPTIONS);
3851
f99c9c28
MD
3852 scm_tc16_promise = scm_make_smob_type ("promise", 0);
3853 scm_set_smob_mark (scm_tc16_promise, scm_markcdr);
3854 scm_set_smob_print (scm_tc16_promise, prinprom);
b8229a3b 3855
81123e6d 3856 scm_f_apply = scm_make_subr ("apply", scm_tc7_lsubr_2, scm_apply);
0f2d19dd 3857 scm_system_transformer = scm_sysintern ("scm:eval-transformer", SCM_UNDEFINED);
2f0d1375
MD
3858 scm_sym_dot = SCM_CAR (scm_sysintern (".", SCM_UNDEFINED));
3859 scm_sym_arrow = SCM_CAR (scm_sysintern ("=>", SCM_UNDEFINED));
3860 scm_sym_else = SCM_CAR (scm_sysintern ("else", SCM_UNDEFINED));
3861 scm_sym_unquote = SCM_CAR (scm_sysintern ("unquote", SCM_UNDEFINED));
3862 scm_sym_uq_splicing = SCM_CAR (scm_sysintern ("unquote-splicing", SCM_UNDEFINED));
0f2d19dd 3863
43a912cf
MD
3864 scm_lisp_nil = scm_sysintern ("nil", SCM_UNDEFINED);
3865 SCM_SETCDR (scm_lisp_nil, SCM_CAR (scm_lisp_nil));
3866 scm_lisp_nil = SCM_CAR (scm_lisp_nil);
3867 scm_lisp_t = scm_sysintern ("t", SCM_UNDEFINED);
3868 SCM_SETCDR (scm_lisp_t, SCM_CAR (scm_lisp_t));
3869 scm_lisp_t = SCM_CAR (scm_lisp_t);
73b64342 3870
0f2d19dd 3871 /* acros */
0f2d19dd
JB
3872 /* end of acros */
3873
dc19d1d2
JB
3874 scm_top_level_lookup_closure_var =
3875 scm_sysintern("*top-level-lookup-closure*", SCM_BOOL_F);
9b8d3288 3876 scm_can_use_top_level_lookup_closure_var = 1;
0f2d19dd 3877
6dbd0af5 3878#ifdef DEBUG_EXTENSIONS
2f0d1375
MD
3879 scm_sym_enter_frame = SCM_CAR (scm_sysintern ("enter-frame", SCM_UNDEFINED));
3880 scm_sym_apply_frame = SCM_CAR (scm_sysintern ("apply-frame", SCM_UNDEFINED));
3881 scm_sym_exit_frame = SCM_CAR (scm_sysintern ("exit-frame", SCM_UNDEFINED));
3882 scm_sym_trace = SCM_CAR (scm_sysintern ("trace", SCM_UNDEFINED));
6dbd0af5
MD
3883#endif
3884
a0599745 3885#include "libguile/eval.x"
25eaf21a
MD
3886
3887 scm_add_feature ("delay");
0f2d19dd 3888}
0f2d19dd 3889
6dbd0af5 3890#endif /* !DEVAL */
89e00824
ML
3891
3892/*
3893 Local Variables:
3894 c-file-style: "gnu"
3895 End:
3896*/