1 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010
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
];
53 SCM_MAKE_EXPANDED_VOID(src)
54 #define CONST(src, exp) \
55 SCM_MAKE_EXPANDED_CONST(src, exp)
56 #define PRIMITIVE_REF_TYPE(src, name) \
57 SCM_MAKE_EXPANDED_PRIMITIVE_REF_TYPE(src, name)
58 #define LEXICAL_REF(src, name, gensym) \
59 SCM_MAKE_EXPANDED_LEXICAL_REF(src, name, gensym)
60 #define LEXICAL_SET(src, name, gensym, exp) \
61 SCM_MAKE_EXPANDED_LEXICAL_SET(src, name, gensym, exp)
62 #define MODULE_REF(src, mod, name, public) \
63 SCM_MAKE_EXPANDED_MODULE_REF(src, mod, name, public)
64 #define MODULE_SET(src, mod, name, public, exp) \
65 SCM_MAKE_EXPANDED_MODULE_SET(src, mod, name, public, exp)
66 #define TOPLEVEL_REF(src, name) \
67 SCM_MAKE_EXPANDED_TOPLEVEL_REF(src, name)
68 #define TOPLEVEL_SET(src, name, exp) \
69 SCM_MAKE_EXPANDED_TOPLEVEL_SET(src, name, exp)
70 #define TOPLEVEL_DEFINE(src, name, exp) \
71 SCM_MAKE_EXPANDED_TOPLEVEL_DEFINE(src, name, exp)
72 #define CONDITIONAL(src, test, consequent, alternate) \
73 SCM_MAKE_EXPANDED_CONDITIONAL(src, test, consequent, alternate)
74 #define APPLICATION(src, proc, exps) \
75 SCM_MAKE_EXPANDED_APPLICATION(src, proc, exps)
76 #define SEQUENCE(src, exps) \
77 SCM_MAKE_EXPANDED_SEQUENCE(src, exps)
78 #define LAMBDA(src, meta, body) \
79 SCM_MAKE_EXPANDED_LAMBDA(src, meta, body)
80 #define LAMBDA_CASE(src, req, opt, rest, kw, inits, gensyms, body, alternate) \
81 SCM_MAKE_EXPANDED_LAMBDA_CASE(src, req, opt, rest, kw, inits, gensyms, body, alternate)
82 #define LET(src, names, gensyms, vals, body) \
83 SCM_MAKE_EXPANDED_LET(src, names, gensyms, vals, body)
84 #define LETREC(src, in_order_p, names, gensyms, vals, body) \
85 SCM_MAKE_EXPANDED_LETREC(src, in_order_p, names, gensyms, vals, body)
86 #define DYNLET(src, fluids, vals, body) \
87 SCM_MAKE_EXPANDED_DYNLET(src, fluids, vals, body)
89 #define CAR(x) SCM_CAR(x)
90 #define CDR(x) SCM_CDR(x)
91 #define CAAR(x) SCM_CAAR(x)
92 #define CADR(x) SCM_CADR(x)
93 #define CDAR(x) SCM_CDAR(x)
94 #define CDDR(x) SCM_CDDR(x)
95 #define CADDR(x) SCM_CADDR(x)
96 #define CDDDR(x) SCM_CDDDR(x)
97 #define CADDDR(x) SCM_CADDDR(x)
100 static const char s_bad_expression
[] = "Bad expression";
101 static const char s_expression
[] = "Missing or extra expression in";
102 static const char s_missing_expression
[] = "Missing expression in";
103 static const char s_extra_expression
[] = "Extra expression in";
104 static const char s_empty_combination
[] = "Illegal empty combination";
105 static const char s_missing_body_expression
[] = "Missing body expression in";
106 static const char s_mixed_body_forms
[] = "Mixed definitions and expressions in";
107 static const char s_bad_define
[] = "Bad define placement";
108 static const char s_missing_clauses
[] = "Missing clauses";
109 static const char s_misplaced_else_clause
[] = "Misplaced else clause";
110 static const char s_bad_case_clause
[] = "Bad case clause";
111 static const char s_bad_case_labels
[] = "Bad case labels";
112 static const char s_duplicate_case_label
[] = "Duplicate case label";
113 static const char s_bad_cond_clause
[] = "Bad cond clause";
114 static const char s_missing_recipient
[] = "Missing recipient in";
115 static const char s_bad_variable
[] = "Bad variable";
116 static const char s_bad_bindings
[] = "Bad bindings";
117 static const char s_bad_binding
[] = "Bad binding";
118 static const char s_duplicate_binding
[] = "Duplicate binding";
119 static const char s_bad_exit_clause
[] = "Bad exit clause";
120 static const char s_bad_formals
[] = "Bad formals";
121 static const char s_bad_formal
[] = "Bad formal";
122 static const char s_duplicate_formal
[] = "Duplicate formal";
123 static const char s_splicing
[] = "Non-list result for unquote-splicing";
124 static const char s_bad_slot_number
[] = "Bad slot number";
126 static void syntax_error (const char* const, const SCM
, const SCM
) SCM_NORETURN
;
128 SCM_SYMBOL (syntax_error_key
, "syntax-error");
130 /* Shortcut macros to simplify syntax error handling. */
131 #define ASSERT_SYNTAX(cond, message, form) \
132 { if (SCM_UNLIKELY (!(cond))) \
133 syntax_error (message, form, SCM_UNDEFINED); }
134 #define ASSERT_SYNTAX_2(cond, message, form, expr) \
135 { if (SCM_UNLIKELY (!(cond))) \
136 syntax_error (message, form, expr); }
141 /* Primitive syntax. */
143 #define SCM_SYNTAX(STR, CFN) \
144 SCM_SNARF_HERE(static SCM CFN (SCM xorig, SCM env)) \
145 SCM_SNARF_INIT(scm_c_define (STR, scm_i_make_primitive_macro (STR, CFN)))
148 /* True primitive syntax */
149 SCM_SYNTAX ("@", expand_at
);
150 SCM_SYNTAX ("@@", expand_atat
);
151 SCM_SYNTAX ("begin", expand_begin
);
152 SCM_SYNTAX ("define", expand_define
);
153 SCM_SYNTAX ("with-fluids", expand_with_fluids
);
154 SCM_SYNTAX ("eval-when", expand_eval_when
);
155 SCM_SYNTAX ("if", expand_if
);
156 SCM_SYNTAX ("lambda", expand_lambda
);
157 SCM_SYNTAX ("let", expand_let
);
158 SCM_SYNTAX ("quote", expand_quote
);
159 SCM_SYNTAX ("set!", expand_set_x
);
161 /* Convenient syntax during boot, expands to primitive syntax. Replaced after
163 SCM_SYNTAX ("and", expand_and
);
164 SCM_SYNTAX ("cond", expand_cond
);
165 SCM_SYNTAX ("letrec", expand_letrec
);
166 SCM_SYNTAX ("letrec*", expand_letrec_star
);
167 SCM_SYNTAX ("let*", expand_letstar
);
168 SCM_SYNTAX ("or", expand_or
);
169 SCM_SYNTAX ("lambda*", expand_lambda_star
);
170 SCM_SYNTAX ("case-lambda", expand_case_lambda
);
171 SCM_SYNTAX ("case-lambda*", expand_case_lambda_star
);
174 SCM_GLOBAL_SYMBOL (scm_sym_apply
, "apply");
175 SCM_GLOBAL_SYMBOL (scm_sym_arrow
, "=>");
176 SCM_GLOBAL_SYMBOL (scm_sym_at
, "@");
177 SCM_GLOBAL_SYMBOL (scm_sym_atat
, "@@");
178 SCM_GLOBAL_SYMBOL (scm_sym_at_call_with_values
, "@call-with-values");
179 SCM_GLOBAL_SYMBOL (scm_sym_atapply
, "@apply");
180 SCM_GLOBAL_SYMBOL (scm_sym_atcall_cc
, "@call-with-current-continuation");
181 SCM_GLOBAL_SYMBOL (scm_sym_begin
, "begin");
182 SCM_GLOBAL_SYMBOL (scm_sym_case
, "case");
183 SCM_GLOBAL_SYMBOL (scm_sym_cond
, "cond");
184 SCM_GLOBAL_SYMBOL (scm_sym_define
, "define");
185 SCM_GLOBAL_SYMBOL (scm_sym_at_dynamic_wind
, "@dynamic-wind");
186 SCM_GLOBAL_SYMBOL (scm_sym_with_fluids
, "with-fluids");
187 SCM_GLOBAL_SYMBOL (scm_sym_else
, "else");
188 SCM_GLOBAL_SYMBOL (scm_sym_eval_when
, "eval-when");
189 SCM_GLOBAL_SYMBOL (scm_sym_if
, "if");
190 SCM_GLOBAL_SYMBOL (scm_sym_lambda
, "lambda");
191 SCM_GLOBAL_SYMBOL (scm_sym_let
, "let");
192 SCM_GLOBAL_SYMBOL (scm_sym_letrec
, "letrec");
193 SCM_GLOBAL_SYMBOL (scm_sym_letstar
, "let*");
194 SCM_GLOBAL_SYMBOL (scm_sym_or
, "or");
195 SCM_GLOBAL_SYMBOL (scm_sym_at_prompt
, "@prompt");
196 SCM_GLOBAL_SYMBOL (scm_sym_quote
, "quote");
197 SCM_GLOBAL_SYMBOL (scm_sym_set_x
, "set!");
198 SCM_SYMBOL (sym_lambda_star
, "lambda*");
199 SCM_SYMBOL (sym_eval
, "eval");
200 SCM_SYMBOL (sym_load
, "load");
202 SCM_GLOBAL_SYMBOL (scm_sym_unquote
, "unquote");
203 SCM_GLOBAL_SYMBOL (scm_sym_quasiquote
, "quasiquote");
204 SCM_GLOBAL_SYMBOL (scm_sym_uq_splicing
, "unquote-splicing");
206 SCM_KEYWORD (kw_allow_other_keys
, "allow-other-keys");
207 SCM_KEYWORD (kw_optional
, "optional");
208 SCM_KEYWORD (kw_key
, "key");
209 SCM_KEYWORD (kw_rest
, "rest");
215 /* Signal a syntax error. We distinguish between the form that caused the
216 * error and the enclosing expression. The error message will print out as
217 * shown in the following pattern. The file name and line number are only
218 * given when they can be determined from the erroneous form or from the
219 * enclosing expression.
221 * <filename>: In procedure memoization:
222 * <filename>: In file <name>, line <nr>: <error-message> in <expression>. */
225 syntax_error (const char* const msg
, const SCM form
, const SCM expr
)
227 SCM msg_string
= scm_from_locale_string (msg
);
228 SCM filename
= SCM_BOOL_F
;
229 SCM linenr
= SCM_BOOL_F
;
233 if (scm_is_pair (form
))
235 filename
= scm_source_property (form
, scm_sym_filename
);
236 linenr
= scm_source_property (form
, scm_sym_line
);
239 if (scm_is_false (filename
) && scm_is_false (linenr
) && scm_is_pair (expr
))
241 filename
= scm_source_property (expr
, scm_sym_filename
);
242 linenr
= scm_source_property (expr
, scm_sym_line
);
245 if (!SCM_UNBNDP (expr
))
247 if (scm_is_true (filename
))
249 format
= "In file ~S, line ~S: ~A ~S in expression ~S.";
250 args
= scm_list_5 (filename
, linenr
, msg_string
, form
, expr
);
252 else if (scm_is_true (linenr
))
254 format
= "In line ~S: ~A ~S in expression ~S.";
255 args
= scm_list_4 (linenr
, msg_string
, form
, expr
);
259 format
= "~A ~S in expression ~S.";
260 args
= scm_list_3 (msg_string
, form
, expr
);
265 if (scm_is_true (filename
))
267 format
= "In file ~S, line ~S: ~A ~S.";
268 args
= scm_list_4 (filename
, linenr
, msg_string
, form
);
270 else if (scm_is_true (linenr
))
272 format
= "In line ~S: ~A ~S.";
273 args
= scm_list_3 (linenr
, msg_string
, form
);
278 args
= scm_list_2 (msg_string
, form
);
282 scm_error (syntax_error_key
, "memoization", format
, args
, SCM_BOOL_F
);
290 expand_env_var_is_free (SCM env
, SCM x
)
292 for (; scm_is_pair (env
); env
= CDR (env
))
293 if (scm_is_eq (x
, CAAR (env
)))
294 return 0; /* bound */
299 expand_env_ref_macro (SCM env
, SCM x
)
302 if (!expand_env_var_is_free (env
, x
))
303 return SCM_BOOL_F
; /* lexical */
305 var
= scm_module_variable (scm_current_module (), x
);
306 if (scm_is_true (var
) && scm_is_true (scm_variable_bound_p (var
))
307 && scm_is_true (scm_macro_p (scm_variable_ref (var
))))
308 return scm_variable_ref (var
);
310 return SCM_BOOL_F
; /* anything else */
314 expand_env_lexical_gensym (SCM env
, SCM name
)
316 for (; scm_is_pair (env
); env
= CDR (env
))
317 if (scm_is_eq (name
, CAAR (env
)))
318 return CDAR (env
); /* bound */
319 return SCM_BOOL_F
; /* free */
323 expand_env_extend (SCM env
, SCM names
, SCM vars
)
325 while (scm_is_pair (names
))
327 env
= scm_acons (CAR (names
), CAR (vars
), env
);
335 expand (SCM exp
, SCM env
)
337 if (scm_is_pair (exp
))
340 scm_t_macro_primitive trans
= NULL
;
341 SCM macro
= SCM_BOOL_F
;
344 if (scm_is_symbol (car
))
345 macro
= expand_env_ref_macro (env
, car
);
347 if (scm_is_true (macro
))
348 trans
= scm_i_macro_primitive (macro
);
351 return trans (exp
, env
);
354 SCM arg_exps
= SCM_EOL
;
356 SCM proc
= CAR (exp
);
358 for (arg_exps
= CDR (exp
); scm_is_pair (arg_exps
);
359 arg_exps
= CDR (arg_exps
))
360 args
= scm_cons (expand (CAR (arg_exps
), env
), args
);
361 if (scm_is_null (arg_exps
))
362 return APPLICATION (scm_source_properties (exp
),
364 scm_reverse_x (args
, SCM_UNDEFINED
));
366 syntax_error ("expected a proper list", exp
, SCM_UNDEFINED
);
369 else if (scm_is_symbol (exp
))
371 SCM gensym
= expand_env_lexical_gensym (env
, exp
);
372 if (scm_is_true (gensym
))
373 return LEXICAL_REF (SCM_BOOL_F
, exp
, gensym
);
375 return TOPLEVEL_REF (SCM_BOOL_F
, exp
);
378 return CONST (SCM_BOOL_F
, exp
);
382 expand_exprs (SCM forms
, const SCM env
)
386 for (; !scm_is_null (forms
); forms
= CDR (forms
))
387 ret
= scm_cons (expand (CAR (forms
), env
), ret
);
388 return scm_reverse_x (ret
, SCM_UNDEFINED
);
392 expand_sequence (const SCM forms
, const SCM env
)
394 ASSERT_SYNTAX (scm_ilength (forms
) >= 1, s_bad_expression
,
395 scm_cons (scm_sym_begin
, forms
));
396 if (scm_is_null (CDR (forms
)))
397 return expand (CAR (forms
), env
);
399 return SEQUENCE (SCM_BOOL_F
, expand_exprs (forms
, env
));
407 expand_at (SCM expr
, SCM env SCM_UNUSED
)
409 ASSERT_SYNTAX (scm_ilength (expr
) == 3, s_bad_expression
, expr
);
410 ASSERT_SYNTAX (scm_ilength (CADR (expr
)) > 0, s_bad_expression
, expr
);
411 ASSERT_SYNTAX (scm_is_symbol (CADDR (expr
)), s_bad_expression
, expr
);
413 return MODULE_REF (scm_source_properties (expr
),
414 CADR (expr
), CADDR (expr
), SCM_BOOL_T
);
418 expand_atat (SCM expr
, SCM env SCM_UNUSED
)
420 ASSERT_SYNTAX (scm_ilength (expr
) == 3, s_bad_expression
, expr
);
421 ASSERT_SYNTAX (scm_ilength (CADR (expr
)) > 0, s_bad_expression
, expr
);
422 ASSERT_SYNTAX (scm_is_symbol (CADDR (expr
)), s_bad_expression
, expr
);
424 return MODULE_REF (scm_source_properties (expr
),
425 CADR (expr
), CADDR (expr
), SCM_BOOL_F
);
429 expand_and (SCM expr
, SCM env
)
431 const SCM cdr_expr
= CDR (expr
);
433 if (scm_is_null (cdr_expr
))
434 return CONST (SCM_BOOL_F
, SCM_BOOL_T
);
436 ASSERT_SYNTAX (scm_is_pair (cdr_expr
), s_bad_expression
, expr
);
438 if (scm_is_null (CDR (cdr_expr
)))
439 return expand (CAR (cdr_expr
), env
);
441 return CONDITIONAL (scm_source_properties (expr
),
442 expand (CAR (cdr_expr
), env
),
443 expand_and (cdr_expr
, env
),
444 CONST (SCM_BOOL_F
, SCM_BOOL_F
));
448 expand_begin (SCM expr
, SCM env
)
450 const SCM cdr_expr
= CDR (expr
);
451 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 1, s_bad_expression
, expr
);
452 return expand_sequence (cdr_expr
, env
);
456 expand_cond_clauses (SCM clause
, SCM rest
, int elp
, int alp
, SCM env
)
459 const long length
= scm_ilength (clause
);
460 ASSERT_SYNTAX (length
>= 1, s_bad_cond_clause
, clause
);
463 if (scm_is_eq (test
, scm_sym_else
) && elp
)
465 const int last_clause_p
= scm_is_null (rest
);
466 ASSERT_SYNTAX (length
>= 2, s_bad_cond_clause
, clause
);
467 ASSERT_SYNTAX (last_clause_p
, s_misplaced_else_clause
, clause
);
468 return expand_sequence (CDR (clause
), env
);
471 if (scm_is_null (rest
))
472 rest
= VOID (SCM_BOOL_F
);
474 rest
= expand_cond_clauses (CAR (rest
), CDR (rest
), elp
, alp
, env
);
477 && scm_is_eq (CADR (clause
), scm_sym_arrow
)
480 SCM tmp
= scm_gensym (scm_from_locale_string ("cond "));
481 SCM new_env
= scm_acons (tmp
, tmp
, env
);
482 ASSERT_SYNTAX (length
> 2, s_missing_recipient
, clause
);
483 ASSERT_SYNTAX (length
== 3, s_extra_expression
, clause
);
484 return LET (SCM_BOOL_F
,
487 scm_list_1 (expand (test
, env
)),
488 CONDITIONAL (SCM_BOOL_F
,
489 LEXICAL_REF (SCM_BOOL_F
, tmp
, tmp
),
490 APPLICATION (SCM_BOOL_F
,
491 expand (CADDR (clause
), new_env
),
492 scm_list_1 (LEXICAL_REF (SCM_BOOL_F
,
496 /* FIXME length == 1 case */
498 return CONDITIONAL (SCM_BOOL_F
,
500 expand_sequence (CDR (clause
), env
),
505 expand_cond (SCM expr
, SCM env
)
507 const int else_literal_p
= expand_env_var_is_free (env
, scm_sym_else
);
508 const int arrow_literal_p
= expand_env_var_is_free (env
, scm_sym_arrow
);
509 const SCM clauses
= CDR (expr
);
511 ASSERT_SYNTAX (scm_ilength (clauses
) >= 0, s_bad_expression
, expr
);
512 ASSERT_SYNTAX (scm_ilength (clauses
) >= 1, s_missing_clauses
, expr
);
514 return expand_cond_clauses (CAR (clauses
), CDR (clauses
),
515 else_literal_p
, arrow_literal_p
, env
);
518 /* lone forward decl */
519 static SCM
expand_lambda (SCM expr
, SCM env
);
521 /* According to Section 5.2.1 of R5RS we first have to make sure that the
522 variable is bound, and then perform the `(set! variable expression)'
523 operation. However, EXPRESSION _can_ be evaluated before VARIABLE is
524 bound. This means that EXPRESSION won't necessarily be able to assign
525 values to VARIABLE as in `(define foo (begin (set! foo 1) (+ foo 1)))'. */
527 expand_define (SCM expr
, SCM env
)
529 const SCM cdr_expr
= CDR (expr
);
533 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
534 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 2, s_missing_expression
, expr
);
535 ASSERT_SYNTAX (!scm_is_pair (env
), s_bad_define
, expr
);
537 body
= CDR (cdr_expr
);
538 variable
= CAR (cdr_expr
);
540 if (scm_is_pair (variable
))
542 ASSERT_SYNTAX_2 (scm_is_symbol (CAR (variable
)), s_bad_variable
, variable
, expr
);
543 return TOPLEVEL_DEFINE
544 (scm_source_properties (expr
),
546 expand_lambda (scm_cons (scm_sym_lambda
, scm_cons (CDR (variable
), body
)),
549 ASSERT_SYNTAX_2 (scm_is_symbol (variable
), s_bad_variable
, variable
, expr
);
550 ASSERT_SYNTAX (scm_ilength (body
) == 1, s_expression
, expr
);
551 return TOPLEVEL_DEFINE (scm_source_properties (expr
), variable
,
552 expand (CAR (body
), env
));
556 expand_with_fluids (SCM expr
, SCM env
)
558 SCM binds
, fluids
, vals
;
559 ASSERT_SYNTAX (scm_ilength (expr
) >= 3, s_bad_expression
, expr
);
561 ASSERT_SYNTAX_2 (scm_ilength (binds
) >= 0, s_bad_bindings
, binds
, expr
);
562 for (fluids
= SCM_EOL
, vals
= SCM_EOL
;
566 SCM binding
= CAR (binds
);
567 ASSERT_SYNTAX_2 (scm_ilength (CAR (binds
)) == 2, s_bad_binding
,
569 fluids
= scm_cons (expand (CAR (binding
), env
), fluids
);
570 vals
= scm_cons (expand (CADR (binding
), env
), vals
);
573 return DYNLET (scm_source_properties (expr
),
574 scm_reverse_x (fluids
, SCM_UNDEFINED
),
575 scm_reverse_x (vals
, SCM_UNDEFINED
),
576 expand_sequence (CDDR (expr
), env
));
580 expand_eval_when (SCM expr
, SCM env
)
582 ASSERT_SYNTAX (scm_ilength (expr
) >= 3, s_bad_expression
, expr
);
583 ASSERT_SYNTAX (scm_ilength (CADR (expr
)) > 0, s_bad_expression
, expr
);
585 if (scm_is_true (scm_memq (sym_eval
, CADR (expr
)))
586 || scm_is_true (scm_memq (sym_load
, CADR (expr
))))
587 return expand_sequence (CDDR (expr
), env
);
589 return VOID (scm_source_properties (expr
));
593 expand_if (SCM expr
, SCM env SCM_UNUSED
)
595 const SCM cdr_expr
= CDR (expr
);
596 const long length
= scm_ilength (cdr_expr
);
597 ASSERT_SYNTAX (length
== 2 || length
== 3, s_expression
, expr
);
598 return CONDITIONAL (scm_source_properties (expr
),
599 expand (CADR (expr
), env
),
600 expand (CADDR (expr
), env
),
602 ? expand (CADDDR (expr
), env
)
603 : VOID (SCM_BOOL_F
)));
606 /* A helper function for expand_lambda to support checking for duplicate
607 * formal arguments: Return true if OBJ is `eq?' to one of the elements of
608 * LIST or to the CDR of the last cons. Therefore, LIST may have any of the
609 * forms that a formal argument can have:
610 * <rest>, (<arg1> ...), (<arg1> ... . <rest>) */
612 c_improper_memq (SCM obj
, SCM list
)
614 for (; scm_is_pair (list
); list
= CDR (list
))
616 if (scm_is_eq (CAR (list
), obj
))
619 return scm_is_eq (list
, obj
);
623 expand_lambda_case (SCM clause
, SCM alternate
, SCM env
)
632 ASSERT_SYNTAX (scm_is_pair (clause
) && scm_is_pair (CDR (clause
)),
633 s_bad_expression
, scm_cons (scm_sym_lambda
, clause
));
635 /* Before iterating the list of formal arguments, make sure the formals
636 * actually are given as either a symbol or a non-cyclic list. */
637 formals
= CAR (clause
);
638 if (scm_is_pair (formals
))
640 /* Dirk:FIXME:: We should check for a cyclic list of formals, and if
641 * detected, report a 'Bad formals' error. */
644 ASSERT_SYNTAX_2 (scm_is_symbol (formals
) || scm_is_null (formals
),
645 s_bad_formals
, formals
, scm_cons (scm_sym_lambda
, clause
));
647 /* Now iterate the list of formal arguments to check if all formals are
648 * symbols, and that there are no duplicates. */
649 while (scm_is_pair (formals
))
651 const SCM formal
= CAR (formals
);
652 formals
= CDR (formals
);
653 ASSERT_SYNTAX_2 (scm_is_symbol (formal
), s_bad_formal
, formal
,
654 scm_cons (scm_sym_lambda
, clause
));
655 ASSERT_SYNTAX_2 (!c_improper_memq (formal
, formals
), s_duplicate_formal
,
656 formal
, scm_cons (scm_sym_lambda
, clause
));
658 req
= scm_cons (formal
, req
);
659 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
660 env
= scm_acons (formal
, CAR (vars
), env
);
663 ASSERT_SYNTAX_2 (scm_is_null (formals
) || scm_is_symbol (formals
),
664 s_bad_formal
, formals
, scm_cons (scm_sym_lambda
, clause
));
665 if (scm_is_symbol (formals
))
668 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
669 env
= scm_acons (rest
, CAR (vars
), env
);
674 body
= expand_sequence (CDR (clause
), env
);
675 req
= scm_reverse_x (req
, SCM_UNDEFINED
);
676 vars
= scm_reverse_x (vars
, SCM_UNDEFINED
);
678 if (scm_is_true (alternate
) && !(SCM_EXPANDED_P (alternate
) && SCM_EXPANDED_TYPE (alternate
) == SCM_EXPANDED_LAMBDA_CASE
))
681 return LAMBDA_CASE (SCM_BOOL_F
, req
, SCM_BOOL_F
, rest
, SCM_BOOL_F
,
682 SCM_EOL
, vars
, body
, alternate
);
686 expand_lambda (SCM expr
, SCM env
)
688 return LAMBDA (scm_source_properties (expr
),
690 expand_lambda_case (CDR (expr
), SCM_BOOL_F
, env
));
694 expand_lambda_star_case (SCM clause
, SCM alternate
, SCM env
)
696 SCM req
, opt
, kw
, allow_other_keys
, rest
, formals
, vars
, body
, tmp
;
700 const long length
= scm_ilength (clause
);
701 ASSERT_SYNTAX (length
>= 1, s_bad_expression
,
702 scm_cons (sym_lambda_star
, clause
));
703 ASSERT_SYNTAX (length
>= 2, s_missing_expression
,
704 scm_cons (sym_lambda_star
, clause
));
706 formals
= CAR (clause
);
710 req
= opt
= kw
= SCM_EOL
;
711 rest
= allow_other_keys
= SCM_BOOL_F
;
713 while (scm_is_pair (formals
) && scm_is_symbol (CAR (formals
)))
716 req
= scm_cons (CAR (formals
), req
);
717 formals
= scm_cdr (formals
);
720 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_optional
))
722 formals
= CDR (formals
);
723 while (scm_is_pair (formals
)
724 && (scm_is_symbol (CAR (formals
)) || scm_is_pair (CAR (formals
))))
727 opt
= scm_cons (CAR (formals
), opt
);
728 formals
= scm_cdr (formals
);
732 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_key
))
734 formals
= CDR (formals
);
735 while (scm_is_pair (formals
)
736 && (scm_is_symbol (CAR (formals
)) || scm_is_pair (CAR (formals
))))
738 kw
= scm_cons (CAR (formals
), kw
);
739 formals
= scm_cdr (formals
);
743 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_allow_other_keys
))
745 formals
= CDR (formals
);
746 allow_other_keys
= SCM_BOOL_T
;
749 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_rest
))
751 ASSERT_SYNTAX (scm_ilength (formals
) == 2, s_bad_formals
,
753 rest
= CADR (formals
);
755 else if (scm_is_symbol (formals
))
759 ASSERT_SYNTAX (scm_is_null (formals
), s_bad_formals
, CAR (clause
));
763 /* Now, iterate through them a second time, building up an expansion-time
764 environment, checking, expanding and canonicalizing the opt/kw init forms,
765 and eventually memoizing the body as well. Note that the rest argument, if
766 any, is expanded before keyword args, thus necessitating the second
769 Also note that the specific environment during expansion of init
770 expressions here needs to coincide with the environment when psyntax
771 expands. A lot of effort for something that is only used in the bootstrap
772 expandr, you say? Yes. Yes it is.
776 req
= scm_reverse_x (req
, SCM_EOL
);
777 for (tmp
= req
; scm_is_pair (tmp
); tmp
= scm_cdr (tmp
))
779 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
780 env
= scm_acons (CAR (tmp
), CAR (vars
), env
);
783 /* Build up opt inits and env */
785 opt
= scm_reverse_x (opt
, SCM_EOL
);
786 for (tmp
= opt
; scm_is_pair (tmp
); tmp
= scm_cdr (tmp
))
789 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
790 env
= scm_acons (x
, CAR (vars
), env
);
791 if (scm_is_symbol (x
))
792 inits
= scm_cons (CONST (SCM_BOOL_F
, SCM_BOOL_F
), inits
);
795 ASSERT_SYNTAX (scm_ilength (x
) == 2 && scm_is_symbol (CAR (x
)),
796 s_bad_formals
, CAR (clause
));
797 inits
= scm_cons (expand (CADR (x
), env
), inits
);
799 env
= scm_acons (scm_is_symbol (x
) ? x
: CAR (x
), CAR (vars
), env
);
801 if (scm_is_null (opt
))
804 /* Process rest before keyword args */
805 if (scm_is_true (rest
))
807 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
808 env
= scm_acons (rest
, CAR (vars
), env
);
811 /* Build up kw inits, env, and kw-canon list */
812 if (scm_is_null (kw
))
816 SCM kw_canon
= SCM_EOL
;
817 kw
= scm_reverse_x (kw
, SCM_UNDEFINED
);
818 for (tmp
= kw
; scm_is_pair (tmp
); tmp
= scm_cdr (tmp
))
822 if (scm_is_symbol (x
))
826 k
= scm_symbol_to_keyword (sym
);
828 else if (scm_ilength (x
) == 2 && scm_is_symbol (CAR (x
)))
832 k
= scm_symbol_to_keyword (sym
);
834 else if (scm_ilength (x
) == 3 && scm_is_symbol (CAR (x
))
835 && scm_is_keyword (CADDR (x
)))
842 syntax_error (s_bad_formals
, CAR (clause
), SCM_UNDEFINED
);
844 inits
= scm_cons (expand (init
, env
), inits
);
845 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
846 kw_canon
= scm_cons (scm_list_3 (k
, sym
, CAR (vars
)), kw_canon
);
847 env
= scm_acons (sym
, CAR (vars
), env
);
849 kw_canon
= scm_reverse_x (kw_canon
, SCM_UNDEFINED
);
850 kw
= scm_cons (allow_other_keys
, kw_canon
);
853 /* We should check for no duplicates, but given that psyntax does this
854 already, we can punt on it here... */
856 vars
= scm_reverse_x (vars
, SCM_UNDEFINED
);
857 inits
= scm_reverse_x (inits
, SCM_UNDEFINED
);
858 body
= expand_sequence (body
, env
);
860 return LAMBDA_CASE (SCM_BOOL_F
, req
, opt
, rest
, kw
, inits
, vars
, body
,
865 expand_lambda_star (SCM expr
, SCM env
)
867 return LAMBDA (scm_source_properties (expr
),
869 expand_lambda_star_case (CDR (expr
), SCM_BOOL_F
, env
));
873 expand_case_lambda_clauses (SCM expr
, SCM rest
, SCM env
)
877 if (scm_is_pair (rest
))
878 alt
= expand_case_lambda_clauses (CAR (rest
), CDR (rest
), env
);
882 return expand_lambda_case (expr
, alt
, env
);
886 expand_case_lambda (SCM expr
, SCM env
)
888 ASSERT_SYNTAX (scm_is_pair (CDR (expr
)), s_missing_expression
, expr
);
890 return LAMBDA (scm_source_properties (expr
),
892 expand_case_lambda_clauses (CADR (expr
), CDDR (expr
), env
));
896 expand_case_lambda_star_clauses (SCM expr
, SCM rest
, SCM env
)
900 if (scm_is_pair (rest
))
901 alt
= expand_case_lambda_star_clauses (CAR (rest
), CDR (rest
), env
);
905 return expand_lambda_star_case (expr
, alt
, env
);
909 expand_case_lambda_star (SCM expr
, SCM env
)
911 ASSERT_SYNTAX (scm_is_pair (CDR (expr
)), s_missing_expression
, expr
);
913 return LAMBDA (scm_source_properties (expr
),
915 expand_case_lambda_star_clauses (CADR (expr
), CDDR (expr
), env
));
918 /* Check if the format of the bindings is ((<symbol> <init-form>) ...). */
920 check_bindings (const SCM bindings
, const SCM expr
)
924 ASSERT_SYNTAX_2 (scm_ilength (bindings
) >= 0,
925 s_bad_bindings
, bindings
, expr
);
927 binding_idx
= bindings
;
928 for (; !scm_is_null (binding_idx
); binding_idx
= CDR (binding_idx
))
930 SCM name
; /* const */
932 const SCM binding
= CAR (binding_idx
);
933 ASSERT_SYNTAX_2 (scm_ilength (binding
) == 2,
934 s_bad_binding
, binding
, expr
);
936 name
= CAR (binding
);
937 ASSERT_SYNTAX_2 (scm_is_symbol (name
), s_bad_variable
, name
, expr
);
941 /* The bindings, which must have the format ((v1 i1) (v2 i2) ... (vn in)), are
942 * transformed to the lists (vn .. v2 v1) and (i1 i2 ... in). If a duplicate
943 * variable name is detected, an error is signalled. */
945 transform_bindings (const SCM bindings
, const SCM expr
,
946 SCM
*const names
, SCM
*const vars
, SCM
*const initptr
)
948 SCM rnames
= SCM_EOL
;
950 SCM rinits
= SCM_EOL
;
951 SCM binding_idx
= bindings
;
952 for (; !scm_is_null (binding_idx
); binding_idx
= CDR (binding_idx
))
954 const SCM binding
= CAR (binding_idx
);
955 const SCM CDR_binding
= CDR (binding
);
956 const SCM name
= CAR (binding
);
957 ASSERT_SYNTAX_2 (scm_is_false (scm_c_memq (name
, rnames
)),
958 s_duplicate_binding
, name
, expr
);
959 rnames
= scm_cons (name
, rnames
);
960 rvars
= scm_cons (scm_gensym (SCM_UNDEFINED
), rvars
);
961 rinits
= scm_cons (CAR (CDR_binding
), rinits
);
963 *names
= scm_reverse_x (rnames
, SCM_UNDEFINED
);
964 *vars
= scm_reverse_x (rvars
, SCM_UNDEFINED
);
965 *initptr
= scm_reverse_x (rinits
, SCM_UNDEFINED
);
968 /* FIXME: Remove named let in this boot expander. */
970 expand_named_let (const SCM expr
, SCM env
)
972 SCM var_names
, var_syms
, inits
;
976 const SCM cdr_expr
= CDR (expr
);
977 const SCM name
= CAR (cdr_expr
);
978 const SCM cddr_expr
= CDR (cdr_expr
);
979 const SCM bindings
= CAR (cddr_expr
);
980 check_bindings (bindings
, expr
);
982 transform_bindings (bindings
, expr
, &var_names
, &var_syms
, &inits
);
983 name_sym
= scm_gensym (SCM_UNDEFINED
);
984 inner_env
= scm_acons (name
, name_sym
, env
);
985 inner_env
= expand_env_extend (inner_env
, var_names
, var_syms
);
988 (scm_source_properties (expr
), SCM_BOOL_F
,
989 scm_list_1 (name
), scm_list_1 (name_sym
),
990 scm_list_1 (LAMBDA (SCM_BOOL_F
,
992 LAMBDA_CASE (SCM_BOOL_F
, var_names
, SCM_BOOL_F
, SCM_BOOL_F
,
993 SCM_BOOL_F
, SCM_BOOL_F
, var_syms
,
994 expand_sequence (CDDDR (expr
), inner_env
),
996 APPLICATION (SCM_BOOL_F
,
997 LEXICAL_REF (SCM_BOOL_F
, name
, name_sym
),
998 expand_exprs (inits
, env
)));
1002 expand_let (SCM expr
, SCM env
)
1006 const SCM cdr_expr
= CDR (expr
);
1007 const long length
= scm_ilength (cdr_expr
);
1008 ASSERT_SYNTAX (length
>= 0, s_bad_expression
, expr
);
1009 ASSERT_SYNTAX (length
>= 2, s_missing_expression
, expr
);
1011 bindings
= CAR (cdr_expr
);
1012 if (scm_is_symbol (bindings
))
1014 ASSERT_SYNTAX (length
>= 3, s_missing_expression
, expr
);
1015 return expand_named_let (expr
, env
);
1018 check_bindings (bindings
, expr
);
1019 if (scm_is_null (bindings
))
1020 return expand_sequence (CDDR (expr
), env
);
1023 SCM var_names
, var_syms
, inits
;
1024 transform_bindings (bindings
, expr
, &var_names
, &var_syms
, &inits
);
1025 return LET (SCM_BOOL_F
,
1026 var_names
, var_syms
, expand_exprs (inits
, env
),
1027 expand_sequence (CDDR (expr
),
1028 expand_env_extend (env
, var_names
,
1034 expand_letrec_helper (SCM expr
, SCM env
, SCM in_order_p
)
1038 const SCM cdr_expr
= CDR (expr
);
1039 const long length
= scm_ilength (cdr_expr
);
1040 ASSERT_SYNTAX (length
>= 0, s_bad_expression
, expr
);
1041 ASSERT_SYNTAX (length
>= 2, s_missing_expression
, expr
);
1043 bindings
= CAR (cdr_expr
);
1044 check_bindings (bindings
, expr
);
1045 if (scm_is_null (bindings
))
1046 return expand_sequence (CDDR (expr
), env
);
1049 SCM var_names
, var_syms
, inits
;
1050 transform_bindings (bindings
, expr
, &var_names
, &var_syms
, &inits
);
1051 env
= expand_env_extend (env
, var_names
, var_syms
);
1052 return LETREC (SCM_BOOL_F
, in_order_p
,
1053 var_names
, var_syms
, expand_exprs (inits
, env
),
1054 expand_sequence (CDDR (expr
), env
));
1059 expand_letrec (SCM expr
, SCM env
)
1061 return expand_letrec_helper (expr
, env
, SCM_BOOL_F
);
1065 expand_letrec_star (SCM expr
, SCM env
)
1067 return expand_letrec_helper (expr
, env
, SCM_BOOL_T
);
1071 expand_letstar_clause (SCM bindings
, SCM body
, SCM env SCM_UNUSED
)
1073 if (scm_is_null (bindings
))
1074 return expand_sequence (body
, env
);
1077 SCM bind
, name
, sym
, init
;
1079 ASSERT_SYNTAX (scm_is_pair (bindings
), s_bad_expression
, bindings
);
1080 bind
= CAR (bindings
);
1081 ASSERT_SYNTAX (scm_ilength (bind
) == 2, s_bad_binding
, bind
);
1083 sym
= scm_gensym (SCM_UNDEFINED
);
1086 return LET (SCM_BOOL_F
, scm_list_1 (name
), scm_list_1 (sym
),
1087 scm_list_1 (expand (init
, env
)),
1088 expand_letstar_clause (CDR (bindings
), body
,
1089 scm_acons (name
, sym
, env
)));
1094 expand_letstar (SCM expr
, SCM env SCM_UNUSED
)
1096 const SCM cdr_expr
= CDR (expr
);
1097 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
1098 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 2, s_missing_expression
, expr
);
1100 return expand_letstar_clause (CADR (expr
), CDDR (expr
), env
);
1104 expand_or (SCM expr
, SCM env SCM_UNUSED
)
1106 SCM tail
= CDR (expr
);
1107 const long length
= scm_ilength (tail
);
1109 ASSERT_SYNTAX (length
>= 0, s_bad_expression
, expr
);
1111 if (scm_is_null (CDR (expr
)))
1112 return CONST (SCM_BOOL_F
, SCM_BOOL_F
);
1115 SCM tmp
= scm_gensym (SCM_UNDEFINED
);
1116 return LET (SCM_BOOL_F
,
1117 scm_list_1 (tmp
), scm_list_1 (tmp
),
1118 scm_list_1 (expand (CADR (expr
), env
)),
1119 CONDITIONAL (SCM_BOOL_F
,
1120 LEXICAL_REF (SCM_BOOL_F
, tmp
, tmp
),
1121 LEXICAL_REF (SCM_BOOL_F
, tmp
, tmp
),
1122 expand_or (CDR (expr
),
1123 scm_acons (tmp
, tmp
, env
))));
1128 expand_quote (SCM expr
, SCM env SCM_UNUSED
)
1132 const SCM cdr_expr
= CDR (expr
);
1133 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
1134 ASSERT_SYNTAX (scm_ilength (cdr_expr
) == 1, s_expression
, expr
);
1135 quotee
= CAR (cdr_expr
);
1136 return CONST (scm_source_properties (expr
), quotee
);
1140 expand_set_x (SCM expr
, SCM env
)
1145 const SCM cdr_expr
= CDR (expr
);
1146 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
1147 ASSERT_SYNTAX (scm_ilength (cdr_expr
) == 2, s_expression
, expr
);
1148 variable
= CAR (cdr_expr
);
1149 vmem
= expand (variable
, env
);
1151 switch (SCM_EXPANDED_TYPE (vmem
))
1153 case SCM_EXPANDED_LEXICAL_REF
:
1154 return LEXICAL_SET (scm_source_properties (expr
),
1155 SCM_EXPANDED_REF (vmem
, LEXICAL_REF
, NAME
),
1156 SCM_EXPANDED_REF (vmem
, LEXICAL_REF
, GENSYM
),
1157 expand (CADDR (expr
), env
));
1158 case SCM_EXPANDED_TOPLEVEL_REF
:
1159 return TOPLEVEL_SET (scm_source_properties (expr
),
1160 SCM_EXPANDED_REF (vmem
, TOPLEVEL_REF
, NAME
),
1161 expand (CADDR (expr
), env
));
1162 case SCM_EXPANDED_MODULE_REF
:
1163 return MODULE_SET (scm_source_properties (expr
),
1164 SCM_EXPANDED_REF (vmem
, MODULE_REF
, MOD
),
1165 SCM_EXPANDED_REF (vmem
, MODULE_REF
, NAME
),
1166 SCM_EXPANDED_REF (vmem
, MODULE_REF
, PUBLIC
),
1167 expand (CADDR (expr
), env
));
1169 syntax_error (s_bad_variable
, variable
, expr
);
1176 /* This is the boot expander. It is later replaced with psyntax's sc-expand. */
1177 SCM_DEFINE (scm_macroexpand
, "macroexpand", 1, 0, 0,
1179 "Expand the expression @var{exp}.")
1180 #define FUNC_NAME s_scm_macroexpand
1182 return expand (exp
, scm_current_module ());
1186 SCM_DEFINE (scm_macroexpanded_p
, "macroexpanded?", 1, 0, 0,
1188 "Return @code{#t} if @var{exp} is an expanded expression.")
1189 #define FUNC_NAME s_scm_macroexpanded_p
1191 return scm_from_bool (SCM_EXPANDED_P (exp
));
1198 #define DEFINE_NAMES(type) \
1200 static const char *fields[] = SCM_EXPANDED_##type##_FIELD_NAMES; \
1201 exp_field_names[SCM_EXPANDED_##type] = fields; \
1202 exp_names[SCM_EXPANDED_##type] = SCM_EXPANDED_##type##_TYPE_NAME; \
1203 exp_nfields[SCM_EXPANDED_##type] = SCM_NUM_EXPANDED_##type##_FIELDS; \
1207 make_exp_vtable (size_t n
)
1209 SCM layout
, printer
, name
, code
, fields
;
1211 layout
= scm_string_to_symbol
1212 (scm_string_append (scm_make_list (scm_from_size_t (exp_nfields
[n
]),
1213 scm_from_locale_string ("pw"))));
1214 printer
= SCM_BOOL_F
;
1215 name
= scm_from_locale_symbol (exp_names
[n
]);
1216 code
= scm_from_size_t (n
);
1219 size_t m
= exp_nfields
[n
];
1221 fields
= scm_cons (scm_from_locale_symbol (exp_field_names
[n
][m
]), fields
);
1224 return scm_c_make_struct (scm_exp_vtable_vtable
, 0, 5,
1225 SCM_UNPACK (layout
), SCM_UNPACK (printer
), SCM_UNPACK (name
),
1226 SCM_UNPACK (code
), SCM_UNPACK (fields
));
1233 SCM exp_vtable_list
= SCM_EOL
;
1235 DEFINE_NAMES (VOID
);
1236 DEFINE_NAMES (CONST
);
1237 DEFINE_NAMES (PRIMITIVE_REF
);
1238 DEFINE_NAMES (LEXICAL_REF
);
1239 DEFINE_NAMES (LEXICAL_SET
);
1240 DEFINE_NAMES (MODULE_REF
);
1241 DEFINE_NAMES (MODULE_SET
);
1242 DEFINE_NAMES (TOPLEVEL_REF
);
1243 DEFINE_NAMES (TOPLEVEL_SET
);
1244 DEFINE_NAMES (TOPLEVEL_DEFINE
);
1245 DEFINE_NAMES (CONDITIONAL
);
1246 DEFINE_NAMES (APPLICATION
);
1247 DEFINE_NAMES (SEQUENCE
);
1248 DEFINE_NAMES (LAMBDA
);
1249 DEFINE_NAMES (LAMBDA_CASE
);
1251 DEFINE_NAMES (LETREC
);
1252 DEFINE_NAMES (DYNLET
);
1254 scm_exp_vtable_vtable
=
1255 scm_make_vtable (scm_from_locale_string (SCM_VTABLE_BASE_LAYOUT
"pwuwpw"),
1258 for (n
= 0; n
< SCM_NUM_EXPANDED_TYPES
; n
++)
1259 exp_vtables
[n
] = make_exp_vtable (n
);
1261 /* Now walk back down, consing in reverse. */
1263 exp_vtable_list
= scm_cons (exp_vtables
[n
], exp_vtable_list
);
1265 scm_c_define ("%expanded-vtables", scm_vector (exp_vtable_list
));
1267 #include "libguile/expand.x"