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