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