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_at_dynamic_wind
, "@dynamic-wind");
188 SCM_GLOBAL_SYMBOL (scm_sym_with_fluids
, "with-fluids");
189 SCM_GLOBAL_SYMBOL (scm_sym_else
, "else");
190 SCM_GLOBAL_SYMBOL (scm_sym_eval_when
, "eval-when");
191 SCM_GLOBAL_SYMBOL (scm_sym_if
, "if");
192 SCM_GLOBAL_SYMBOL (scm_sym_lambda
, "lambda");
193 SCM_GLOBAL_SYMBOL (scm_sym_let
, "let");
194 SCM_GLOBAL_SYMBOL (scm_sym_letrec
, "letrec");
195 SCM_GLOBAL_SYMBOL (scm_sym_letstar
, "let*");
196 SCM_GLOBAL_SYMBOL (scm_sym_or
, "or");
197 SCM_SYMBOL (sym_call_with_prompt
, "call-with-prompt");
198 SCM_GLOBAL_SYMBOL (scm_sym_quote
, "quote");
199 SCM_GLOBAL_SYMBOL (scm_sym_set_x
, "set!");
200 SCM_SYMBOL (sym_lambda_star
, "lambda*");
201 SCM_SYMBOL (sym_eval
, "eval");
202 SCM_SYMBOL (sym_load
, "load");
203 SCM_SYMBOL (sym_primitive
, "primitive");
205 SCM_GLOBAL_SYMBOL (scm_sym_unquote
, "unquote");
206 SCM_GLOBAL_SYMBOL (scm_sym_quasiquote
, "quasiquote");
207 SCM_GLOBAL_SYMBOL (scm_sym_uq_splicing
, "unquote-splicing");
209 SCM_KEYWORD (kw_allow_other_keys
, "allow-other-keys");
210 SCM_KEYWORD (kw_optional
, "optional");
211 SCM_KEYWORD (kw_key
, "key");
212 SCM_KEYWORD (kw_rest
, "rest");
218 /* Signal a syntax error. We distinguish between the form that caused the
219 * error and the enclosing expression. The error message will print out as
220 * shown in the following pattern. The file name and line number are only
221 * given when they can be determined from the erroneous form or from the
222 * enclosing expression.
224 * <filename>: In procedure memoization:
225 * <filename>: In file <name>, line <nr>: <error-message> in <expression>. */
228 syntax_error (const char* const msg
, const SCM form
, const SCM expr
)
230 SCM msg_string
= scm_from_locale_string (msg
);
231 SCM filename
= SCM_BOOL_F
;
232 SCM linenr
= SCM_BOOL_F
;
236 if (scm_is_pair (form
))
238 filename
= scm_source_property (form
, scm_sym_filename
);
239 linenr
= scm_source_property (form
, scm_sym_line
);
242 if (scm_is_false (filename
) && scm_is_false (linenr
) && scm_is_pair (expr
))
244 filename
= scm_source_property (expr
, scm_sym_filename
);
245 linenr
= scm_source_property (expr
, scm_sym_line
);
248 if (!SCM_UNBNDP (expr
))
250 if (scm_is_true (filename
))
252 format
= "In file ~S, line ~S: ~A ~S in expression ~S.";
253 args
= scm_list_5 (filename
, linenr
, msg_string
, form
, expr
);
255 else if (scm_is_true (linenr
))
257 format
= "In line ~S: ~A ~S in expression ~S.";
258 args
= scm_list_4 (linenr
, msg_string
, form
, expr
);
262 format
= "~A ~S in expression ~S.";
263 args
= scm_list_3 (msg_string
, form
, expr
);
268 if (scm_is_true (filename
))
270 format
= "In file ~S, line ~S: ~A ~S.";
271 args
= scm_list_4 (filename
, linenr
, msg_string
, form
);
273 else if (scm_is_true (linenr
))
275 format
= "In line ~S: ~A ~S.";
276 args
= scm_list_3 (linenr
, msg_string
, form
);
281 args
= scm_list_2 (msg_string
, form
);
285 scm_error (syntax_error_key
, "memoization", format
, args
, SCM_BOOL_F
);
293 expand_env_var_is_free (SCM env
, SCM x
)
295 for (; scm_is_pair (env
); env
= CDR (env
))
296 if (scm_is_eq (x
, CAAR (env
)))
297 return 0; /* bound */
302 expand_env_ref_macro (SCM env
, SCM x
)
305 if (!expand_env_var_is_free (env
, x
))
306 return SCM_BOOL_F
; /* lexical */
308 var
= scm_module_variable (scm_current_module (), x
);
309 if (scm_is_true (var
) && scm_is_true (scm_variable_bound_p (var
))
310 && scm_is_true (scm_macro_p (scm_variable_ref (var
))))
311 return scm_variable_ref (var
);
313 return SCM_BOOL_F
; /* anything else */
317 expand_env_lexical_gensym (SCM env
, SCM name
)
319 for (; scm_is_pair (env
); env
= CDR (env
))
320 if (scm_is_eq (name
, CAAR (env
)))
321 return CDAR (env
); /* bound */
322 return SCM_BOOL_F
; /* free */
326 expand_env_extend (SCM env
, SCM names
, SCM vars
)
328 while (scm_is_pair (names
))
330 env
= scm_acons (CAR (names
), CAR (vars
), env
);
338 expand (SCM exp
, SCM env
)
340 if (scm_is_pair (exp
))
343 scm_t_macro_primitive trans
= NULL
;
344 SCM macro
= SCM_BOOL_F
;
347 if (scm_is_symbol (car
))
348 macro
= expand_env_ref_macro (env
, car
);
350 if (scm_is_true (macro
))
351 trans
= scm_i_macro_primitive (macro
);
354 return trans (exp
, env
);
357 SCM arg_exps
= SCM_EOL
;
359 SCM proc
= expand (CAR (exp
), env
);
361 for (arg_exps
= CDR (exp
); scm_is_pair (arg_exps
);
362 arg_exps
= CDR (arg_exps
))
363 args
= scm_cons (expand (CAR (arg_exps
), env
), args
);
364 args
= scm_reverse_x (args
, SCM_UNDEFINED
);
366 if (!scm_is_null (arg_exps
))
367 syntax_error ("expected a proper list", exp
, SCM_UNDEFINED
);
369 if (SCM_EXPANDED_TYPE (proc
) == SCM_EXPANDED_PRIMITIVE_REF
)
370 return PRIMCALL (scm_source_properties (exp
),
371 SCM_EXPANDED_REF (proc
, PRIMITIVE_REF
, NAME
),
374 return CALL (scm_source_properties (exp
), proc
, args
);
377 else if (scm_is_symbol (exp
))
379 SCM gensym
= expand_env_lexical_gensym (env
, exp
);
380 if (scm_is_true (gensym
))
381 return LEXICAL_REF (SCM_BOOL_F
, exp
, gensym
);
383 return TOPLEVEL_REF (SCM_BOOL_F
, exp
);
386 return CONST_ (SCM_BOOL_F
, exp
);
390 expand_exprs (SCM forms
, const SCM env
)
394 for (; !scm_is_null (forms
); forms
= CDR (forms
))
395 ret
= scm_cons (expand (CAR (forms
), env
), ret
);
396 return scm_reverse_x (ret
, SCM_UNDEFINED
);
400 expand_sequence (const SCM forms
, const SCM env
)
402 ASSERT_SYNTAX (scm_ilength (forms
) >= 1, s_bad_expression
,
403 scm_cons (scm_sym_begin
, forms
));
404 if (scm_is_null (CDR (forms
)))
405 return expand (CAR (forms
), env
);
407 return SEQ (scm_source_properties (forms
),
408 expand (CAR (forms
), env
),
409 expand_sequence (CDR (forms
), env
));
417 expand_at (SCM expr
, SCM env SCM_UNUSED
)
419 ASSERT_SYNTAX (scm_ilength (expr
) == 3, s_bad_expression
, expr
);
420 ASSERT_SYNTAX (scm_ilength (CADR (expr
)) > 0, s_bad_expression
, expr
);
421 ASSERT_SYNTAX (scm_is_symbol (CADDR (expr
)), s_bad_expression
, expr
);
423 return MODULE_REF (scm_source_properties (expr
),
424 CADR (expr
), CADDR (expr
), SCM_BOOL_T
);
428 expand_atat (SCM expr
, SCM env SCM_UNUSED
)
430 ASSERT_SYNTAX (scm_ilength (expr
) == 3, s_bad_expression
, expr
);
431 ASSERT_SYNTAX (scm_is_symbol (CADDR (expr
)), s_bad_expression
, expr
);
433 if (scm_is_eq (CADR (expr
), sym_primitive
))
434 return PRIMITIVE_REF (scm_source_properties (expr
), CADDR (expr
));
436 ASSERT_SYNTAX (scm_ilength (CADR (expr
)) > 0, s_bad_expression
, expr
);
437 return MODULE_REF (scm_source_properties (expr
),
438 CADR (expr
), CADDR (expr
), SCM_BOOL_F
);
442 expand_and (SCM expr
, SCM env
)
444 const SCM cdr_expr
= CDR (expr
);
446 if (scm_is_null (cdr_expr
))
447 return CONST_ (SCM_BOOL_F
, SCM_BOOL_T
);
449 ASSERT_SYNTAX (scm_is_pair (cdr_expr
), s_bad_expression
, expr
);
451 if (scm_is_null (CDR (cdr_expr
)))
452 return expand (CAR (cdr_expr
), env
);
454 return CONDITIONAL (scm_source_properties (expr
),
455 expand (CAR (cdr_expr
), env
),
456 expand_and (cdr_expr
, env
),
457 CONST_ (SCM_BOOL_F
, SCM_BOOL_F
));
461 expand_begin (SCM expr
, SCM env
)
463 const SCM cdr_expr
= CDR (expr
);
464 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 1, s_bad_expression
, expr
);
465 return expand_sequence (cdr_expr
, env
);
469 expand_cond_clauses (SCM clause
, SCM rest
, int elp
, int alp
, SCM env
)
472 const long length
= scm_ilength (clause
);
473 ASSERT_SYNTAX (length
>= 1, s_bad_cond_clause
, clause
);
476 if (scm_is_eq (test
, scm_sym_else
) && elp
)
478 const int last_clause_p
= scm_is_null (rest
);
479 ASSERT_SYNTAX (length
>= 2, s_bad_cond_clause
, clause
);
480 ASSERT_SYNTAX (last_clause_p
, s_misplaced_else_clause
, clause
);
481 return expand_sequence (CDR (clause
), env
);
484 if (scm_is_null (rest
))
485 rest
= VOID_ (SCM_BOOL_F
);
487 rest
= expand_cond_clauses (CAR (rest
), CDR (rest
), elp
, alp
, env
);
490 && scm_is_eq (CADR (clause
), scm_sym_arrow
)
493 SCM tmp
= scm_gensym (scm_from_locale_string ("cond "));
494 SCM new_env
= scm_acons (tmp
, tmp
, env
);
495 ASSERT_SYNTAX (length
> 2, s_missing_recipient
, clause
);
496 ASSERT_SYNTAX (length
== 3, s_extra_expression
, clause
);
497 return LET (SCM_BOOL_F
,
500 scm_list_1 (expand (test
, env
)),
501 CONDITIONAL (SCM_BOOL_F
,
502 LEXICAL_REF (SCM_BOOL_F
, tmp
, tmp
),
504 expand (CADDR (clause
), new_env
),
505 scm_list_1 (LEXICAL_REF (SCM_BOOL_F
,
509 /* FIXME length == 1 case */
511 return CONDITIONAL (SCM_BOOL_F
,
513 expand_sequence (CDR (clause
), env
),
518 expand_cond (SCM expr
, SCM env
)
520 const int else_literal_p
= expand_env_var_is_free (env
, scm_sym_else
);
521 const int arrow_literal_p
= expand_env_var_is_free (env
, scm_sym_arrow
);
522 const SCM clauses
= CDR (expr
);
524 ASSERT_SYNTAX (scm_ilength (clauses
) >= 0, s_bad_expression
, expr
);
525 ASSERT_SYNTAX (scm_ilength (clauses
) >= 1, s_missing_clauses
, expr
);
527 return expand_cond_clauses (CAR (clauses
), CDR (clauses
),
528 else_literal_p
, arrow_literal_p
, env
);
531 /* lone forward decl */
532 static SCM
expand_lambda (SCM expr
, SCM env
);
534 /* According to Section 5.2.1 of R5RS we first have to make sure that the
535 variable is bound, and then perform the `(set! variable expression)'
536 operation. However, EXPRESSION _can_ be evaluated before VARIABLE is
537 bound. This means that EXPRESSION won't necessarily be able to assign
538 values to VARIABLE as in `(define foo (begin (set! foo 1) (+ foo 1)))'. */
540 expand_define (SCM expr
, SCM env
)
542 const SCM cdr_expr
= CDR (expr
);
546 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
547 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 2, s_missing_expression
, expr
);
548 ASSERT_SYNTAX (!scm_is_pair (env
), s_bad_define
, expr
);
550 body
= CDR (cdr_expr
);
551 variable
= CAR (cdr_expr
);
553 if (scm_is_pair (variable
))
555 ASSERT_SYNTAX_2 (scm_is_symbol (CAR (variable
)), s_bad_variable
, variable
, expr
);
556 return TOPLEVEL_DEFINE
557 (scm_source_properties (expr
),
559 expand_lambda (scm_cons (scm_sym_lambda
, scm_cons (CDR (variable
), body
)),
562 ASSERT_SYNTAX_2 (scm_is_symbol (variable
), s_bad_variable
, variable
, expr
);
563 ASSERT_SYNTAX (scm_ilength (body
) == 1, s_expression
, expr
);
564 return TOPLEVEL_DEFINE (scm_source_properties (expr
), variable
,
565 expand (CAR (body
), env
));
569 expand_with_fluids (SCM expr
, SCM env
)
571 SCM binds
, fluids
, vals
;
572 ASSERT_SYNTAX (scm_ilength (expr
) >= 3, s_bad_expression
, expr
);
574 ASSERT_SYNTAX_2 (scm_ilength (binds
) >= 0, s_bad_bindings
, binds
, expr
);
575 for (fluids
= SCM_EOL
, vals
= SCM_EOL
;
579 SCM binding
= CAR (binds
);
580 ASSERT_SYNTAX_2 (scm_ilength (CAR (binds
)) == 2, s_bad_binding
,
582 fluids
= scm_cons (expand (CAR (binding
), env
), fluids
);
583 vals
= scm_cons (expand (CADR (binding
), env
), vals
);
586 return DYNLET (scm_source_properties (expr
),
587 scm_reverse_x (fluids
, SCM_UNDEFINED
),
588 scm_reverse_x (vals
, SCM_UNDEFINED
),
589 expand_sequence (CDDR (expr
), env
));
593 expand_eval_when (SCM expr
, SCM env
)
595 ASSERT_SYNTAX (scm_ilength (expr
) >= 3, s_bad_expression
, expr
);
596 ASSERT_SYNTAX (scm_ilength (CADR (expr
)) > 0, s_bad_expression
, expr
);
598 if (scm_is_true (scm_memq (sym_eval
, CADR (expr
)))
599 || scm_is_true (scm_memq (sym_load
, CADR (expr
))))
600 return expand_sequence (CDDR (expr
), env
);
602 return VOID_ (scm_source_properties (expr
));
606 expand_if (SCM expr
, SCM env SCM_UNUSED
)
608 const SCM cdr_expr
= CDR (expr
);
609 const long length
= scm_ilength (cdr_expr
);
610 ASSERT_SYNTAX (length
== 2 || length
== 3, s_expression
, expr
);
611 return CONDITIONAL (scm_source_properties (expr
),
612 expand (CADR (expr
), env
),
613 expand (CADDR (expr
), env
),
615 ? expand (CADDDR (expr
), env
)
616 : VOID_ (SCM_BOOL_F
)));
619 /* A helper function for expand_lambda to support checking for duplicate
620 * formal arguments: Return true if OBJ is `eq?' to one of the elements of
621 * LIST or to the CDR of the last cons. Therefore, LIST may have any of the
622 * forms that a formal argument can have:
623 * <rest>, (<arg1> ...), (<arg1> ... . <rest>) */
625 c_improper_memq (SCM obj
, SCM list
)
627 for (; scm_is_pair (list
); list
= CDR (list
))
629 if (scm_is_eq (CAR (list
), obj
))
632 return scm_is_eq (list
, obj
);
636 expand_lambda_case (SCM clause
, SCM alternate
, SCM env
)
645 ASSERT_SYNTAX (scm_is_pair (clause
) && scm_is_pair (CDR (clause
)),
646 s_bad_expression
, scm_cons (scm_sym_lambda
, clause
));
648 /* Before iterating the list of formal arguments, make sure the formals
649 * actually are given as either a symbol or a non-cyclic list. */
650 formals
= CAR (clause
);
651 if (scm_is_pair (formals
))
653 /* Dirk:FIXME:: We should check for a cyclic list of formals, and if
654 * detected, report a 'Bad formals' error. */
657 ASSERT_SYNTAX_2 (scm_is_symbol (formals
) || scm_is_null (formals
),
658 s_bad_formals
, formals
, scm_cons (scm_sym_lambda
, clause
));
660 /* Now iterate the list of formal arguments to check if all formals are
661 * symbols, and that there are no duplicates. */
662 while (scm_is_pair (formals
))
664 const SCM formal
= CAR (formals
);
665 formals
= CDR (formals
);
666 ASSERT_SYNTAX_2 (scm_is_symbol (formal
), s_bad_formal
, formal
,
667 scm_cons (scm_sym_lambda
, clause
));
668 ASSERT_SYNTAX_2 (!c_improper_memq (formal
, formals
), s_duplicate_formal
,
669 formal
, scm_cons (scm_sym_lambda
, clause
));
671 req
= scm_cons (formal
, req
);
672 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
673 env
= scm_acons (formal
, CAR (vars
), env
);
676 ASSERT_SYNTAX_2 (scm_is_null (formals
) || scm_is_symbol (formals
),
677 s_bad_formal
, formals
, scm_cons (scm_sym_lambda
, clause
));
678 if (scm_is_symbol (formals
))
681 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
682 env
= scm_acons (rest
, CAR (vars
), env
);
687 body
= expand_sequence (CDR (clause
), env
);
688 req
= scm_reverse_x (req
, SCM_UNDEFINED
);
689 vars
= scm_reverse_x (vars
, SCM_UNDEFINED
);
691 if (scm_is_true (alternate
) && !(SCM_EXPANDED_P (alternate
) && SCM_EXPANDED_TYPE (alternate
) == SCM_EXPANDED_LAMBDA_CASE
))
694 return LAMBDA_CASE (SCM_BOOL_F
, req
, SCM_BOOL_F
, rest
, SCM_BOOL_F
,
695 SCM_EOL
, vars
, body
, alternate
);
699 expand_lambda (SCM expr
, SCM env
)
701 return LAMBDA (scm_source_properties (expr
),
703 expand_lambda_case (CDR (expr
), SCM_BOOL_F
, env
));
707 expand_lambda_star_case (SCM clause
, SCM alternate
, SCM env
)
709 SCM req
, opt
, kw
, allow_other_keys
, rest
, formals
, vars
, body
, tmp
;
713 const long length
= scm_ilength (clause
);
714 ASSERT_SYNTAX (length
>= 1, s_bad_expression
,
715 scm_cons (sym_lambda_star
, clause
));
716 ASSERT_SYNTAX (length
>= 2, s_missing_expression
,
717 scm_cons (sym_lambda_star
, clause
));
719 formals
= CAR (clause
);
723 req
= opt
= kw
= SCM_EOL
;
724 rest
= allow_other_keys
= SCM_BOOL_F
;
726 while (scm_is_pair (formals
) && scm_is_symbol (CAR (formals
)))
729 req
= scm_cons (CAR (formals
), req
);
730 formals
= scm_cdr (formals
);
733 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_optional
))
735 formals
= CDR (formals
);
736 while (scm_is_pair (formals
)
737 && (scm_is_symbol (CAR (formals
)) || scm_is_pair (CAR (formals
))))
740 opt
= scm_cons (CAR (formals
), opt
);
741 formals
= scm_cdr (formals
);
745 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_key
))
747 formals
= CDR (formals
);
748 while (scm_is_pair (formals
)
749 && (scm_is_symbol (CAR (formals
)) || scm_is_pair (CAR (formals
))))
751 kw
= scm_cons (CAR (formals
), kw
);
752 formals
= scm_cdr (formals
);
756 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_allow_other_keys
))
758 formals
= CDR (formals
);
759 allow_other_keys
= SCM_BOOL_T
;
762 if (scm_is_pair (formals
) && scm_is_eq (CAR (formals
), kw_rest
))
764 ASSERT_SYNTAX (scm_ilength (formals
) == 2, s_bad_formals
,
766 rest
= CADR (formals
);
768 else if (scm_is_symbol (formals
))
772 ASSERT_SYNTAX (scm_is_null (formals
), s_bad_formals
, CAR (clause
));
776 /* Now, iterate through them a second time, building up an expansion-time
777 environment, checking, expanding and canonicalizing the opt/kw init forms,
778 and eventually memoizing the body as well. Note that the rest argument, if
779 any, is expanded before keyword args, thus necessitating the second
782 Also note that the specific environment during expansion of init
783 expressions here needs to coincide with the environment when psyntax
784 expands. A lot of effort for something that is only used in the bootstrap
785 expandr, you say? Yes. Yes it is.
789 req
= scm_reverse_x (req
, SCM_EOL
);
790 for (tmp
= req
; scm_is_pair (tmp
); tmp
= scm_cdr (tmp
))
792 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
793 env
= scm_acons (CAR (tmp
), CAR (vars
), env
);
796 /* Build up opt inits and env */
798 opt
= scm_reverse_x (opt
, SCM_EOL
);
799 for (tmp
= opt
; scm_is_pair (tmp
); tmp
= scm_cdr (tmp
))
802 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
803 env
= scm_acons (x
, CAR (vars
), env
);
804 if (scm_is_symbol (x
))
805 inits
= scm_cons (CONST_ (SCM_BOOL_F
, SCM_BOOL_F
), inits
);
808 ASSERT_SYNTAX (scm_ilength (x
) == 2 && scm_is_symbol (CAR (x
)),
809 s_bad_formals
, CAR (clause
));
810 inits
= scm_cons (expand (CADR (x
), env
), inits
);
812 env
= scm_acons (scm_is_symbol (x
) ? x
: CAR (x
), CAR (vars
), env
);
814 if (scm_is_null (opt
))
817 /* Process rest before keyword args */
818 if (scm_is_true (rest
))
820 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
821 env
= scm_acons (rest
, CAR (vars
), env
);
824 /* Build up kw inits, env, and kw-canon list */
825 if (scm_is_null (kw
))
829 SCM kw_canon
= SCM_EOL
;
830 kw
= scm_reverse_x (kw
, SCM_UNDEFINED
);
831 for (tmp
= kw
; scm_is_pair (tmp
); tmp
= scm_cdr (tmp
))
835 if (scm_is_symbol (x
))
839 k
= scm_symbol_to_keyword (sym
);
841 else if (scm_ilength (x
) == 2 && scm_is_symbol (CAR (x
)))
845 k
= scm_symbol_to_keyword (sym
);
847 else if (scm_ilength (x
) == 3 && scm_is_symbol (CAR (x
))
848 && scm_is_keyword (CADDR (x
)))
855 syntax_error (s_bad_formals
, CAR (clause
), SCM_UNDEFINED
);
857 inits
= scm_cons (expand (init
, env
), inits
);
858 vars
= scm_cons (scm_gensym (SCM_UNDEFINED
), vars
);
859 kw_canon
= scm_cons (scm_list_3 (k
, sym
, CAR (vars
)), kw_canon
);
860 env
= scm_acons (sym
, CAR (vars
), env
);
862 kw_canon
= scm_reverse_x (kw_canon
, SCM_UNDEFINED
);
863 kw
= scm_cons (allow_other_keys
, kw_canon
);
866 /* We should check for no duplicates, but given that psyntax does this
867 already, we can punt on it here... */
869 vars
= scm_reverse_x (vars
, SCM_UNDEFINED
);
870 inits
= scm_reverse_x (inits
, SCM_UNDEFINED
);
871 body
= expand_sequence (body
, env
);
873 return LAMBDA_CASE (SCM_BOOL_F
, req
, opt
, rest
, kw
, inits
, vars
, body
,
878 expand_lambda_star (SCM expr
, SCM env
)
880 return LAMBDA (scm_source_properties (expr
),
882 expand_lambda_star_case (CDR (expr
), SCM_BOOL_F
, env
));
886 expand_case_lambda_clauses (SCM expr
, SCM rest
, SCM env
)
890 if (scm_is_pair (rest
))
891 alt
= expand_case_lambda_clauses (CAR (rest
), CDR (rest
), env
);
895 return expand_lambda_case (expr
, alt
, env
);
899 expand_case_lambda (SCM expr
, SCM env
)
901 ASSERT_SYNTAX (scm_is_pair (CDR (expr
)), s_missing_expression
, expr
);
903 return LAMBDA (scm_source_properties (expr
),
905 expand_case_lambda_clauses (CADR (expr
), CDDR (expr
), env
));
909 expand_case_lambda_star_clauses (SCM expr
, SCM rest
, SCM env
)
913 if (scm_is_pair (rest
))
914 alt
= expand_case_lambda_star_clauses (CAR (rest
), CDR (rest
), env
);
918 return expand_lambda_star_case (expr
, alt
, env
);
922 expand_case_lambda_star (SCM expr
, SCM env
)
924 ASSERT_SYNTAX (scm_is_pair (CDR (expr
)), s_missing_expression
, expr
);
926 return LAMBDA (scm_source_properties (expr
),
928 expand_case_lambda_star_clauses (CADR (expr
), CDDR (expr
), env
));
931 /* Check if the format of the bindings is ((<symbol> <init-form>) ...). */
933 check_bindings (const SCM bindings
, const SCM expr
)
937 ASSERT_SYNTAX_2 (scm_ilength (bindings
) >= 0,
938 s_bad_bindings
, bindings
, expr
);
940 binding_idx
= bindings
;
941 for (; !scm_is_null (binding_idx
); binding_idx
= CDR (binding_idx
))
943 SCM name
; /* const */
945 const SCM binding
= CAR (binding_idx
);
946 ASSERT_SYNTAX_2 (scm_ilength (binding
) == 2,
947 s_bad_binding
, binding
, expr
);
949 name
= CAR (binding
);
950 ASSERT_SYNTAX_2 (scm_is_symbol (name
), s_bad_variable
, name
, expr
);
954 /* The bindings, which must have the format ((v1 i1) (v2 i2) ... (vn in)), are
955 * transformed to the lists (vn .. v2 v1) and (i1 i2 ... in). If a duplicate
956 * variable name is detected, an error is signalled. */
958 transform_bindings (const SCM bindings
, const SCM expr
,
959 SCM
*const names
, SCM
*const vars
, SCM
*const initptr
)
961 SCM rnames
= SCM_EOL
;
963 SCM rinits
= SCM_EOL
;
964 SCM binding_idx
= bindings
;
965 for (; !scm_is_null (binding_idx
); binding_idx
= CDR (binding_idx
))
967 const SCM binding
= CAR (binding_idx
);
968 const SCM CDR_binding
= CDR (binding
);
969 const SCM name
= CAR (binding
);
970 ASSERT_SYNTAX_2 (scm_is_false (scm_c_memq (name
, rnames
)),
971 s_duplicate_binding
, name
, expr
);
972 rnames
= scm_cons (name
, rnames
);
973 rvars
= scm_cons (scm_gensym (SCM_UNDEFINED
), rvars
);
974 rinits
= scm_cons (CAR (CDR_binding
), rinits
);
976 *names
= scm_reverse_x (rnames
, SCM_UNDEFINED
);
977 *vars
= scm_reverse_x (rvars
, SCM_UNDEFINED
);
978 *initptr
= scm_reverse_x (rinits
, SCM_UNDEFINED
);
981 /* FIXME: Remove named let in this boot expander. */
983 expand_named_let (const SCM expr
, SCM env
)
985 SCM var_names
, var_syms
, inits
;
989 const SCM cdr_expr
= CDR (expr
);
990 const SCM name
= CAR (cdr_expr
);
991 const SCM cddr_expr
= CDR (cdr_expr
);
992 const SCM bindings
= CAR (cddr_expr
);
993 check_bindings (bindings
, expr
);
995 transform_bindings (bindings
, expr
, &var_names
, &var_syms
, &inits
);
996 name_sym
= scm_gensym (SCM_UNDEFINED
);
997 inner_env
= scm_acons (name
, name_sym
, env
);
998 inner_env
= expand_env_extend (inner_env
, var_names
, var_syms
);
1001 (scm_source_properties (expr
), SCM_BOOL_F
,
1002 scm_list_1 (name
), scm_list_1 (name_sym
),
1003 scm_list_1 (LAMBDA (SCM_BOOL_F
,
1005 LAMBDA_CASE (SCM_BOOL_F
, var_names
, SCM_BOOL_F
, SCM_BOOL_F
,
1006 SCM_BOOL_F
, SCM_BOOL_F
, var_syms
,
1007 expand_sequence (CDDDR (expr
), inner_env
),
1010 LEXICAL_REF (SCM_BOOL_F
, name
, name_sym
),
1011 expand_exprs (inits
, env
)));
1015 expand_let (SCM expr
, SCM env
)
1019 const SCM cdr_expr
= CDR (expr
);
1020 const long length
= scm_ilength (cdr_expr
);
1021 ASSERT_SYNTAX (length
>= 0, s_bad_expression
, expr
);
1022 ASSERT_SYNTAX (length
>= 2, s_missing_expression
, expr
);
1024 bindings
= CAR (cdr_expr
);
1025 if (scm_is_symbol (bindings
))
1027 ASSERT_SYNTAX (length
>= 3, s_missing_expression
, expr
);
1028 return expand_named_let (expr
, env
);
1031 check_bindings (bindings
, expr
);
1032 if (scm_is_null (bindings
))
1033 return expand_sequence (CDDR (expr
), env
);
1036 SCM var_names
, var_syms
, inits
;
1037 transform_bindings (bindings
, expr
, &var_names
, &var_syms
, &inits
);
1038 return LET (SCM_BOOL_F
,
1039 var_names
, var_syms
, expand_exprs (inits
, env
),
1040 expand_sequence (CDDR (expr
),
1041 expand_env_extend (env
, var_names
,
1047 expand_letrec_helper (SCM expr
, SCM env
, SCM in_order_p
)
1051 const SCM cdr_expr
= CDR (expr
);
1052 const long length
= scm_ilength (cdr_expr
);
1053 ASSERT_SYNTAX (length
>= 0, s_bad_expression
, expr
);
1054 ASSERT_SYNTAX (length
>= 2, s_missing_expression
, expr
);
1056 bindings
= CAR (cdr_expr
);
1057 check_bindings (bindings
, expr
);
1058 if (scm_is_null (bindings
))
1059 return expand_sequence (CDDR (expr
), env
);
1062 SCM var_names
, var_syms
, inits
;
1063 transform_bindings (bindings
, expr
, &var_names
, &var_syms
, &inits
);
1064 env
= expand_env_extend (env
, var_names
, var_syms
);
1065 return LETREC (SCM_BOOL_F
, in_order_p
,
1066 var_names
, var_syms
, expand_exprs (inits
, env
),
1067 expand_sequence (CDDR (expr
), env
));
1072 expand_letrec (SCM expr
, SCM env
)
1074 return expand_letrec_helper (expr
, env
, SCM_BOOL_F
);
1078 expand_letrec_star (SCM expr
, SCM env
)
1080 return expand_letrec_helper (expr
, env
, SCM_BOOL_T
);
1084 expand_letstar_clause (SCM bindings
, SCM body
, SCM env SCM_UNUSED
)
1086 if (scm_is_null (bindings
))
1087 return expand_sequence (body
, env
);
1090 SCM bind
, name
, sym
, init
;
1092 ASSERT_SYNTAX (scm_is_pair (bindings
), s_bad_expression
, bindings
);
1093 bind
= CAR (bindings
);
1094 ASSERT_SYNTAX (scm_ilength (bind
) == 2, s_bad_binding
, bind
);
1096 sym
= scm_gensym (SCM_UNDEFINED
);
1099 return LET (SCM_BOOL_F
, scm_list_1 (name
), scm_list_1 (sym
),
1100 scm_list_1 (expand (init
, env
)),
1101 expand_letstar_clause (CDR (bindings
), body
,
1102 scm_acons (name
, sym
, env
)));
1107 expand_letstar (SCM expr
, SCM env SCM_UNUSED
)
1109 const SCM cdr_expr
= CDR (expr
);
1110 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
1111 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 2, s_missing_expression
, expr
);
1113 return expand_letstar_clause (CADR (expr
), CDDR (expr
), env
);
1117 expand_or (SCM expr
, SCM env SCM_UNUSED
)
1119 SCM tail
= CDR (expr
);
1120 const long length
= scm_ilength (tail
);
1122 ASSERT_SYNTAX (length
>= 0, s_bad_expression
, expr
);
1124 if (scm_is_null (CDR (expr
)))
1125 return CONST_ (SCM_BOOL_F
, SCM_BOOL_F
);
1128 SCM tmp
= scm_gensym (SCM_UNDEFINED
);
1129 return LET (SCM_BOOL_F
,
1130 scm_list_1 (tmp
), scm_list_1 (tmp
),
1131 scm_list_1 (expand (CADR (expr
), env
)),
1132 CONDITIONAL (SCM_BOOL_F
,
1133 LEXICAL_REF (SCM_BOOL_F
, tmp
, tmp
),
1134 LEXICAL_REF (SCM_BOOL_F
, tmp
, tmp
),
1135 expand_or (CDR (expr
),
1136 scm_acons (tmp
, tmp
, env
))));
1141 expand_quote (SCM expr
, SCM env SCM_UNUSED
)
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
) == 1, s_expression
, expr
);
1148 quotee
= CAR (cdr_expr
);
1149 return CONST_ (scm_source_properties (expr
), quotee
);
1153 expand_set_x (SCM expr
, SCM env
)
1158 const SCM cdr_expr
= CDR (expr
);
1159 ASSERT_SYNTAX (scm_ilength (cdr_expr
) >= 0, s_bad_expression
, expr
);
1160 ASSERT_SYNTAX (scm_ilength (cdr_expr
) == 2, s_expression
, expr
);
1161 variable
= CAR (cdr_expr
);
1162 vmem
= expand (variable
, env
);
1164 switch (SCM_EXPANDED_TYPE (vmem
))
1166 case SCM_EXPANDED_LEXICAL_REF
:
1167 return LEXICAL_SET (scm_source_properties (expr
),
1168 SCM_EXPANDED_REF (vmem
, LEXICAL_REF
, NAME
),
1169 SCM_EXPANDED_REF (vmem
, LEXICAL_REF
, GENSYM
),
1170 expand (CADDR (expr
), env
));
1171 case SCM_EXPANDED_TOPLEVEL_REF
:
1172 return TOPLEVEL_SET (scm_source_properties (expr
),
1173 SCM_EXPANDED_REF (vmem
, TOPLEVEL_REF
, NAME
),
1174 expand (CADDR (expr
), env
));
1175 case SCM_EXPANDED_MODULE_REF
:
1176 return MODULE_SET (scm_source_properties (expr
),
1177 SCM_EXPANDED_REF (vmem
, MODULE_REF
, MOD
),
1178 SCM_EXPANDED_REF (vmem
, MODULE_REF
, NAME
),
1179 SCM_EXPANDED_REF (vmem
, MODULE_REF
, PUBLIC
),
1180 expand (CADDR (expr
), env
));
1182 syntax_error (s_bad_variable
, variable
, expr
);
1189 /* This is the boot expander. It is later replaced with psyntax's sc-expand. */
1190 SCM_DEFINE (scm_macroexpand
, "macroexpand", 1, 0, 0,
1192 "Expand the expression @var{exp}.")
1193 #define FUNC_NAME s_scm_macroexpand
1195 return expand (exp
, scm_current_module ());
1199 SCM_DEFINE (scm_macroexpanded_p
, "macroexpanded?", 1, 0, 0,
1201 "Return @code{#t} if @var{exp} is an expanded expression.")
1202 #define FUNC_NAME s_scm_macroexpanded_p
1204 return scm_from_bool (SCM_EXPANDED_P (exp
));
1211 #define DEFINE_NAMES(type) \
1213 static const char *fields[] = SCM_EXPANDED_##type##_FIELD_NAMES; \
1214 exp_field_names[SCM_EXPANDED_##type] = fields; \
1215 exp_names[SCM_EXPANDED_##type] = SCM_EXPANDED_##type##_TYPE_NAME; \
1216 exp_nfields[SCM_EXPANDED_##type] = SCM_NUM_EXPANDED_##type##_FIELDS; \
1220 make_exp_vtable (size_t n
)
1222 SCM layout
, printer
, name
, code
, fields
;
1224 layout
= scm_string_to_symbol
1225 (scm_string_append (scm_make_list (scm_from_size_t (exp_nfields
[n
]),
1226 scm_from_locale_string ("pw"))));
1227 printer
= SCM_BOOL_F
;
1228 name
= scm_from_utf8_symbol (exp_names
[n
]);
1229 code
= scm_from_size_t (n
);
1232 size_t m
= exp_nfields
[n
];
1234 fields
= scm_cons (scm_from_utf8_symbol (exp_field_names
[n
][m
]), fields
);
1237 return scm_c_make_struct (scm_exp_vtable_vtable
, 0, 5,
1238 SCM_UNPACK (layout
), SCM_UNPACK (printer
), SCM_UNPACK (name
),
1239 SCM_UNPACK (code
), SCM_UNPACK (fields
));
1246 SCM exp_vtable_list
= SCM_EOL
;
1248 DEFINE_NAMES (VOID
);
1249 DEFINE_NAMES (CONST
);
1250 DEFINE_NAMES (PRIMITIVE_REF
);
1251 DEFINE_NAMES (LEXICAL_REF
);
1252 DEFINE_NAMES (LEXICAL_SET
);
1253 DEFINE_NAMES (MODULE_REF
);
1254 DEFINE_NAMES (MODULE_SET
);
1255 DEFINE_NAMES (TOPLEVEL_REF
);
1256 DEFINE_NAMES (TOPLEVEL_SET
);
1257 DEFINE_NAMES (TOPLEVEL_DEFINE
);
1258 DEFINE_NAMES (CONDITIONAL
);
1259 DEFINE_NAMES (CALL
);
1260 DEFINE_NAMES (PRIMCALL
);
1262 DEFINE_NAMES (LAMBDA
);
1263 DEFINE_NAMES (LAMBDA_CASE
);
1265 DEFINE_NAMES (LETREC
);
1266 DEFINE_NAMES (DYNLET
);
1268 scm_exp_vtable_vtable
=
1269 scm_make_vtable (scm_from_locale_string (SCM_VTABLE_BASE_LAYOUT
"pwuwpw"),
1272 for (n
= 0; n
< SCM_NUM_EXPANDED_TYPES
; n
++)
1273 exp_vtables
[n
] = make_exp_vtable (n
);
1275 /* Now walk back down, consing in reverse. */
1277 exp_vtable_list
= scm_cons (exp_vtables
[n
], exp_vtable_list
);
1279 scm_c_define ("%expanded-vtables", scm_vector (exp_vtable_list
));
1281 #include "libguile/expand.x"