1 /*===========================================================================
2 * Filename : syntax.c
3 * About : R5RS syntaxes
4 *
5 * Copyright (C) 2005 Kazuki Ohta <mover AT hct.zaq.ne.jp>
6 * Copyright (C) 2005-2006 Jun Inoue <jun.lambda AT gmail.com>
7 * Copyright (C) 2005-2006 YAMAMOTO Kengo <yamaken AT bp.iij4u.or.jp>
8 * Copyright (c) 2007-2008 SigScheme Project <uim-en AT googlegroups.com>
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of authors nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
26 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 ===========================================================================*/
37
38 #include <config.h>
39
40 #include "sigscheme.h"
41 #include "sigschemeinternal.h"
42
43 /*=======================================
44 File Local Macro Definitions
45 =======================================*/
46 #define ERRMSG_CLAUSE_REQUIRED "at least 1 clause required"
47 #define ERRMSG_EXPRESSION_REQUIRED "at least 1 expression required"
48 #define ERRMSG_INVALID_BINDINGS "invalid bindings form"
49 #define ERRMSG_INVALID_BINDING "invalid binding form"
50 #define ERRMSG_SYNTAX_AS_VALUE "syntactic keyword is passed as value"
51 #define ERRMSG_DUPLICATE_VARNAME "duplicate variable name"
52 #define ERRMSG_BAD_DEFINE_FORM "bad definition form"
53
54 #if SCM_USE_INTERNAL_DEFINITIONS
55 #define ERRMSG_BAD_DEFINE_PLACEMENT "definitions are valid only at toplevel" \
56 " or beginning of a binding construct"
57 #else
58 #define ERRMSG_BAD_DEFINE_PLACEMENT "internal definitions feature is disabled"
59 #endif
60
61 /* FIXME: temporary hack */
62 #if SCM_STRICT_TOPLEVEL_DEFINITIONS
63 #define FORBID_TOPLEVEL_DEFINITIONS(env) \
64 (EQ((env), SCM_INTERACTION_ENV) ? SCM_INTERACTION_ENV_INDEFINABLE : (env))
65 #else
66 #define FORBID_TOPLEVEL_DEFINITIONS(env) (env)
67 #endif
68
69 #if SCM_USE_HYGIENIC_MACRO
70 #define CHECK_VALID_BINDEE(permitted_type, bindee) \
71 do { \
72 if (permitted_type == ScmFirstClassObj) \
73 CHECK_VALID_EVALED_VALUE(bindee); \
74 else if (permitted_type == ScmMacro) \
75 SCM_ASSERT(HMACROP(bindee)); \
76 else \
77 SCM_NOTREACHED; \
78 } while (/* CONSTCOND */ 0)
79 #else
80 #define CHECK_VALID_BINDEE(permitted_type, bindee) \
81 do { \
82 if (permitted_type == ScmFirstClassObj) \
83 CHECK_VALID_EVALED_VALUE(bindee); \
84 else \
85 SCM_NOTREACHED; \
86 } while (/* CONSTCOND */ 0)
87 #endif
88
89 /*=======================================
90 File Local Type Definitions
91 =======================================*/
92
93 /*=======================================
94 Variable Definitions
95 =======================================*/
96 #include "functable-r5rs-syntax.c"
97
98 SCM_DEFINE_EXPORTED_VARS(syntax);
99
100 SCM_GLOBAL_VARS_BEGIN(static_syntax);
101 #define static
102 static ScmObj l_sym_else, l_sym_yields, l_sym_define;
103 #if SCM_USE_INTERNAL_DEFINITIONS
104 static ScmObj l_sym_begin, l_syn_lambda;
105 #endif /* SCM_USE_INTERNAL_DEFINITIONS */
106 #undef static
107 SCM_GLOBAL_VARS_END(static_syntax);
108 #define l_sym_else SCM_GLOBAL_VAR(static_syntax, l_sym_else)
109 #define l_sym_yields SCM_GLOBAL_VAR(static_syntax, l_sym_yields)
110 #define l_sym_define SCM_GLOBAL_VAR(static_syntax, l_sym_define)
111 #define l_sym_begin SCM_GLOBAL_VAR(static_syntax, l_sym_begin)
112 #define l_syn_lambda SCM_GLOBAL_VAR(static_syntax, l_syn_lambda)
113 SCM_DEFINE_STATIC_VARS(static_syntax);
114
115 /*=======================================
116 File Local Function Declarations
117 =======================================*/
118 #if SCM_USE_INTERNAL_DEFINITIONS
119 static ScmObj filter_definitions(ScmObj body, ScmObj *formals, ScmObj *actuals,
120 ScmQueue *def_expq);
121 #endif
122
123 /*=======================================
124 Function Definitions
125 =======================================*/
126 SCM_EXPORT void
scm_init_syntax(void)127 scm_init_syntax(void)
128 {
129 SCM_GLOBAL_VARS_INIT(syntax);
130 SCM_GLOBAL_VARS_INIT(static_syntax);
131
132 scm_register_funcs(scm_functable_r5rs_syntax);
133
134 scm_sym_quote = scm_intern("quote");
135 scm_sym_quasiquote = scm_intern("quasiquote");
136 scm_sym_unquote = scm_intern("unquote");
137 scm_sym_unquote_splicing = scm_intern("unquote-splicing");
138 scm_sym_ellipsis = scm_intern("...");
139
140 l_sym_else = scm_intern("else");
141 l_sym_yields = scm_intern("=>");
142 l_sym_define = scm_intern("define");
143 #if SCM_USE_INTERNAL_DEFINITIONS
144 l_sym_begin = scm_intern("begin");
145 scm_gc_protect_with_init(&l_syn_lambda,
146 scm_symbol_value(scm_intern("lambda"),
147 SCM_INTERACTION_ENV));
148 #endif
149 }
150
151 /*=======================================
152 R5RS : 4.1 Primitive expression types
153 =======================================*/
154 /*===========================================================================
155 R5RS : 4.1 Primitive expression types : 4.1.2 Literal expressions
156 ===========================================================================*/
157 SCM_EXPORT ScmObj
scm_s_quote(ScmObj datum,ScmObj env)158 scm_s_quote(ScmObj datum, ScmObj env)
159 {
160 DECLARE_FUNCTION("quote", syntax_fixed_1);
161
162 #if SCM_USE_HYGIENIC_MACRO
163 /* Passing objects that contain a circular list to SCM_UNWRAP_SYNTAX()
164 * causes infinite loop. For instance, (error circular-list) raises it via
165 * the error object which contains the circular list.
166 * -- YamaKen 2006-10-02 */
167 if (ERROBJP(datum))
168 return datum;
169 #endif
170
171 return SCM_UNWRAP_SYNTAX(datum);
172 }
173
174 /*===========================================================================
175 R5RS : 4.1 Primitive expression types : 4.1.4 Procedures
176 ===========================================================================*/
177 SCM_EXPORT ScmObj
scm_s_lambda(ScmObj formals,ScmObj body,ScmObj env)178 scm_s_lambda(ScmObj formals, ScmObj body, ScmObj env)
179 {
180 DECLARE_FUNCTION("lambda", syntax_variadic_1);
181
182 #if SCM_STRICT_ARGCHECK
183 if (SCM_LISTLEN_ERRORP(scm_validate_formals(formals)))
184 ERR_OBJ("bad formals", formals);
185
186 /* Keeping variable name unique is user's responsibility. R5RS: "It is an
187 * error for a <variable> to appear more than once in <formals>.". */
188 #else
189 /* Crashless no-validation:
190 * Regard any non-list object as symbol. Since the lookup operation search
191 * for a variable by EQ, this is safe although loosely allows
192 * R5RS-incompatible code. */
193 #endif
194
195 /* Internal definitions-only body such as ((define foo bar)) is
196 * invalid. But since checking it here is inefficient, it is deferred to
197 * scm_s_body() on being called. */
198 if (!CONSP(body))
199 ERR_OBJ(ERRMSG_EXPRESSION_REQUIRED, body);
200
201 return MAKE_CLOSURE(CONS(formals, body), env);
202 }
203
204 /*===========================================================================
205 R5RS : 4.1 Primitive expression types : 4.1.5 Conditionals
206 ===========================================================================*/
207 SCM_EXPORT ScmObj
scm_s_if(ScmObj test,ScmObj conseq,ScmObj rest,ScmEvalState * eval_state)208 scm_s_if(ScmObj test, ScmObj conseq, ScmObj rest, ScmEvalState *eval_state)
209 {
210 ScmObj env, alt;
211 DECLARE_FUNCTION("if", syntax_variadic_tailrec_2);
212
213 env = eval_state->env;
214
215 /*=======================================================================
216 (if <test> <consequent>)
217 (if <test> <consequent> <alternate>)
218 =======================================================================*/
219
220 test = EVAL(test, env);
221 CHECK_VALID_EVALED_VALUE(test);
222 if (TRUEP(test)) {
223 #if SCM_STRICT_ARGCHECK
224 SAFE_POP(rest);
225 ASSERT_NO_MORE_ARG(rest);
226 #endif
227 return conseq;
228 } else {
229 #if SCM_COMPAT_SIOD_BUGS
230 alt = (CONSP(rest)) ? CAR(rest) : SCM_FALSE;
231 #else
232 alt = (CONSP(rest)) ? CAR(rest) : SCM_UNDEF;
233 #endif
234 #if SCM_STRICT_ARGCHECK
235 SAFE_POP(rest);
236 ASSERT_NO_MORE_ARG(rest);
237 #endif
238 return alt;
239 }
240 }
241
242 /*===========================================================================
243 R5RS : 4.1 Primitive expression types : 4.1.6 Assignments
244 ===========================================================================*/
245 SCM_EXPORT ScmObj
scm_s_setx(ScmObj sym,ScmObj exp,ScmObj env)246 scm_s_setx(ScmObj sym, ScmObj exp, ScmObj env)
247 {
248 ScmObj evaled;
249 ScmRef locally_bound;
250 DECLARE_FUNCTION("set!", syntax_fixed_2);
251
252 ENSURE_SYMBOL(sym);
253
254 evaled = EVAL(exp, env);
255 CHECK_VALID_EVALED_VALUE(evaled);
256 locally_bound = scm_lookup_environment(sym, env);
257 if (locally_bound != SCM_INVALID_REF) {
258 SET(locally_bound, evaled);
259 } else {
260 if (!SCM_SYMBOL_BOUNDP(sym))
261 ERR_OBJ("unbound variable", sym);
262
263 SCM_SYMBOL_SET_VCELL(sym, evaled);
264 }
265
266 #if SCM_STRICT_R5RS
267 return SCM_UNDEF;
268 #else
269 return evaled;
270 #endif
271 }
272
273
274 /*=======================================
275 R5RS : 4.2 Derived expression types
276 =======================================*/
277 /*===========================================================================
278 R5RS : 4.2 Derived expression types : 4.2.1 Conditionals
279 ===========================================================================*/
280 /* body of 'cond' and 'guard' of SRFI-34 */
281 SCM_EXPORT ScmObj
scm_s_cond_internal(ScmObj clauses,ScmEvalState * eval_state)282 scm_s_cond_internal(ScmObj clauses, ScmEvalState *eval_state)
283 {
284 ScmObj env, clause, test, exps, proc;
285 DECLARE_INTERNAL_FUNCTION("cond" /* , syntax_variadic_tailrec_0 */);
286
287 env = eval_state->env;
288 #if SCM_STRICT_TOPLEVEL_DEFINITIONS
289 eval_state->nest = SCM_NEST_COMMAND;
290 #endif
291
292 /*
293 * (cond <cond clause>+)
294 * (cond <cond clause>* (else <sequence>))
295 *
296 * <cond clause> --> (<test> <sequence>)
297 * | (<test>)
298 * | (<test> => <recipient>)
299 * <recipient> --> <expression>
300 * <test> --> <expression>
301 * <sequence> --> <command>* <expression>
302 * <command> --> <expression>
303 */
304
305 if (NO_MORE_ARG(clauses))
306 ERR(ERRMSG_CLAUSE_REQUIRED);
307
308 /* looping in each clause */
309 FOR_EACH (clause, clauses) {
310 if (!CONSP(clause))
311 ERR_OBJ("bad clause", clause);
312
313 test = CAR(clause);
314 exps = CDR(clause);
315
316 #if 0
317 test = SCM_UNWRAP_SYNTAX(test); /* FIXME: needed? */
318 #endif
319 if (EQ(test, l_sym_else)) {
320 ASSERT_NO_MORE_ARG(clauses);
321 return scm_s_begin(exps, eval_state);
322 }
323
324 test = EVAL(test, env);
325 CHECK_VALID_EVALED_VALUE(test);
326 if (TRUEP(test)) {
327 /*
328 * if the selected <clause> contains only the <test> and no
329 * <expression>s, then the value of the <test> is returned as the
330 * result.
331 */
332 if (NULLP(exps)) {
333 eval_state->ret_type = SCM_VALTYPE_AS_IS;
334 return test;
335 }
336
337 /*
338 * If the selected <clause> uses the => alternate form, then the
339 * <expression> is evaluated. Its value must be a procedure that
340 * accepts one argument; this procedure is then called on the value
341 * of the <test> and the value returned by this procedure is
342 * returned by the cond expression.
343 */
344 if (EQ(l_sym_yields, CAR(exps)) && LIST_2_P(exps)) {
345 proc = EVAL(CADR(exps), env);
346 if (!PROCEDUREP(proc))
347 ERR_OBJ("exp after => must be a procedure but got", proc);
348
349 /*
350 * R5RS: 3.5 Proper tail recursion
351 *
352 * If a `cond' expression is in a tail context, and has a
353 * clause of the form `(<expression1> => <expression2>)' then
354 * the (implied) call to the procedure that results from the
355 * evaluation of <expression2> is in a tail
356 * context. <expression2> itself is not in a tail context.
357 */
358 return LIST_2(proc, LIST_2(SYM_QUOTE, test));
359 }
360
361 return scm_s_begin(exps, eval_state);
362 }
363 }
364 ASSERT_NO_MORE_ARG(clauses);
365
366 /*
367 * To distinguish unmatched status from SCM_UNDEF from a clause, pure
368 * internal value SCM_INVALID is returned. Don't pass it to Scheme world.
369 */
370 eval_state->ret_type = SCM_VALTYPE_AS_IS;
371 return SCM_INVALID;
372 }
373
374 SCM_EXPORT ScmObj
scm_s_cond(ScmObj clauses,ScmEvalState * eval_state)375 scm_s_cond(ScmObj clauses, ScmEvalState *eval_state)
376 {
377 ScmObj ret;
378 DECLARE_FUNCTION("cond", syntax_variadic_tailrec_0);
379
380 ret = scm_s_cond_internal(clauses, eval_state);
381 return (VALIDP(ret)) ? ret : SCM_UNDEF;
382 }
383
384 SCM_EXPORT ScmObj
scm_s_case(ScmObj key,ScmObj clauses,ScmEvalState * eval_state)385 scm_s_case(ScmObj key, ScmObj clauses, ScmEvalState *eval_state)
386 {
387 ScmObj clause, test, exps;
388 DECLARE_FUNCTION("case", syntax_variadic_tailrec_1);
389
390 /*
391 * (case <expression>
392 * <case clause>+)
393 *
394 * (case <expression>
395 * <case clause>*
396 * (else <sequence>))
397 *
398 * <case clause> --> ((<datum>*) <sequence>)
399 * <sequence> --> <command>* <expression>
400 * <command> --> <expression>
401 * <Datum> is what the read procedure (see section 6.6.2 Input)
402 * successfully parses.
403 */
404
405 if (NO_MORE_ARG(clauses))
406 ERR(ERRMSG_CLAUSE_REQUIRED);
407
408 key = EVAL(key, eval_state->env);
409 CHECK_VALID_EVALED_VALUE(key);
410
411 FOR_EACH (clause, clauses) {
412 if (!CONSP(clause))
413 ERR_OBJ("bad clause", clause);
414
415 test = CAR(clause);
416 exps = CDR(clause);
417
418 test = SCM_UNWRAP_SYNTAX(test);
419 if (EQ(test, l_sym_else))
420 ASSERT_NO_MORE_ARG(clauses);
421 else
422 test = scm_p_memv(key, test);
423
424 if (TRUEP(test)) {
425 #if SCM_STRICT_TOPLEVEL_DEFINITIONS
426 eval_state->nest = SCM_NEST_COMMAND;
427 #endif
428 return scm_s_begin(exps, eval_state);
429 }
430 }
431 ASSERT_NO_MORE_ARG(clauses);
432
433 return SCM_UNDEF;
434 }
435
436 SCM_EXPORT ScmObj
scm_s_and(ScmObj args,ScmEvalState * eval_state)437 scm_s_and(ScmObj args, ScmEvalState *eval_state)
438 {
439 ScmObj expr, val, env;
440 DECLARE_FUNCTION("and", syntax_variadic_tailrec_0);
441
442 if (NO_MORE_ARG(args)) {
443 eval_state->ret_type = SCM_VALTYPE_AS_IS;
444 return SCM_TRUE;
445 }
446 env = FORBID_TOPLEVEL_DEFINITIONS(eval_state->env);
447
448 FOR_EACH_BUTLAST (expr, args) {
449 val = EVAL(expr, env);
450 CHECK_VALID_EVALED_VALUE(val);
451 if (FALSEP(val)) {
452 ASSERT_PROPER_ARG_LIST(args);
453 eval_state->ret_type = SCM_VALTYPE_AS_IS;
454 return SCM_FALSE;
455 }
456 }
457 ASSERT_NO_MORE_ARG(args);
458
459 return expr;
460 }
461
462 SCM_EXPORT ScmObj
scm_s_or(ScmObj args,ScmEvalState * eval_state)463 scm_s_or(ScmObj args, ScmEvalState *eval_state)
464 {
465 ScmObj expr, val, env;
466 DECLARE_FUNCTION("or", syntax_variadic_tailrec_0);
467
468 if (NO_MORE_ARG(args)) {
469 eval_state->ret_type = SCM_VALTYPE_AS_IS;
470 return SCM_FALSE;
471 }
472 env = FORBID_TOPLEVEL_DEFINITIONS(eval_state->env);
473
474 FOR_EACH_BUTLAST (expr, args) {
475 val = EVAL(expr, env);
476 CHECK_VALID_EVALED_VALUE(val);
477 if (TRUEP(val)) {
478 ASSERT_PROPER_ARG_LIST(args);
479 eval_state->ret_type = SCM_VALTYPE_AS_IS;
480 return val;
481 }
482 }
483 ASSERT_NO_MORE_ARG(args);
484
485 return expr;
486 }
487
488 /*===========================================================================
489 R5RS : 4.2 Derived expression types : 4.2.2 Binding constructs
490 ===========================================================================*/
491 SCM_EXPORT ScmObj
scm_s_let(ScmObj bindings,ScmObj body,ScmEvalState * eval_state)492 scm_s_let(ScmObj bindings, ScmObj body, ScmEvalState *eval_state)
493 {
494 DECLARE_FUNCTION("let", syntax_variadic_tailrec_1);
495
496 return scm_s_let_internal(ScmFirstClassObj, bindings, body, eval_state);
497 }
498
499 SCM_EXPORT ScmObj
scm_s_let_internal(enum ScmObjType permitted,ScmObj bindings,ScmObj body,ScmEvalState * eval_state)500 scm_s_let_internal(enum ScmObjType permitted, ScmObj bindings, ScmObj body,
501 ScmEvalState *eval_state)
502 {
503 ScmObj env, named_let_sym, proc, binding;
504 ScmObj formals, var, actuals, val, exp;
505 ScmQueue varq, valq;
506 DECLARE_INTERNAL_FUNCTION("let" /* , syntax_variadic_tailrec_1 */);
507
508 env = eval_state->env;
509 named_let_sym = SCM_FALSE;
510
511 /*=======================================================================
512 normal let:
513
514 (let (<binding spec>*) <body>)
515
516 named let:
517
518 (let <variable> (<binding spec>*) <body>)
519
520 <binding spec> --> (<variable> <expression>)
521 <body> --> <definition>* <sequence>
522 <definition> --> (define <variable> <expression>)
523 | (define (<variable> <def formals>) <body>)
524 | (begin <definition>*)
525 <sequence> --> <command>* <expression>
526 <command> --> <expression>
527 =======================================================================*/
528
529 /* named let */
530 if (IDENTIFIERP(bindings)) {
531 named_let_sym = bindings;
532
533 if (!CONSP(body))
534 ERR("invalid named let form");
535 bindings = POP(body);
536 }
537
538 formals = actuals = SCM_NULL;
539 SCM_QUEUE_POINT_TO(varq, formals);
540 SCM_QUEUE_POINT_TO(valq, actuals);
541 FOR_EACH (binding, bindings) {
542 #if SCM_COMPAT_SIOD_BUGS
543 /* temporary solution. the inefficiency is not a problem */
544 if (LIST_1_P(binding))
545 binding = LIST_2(CAR(binding), SCM_FALSE);
546 #endif
547
548 if (!LIST_2_P(binding) || !IDENTIFIERP(var = CAR(binding)))
549 ERR_OBJ(ERRMSG_INVALID_BINDING, binding);
550 #if SCM_STRICT_ARGCHECK
551 /* Optional check. Keeping variable name unique is user's
552 * responsibility. R5RS: "It is an error for a <variable> to appear
553 * more than once in the list of variables being bound." */
554 if (TRUEP(scm_p_memq(var, formals)))
555 ERR_OBJ(ERRMSG_DUPLICATE_VARNAME, var);
556 #endif
557 exp = CADR(binding);
558 val = EVAL(exp, env);
559 CHECK_VALID_BINDEE(permitted, val);
560
561 SCM_QUEUE_ADD(varq, var);
562 SCM_QUEUE_ADD(valq, val);
563 }
564 if (!NULLP(bindings))
565 ERR_OBJ(ERRMSG_INVALID_BINDINGS, bindings);
566
567 env = scm_extend_environment(formals, actuals, env);
568
569 /* named let */
570 if (IDENTIFIERP(named_let_sym)) {
571 proc = MAKE_CLOSURE(CONS(formals, body), env);
572 env = scm_add_environment(named_let_sym, proc, env);
573 SCM_CLOSURE_SET_ENV(proc, env);
574 }
575
576 eval_state->env = env;
577 return scm_s_body(body, eval_state);
578 }
579
580 SCM_EXPORT ScmObj
scm_s_letstar(ScmObj bindings,ScmObj body,ScmEvalState * eval_state)581 scm_s_letstar(ScmObj bindings, ScmObj body, ScmEvalState *eval_state)
582 {
583 ScmObj env, var, val, exp, binding;
584 DECLARE_FUNCTION("let*", syntax_variadic_tailrec_1);
585
586 env = eval_state->env;
587
588 /*=======================================================================
589 (let* (<binding spec>*) <body>)
590
591 <binding spec> --> (<variable> <expression>)
592 <body> --> <definition>* <sequence>
593 <definition> --> (define <variable> <expression>)
594 | (define (<variable> <def formals>) <body>)
595 | (begin <definition>*)
596 <sequence> --> <command>* <expression>
597 <command> --> <expression>
598 =======================================================================*/
599
600 FOR_EACH (binding, bindings) {
601 #if SCM_COMPAT_SIOD_BUGS
602 /* temporary solution. the inefficiency is not a problem */
603 if (LIST_1_P(binding))
604 binding = LIST_2(CAR(binding), SCM_FALSE);
605 #endif
606
607 if (!LIST_2_P(binding) || !IDENTIFIERP(var = CAR(binding)))
608 ERR_OBJ(ERRMSG_INVALID_BINDING, binding);
609
610 exp = CADR(binding);
611 val = EVAL(exp, env);
612 CHECK_VALID_EVALED_VALUE(val);
613
614 /* extend env for each variable */
615 env = scm_extend_environment(LIST_1(var), LIST_1(val), env);
616 }
617 if (!NULLP(bindings))
618 ERR_OBJ(ERRMSG_INVALID_BINDINGS, bindings);
619
620 eval_state->env = env;
621 return scm_s_body(body, eval_state);
622 }
623
624 SCM_EXPORT ScmObj
scm_s_letrec(ScmObj bindings,ScmObj body,ScmEvalState * eval_state)625 scm_s_letrec(ScmObj bindings, ScmObj body, ScmEvalState *eval_state)
626 {
627 DECLARE_FUNCTION("letrec", syntax_variadic_tailrec_1);
628
629 return scm_s_letrec_internal(ScmFirstClassObj, bindings, body, eval_state);
630 }
631
632 SCM_EXPORT ScmObj
scm_s_letrec_internal(enum ScmObjType permitted,ScmObj bindings,ScmObj body,ScmEvalState * eval_state)633 scm_s_letrec_internal(enum ScmObjType permitted, ScmObj bindings, ScmObj body,
634 ScmEvalState *eval_state)
635 {
636 ScmObj binding, formals, actuals, var, val, exp, env;
637 DECLARE_INTERNAL_FUNCTION("letrec" /* , syntax_variadic_tailrec_1 */);
638
639 /*=======================================================================
640 (letrec (<binding spec>*) <body>)
641
642 <binding spec> --> (<variable> <expression>)
643 <body> --> <definition>* <sequence>
644 <definition> --> (define <variable> <expression>)
645 | (define (<variable> <def formals>) <body>)
646 | (begin <definition>*)
647 <sequence> --> <command>* <expression>
648 <command> --> <expression>
649 =======================================================================*/
650
651 /* extend env by placeholder frame for subsequent lambda evaluations */
652 env = scm_extend_environment(SCM_NULL, SCM_NULL, eval_state->env);
653
654 formals = actuals = SCM_NULL;
655 FOR_EACH (binding, bindings) {
656 if (!LIST_2_P(binding) || !IDENTIFIERP(var = CAR(binding)))
657 ERR_OBJ(ERRMSG_INVALID_BINDING, binding);
658 #if SCM_STRICT_ARGCHECK
659 /* Optional check. Keeping variable name unique is user's
660 * responsibility. R5RS: "It is an error for a <variable> to appear
661 * more than once in the list of variables being bound." */
662 if (TRUEP(scm_p_memq(var, formals)))
663 ERR_OBJ(ERRMSG_DUPLICATE_VARNAME, var);
664 #endif
665 exp = CADR(binding);
666 val = EVAL(exp, env);
667 CHECK_VALID_BINDEE(permitted, val);
668
669 /* construct formals and actuals list: any <init> must not refer a
670 * <variable> at this time */
671 formals = CONS(var, formals);
672 actuals = CONS(val, actuals);
673 }
674 if (!NULLP(bindings))
675 ERR_OBJ(ERRMSG_INVALID_BINDINGS, bindings);
676
677 /* fill the placeholder frame */
678 eval_state->env = scm_replace_environment(formals, actuals, env);
679
680 return scm_s_body(body, eval_state);
681 }
682
683 /*
684 * Valid placement for definitions
685 *
686 * Definitions on SigScheme is strictly conformed to the three rule specified
687 * in R5RS (see below), when SCM_USE_INTERNAL_DEFINITIONS is enabled. All
688 * conditions that are not specified by the rules cause syntax error.
689 *
690 * 5.2 Definitions
691 *
692 * Definitions are valid in some, but not all, contexts where expressions are
693 * allowed. They are valid only at the top level of a <program> and at the
694 * beginning of a <body>.
695 *
696 * 5.2.2 Internal definitions
697 *
698 * Definitions may occur at the beginning of a <body> (that is, the body of a
699 * lambda, let, let*, letrec, let-syntax, or letrec-syntax expression or that
700 * of a definition of an appropriate form).
701 *
702 * Wherever an internal definition may occur (begin <definition1> ...) is
703 * equivalent to the sequence of definitions that form the body of the begin.
704 *
705 * 7.1.6 Programs and definitions
706 *
707 * <definition> --> (define <variable> <expression>)
708 * | (define (<variable> <def formals>) <body>)
709 * | (begin <definition>*)
710 */
711
712 #if SCM_USE_INTERNAL_DEFINITIONS
713 static ScmObj
filter_definitions(ScmObj body,ScmObj * formals,ScmObj * actuals,ScmQueue * def_expq)714 filter_definitions(ScmObj body, ScmObj *formals, ScmObj *actuals,
715 ScmQueue *def_expq)
716 {
717 ScmObj exp, var, sym, begin_rest, lambda_formals, lambda_body;
718 DECLARE_INTERNAL_FUNCTION("(body)");
719
720 for (; CONSP(body); POP(body)) {
721 exp = CAR(body);
722 if (!CONSP(exp))
723 break;
724 sym = POP(exp);
725 if (EQ(sym, l_sym_begin)) {
726 begin_rest = filter_definitions(exp, formals, actuals, def_expq);
727 if (!NULLP(begin_rest)) {
728 /* no definitions found */
729 if (begin_rest == exp)
730 return body;
731
732 ERR_OBJ("definitions and expressions intermixed", CAR(body));
733 }
734 /* '(begin)' is a valid R5RS definition form */
735 } else if (EQ(sym, l_sym_define)) {
736 var = MUST_POP_ARG(exp);
737 if (IDENTIFIERP(var)) {
738 /* (define <variable> <expression>) */
739 if (!LIST_1_P(exp))
740 ERR_OBJ(ERRMSG_BAD_DEFINE_FORM, CAR(body));
741 exp = CAR(exp);
742 } else if (CONSP(var)) {
743 /* (define (<variable> . <formals>) <body>) */
744 sym = CAR(var);
745 lambda_formals = CDR(var);
746 lambda_body = exp;
747
748 ENSURE_SYMBOL(sym);
749 var = sym;
750 exp = CONS(l_syn_lambda, CONS(lambda_formals, lambda_body));
751 } else {
752 ERR_OBJ(ERRMSG_BAD_DEFINE_FORM, CAR(body));
753 }
754 *formals = CONS(var, *formals);
755 *actuals = CONS(SCM_UNBOUND, *actuals);
756 SCM_QUEUE_ADD(*def_expq, exp);
757 } else {
758 break;
759 }
760 }
761
762 return body;
763 }
764
765 /* <body> part of let, let*, letrec and lambda. This function performs strict
766 * form validation for internal definitions as specified in R5RS ("5.2.2
767 * Internal definitions" and "7.1.6 Programs and definitions"). */
768 /* TODO: Introduce compilation phase and reorganize into compile-time syntax
769 * transformer */
770 SCM_EXPORT ScmObj
scm_s_body(ScmObj body,ScmEvalState * eval_state)771 scm_s_body(ScmObj body, ScmEvalState *eval_state)
772 {
773 ScmQueue def_expq;
774 ScmObj env, formals, actuals, def_exps, exp, val;
775 DECLARE_INTERNAL_FUNCTION("(body)" /* , syntax_variadic_tailrec_0 */);
776
777 if (CONSP(body)) {
778 /* collect internal definitions */
779 def_exps = formals = actuals = SCM_NULL;
780 SCM_QUEUE_POINT_TO(def_expq, def_exps);
781 body = filter_definitions(body, &formals, &actuals, &def_expq);
782
783 if (!NULLP(def_exps)) {
784 /* extend env with the unbound variables */
785 env = scm_extend_environment(formals, actuals, eval_state->env);
786
787 /* eval the definitions and fill the variables with the results as
788 * if letrec */
789 actuals = SCM_NULL;
790 FOR_EACH (exp, def_exps) {
791 val = EVAL(exp, env);
792 CHECK_VALID_EVALED_VALUE(val);
793 actuals = CONS(val, actuals);
794 }
795 eval_state->env = scm_update_environment(actuals, env);
796 }
797 }
798 /* eval rest of the body */
799 return scm_s_begin(body, eval_state);
800 }
801 #endif /* SCM_USE_INTERNAL_DEFINITIONS */
802
803 /*===========================================================================
804 R5RS : 4.2 Derived expression types : 4.2.3 Sequencing
805 ===========================================================================*/
806 SCM_EXPORT ScmObj
scm_s_begin(ScmObj args,ScmEvalState * eval_state)807 scm_s_begin(ScmObj args, ScmEvalState *eval_state)
808 {
809 ScmObj expr, env;
810 DECLARE_FUNCTION("begin", syntax_variadic_tailrec_0);
811
812 if (SCM_DEFINABLE_TOPLEVELP(eval_state)) {
813 if (!CONSP(args)) {
814 /* '(begin)' */
815 ASSERT_NO_MORE_ARG(args);
816 eval_state->ret_type = SCM_VALTYPE_AS_IS;
817 return SCM_UNDEF;
818 }
819 env = eval_state->env;
820 #if SCM_STRICT_TOPLEVEL_DEFINITIONS
821 eval_state->nest = SCM_NEST_RETTYPE_BEGIN;
822 #endif
823 } else {
824 if (!CONSP(args))
825 ERR(ERRMSG_EXPRESSION_REQUIRED);
826 env = FORBID_TOPLEVEL_DEFINITIONS(eval_state->env);
827 }
828
829 FOR_EACH_BUTLAST (expr, args) {
830 expr = EVAL(expr, env);
831 CHECK_VALID_EVALED_VALUE(expr);
832 }
833 ASSERT_NO_MORE_ARG(args);
834
835 return expr;
836 }
837
838 /*===========================================================================
839 R5RS : 4.2 Derived expression types : 4.2.4 Iteration
840 ===========================================================================*/
841 SCM_EXPORT ScmObj
scm_s_do(ScmObj bindings,ScmObj test_exps,ScmObj commands,ScmEvalState * eval_state)842 scm_s_do(ScmObj bindings, ScmObj test_exps, ScmObj commands,
843 ScmEvalState *eval_state)
844 {
845 ScmQueue stepq;
846 ScmObj env, orig_env, rest, rest_commands, val, termp;
847 ScmObj formals, actuals, steps;
848 ScmObj binding, var, init, step;
849 ScmObj test, exps, command;
850 DECLARE_FUNCTION("do", syntax_variadic_tailrec_2);
851
852 orig_env = eval_state->env;
853
854 /*
855 * (do ((<variable1> <init1> <step1>)
856 * (<variable2> <init2> <step2>)
857 * ...)
858 * (<test> <expression> ...)
859 * <command> ...)
860 */
861
862 /* extract bindings ((<variable> <init> <step>) ...) */
863 env = FORBID_TOPLEVEL_DEFINITIONS(orig_env);
864 formals = actuals = steps = SCM_NULL;
865 SCM_QUEUE_POINT_TO(stepq, steps);
866 rest = bindings;
867 FOR_EACH (binding, rest) {
868 if (!CONSP(binding))
869 goto err;
870 var = POP(binding);
871 ENSURE_SYMBOL(var);
872 #if SCM_STRICT_ARGCHECK
873 /* Optional check. Keeping variable name unique is user's
874 * responsibility. R5RS: "It is an error for a <variable> to appear
875 * more than once in the list of `do' variables.". */
876 if (TRUEP(scm_p_memq(var, formals)))
877 ERR_OBJ(ERRMSG_DUPLICATE_VARNAME, var);
878 #endif
879
880 if (!CONSP(binding))
881 goto err;
882 init = POP(binding);
883
884 step = (CONSP(binding)) ? POP(binding) : var;
885 if (!NULLP(binding))
886 goto err;
887
888 init = EVAL(init, env);
889 CHECK_VALID_EVALED_VALUE(init);
890 formals = CONS(var, formals);
891 actuals = CONS(init, actuals);
892 SCM_QUEUE_ADD(stepq, step);
893 }
894 if (!NULLP(rest))
895 goto err;
896
897 /* (<test> <expression> ...) */
898 if (!CONSP(test_exps))
899 ERR_OBJ("invalid test form", test_exps);
900 test = CAR(test_exps);
901 exps = CDR(test_exps);
902
903 /* iteration phase */
904 rest_commands = commands;
905 /* extend env by <init>s */
906 env = scm_extend_environment(formals, actuals, orig_env);
907 while (termp = EVAL(test, env), FALSEP(termp)) {
908 rest_commands = commands;
909 FOR_EACH (command, rest_commands)
910 EVAL(command, env);
911 ASSERT_NO_MORE_ARG(rest_commands);
912
913 /* Update variables by <step>s: <step>s evaluation must be isolated
914 * from the env for the next iteration. */
915 actuals = SCM_NULL;
916 rest = steps;
917 FOR_EACH (step, rest) {
918 val = EVAL(step, env);
919 CHECK_VALID_EVALED_VALUE(val);
920 actuals = CONS(val, actuals);
921 }
922 /* the envs for each iteration must be isolated and not be
923 * overwritten */
924 env = scm_extend_environment(formals, actuals, orig_env);
925 }
926 #if SCM_STRICT_ARGCHECK
927 /* no iteration occurred */
928 if (rest_commands == commands)
929 ENSURE_PROPER_ARG_LIST(commands);
930 #endif
931
932 /* R5RS: If no <expression>s are present, then the value of the `do'
933 * expression is unspecified. */
934 eval_state->env = env;
935 if (NULLP(exps)) {
936 eval_state->ret_type = SCM_VALTYPE_AS_IS;
937 return SCM_UNDEF;
938 } else {
939 #if SCM_STRICT_TOPLEVEL_DEFINITIONS
940 eval_state->nest = SCM_NEST_COMMAND;
941 #endif
942 return scm_s_begin(exps, eval_state);
943 }
944
945 err:
946 ERR_OBJ(ERRMSG_INVALID_BINDINGS, bindings);
947 /* NOTREACHED */
948 return SCM_FALSE;
949 }
950
951 /*=======================================
952 R5RS : 5.2 Definitions
953 =======================================*/
954 SCM_EXPORT void
scm_s_define_internal(enum ScmObjType permitted,ScmObj var,ScmObj exp,ScmObj env)955 scm_s_define_internal(enum ScmObjType permitted,
956 ScmObj var, ScmObj exp, ScmObj env)
957 {
958 ScmObj val;
959 DECLARE_INTERNAL_FUNCTION("define");
960
961 #if SCM_USE_HYGIENIC_MACRO
962 SCM_ASSERT(SYMBOLP(var) || SYMBOLP(SCM_FARSYMBOL_SYM(var)));
963 #else
964 SCM_ASSERT(SYMBOLP(var));
965 #endif
966 var = SCM_UNWRAP_KEYWORD(var);
967 val = EVAL(exp, env);
968 CHECK_VALID_BINDEE(permitted, val);
969
970 SCM_SYMBOL_SET_VCELL(var, val);
971 }
972
973 /* To test ScmNestState, scm_s_define() needs eval_state although this is not a
974 * tail-recursive syntax */
975 SCM_EXPORT ScmObj
scm_s_define(ScmObj var,ScmObj rest,ScmEvalState * eval_state)976 scm_s_define(ScmObj var, ScmObj rest, ScmEvalState *eval_state)
977 {
978 ScmObj procname, body, formals, proc, env;
979 DECLARE_FUNCTION("define", syntax_variadic_tailrec_1);
980
981 /* internal definitions are handled as a virtual letrec in
982 * scm_s_body() */
983 if (!SCM_DEFINABLE_TOPLEVELP(eval_state)) {
984 #if SCM_STRICT_TOPLEVEL_DEFINITIONS
985 if (scm_toplevel_environmentp(eval_state->env))
986 ERR_OBJ("toplevel definition is not allowed here", var);
987 else
988 #endif
989 ERR_OBJ(ERRMSG_BAD_DEFINE_PLACEMENT, var);
990 }
991 env = eval_state->env;
992
993 /*=======================================================================
994 (define <variable> <expression>)
995 =======================================================================*/
996 if (IDENTIFIERP(var)) {
997 if (!LIST_1_P(rest))
998 goto err;
999
1000 scm_s_define_internal(ScmFirstClassObj, var, CAR(rest), env);
1001 }
1002
1003 /*=======================================================================
1004 (define (<variable> . <formals>) <body>)
1005
1006 => (define <variable>
1007 (lambda <formals> <body>))
1008 =======================================================================*/
1009 else if (CONSP(var)) {
1010 procname = CAR(var);
1011 formals = CDR(var);
1012 body = rest;
1013
1014 ENSURE_SYMBOL(procname);
1015 proc = scm_s_lambda(formals, body, env);
1016 scm_s_define_internal(ScmFirstClassObj, procname, proc, env);
1017 } else {
1018 goto err;
1019 }
1020
1021 eval_state->ret_type = SCM_VALTYPE_AS_IS;
1022 #if SCM_STRICT_R5RS
1023 return SCM_UNDEF;
1024 #else
1025 return var;
1026 #endif
1027
1028 err:
1029 ERR_OBJ(ERRMSG_BAD_DEFINE_FORM,
1030 CONS(l_sym_define, CONS(var, rest)));
1031 /* NOTREACHED */
1032 return SCM_FALSE;
1033 }
1034