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