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