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