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