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