1 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013
2 * Free Software Foundation, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "libguile/__scm.h"
27 #include "libguile/_scm.h"
28 #include "libguile/continuations.h"
29 #include "libguile/eq.h"
30 #include "libguile/list.h"
31 #include "libguile/macros.h"
32 #include "libguile/expand.h"
33 #include "libguile/modules.h"
34 #include "libguile/srcprop.h"
35 #include "libguile/ports.h"
36 #include "libguile/print.h"
37 #include "libguile/strings.h"
38 #include "libguile/throw.h"
39 #include "libguile/validate.h"
45 SCM scm_exp_vtable_vtable
;
46 static SCM exp_vtables
[SCM_NUM_EXPANDED_TYPES
];
47 static size_t exp_nfields
[SCM_NUM_EXPANDED_TYPES
];
48 static const char* exp_names
[SCM_NUM_EXPANDED_TYPES
];
49 static const char** exp_field_names
[SCM_NUM_EXPANDED_TYPES
];
52 /* The trailing underscores on these first to are to avoid spurious
53 conflicts with macros defined on MinGW. */
56 SCM_MAKE_EXPANDED_VOID(src)
57 #define CONST_(src, exp) \
58 SCM_MAKE_EXPANDED_CONST(src, exp)
59 #define PRIMITIVE_REF(src, name) \
60 SCM_MAKE_EXPANDED_PRIMITIVE_REF(src, name)
61 #define LEXICAL_REF(src, name, gensym) \
62 SCM_MAKE_EXPANDED_LEXICAL_REF(src, name, gensym)
63 #define LEXICAL_SET(src, name, gensym, exp) \
64 SCM_MAKE_EXPANDED_LEXICAL_SET(src, name, gensym, exp)
65 #define MODULE_REF(src, mod, name, public) \
66 SCM_MAKE_EXPANDED_MODULE_REF(src, mod, name, public)
67 #define MODULE_SET(src, mod, name, public, exp) \
68 SCM_MAKE_EXPANDED_MODULE_SET(src, mod, name, public, exp)
69 #define TOPLEVEL_REF(src, name) \
70 SCM_MAKE_EXPANDED_TOPLEVEL_REF(src, name)
71 #define TOPLEVEL_SET(src, name, exp) \
72 SCM_MAKE_EXPANDED_TOPLEVEL_SET(src, name, exp)
73 #define TOPLEVEL_DEFINE(src, name, exp) \
74 SCM_MAKE_EXPANDED_TOPLEVEL_DEFINE(src, name, exp)
75 #define CONDITIONAL(src, test, consequent, alternate) \
76 SCM_MAKE_EXPANDED_CONDITIONAL(src, test, consequent, alternate)
77 #define PRIMCALL(src, name, exps) \
78 SCM_MAKE_EXPANDED_PRIMCALL(src, name, exps)
79 #define CALL(src, proc, exps) \
80 SCM_MAKE_EXPANDED_CALL(src, proc, exps)
81 #define SEQ(src, head, tail) \
82 SCM_MAKE_EXPANDED_SEQ(src, head, tail)
83 #define LAMBDA(src, meta, body) \
84 SCM_MAKE_EXPANDED_LAMBDA(src, meta, body)
85 #define LAMBDA_CASE(src, req, opt, rest, kw, inits, gensyms, body, alternate) \
86 SCM_MAKE_EXPANDED_LAMBDA_CASE(src, req, opt, rest, kw, inits, gensyms, body, alternate)
87 #define LET(src, names, gensyms, vals, body) \
88 SCM_MAKE_EXPANDED_LET(src, names, gensyms, vals, body)
89 #define LETREC(src, in_order_p, names, gensyms, vals, body) \
90 SCM_MAKE_EXPANDED_LETREC(src, in_order_p, names, gensyms, vals, body)
91 #define DYNLET(src, fluids, vals, body) \
92 SCM_MAKE_EXPANDED_DYNLET(src, fluids, vals, body)
94 #define CAR(x) SCM_CAR(x)
95 #define CDR(x) SCM_CDR(x)
96 #define CAAR(x) SCM_CAAR(x)
97 #define CADR(x) SCM_CADR(x)
98 #define CDAR(x) SCM_CDAR(x)
99 #define CDDR(x) SCM_CDDR(x)
100 #define CADDR(x) SCM_CADDR(x)
101 #define CDDDR(x) SCM_CDDDR(x)
102 #define CADDDR(x) SCM_CADDDR(x)
105 static const char s_bad_expression
[] = "Bad expression";
106 static const char s_expression
[] = "Missing or extra expression in";
107 static const char s_missing_expression
[] = "Missing expression in";
108 static const char s_extra_expression
[] = "Extra expression in";
109 static const char s_empty_combination
[] = "Illegal empty combination";
110 static const char s_missing_body_expression
[] = "Missing body expression in";
111 static const char s_mixed_body_forms
[] = "Mixed definitions and expressions in";
112 static const char s_bad_define
[] = "Bad define placement";
113 static const char s_missing_clauses
[] = "Missing clauses";
114 static const char s_misplaced_else_clause
[] = "Misplaced else clause";
115 static const char s_bad_case_clause
[] = "Bad case clause";
116 static const char s_bad_case_labels
[] = "Bad case labels";
117 static const char s_duplicate_case_label
[] = "Duplicate case label";
118 static const char s_bad_cond_clause
[] = "Bad cond clause";
119 static const char s_missing_recipient
[] = "Missing recipient in";
120 static const char s_bad_variable
[] = "Bad variable";
121 static const char s_bad_bindings
[] = "Bad bindings";
122 static const char s_bad_binding
[] = "Bad binding";
123 static const char s_duplicate_binding
[] = "Duplicate binding";
124 static const char s_bad_exit_clause
[] = "Bad exit clause";
125 static const char s_bad_formals
[] = "Bad formals";
126 static const char s_bad_formal
[] = "Bad formal";
127 static const char s_duplicate_formal
[] = "Duplicate formal";
128 static const char s_splicing
[] = "Non-list result for unquote-splicing";
129 static const char s_bad_slot_number
[] = "Bad slot number";
131 static void syntax_error (const char* const, const SCM
, const SCM
) SCM_NORETURN
;
133 SCM_SYMBOL (syntax_error_key
, "syntax-error");
135 /* Shortcut macros to simplify syntax error handling. */
136 #define ASSERT_SYNTAX(cond, message, form) \
137 { if (SCM_UNLIKELY (!(cond))) \
138 syntax_error (message, form, SCM_UNDEFINED); }
139 #define ASSERT_SYNTAX_2(cond, message, form, expr) \
140 { if (SCM_UNLIKELY (!(cond))) \
141 syntax_error (message, form, expr); }
146 /* Primitive syntax. */
148 #define SCM_SYNTAX(STR, CFN) \
149 SCM_SNARF_HERE(static SCM CFN (SCM xorig, SCM env)) \
150 SCM_SNARF_INIT(scm_c_define (STR, scm_i_make_primitive_macro (STR, CFN)))
153 /* True primitive syntax */
154 SCM_SYNTAX ("@", expand_at
);
155 SCM_SYNTAX ("@@", expand_atat
);
156 SCM_SYNTAX ("begin", expand_begin
);
157 SCM_SYNTAX ("define", expand_define
);
158 SCM_SYNTAX ("with-fluids", expand_with_fluids
);
159 SCM_SYNTAX ("eval-when", expand_eval_when
);
160 SCM_SYNTAX ("if", expand_if
);
161 SCM_SYNTAX ("lambda", expand_lambda
);
162 SCM_SYNTAX ("let", expand_let
);
163 SCM_SYNTAX ("quote", expand_quote
);
164 SCM_SYNTAX ("set!", expand_set_x
);
166 /* Convenient syntax during boot, expands to primitive syntax. Replaced after
168 SCM_SYNTAX ("and", expand_and
);
169 SCM_SYNTAX ("cond", expand_cond
);
170 SCM_SYNTAX ("letrec", expand_letrec
);
171 SCM_SYNTAX ("letrec*", expand_letrec_star
);
172 SCM_SYNTAX ("let*", expand_letstar
);
173 SCM_SYNTAX ("or", expand_or
);
174 SCM_SYNTAX ("lambda*", expand_lambda_star
);
175 SCM_SYNTAX ("case-lambda", expand_case_lambda
);
176 SCM_SYNTAX ("case-lambda*", expand_case_lambda_star
);
179 SCM_GLOBAL_SYMBOL (scm_sym_apply
, "apply");
180 SCM_GLOBAL_SYMBOL (scm_sym_arrow
, "=>");
181 SCM_GLOBAL_SYMBOL (scm_sym_at
, "@");
182 SCM_GLOBAL_SYMBOL (scm_sym_atat
, "@@");
183 SCM_GLOBAL_SYMBOL (scm_sym_begin
, "begin");
184 SCM_GLOBAL_SYMBOL (scm_sym_case
, "case");
185 SCM_GLOBAL_SYMBOL (scm_sym_cond
, "cond");
186 SCM_GLOBAL_SYMBOL (scm_sym_define
, "define");
187 SCM_GLOBAL_SYMBOL (scm_sym_with_fluids
, "with-fluids");
188 SCM_GLOBAL_SYMBOL (scm_sym_else
, "else");
189 SCM_GLOBAL_SYMBOL (scm_sym_eval_when
, "eval-when");
190 SCM_GLOBAL_SYMBOL (scm_sym_if
, "if");
191 SCM_GLOBAL_SYMBOL (scm_sym_lambda
, "lambda");
192 SCM_GLOBAL_SYMBOL (scm_sym_let
, "let");
193 SCM_GLOBAL_SYMBOL (scm_sym_letrec
, "letrec");
194 SCM_GLOBAL_SYMBOL (scm_sym_letstar
, "let*");
195 SCM_GLOBAL_SYMBOL (scm_sym_or
, "or");
196 SCM_SYMBOL (sym_call_with_prompt
, "call-with-prompt");
197 SCM_GLOBAL_SYMBOL (scm_sym_quote
, "quote");
198 SCM_GLOBAL_SYMBOL (scm_sym_set_x
, "set!");
199 SCM_SYMBOL (sym_lambda_star
, "lambda*");
200 SCM_SYMBOL (sym_eval
, "eval");
201 SCM_SYMBOL (sym_load
, "load");
202 SCM_SYMBOL (sym_primitive
, "primitive");
204 SCM_GLOBAL_SYMBOL (scm_sym_unquote
, "unquote");
205 SCM_GLOBAL_SYMBOL (scm_sym_quasiquote
, "quasiquote");
206 SCM_GLOBAL_SYMBOL (scm_sym_uq_splicing
, "unquote-splicing");
208 SCM_KEYWORD (kw_allow_other_keys
, "allow-other-keys");
209 SCM_KEYWORD (kw_optional
, "optional");
210 SCM_KEYWORD (kw_key
, "key");
211 SCM_KEYWORD (kw_rest
, "rest");
217 /* Signal a syntax error. We distinguish between the form that caused the
218 * error and the enclosing expression. The error message will print out as
219 * shown in the following pattern. The file name and line number are only
220 * given when they can be determined from the erroneous form or from the
221 * enclosing expression.
223 * <filename>: In procedure memoization:
224 * <filename>: In file <name>, line <nr>: <error-message> in <expression>. */
227 syntax_error (const char* const msg
, const SCM form
, const SCM expr
)
229 SCM msg_string
= scm_from_locale_string (msg
);
230 SCM filename
= SCM_BOOL_F
;
231 SCM linenr
= SCM_BOOL_F
;
235 if (scm_is_pair (form
))
237 filename
= scm_source_property (form
, scm_sym_filename
);
238 linenr
= scm_source_property (form
, scm_sym_line
);
241 if (scm_is_false (filename
) && scm_is_false (linenr
) && scm_is_pair (expr
))
243 filename
= scm_source_property (expr
, scm_sym_filename
);
244 linenr
= scm_source_property (expr
, scm_sym_line
);
247 if (!SCM_UNBNDP (expr
))
249 if (scm_is_true (filename
))
251 format
= "In file ~S, line ~S: ~A ~S in expression ~S.";
252 args
= scm_list_5 (filename
, linenr
, msg_string
, form
, expr
);
254 else if (scm_is_true (linenr
))
256 format
= "In line ~S: ~A ~S in expression ~S.";
257 args
= scm_list_4 (linenr
, msg_string
, form
, expr
);
261 format
= "~A ~S in expression ~S.";
262 args
= scm_list_3 (msg_string
, form
, expr
);
267 if (scm_is_true (filename
))
269 format
= "In file ~S, line ~S: ~A ~S.";
270 args
= scm_list_4 (filename
, linenr
, msg_string
, form
);
272 else if (scm_is_true (linenr
))
274 format
= "In line ~S: ~A ~S.";
275 args
= scm_list_3 (linenr
, msg_string
, form
);
280 args
= scm_list_2 (msg_string
, form
);
284 scm_error (syntax_error_key
, "memoization", format
, args
, SCM_BOOL_F
);
292 expand_env_var_is_free (SCM env
, SCM x
)
294 for (; scm_is_pair (env
); env
= CDR (env
))
295 if (scm_is_eq (x
, CAAR (env
)))
296 return 0; /* bound */
301 expand_env_ref_macro (SCM env
, SCM x
)
304 if (!expand_env_var_is_free (env
, x
))
305 return SCM_BOOL_F
; /* lexical */
307 var
= scm_module_variable (scm_current_module (), x
);
308 if (scm_is_true (var
) && scm_is_true (scm_variable_bound_p (var
))
309 && scm_is_true (scm_macro_p (scm_variable_ref (var
))))
310 return scm_variable_ref (var
);
312 return SCM_BOOL_F
; /* anything else */
316 expand_env_lexical_gensym (SCM env
, SCM name
)
318 for (; scm_is_pair (env
); env
= CDR (env
))
319 if (scm_is_eq (name
, CAAR (env
)))
320 return CDAR (env
); /* bound */
321 return SCM_BOOL_F
; /* free */
325 expand_env_extend (SCM env
, SCM names
, SCM vars
)
327 while (scm_is_pair (names
))
329 env
= scm_acons (CAR (names
), CAR (vars
), env
);
337 expand (SCM exp
, SCM env
)
339 if (scm_is_pair (exp
))
342 scm_t_macro_primitive trans
= NULL
;
343 SCM macro
= SCM_BOOL_F
;
346 if (scm_is_symbol (car
))
347 macro
= expand_env_ref_macro (env
, car
);
349 if (scm_is_true (macro
))
350 trans
= scm_i_macro_primitive (macro
);
353 return trans (exp
, env
);
356 SCM arg_exps
= SCM_EOL
;
358 SCM proc
= expand (CAR (exp
), env
);
360 for (arg_exps
= CDR (exp
); scm_is_pair (arg_exps
);
361 arg_exps
= CDR (arg_exps
))
362 args
= scm_cons (expand (CAR (arg_exps
), env
), args
);
363 args
= scm_reverse_x (args
, SCM_UNDEFINED
);
365 if (!scm_is_null (arg_exps
))
366 syntax_error ("expected a proper list", exp
, SCM_UNDEFINED
);
368 if (SCM_EXPANDED_TYPE (proc
) == SCM_EXPANDED_PRIMITIVE_REF
)
369 return PRIMCALL (scm_source_properties (exp
),
370 SCM_EXPANDED_REF (proc
, PRIMITIVE_REF
, NAME
),
373 return CALL (scm_source_properties (exp
), proc
, args
);
376 else if (scm_is_symbol (exp
))
378 SCM gensym
= expand_env_lexical_gensym (env
, exp
);
379 if (scm_is_true (gensym
))
380 return LEXICAL_REF (SCM_BOOL_F
, exp
, gensym
);
382 return TOPLEVEL_REF (SCM_BOOL_F
, exp
);
385 return CONST_ (SCM_BOOL_F
, exp
);
389 expand_exprs (SCM forms
, const SCM env
)
393 for (; !scm_is_null (forms
); forms
= CDR (forms
))
394 ret
= scm_cons (expand (CAR (forms
), env
), ret
);
395 return scm_reverse_x (ret
, SCM_UNDEFINED
);
399 expand_sequence (const SCM forms
, const SCM env
)
401 ASSERT_SYNTAX (scm_ilength (forms
) >= 1, s_bad_expression
,
402 scm_cons (scm_sym_begin
, forms
));
403 if (scm_is_null (CDR (forms
)))
404 return expand (CAR (forms
), env
);
406 return SEQ (scm_source_properties (forms
),
407 expand (CAR (forms
), env
),
408 expand_sequence (CDR (forms
), env
));
416 expand_at (SCM expr
, SCM env SCM_UNUSED
)
418 ASSERT_SYNTAX (scm_ilength (expr
) == 3, s_bad_expression
, expr
);
419 ASSERT_SYNTAX (scm_ilength (CADR (expr
)) > 0, s_bad_expression
, expr
);
420 ASSERT_SYNTAX (scm_is_symbol (CADDR (expr
)), s_bad_expression
, expr
);
422 return MODULE_REF (scm_source_properties (expr
),
423 CADR (expr
), CADDR (expr
), SCM_BOOL_T
);
427 expand_atat (SCM expr
, SCM env SCM_UNUSED
)
429 ASSERT_SYNTAX (scm_ilength (expr
) == 3, s_bad_expression
, expr
);
430 ASSERT_SYNTAX (scm_is_symbol (CADDR (expr
)), s_bad_expression
, expr
);
432 if (scm_is_eq (CADR (expr
), sym_primitive
))
433 return PRIMITIVE_REF (scm_source_properties (expr
), CADDR (expr
));
435 ASSERT_SYNTAX (scm_ilength (CADR (expr
)) > 0, s_bad_expression
, expr
);
436 return MODULE_REF (scm_source_properties (expr
),
437 CADR (expr
), CADDR (expr
), SCM_BOOL_F
);
441 expand_and (SCM expr
, SCM env
)
443 const SCM cdr_expr
= CDR (expr
);
445 if (scm_is_null (cdr_expr
))
446 return CONST_ (SCM_BOOL_F
, SCM_BOOL_T
);
448 ASSERT_SYNTAX (scm_is_pair (cdr_expr
), s_bad_expression
, expr
);
450 if (scm_is_null (CDR (cdr_expr
)))
451 return expand (CAR (cdr_expr
), env
);
453 return CONDITIONAL (scm_source_properties (expr
),
454 expand (CAR (cdr_expr
), env
),
455 expand_and (cdr_expr
, env
),
456 CONST_ (SCM_BOOL_F
, SCM_BOOL_F
));
460 expand_begin (SCM expr
, SCM env
)
462 const SCM cdr_expr
= CDR (expr
);
463 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 1, s_bad_expression
, expr
);
464 return expand_sequence (cdr_expr
, env
);
468 expand_cond_clauses (SCM clause
, SCM rest
, int elp
, int alp
, SCM env
)
471 const long length
= scm_ilength (clause
);
472 ASSERT_SYNTAX (length
>= 1, s_bad_cond_clause
, clause
);
475 if (scm_is_eq (test
, scm_sym_else
) && elp
)
477 const int last_clause_p
= scm_is_null (rest
);
478 ASSERT_SYNTAX (length
>= 2, s_bad_cond_clause
, clause
);
479 ASSERT_SYNTAX (last_clause_p
, s_misplaced_else_clause
, clause
);
480 return expand_sequence (CDR (clause
), env
);
483 if (scm_is_null (rest
))
484 rest
= VOID_ (SCM_BOOL_F
);
486 rest
= expand_cond_clauses (CAR (rest
), CDR (rest
), elp
, alp
, env
);
489 && scm_is_eq (CADR (clause
), scm_sym_arrow
)
492 SCM tmp
= scm_gensym (scm_from_locale_string ("cond "));
493 SCM new_env
= scm_acons (tmp
, tmp
, env
);
494 ASSERT_SYNTAX (length
> 2, s_missing_recipient
, clause
);
495 ASSERT_SYNTAX (length
== 3, s_extra_expression
, clause
);
496 return LET (SCM_BOOL_F
,
499 scm_list_1 (expand (test
, env
)),
500 CONDITIONAL (SCM_BOOL_F
,
501 LEXICAL_REF (SCM_BOOL_F
, tmp
, tmp
),
503 expand (CADDR (clause
), new_env
),
504 scm_list_1 (LEXICAL_REF (SCM_BOOL_F
,
508 /* FIXME length == 1 case */
510 return CONDITIONAL (SCM_BOOL_F
,
512 expand_sequence (CDR (clause
), env
),
517 expand_cond (SCM expr
, SCM env
)
519 const int else_literal_p
= expand_env_var_is_free (env
, scm_sym_else
);
520 const int arrow_literal_p
= expand_env_var_is_free (env
, scm_sym_arrow
);
521 const SCM clauses
= CDR (expr
);
523 ASSERT_SYNTAX (scm_ilength (clauses
) >= 0, s_bad_expression
, expr
);
524 ASSERT_SYNTAX (scm_ilength (clauses
) >= 1, s_missing_clauses
, expr
);
526 return expand_cond_clauses (CAR (clauses
), CDR (clauses
),
527 else_literal_p
, arrow_literal_p
, env
);
530 /* lone forward decl */
531 static SCM
expand_lambda (SCM expr
, SCM env
);
533 /* According to Section 5.2.1 of R5RS we first have to make sure that the
534 variable is bound, and then perform the `(set! variable expression)'
535 operation. However, EXPRESSION _can_ be evaluated before VARIABLE is
536 bound. This means that EXPRESSION won't necessarily be able to assign
537 values to VARIABLE as in `(define foo (begin (set! foo 1) (+ foo 1)))'. */
539 expand_define (SCM expr
, SCM env
)
541 const SCM cdr_expr
= CDR (expr
);
545 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
546 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 2, s_missing_expression
, expr
);
547 ASSERT_SYNTAX (!scm_is_pair (env
), s_bad_define
, expr
);
549 body
= CDR (cdr_expr
);
550 variable
= CAR (cdr_expr
);
552 if (scm_is_pair (variable
))
554 ASSERT_SYNTAX_2 (scm_is_symbol (CAR (variable
)), s_bad_variable
, variable
, expr
);
555 return TOPLEVEL_DEFINE
556 (scm_source_properties (expr
),
558 expand_lambda (scm_cons (scm_sym_lambda
, scm_cons (CDR (variable
), body
)),
561 ASSERT_SYNTAX_2 (scm_is_symbol (variable
), s_bad_variable
, variable
, expr
);
562 ASSERT_SYNTAX (scm_ilength (body
) == 1, s_expression
, expr
);
563 return TOPLEVEL_DEFINE (scm_source_properties (expr
), variable
,
564 expand (CAR (body
), env
));
568 expand_with_fluids (SCM expr
, SCM env
)
570 SCM binds
, fluids
, vals
;
571 ASSERT_SYNTAX (scm_ilength (expr
) >= 3, s_bad_expression
, expr
);
573 ASSERT_SYNTAX_2 (scm_ilength (binds
) >= 0, s_bad_bindings
, binds
, expr
);
574 for (fluids
= SCM_EOL
, vals
= SCM_EOL
;
578 SCM binding
= CAR (binds
);
579 ASSERT_SYNTAX_2 (scm_ilength (CAR (binds
)) == 2, s_bad_binding
,
581 fluids
= scm_cons (expand (CAR (binding
), env
), fluids
);
582 vals
= scm_cons (expand (CADR (binding
), env
), vals
);
585 return DYNLET (scm_source_properties (expr
),
586 scm_reverse_x (fluids
, SCM_UNDEFINED
),
587 scm_reverse_x (vals
, SCM_UNDEFINED
),
588 expand_sequence (CDDR (expr
), env
));
592 expand_eval_when (SCM expr
, SCM env
)
594 ASSERT_SYNTAX (scm_ilength (expr
) >= 3, s_bad_expression
, expr
);
595 ASSERT_SYNTAX (scm_ilength (CADR (expr
)) > 0, s_bad_expression
, expr
);
597 if (scm_is_true (scm_memq (sym_eval
, CADR (expr
)))
598 || scm_is_true (scm_memq (sym_load
, CADR (expr
))))
599 return expand_sequence (CDDR (expr
), env
);
601 return VOID_ (scm_source_properties (expr
));
605 expand_if (SCM expr
, SCM env SCM_UNUSED
)
607 const SCM cdr_expr
= CDR (expr
);
608 const long length
= scm_ilength (cdr_expr
);
609 ASSERT_SYNTAX (length
== 2 || length
== 3, s_expression
, expr
);
610 return CONDITIONAL (scm_source_properties (expr
),
611 expand (CADR (expr
), env
),
612 expand (CADDR (expr
), env
),
614 ? expand (CADDDR (expr
), env
)
615 : VOID_ (SCM_BOOL_F
)));
618 /* A helper function for expand_lambda to support checking for duplicate
619 * formal arguments: Return true if OBJ is `eq?' to one of the elements of
620 * LIST or to the CDR of the last cons. Therefore, LIST may have any of the
621 * forms that a formal argument can have:
622 * <rest>, (<arg1> ...), (<arg1> ... . <rest>) */
624 c_improper_memq (SCM obj
, SCM list
)
626 for (; scm_is_pair (list
); list
= CDR (list
))
628 if (scm_is_eq (CAR (list
), obj
))
631 return scm_is_eq (list
, obj
);
635 expand_lambda_case (SCM clause
, SCM alternate
, SCM env
)
644 ASSERT_SYNTAX (scm_is_pair (clause
) && scm_is_pair (CDR (clause
)),
645 s_bad_expression
, scm_cons (scm_sym_lambda
, clause
));
647 /* Before iterating the list of formal arguments, make sure the formals
648 * actually are given as either a symbol or a non-cyclic list. */
649 formals
= CAR (clause
);
650 if (scm_is_pair (formals
))
652 /* Dirk:FIXME:: We should check for a cyclic list of formals, and if
653 * detected, report a 'Bad formals' error. */
656 ASSERT_SYNTAX_2 (scm_is_symbol (formals
) || scm_is_null (formals
),
657 s_bad_formals
, formals
, scm_cons (scm_sym_lambda
, clause
));
659 /* Now iterate the list of formal arguments to check if all formals are
660 * symbols, and that there are no duplicates. */
661 while (scm_is_pair (formals
))
663 const SCM formal
= CAR (formals
);
664 formals
= CDR (formals
);
665 ASSERT_SYNTAX_2 (scm_is_symbol (formal
), s_bad_formal
, formal
,
666 scm_cons (scm_sym_lambda
, clause
));
667 ASSERT_SYNTAX_2 (!c_improper_memq (formal
, formals
), s_duplicate_formal
,
668 formal
, scm_cons (scm_sym_lambda
, clause
));
670 req
= scm_cons (formal
, req
);
671 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
672 env
= scm_acons (formal
, CAR (vars
), env
);
675 ASSERT_SYNTAX_2 (scm_is_null (formals
) || scm_is_symbol (formals
),
676 s_bad_formal
, formals
, scm_cons (scm_sym_lambda
, clause
));
677 if (scm_is_symbol (formals
))
680 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
681 env
= scm_acons (rest
, CAR (vars
), env
);
686 body
= expand_sequence (CDR (clause
), env
);
687 req
= scm_reverse_x (req
, SCM_UNDEFINED
);
688 vars
= scm_reverse_x (vars
, SCM_UNDEFINED
);
690 if (scm_is_true (alternate
) && !(SCM_EXPANDED_P (alternate
) && SCM_EXPANDED_TYPE (alternate
) == SCM_EXPANDED_LAMBDA_CASE
))
693 return LAMBDA_CASE (SCM_BOOL_F
, req
, SCM_BOOL_F
, rest
, SCM_BOOL_F
,
694 SCM_EOL
, vars
, body
, alternate
);
698 expand_lambda (SCM expr
, SCM env
)
700 return LAMBDA (scm_source_properties (expr
),
702 expand_lambda_case (CDR (expr
), SCM_BOOL_F
, env
));
706 expand_lambda_star_case (SCM clause
, SCM alternate
, SCM env
)
708 SCM req
, opt
, kw
, allow_other_keys
, rest
, formals
, vars
, body
, tmp
;
712 const long length
= scm_ilength (clause
);
713 ASSERT_SYNTAX (length
>= 1, s_bad_expression
,
714 scm_cons (sym_lambda_star
, clause
));
715 ASSERT_SYNTAX (length
>= 2, s_missing_expression
,
716 scm_cons (sym_lambda_star
, clause
));
718 formals
= CAR (clause
);
722 req
= opt
= kw
= SCM_EOL
;
723 rest
= allow_other_keys
= SCM_BOOL_F
;
725 while (scm_is_pair (formals
) && scm_is_symbol (CAR (formals
)))
728 req
= scm_cons (CAR (formals
), req
);
729 formals
= scm_cdr (formals
);
732 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_optional
))
734 formals
= CDR (formals
);
735 while (scm_is_pair (formals
)
736 && (scm_is_symbol (CAR (formals
)) || scm_is_pair (CAR (formals
))))
739 opt
= scm_cons (CAR (formals
), opt
);
740 formals
= scm_cdr (formals
);
744 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_key
))
746 formals
= CDR (formals
);
747 while (scm_is_pair (formals
)
748 && (scm_is_symbol (CAR (formals
)) || scm_is_pair (CAR (formals
))))
750 kw
= scm_cons (CAR (formals
), kw
);
751 formals
= scm_cdr (formals
);
755 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_allow_other_keys
))
757 formals
= CDR (formals
);
758 allow_other_keys
= SCM_BOOL_T
;
761 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_rest
))
763 ASSERT_SYNTAX (scm_ilength (formals
) == 2, s_bad_formals
,
765 rest
= CADR (formals
);
767 else if (scm_is_symbol (formals
))
771 ASSERT_SYNTAX (scm_is_null (formals
), s_bad_formals
, CAR (clause
));
775 /* Now, iterate through them a second time, building up an expansion-time
776 environment, checking, expanding and canonicalizing the opt/kw init forms,
777 and eventually memoizing the body as well. Note that the rest argument, if
778 any, is expanded before keyword args, thus necessitating the second
781 Also note that the specific environment during expansion of init
782 expressions here needs to coincide with the environment when psyntax
783 expands. A lot of effort for something that is only used in the bootstrap
784 expandr, you say? Yes. Yes it is.
788 req
= scm_reverse_x (req
, SCM_EOL
);
789 for (tmp
= req
; scm_is_pair (tmp
); tmp
= scm_cdr (tmp
))
791 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
792 env
= scm_acons (CAR (tmp
), CAR (vars
), env
);
795 /* Build up opt inits and env */
797 opt
= scm_reverse_x (opt
, SCM_EOL
);
798 for (tmp
= opt
; scm_is_pair (tmp
); tmp
= scm_cdr (tmp
))
801 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
802 env
= scm_acons (x
, CAR (vars
), env
);
803 if (scm_is_symbol (x
))
804 inits
= scm_cons (CONST_ (SCM_BOOL_F
, SCM_BOOL_F
), inits
);
807 ASSERT_SYNTAX (scm_ilength (x
) == 2 && scm_is_symbol (CAR (x
)),
808 s_bad_formals
, CAR (clause
));
809 inits
= scm_cons (expand (CADR (x
), env
), inits
);
811 env
= scm_acons (scm_is_symbol (x
) ? x
: CAR (x
), CAR (vars
), env
);
813 if (scm_is_null (opt
))
816 /* Process rest before keyword args */
817 if (scm_is_true (rest
))
819 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
820 env
= scm_acons (rest
, CAR (vars
), env
);
823 /* Build up kw inits, env, and kw-canon list */
824 if (scm_is_null (kw
))
828 SCM kw_canon
= SCM_EOL
;
829 kw
= scm_reverse_x (kw
, SCM_UNDEFINED
);
830 for (tmp
= kw
; scm_is_pair (tmp
); tmp
= scm_cdr (tmp
))
834 if (scm_is_symbol (x
))
838 k
= scm_symbol_to_keyword (sym
);
840 else if (scm_ilength (x
) == 2 && scm_is_symbol (CAR (x
)))
844 k
= scm_symbol_to_keyword (sym
);
846 else if (scm_ilength (x
) == 3 && scm_is_symbol (CAR (x
))
847 && scm_is_keyword (CADDR (x
)))
854 syntax_error (s_bad_formals
, CAR (clause
), SCM_UNDEFINED
);
856 inits
= scm_cons (expand (init
, env
), inits
);
857 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
858 kw_canon
= scm_cons (scm_list_3 (k
, sym
, CAR (vars
)), kw_canon
);
859 env
= scm_acons (sym
, CAR (vars
), env
);
861 kw_canon
= scm_reverse_x (kw_canon
, SCM_UNDEFINED
);
862 kw
= scm_cons (allow_other_keys
, kw_canon
);
865 /* We should check for no duplicates, but given that psyntax does this
866 already, we can punt on it here... */
868 vars
= scm_reverse_x (vars
, SCM_UNDEFINED
);
869 inits
= scm_reverse_x (inits
, SCM_UNDEFINED
);
870 body
= expand_sequence (body
, env
);
872 return LAMBDA_CASE (SCM_BOOL_F
, req
, opt
, rest
, kw
, inits
, vars
, body
,
877 expand_lambda_star (SCM expr
, SCM env
)
879 return LAMBDA (scm_source_properties (expr
),
881 expand_lambda_star_case (CDR (expr
), SCM_BOOL_F
, env
));
885 expand_case_lambda_clauses (SCM expr
, SCM rest
, SCM env
)
889 if (scm_is_pair (rest
))
890 alt
= expand_case_lambda_clauses (CAR (rest
), CDR (rest
), env
);
894 return expand_lambda_case (expr
, alt
, env
);
898 expand_case_lambda (SCM expr
, SCM env
)
900 ASSERT_SYNTAX (scm_is_pair (CDR (expr
)), s_missing_expression
, expr
);
902 return LAMBDA (scm_source_properties (expr
),
904 expand_case_lambda_clauses (CADR (expr
), CDDR (expr
), env
));
908 expand_case_lambda_star_clauses (SCM expr
, SCM rest
, SCM env
)
912 if (scm_is_pair (rest
))
913 alt
= expand_case_lambda_star_clauses (CAR (rest
), CDR (rest
), env
);
917 return expand_lambda_star_case (expr
, alt
, env
);
921 expand_case_lambda_star (SCM expr
, SCM env
)
923 ASSERT_SYNTAX (scm_is_pair (CDR (expr
)), s_missing_expression
, expr
);
925 return LAMBDA (scm_source_properties (expr
),
927 expand_case_lambda_star_clauses (CADR (expr
), CDDR (expr
), env
));
930 /* Check if the format of the bindings is ((<symbol> <init-form>) ...). */
932 check_bindings (const SCM bindings
, const SCM expr
)
936 ASSERT_SYNTAX_2 (scm_ilength (bindings
) >= 0,
937 s_bad_bindings
, bindings
, expr
);
939 binding_idx
= bindings
;
940 for (; !scm_is_null (binding_idx
); binding_idx
= CDR (binding_idx
))
942 SCM name
; /* const */
944 const SCM binding
= CAR (binding_idx
);
945 ASSERT_SYNTAX_2 (scm_ilength (binding
) == 2,
946 s_bad_binding
, binding
, expr
);
948 name
= CAR (binding
);
949 ASSERT_SYNTAX_2 (scm_is_symbol (name
), s_bad_variable
, name
, expr
);
953 /* The bindings, which must have the format ((v1 i1) (v2 i2) ... (vn in)), are
954 * transformed to the lists (vn .. v2 v1) and (i1 i2 ... in). If a duplicate
955 * variable name is detected, an error is signalled. */
957 transform_bindings (const SCM bindings
, const SCM expr
,
958 SCM
*const names
, SCM
*const vars
, SCM
*const initptr
)
960 SCM rnames
= SCM_EOL
;
962 SCM rinits
= SCM_EOL
;
963 SCM binding_idx
= bindings
;
964 for (; !scm_is_null (binding_idx
); binding_idx
= CDR (binding_idx
))
966 const SCM binding
= CAR (binding_idx
);
967 const SCM CDR_binding
= CDR (binding
);
968 const SCM name
= CAR (binding
);
969 ASSERT_SYNTAX_2 (scm_is_false (scm_c_memq (name
, rnames
)),
970 s_duplicate_binding
, name
, expr
);
971 rnames
= scm_cons (name
, rnames
);
972 rvars
= scm_cons (scm_gensym (SCM_UNDEFINED
), rvars
);
973 rinits
= scm_cons (CAR (CDR_binding
), rinits
);
975 *names
= scm_reverse_x (rnames
, SCM_UNDEFINED
);
976 *vars
= scm_reverse_x (rvars
, SCM_UNDEFINED
);
977 *initptr
= scm_reverse_x (rinits
, SCM_UNDEFINED
);
980 /* FIXME: Remove named let in this boot expander. */
982 expand_named_let (const SCM expr
, SCM env
)
984 SCM var_names
, var_syms
, inits
;
988 const SCM cdr_expr
= CDR (expr
);
989 const SCM name
= CAR (cdr_expr
);
990 const SCM cddr_expr
= CDR (cdr_expr
);
991 const SCM bindings
= CAR (cddr_expr
);
992 check_bindings (bindings
, expr
);
994 transform_bindings (bindings
, expr
, &var_names
, &var_syms
, &inits
);
995 name_sym
= scm_gensym (SCM_UNDEFINED
);
996 inner_env
= scm_acons (name
, name_sym
, env
);
997 inner_env
= expand_env_extend (inner_env
, var_names
, var_syms
);
1000 (scm_source_properties (expr
), SCM_BOOL_F
,
1001 scm_list_1 (name
), scm_list_1 (name_sym
),
1002 scm_list_1 (LAMBDA (SCM_BOOL_F
,
1004 LAMBDA_CASE (SCM_BOOL_F
, var_names
, SCM_BOOL_F
, SCM_BOOL_F
,
1005 SCM_BOOL_F
, SCM_BOOL_F
, var_syms
,
1006 expand_sequence (CDDDR (expr
), inner_env
),
1009 LEXICAL_REF (SCM_BOOL_F
, name
, name_sym
),
1010 expand_exprs (inits
, env
)));
1014 expand_let (SCM expr
, SCM env
)
1018 const SCM cdr_expr
= CDR (expr
);
1019 const long length
= scm_ilength (cdr_expr
);
1020 ASSERT_SYNTAX (length
>= 0, s_bad_expression
, expr
);
1021 ASSERT_SYNTAX (length
>= 2, s_missing_expression
, expr
);
1023 bindings
= CAR (cdr_expr
);
1024 if (scm_is_symbol (bindings
))
1026 ASSERT_SYNTAX (length
>= 3, s_missing_expression
, expr
);
1027 return expand_named_let (expr
, env
);
1030 check_bindings (bindings
, expr
);
1031 if (scm_is_null (bindings
))
1032 return expand_sequence (CDDR (expr
), env
);
1035 SCM var_names
, var_syms
, inits
;
1036 transform_bindings (bindings
, expr
, &var_names
, &var_syms
, &inits
);
1037 return LET (SCM_BOOL_F
,
1038 var_names
, var_syms
, expand_exprs (inits
, env
),
1039 expand_sequence (CDDR (expr
),
1040 expand_env_extend (env
, var_names
,
1046 expand_letrec_helper (SCM expr
, SCM env
, SCM in_order_p
)
1050 const SCM cdr_expr
= CDR (expr
);
1051 const long length
= scm_ilength (cdr_expr
);
1052 ASSERT_SYNTAX (length
>= 0, s_bad_expression
, expr
);
1053 ASSERT_SYNTAX (length
>= 2, s_missing_expression
, expr
);
1055 bindings
= CAR (cdr_expr
);
1056 check_bindings (bindings
, expr
);
1057 if (scm_is_null (bindings
))
1058 return expand_sequence (CDDR (expr
), env
);
1061 SCM var_names
, var_syms
, inits
;
1062 transform_bindings (bindings
, expr
, &var_names
, &var_syms
, &inits
);
1063 env
= expand_env_extend (env
, var_names
, var_syms
);
1064 return LETREC (SCM_BOOL_F
, in_order_p
,
1065 var_names
, var_syms
, expand_exprs (inits
, env
),
1066 expand_sequence (CDDR (expr
), env
));
1071 expand_letrec (SCM expr
, SCM env
)
1073 return expand_letrec_helper (expr
, env
, SCM_BOOL_F
);
1077 expand_letrec_star (SCM expr
, SCM env
)
1079 return expand_letrec_helper (expr
, env
, SCM_BOOL_T
);
1083 expand_letstar_clause (SCM bindings
, SCM body
, SCM env SCM_UNUSED
)
1085 if (scm_is_null (bindings
))
1086 return expand_sequence (body
, env
);
1089 SCM bind
, name
, sym
, init
;
1091 ASSERT_SYNTAX (scm_is_pair (bindings
), s_bad_expression
, bindings
);
1092 bind
= CAR (bindings
);
1093 ASSERT_SYNTAX (scm_ilength (bind
) == 2, s_bad_binding
, bind
);
1095 sym
= scm_gensym (SCM_UNDEFINED
);
1098 return LET (SCM_BOOL_F
, scm_list_1 (name
), scm_list_1 (sym
),
1099 scm_list_1 (expand (init
, env
)),
1100 expand_letstar_clause (CDR (bindings
), body
,
1101 scm_acons (name
, sym
, env
)));
1106 expand_letstar (SCM expr
, SCM env SCM_UNUSED
)
1108 const SCM cdr_expr
= CDR (expr
);
1109 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
1110 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 2, s_missing_expression
, expr
);
1112 return expand_letstar_clause (CADR (expr
), CDDR (expr
), env
);
1116 expand_or (SCM expr
, SCM env SCM_UNUSED
)
1118 SCM tail
= CDR (expr
);
1119 const long length
= scm_ilength (tail
);
1121 ASSERT_SYNTAX (length
>= 0, s_bad_expression
, expr
);
1123 if (scm_is_null (CDR (expr
)))
1124 return CONST_ (SCM_BOOL_F
, SCM_BOOL_F
);
1127 SCM tmp
= scm_gensym (SCM_UNDEFINED
);
1128 return LET (SCM_BOOL_F
,
1129 scm_list_1 (tmp
), scm_list_1 (tmp
),
1130 scm_list_1 (expand (CADR (expr
), env
)),
1131 CONDITIONAL (SCM_BOOL_F
,
1132 LEXICAL_REF (SCM_BOOL_F
, tmp
, tmp
),
1133 LEXICAL_REF (SCM_BOOL_F
, tmp
, tmp
),
1134 expand_or (CDR (expr
),
1135 scm_acons (tmp
, tmp
, env
))));
1140 expand_quote (SCM expr
, SCM env SCM_UNUSED
)
1144 const SCM cdr_expr
= CDR (expr
);
1145 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
1146 ASSERT_SYNTAX (scm_ilength (cdr_expr
) == 1, s_expression
, expr
);
1147 quotee
= CAR (cdr_expr
);
1148 return CONST_ (scm_source_properties (expr
), quotee
);
1152 expand_set_x (SCM expr
, SCM env
)
1157 const SCM cdr_expr
= CDR (expr
);
1158 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
1159 ASSERT_SYNTAX (scm_ilength (cdr_expr
) == 2, s_expression
, expr
);
1160 variable
= CAR (cdr_expr
);
1161 vmem
= expand (variable
, env
);
1163 switch (SCM_EXPANDED_TYPE (vmem
))
1165 case SCM_EXPANDED_LEXICAL_REF
:
1166 return LEXICAL_SET (scm_source_properties (expr
),
1167 SCM_EXPANDED_REF (vmem
, LEXICAL_REF
, NAME
),
1168 SCM_EXPANDED_REF (vmem
, LEXICAL_REF
, GENSYM
),
1169 expand (CADDR (expr
), env
));
1170 case SCM_EXPANDED_TOPLEVEL_REF
:
1171 return TOPLEVEL_SET (scm_source_properties (expr
),
1172 SCM_EXPANDED_REF (vmem
, TOPLEVEL_REF
, NAME
),
1173 expand (CADDR (expr
), env
));
1174 case SCM_EXPANDED_MODULE_REF
:
1175 return MODULE_SET (scm_source_properties (expr
),
1176 SCM_EXPANDED_REF (vmem
, MODULE_REF
, MOD
),
1177 SCM_EXPANDED_REF (vmem
, MODULE_REF
, NAME
),
1178 SCM_EXPANDED_REF (vmem
, MODULE_REF
, PUBLIC
),
1179 expand (CADDR (expr
), env
));
1181 syntax_error (s_bad_variable
, variable
, expr
);
1188 /* This is the boot expander. It is later replaced with psyntax's sc-expand. */
1189 SCM_DEFINE (scm_macroexpand
, "macroexpand", 1, 0, 0,
1191 "Expand the expression @var{exp}.")
1192 #define FUNC_NAME s_scm_macroexpand
1194 return expand (exp
, scm_current_module ());
1198 SCM_DEFINE (scm_macroexpanded_p
, "macroexpanded?", 1, 0, 0,
1200 "Return @code{#t} if @var{exp} is an expanded expression.")
1201 #define FUNC_NAME s_scm_macroexpanded_p
1203 return scm_from_bool (SCM_EXPANDED_P (exp
));
1210 #define DEFINE_NAMES(type) \
1212 static const char *fields[] = SCM_EXPANDED_##type##_FIELD_NAMES; \
1213 exp_field_names[SCM_EXPANDED_##type] = fields; \
1214 exp_names[SCM_EXPANDED_##type] = SCM_EXPANDED_##type##_TYPE_NAME; \
1215 exp_nfields[SCM_EXPANDED_##type] = SCM_NUM_EXPANDED_##type##_FIELDS; \
1219 make_exp_vtable (size_t n
)
1221 SCM layout
, printer
, name
, code
, fields
;
1223 layout
= scm_string_to_symbol
1224 (scm_string_append (scm_make_list (scm_from_size_t (exp_nfields
[n
]),
1225 scm_from_locale_string ("pw"))));
1226 printer
= SCM_BOOL_F
;
1227 name
= scm_from_utf8_symbol (exp_names
[n
]);
1228 code
= scm_from_size_t (n
);
1231 size_t m
= exp_nfields
[n
];
1233 fields
= scm_cons (scm_from_utf8_symbol (exp_field_names
[n
][m
]), fields
);
1236 return scm_c_make_struct (scm_exp_vtable_vtable
, 0, 5,
1237 SCM_UNPACK (layout
), SCM_UNPACK (printer
), SCM_UNPACK (name
),
1238 SCM_UNPACK (code
), SCM_UNPACK (fields
));
1245 SCM exp_vtable_list
= SCM_EOL
;
1247 DEFINE_NAMES (VOID
);
1248 DEFINE_NAMES (CONST
);
1249 DEFINE_NAMES (PRIMITIVE_REF
);
1250 DEFINE_NAMES (LEXICAL_REF
);
1251 DEFINE_NAMES (LEXICAL_SET
);
1252 DEFINE_NAMES (MODULE_REF
);
1253 DEFINE_NAMES (MODULE_SET
);
1254 DEFINE_NAMES (TOPLEVEL_REF
);
1255 DEFINE_NAMES (TOPLEVEL_SET
);
1256 DEFINE_NAMES (TOPLEVEL_DEFINE
);
1257 DEFINE_NAMES (CONDITIONAL
);
1258 DEFINE_NAMES (CALL
);
1259 DEFINE_NAMES (PRIMCALL
);
1261 DEFINE_NAMES (LAMBDA
);
1262 DEFINE_NAMES (LAMBDA_CASE
);
1264 DEFINE_NAMES (LETREC
);
1265 DEFINE_NAMES (DYNLET
);
1267 scm_exp_vtable_vtable
=
1268 scm_make_vtable (scm_from_locale_string (SCM_VTABLE_BASE_LAYOUT
"pwuwpw"),
1271 for (n
= 0; n
< SCM_NUM_EXPANDED_TYPES
; n
++)
1272 exp_vtables
[n
] = make_exp_vtable (n
);
1274 /* Now walk back down, consing in reverse. */
1276 exp_vtable_list
= scm_cons (exp_vtables
[n
], exp_vtable_list
);
1278 scm_c_define ("%expanded-vtables", scm_vector (exp_vtable_list
));
1280 #include "libguile/expand.x"