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