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