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