~ubuntu-branches/ubuntu/hardy/uim/hardy

« back to all changes in this revision

Viewing changes to sigscheme/src/syntax.c

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2007-04-21 03:46:09 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20070421034609-gpcurkutp8vaysqj
Tags: 1:1.4.1-3
* Switch to dh_gtkmodules for the gtk 2.10 transition (Closes:
  #419318)
  - debian/control: Add ${misc:Depends} and remove libgtk2.0-bin on
    uim-gtk2.0.
  - debian/uim-gtk2.0.post{inst,rm}: Removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 SigScheme Project <uim AT freedesktop.org>
 
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
 
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
 
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
 
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
 
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_NULL;
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
}