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