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