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