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