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