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