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