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

« back to all changes in this revision

Viewing changes to sigscheme/src/procedure.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 : procedure.c
 
3
 *  About    : Miscellaneous R5RS procedures
 
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_UNEVEN_MAP_ARGS "uneven-length lists are passed as arguments"
 
47
 
 
48
/*=======================================
 
49
  File Local Type Definitions
 
50
=======================================*/
 
51
 
 
52
/*=======================================
 
53
  Variable Definitions
 
54
=======================================*/
 
55
/* canonical internal encoding for identifiers */
 
56
SCM_DEFINE_EXPORTED_VARS(procedure);
 
57
 
 
58
/*=======================================
 
59
  File Local Function Declarations
 
60
=======================================*/
 
61
static ScmObj map_single_arg(ScmObj proc, ScmObj lst);
 
62
static ScmObj map_multiple_args(ScmObj proc, ScmObj lsts);
 
63
 
 
64
/*=======================================
 
65
  Function Definitions
 
66
=======================================*/
 
67
/*===========================================================================
 
68
  R5RS : 6.1 Equivalence predicates
 
69
===========================================================================*/
 
70
SCM_EXPORT ScmObj
 
71
scm_p_eqp(ScmObj obj1, ScmObj obj2)
 
72
{
 
73
    DECLARE_FUNCTION("eq?", procedure_fixed_2);
 
74
 
 
75
    return MAKE_BOOL(EQ(obj1, obj2));
 
76
}
 
77
 
 
78
SCM_EXPORT ScmObj
 
79
scm_p_eqvp(ScmObj obj1, ScmObj obj2)
 
80
{
 
81
#if SCM_HAS_EQVP
 
82
 
 
83
#define scm_p_eqvp error_eqvp_recursed__ /* Safety measure. */
 
84
    return EQVP(obj1, obj2);
 
85
#undef scm_p_eqvp
 
86
 
 
87
#else  /* don't have inlined EQVP() */
 
88
 
 
89
#if (!(SCM_HAS_IMMEDIATE_NUMBER_ONLY && SCM_HAS_IMMEDIATE_CHAR_ONLY))
 
90
    enum ScmObjType type;
 
91
#endif
 
92
    DECLARE_FUNCTION("eqv?", procedure_fixed_2);
 
93
 
 
94
    if (EQ(obj1, obj2))
 
95
        return SCM_TRUE;
 
96
 
 
97
#if (!(SCM_HAS_IMMEDIATE_NUMBER_ONLY && SCM_HAS_IMMEDIATE_CHAR_ONLY))
 
98
    type = SCM_TYPE(obj1);
 
99
 
 
100
    /* different type */
 
101
    if (type != SCM_TYPE(obj2))
 
102
        return SCM_FALSE;
 
103
 
 
104
    /* same type */
 
105
    switch (type) {
 
106
#if (SCM_USE_INT && !SCM_HAS_IMMEDIATE_INT_ONLY)
 
107
    case ScmInt:
 
108
        return MAKE_BOOL(SCM_INT_VALUE(obj1) == SCM_INT_VALUE(obj2));
 
109
#endif
 
110
 
 
111
#if (SCM_USE_CHAR && !SCM_HAS_IMMEDIATE_CHAR_ONLY)
 
112
    case ScmChar:
 
113
        return MAKE_BOOL(SCM_CHAR_VALUE(obj1) == SCM_CHAR_VALUE(obj2));
 
114
#endif
 
115
 
 
116
    default:
 
117
        break;
 
118
    }
 
119
#endif /* (!(SCM_HAS_IMMEDIATE_NUMBER_ONLY && SCM_HAS_IMMEDIATE_CHAR_ONLY)) */
 
120
 
 
121
    return SCM_FALSE;
 
122
 
 
123
#endif /* don't have inlined EQVP() */
 
124
}
 
125
 
 
126
SCM_EXPORT ScmObj
 
127
scm_p_equalp(ScmObj obj1, ScmObj obj2)
 
128
{
 
129
    enum ScmObjType type;
 
130
    ScmObj elm1, elm2;
 
131
#if SCM_USE_VECTOR
 
132
    ScmObj *v1, *v2;
 
133
    scm_int_t i, len;
 
134
#endif
 
135
    DECLARE_FUNCTION("equal?", procedure_fixed_2);
 
136
 
 
137
    if (EQ(obj1, obj2))
 
138
        return SCM_TRUE;
 
139
 
 
140
    type = SCM_TYPE(obj1);
 
141
 
 
142
    /* different type */
 
143
    if (type != SCM_TYPE(obj2))
 
144
        return SCM_FALSE;
 
145
 
 
146
    /* same type */
 
147
    switch (type) {
 
148
#if (SCM_USE_INT && !SCM_HAS_IMMEDIATE_INT_ONLY)
 
149
    case ScmInt:
 
150
        return MAKE_BOOL(SCM_INT_VALUE(obj1) == SCM_INT_VALUE(obj2));
 
151
#endif
 
152
 
 
153
#if (SCM_USE_CHAR && !SCM_HAS_IMMEDIATE_CHAR_ONLY)
 
154
    case ScmChar:
 
155
        return MAKE_BOOL(SCM_CHAR_VALUE(obj1) == SCM_CHAR_VALUE(obj2));
 
156
#endif
 
157
 
 
158
#if SCM_USE_STRING
 
159
    case ScmString:
 
160
        return MAKE_BOOL(STRING_EQUALP(obj1, obj2));
 
161
#endif
 
162
 
 
163
    case ScmCons:
 
164
        for (; CONSP(obj1) && CONSP(obj2); obj1 = CDR(obj1), obj2 = CDR(obj2))
 
165
        {
 
166
            elm1 = CAR(obj1);
 
167
            elm2 = CAR(obj2);
 
168
            if (!EQ(elm1, elm2)
 
169
                && (SCM_TYPE(elm1) != SCM_TYPE(elm2)
 
170
                    || !EQUALP(elm1, elm2)))
 
171
                return SCM_FALSE;
 
172
        }
 
173
        /* compare last cdr */
 
174
        return (EQ(obj1, obj2)) ? SCM_TRUE : scm_p_equalp(obj1, obj2);
 
175
 
 
176
#if SCM_USE_VECTOR
 
177
    case ScmVector:
 
178
        len = SCM_VECTOR_LEN(obj1);
 
179
        if (len != SCM_VECTOR_LEN(obj2))
 
180
            return SCM_FALSE;
 
181
 
 
182
        v1 = SCM_VECTOR_VEC(obj1);
 
183
        v2 = SCM_VECTOR_VEC(obj2);
 
184
        for (i = 0; i < len; i++) {
 
185
            elm1 = v1[i];
 
186
            elm2 = v2[i];
 
187
            if (!EQ(elm1, elm2)
 
188
                && (SCM_TYPE(elm1) != SCM_TYPE(elm2)
 
189
                    || !EQUALP(elm1, elm2)))
 
190
                return SCM_FALSE;
 
191
        }
 
192
        return SCM_TRUE;
 
193
#endif
 
194
 
 
195
#if SCM_USE_SSCM_EXTENSIONS
 
196
    case ScmCPointer:
 
197
        return MAKE_BOOL(SCM_C_POINTER_VALUE(obj1)
 
198
                         == SCM_C_POINTER_VALUE(obj2));
 
199
 
 
200
    case ScmCFuncPointer:
 
201
        return MAKE_BOOL(SCM_C_FUNCPOINTER_VALUE(obj1)
 
202
                         == SCM_C_FUNCPOINTER_VALUE(obj2));
 
203
#endif
 
204
 
 
205
    default:
 
206
        break;
 
207
    }
 
208
 
 
209
    return SCM_FALSE;
 
210
}
 
211
 
 
212
/*===================================
 
213
  R5RS : 6.3 Other data types
 
214
===================================*/
 
215
/*===========================================================================
 
216
  R5RS : 6.3 Other data types : 6.3.1 Booleans
 
217
===========================================================================*/
 
218
SCM_EXPORT ScmObj
 
219
scm_p_not(ScmObj obj)
 
220
{
 
221
    DECLARE_FUNCTION("not", procedure_fixed_1);
 
222
 
 
223
    return MAKE_BOOL(FALSEP(obj));
 
224
}
 
225
 
 
226
SCM_EXPORT ScmObj
 
227
scm_p_booleanp(ScmObj obj)
 
228
{
 
229
    DECLARE_FUNCTION("boolean?", procedure_fixed_1);
 
230
 
 
231
    return MAKE_BOOL(EQ(obj, SCM_FALSE) || EQ(obj, SCM_TRUE));
 
232
}
 
233
 
 
234
/*===========================================================================
 
235
  R5RS : 6.3 Other data types : 6.3.3 Symbols
 
236
===========================================================================*/
 
237
SCM_EXPORT ScmObj
 
238
scm_p_symbolp(ScmObj obj)
 
239
{
 
240
    DECLARE_FUNCTION("symbol?", procedure_fixed_1);
 
241
 
 
242
    return MAKE_BOOL(SYMBOLP(obj));
 
243
}
 
244
 
 
245
SCM_EXPORT ScmObj
 
246
scm_p_symbol2string(ScmObj sym)
 
247
{
 
248
    DECLARE_FUNCTION("symbol->string", procedure_fixed_1);
 
249
 
 
250
    ENSURE_SYMBOL(sym);
 
251
 
 
252
    return CONST_STRING(SCM_SYMBOL_NAME(sym));
 
253
}
 
254
 
 
255
SCM_EXPORT ScmObj
 
256
scm_p_string2symbol(ScmObj str)
 
257
{
 
258
    DECLARE_FUNCTION("string->symbol", procedure_fixed_1);
 
259
 
 
260
    ENSURE_STRING(str);
 
261
 
 
262
    return scm_intern(SCM_STRING_STR(str));
 
263
}
 
264
 
 
265
/*=======================================
 
266
  R5RS : 6.4 Control Features
 
267
=======================================*/
 
268
SCM_EXPORT ScmObj
 
269
scm_p_procedurep(ScmObj obj)
 
270
{
 
271
    DECLARE_FUNCTION("procedure?", procedure_fixed_1);
 
272
 
 
273
    return MAKE_BOOL(PROCEDUREP(obj));
 
274
}
 
275
 
 
276
SCM_EXPORT ScmObj
 
277
scm_p_map(ScmObj proc, ScmObj args)
 
278
{
 
279
    DECLARE_FUNCTION("map", procedure_variadic_1);
 
280
 
 
281
    if (NULLP(args))
 
282
        ERR("wrong number of arguments");
 
283
 
 
284
    /* fast path for single arg case */
 
285
    if (NULLP(CDR(args)))
 
286
        return map_single_arg(proc, CAR(args));
 
287
 
 
288
    /* multiple args case */
 
289
    return map_multiple_args(proc, args);
 
290
}
 
291
 
 
292
static ScmObj
 
293
map_single_arg(ScmObj proc, ScmObj lst)
 
294
{
 
295
    ScmQueue q;
 
296
    ScmObj elm, ret;
 
297
    DECLARE_INTERNAL_FUNCTION("map");
 
298
 
 
299
    ret = SCM_NULL;
 
300
    SCM_QUEUE_POINT_TO(q, ret);
 
301
    FOR_EACH (elm, lst) {
 
302
        elm = scm_call(proc, LIST_1(elm));
 
303
        SCM_QUEUE_ADD(q, elm);
 
304
    }
 
305
    NO_MORE_ARG(lst);
 
306
 
 
307
    return ret;
 
308
}
 
309
 
 
310
static ScmObj
 
311
map_multiple_args(ScmObj proc, ScmObj lsts)
 
312
{
 
313
    ScmQueue retq, argq;
 
314
    ScmObj ret, elm, map_args, rest_lsts, lst;
 
315
    DECLARE_INTERNAL_FUNCTION("map");
 
316
 
 
317
    ret = SCM_NULL;
 
318
    SCM_QUEUE_POINT_TO(retq, ret);
 
319
    for (;;) {
 
320
        /* slice args */
 
321
        map_args = SCM_NULL;
 
322
        SCM_QUEUE_POINT_TO(argq, map_args);
 
323
        for (rest_lsts = lsts; CONSP(rest_lsts); rest_lsts = CDR(rest_lsts)) {
 
324
            lst = CAR(rest_lsts);
 
325
            if (CONSP(lst))
 
326
                SCM_QUEUE_ADD(argq, CAR(lst));
 
327
            else if (NULLP(lst))
 
328
                goto finish;
 
329
            else
 
330
                ERR_OBJ("invalid argument", lst);
 
331
            /* pop destructively */
 
332
            SET_CAR(rest_lsts, CDR(lst));
 
333
        }
 
334
 
 
335
        elm = scm_call(proc, map_args);
 
336
        SCM_QUEUE_ADD(retq, elm);
 
337
    }
 
338
 
 
339
 finish:
 
340
#if SCM_STRICT_ARGCHECK
 
341
    /* R5RS: 6.4 Control features
 
342
     * > If more than one list is given, then they must all be the same length.
 
343
     * SigScheme rejects such user-error explicitly. */
 
344
    if (!EQ(lsts, rest_lsts))
 
345
        ERR(ERRMSG_UNEVEN_MAP_ARGS);
 
346
    FOR_EACH (lst, lsts) {
 
347
        if (!NULLP(lst))
 
348
            ERR(ERRMSG_UNEVEN_MAP_ARGS);
 
349
    }
 
350
    NO_MORE_ARG(lsts);
 
351
#endif
 
352
 
 
353
    return ret;
 
354
}
 
355
 
 
356
SCM_EXPORT ScmObj
 
357
scm_p_for_each(ScmObj proc, ScmObj args)
 
358
{
 
359
    DECLARE_FUNCTION("for-each", procedure_variadic_1);
 
360
 
 
361
    scm_p_map(proc, args);
 
362
 
 
363
    return SCM_UNDEF;
 
364
}
 
365
 
 
366
#if SCM_USE_CONTINUATION
 
367
SCM_EXPORT ScmObj
 
368
scm_p_call_with_current_continuation(ScmObj proc, ScmEvalState *eval_state)
 
369
{
 
370
    DECLARE_FUNCTION("call-with-current-continuation",
 
371
                     procedure_fixed_tailrec_1);
 
372
 
 
373
    return scm_call_with_current_continuation(proc, eval_state);
 
374
}
 
375
#endif /* SCM_USE_CONTINUATION */
 
376
 
 
377
SCM_EXPORT ScmObj
 
378
scm_p_values(ScmObj args)
 
379
{
 
380
    DECLARE_FUNCTION("values", procedure_variadic_0);
 
381
 
 
382
    /* Values with one arg must return something that fits an ordinary
 
383
     * continuation. */
 
384
    if (LIST_1_P(args))
 
385
        return CAR(args);
 
386
 
 
387
    /* Otherwise, we'll return the values in a packet. */
 
388
    return SCM_MAKE_VALUEPACKET(args);
 
389
}
 
390
 
 
391
SCM_EXPORT ScmObj
 
392
scm_p_call_with_values(ScmObj producer, ScmObj consumer,
 
393
                       ScmEvalState *eval_state)
 
394
{
 
395
    ScmObj vals;
 
396
    DECLARE_FUNCTION("call-with-values", procedure_fixed_tailrec_2);
 
397
 
 
398
    vals = scm_call(producer, SCM_NULL);
 
399
 
 
400
    return LIST_3(scm_values_applier, consumer, vals);
 
401
}
 
402
 
 
403
#if SCM_USE_CONTINUATION
 
404
SCM_EXPORT ScmObj
 
405
scm_p_dynamic_wind(ScmObj before, ScmObj thunk, ScmObj after)
 
406
{
 
407
    DECLARE_FUNCTION("dynamic-wind", procedure_fixed_3);
 
408
 
 
409
    /* To reject non-procedure arguments before evaluating any other
 
410
     * arguments, ensure the types here instead of call(). */
 
411
    ENSURE_PROCEDURE(before);
 
412
    ENSURE_PROCEDURE(thunk);
 
413
    ENSURE_PROCEDURE(after);
 
414
 
 
415
    return scm_dynamic_wind(before, thunk, after);
 
416
}
 
417
#endif /* SCM_USE_CONTINUATION */