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