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