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