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