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