1
/*===========================================================================
2
* FileName : operations.c
3
* About : basic scheme procedure
5
* Copyright (C) 2005 by Kazuki Ohta (mover@hct.zaq.ne.jp)
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* 3. Neither the name of authors nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
22
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
23
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
26
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
28
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
===========================================================================*/
34
/*=======================================
36
=======================================*/
41
/*=======================================
43
=======================================*/
44
#include "sigscheme.h"
45
#include "sigschemeinternal.h"
47
/*=======================================
48
File Local Struct Declarations
49
=======================================*/
51
/*=======================================
52
File Local Macro Declarations
53
=======================================*/
55
/*=======================================
57
=======================================*/
59
/*=======================================
60
File Local Function Declarations
61
=======================================*/
62
static ScmObj ScmOp_listtail_internal(ScmObj obj, int k);
64
static ScmObj map_single_arg(ScmObj proc, ScmObj args);
65
static ScmObj map_multiple_args(ScmObj proc, ScmObj args);
67
/*=======================================
68
Function Implementations
69
=======================================*/
70
/*==============================================================================
71
R5RS : 6.1 Equivalence predicates
72
==============================================================================*/
73
ScmObj ScmOp_eqvp(ScmObj obj1, ScmObj obj2)
76
DECLARE_FUNCTION("eqv?", ProcedureFixed2);
81
type = SCM_TYPE(obj1);
84
if (type != SCM_TYPE(obj2))
90
if ((SCM_INT_VALUE(obj1) == SCM_INT_VALUE(obj2)))
95
return ScmOp_char_equal(obj1, obj2);
99
SigScm_Error("eqv? : cannnot compare freecell, gc broken?");
110
ScmObj ScmOp_eqp(ScmObj obj1, ScmObj obj2)
112
DECLARE_FUNCTION("eq?", ProcedureFixed2);
113
return (EQ(obj1, obj2)) ? SCM_TRUE : SCM_FALSE;
116
ScmObj ScmOp_equalp(ScmObj obj1, ScmObj obj2)
118
enum ScmObjType type;
120
ScmObj elm1 = SCM_FALSE;
121
ScmObj elm2 = SCM_FALSE;
122
DECLARE_FUNCTION("equal?", ProcedureFixed2);
127
type = SCM_TYPE(obj1);
130
if (type != SCM_TYPE(obj2))
136
if ((SCM_INT_VALUE(obj1) == SCM_INT_VALUE(obj2)))
141
return ScmOp_char_equal(obj1, obj2);
144
if (strcmp(SCM_STRING_STR(obj1), SCM_STRING_STR(obj2)) == 0)
149
for (; CONSP(obj1) && CONSP(obj2); obj1 = CDR(obj1), obj2 = CDR(obj2))
154
&& (SCM_TYPE(elm1) != SCM_TYPE(elm2)
155
|| FALSEP(ScmOp_equalp(elm1, elm2))))
158
/* compare last cdr */
159
return (EQ(obj1, obj2)) ? SCM_TRUE : ScmOp_equalp(obj1, obj2);
162
if (SCM_VECTOR_LEN(obj1) != SCM_VECTOR_LEN(obj2))
165
for (i = 0; i < SCM_VECTOR_LEN(obj1); i++) {
166
elm1 = SCM_VECTOR_CREF(obj1, i);
167
elm2 = SCM_VECTOR_CREF(obj2, i);
169
&& (SCM_TYPE(elm1) != SCM_TYPE(elm2)
170
|| FALSEP(ScmOp_equalp(elm1, elm2))))
175
#if SCM_USE_NONSTD_FEATURES
177
if (SCM_C_POINTER_VALUE(obj1) == SCM_C_POINTER_VALUE(obj2))
181
case ScmCFuncPointer:
182
if (SCM_C_FUNCPOINTER_VALUE(obj1) == SCM_C_FUNCPOINTER_VALUE(obj2))
189
ERR("cannnot compare freecell, gc broken?");
200
/*=======================================
202
=======================================*/
203
/*==============================================================================
204
R5RS : 6.2 Numbers : 6.2.5 Numerical Operations
205
==============================================================================*/
206
/* Note: SigScheme supports only the integer part of the numerical tower. */
208
ScmObj ScmOp_add(ScmObj left, ScmObj right, enum ScmReductionState *state)
211
DECLARE_FUNCTION("+", ReductionOperator);
213
case SCM_REDUCE_PARTWAY:
214
case SCM_REDUCE_LAST:
216
result = SCM_INT_VALUE(left);
220
result += SCM_INT_VALUE(right);
225
ERR("(internal error) unrecognized state specifier: %d", *state);
228
return Scm_NewInt(result);
231
ScmObj ScmOp_multiply(ScmObj left, ScmObj right, enum ScmReductionState *state)
234
DECLARE_FUNCTION("*", ReductionOperator);
236
case SCM_REDUCE_PARTWAY:
237
case SCM_REDUCE_LAST:
239
result = SCM_INT_VALUE(left);
243
result *= SCM_INT_VALUE(right);
248
ERR("(internal error) unrecognized state specifier: %d", *state);
251
return Scm_NewInt(result);
254
ScmObj ScmOp_subtract(ScmObj left, ScmObj right, enum ScmReductionState *state)
257
DECLARE_FUNCTION("-", ReductionOperator);
259
case SCM_REDUCE_PARTWAY:
260
case SCM_REDUCE_LAST:
262
result = SCM_INT_VALUE(left);
266
result -= SCM_INT_VALUE(right);
270
ERR("at least 1 argument required");
272
ERR("(internal error) unrecognized state specifier: %d", *state);
274
return Scm_NewInt(result);
277
ScmObj ScmOp_divide(ScmObj left, ScmObj right, enum ScmReductionState *state)
280
DECLARE_FUNCTION("/", ReductionOperator);
282
case SCM_REDUCE_PARTWAY:
283
case SCM_REDUCE_LAST:
285
result = SCM_INT_VALUE(left);
289
if (SCM_INT_VALUE(right) == 0)
290
ERR("division by zero");
291
result /= SCM_INT_VALUE(right);
294
ERR("at least 1 argument required");
296
ERR("(internal error) unrecognized state specifier: %d", *state);
298
return Scm_NewInt(result);
301
ScmObj ScmOp_numberp(ScmObj obj)
303
DECLARE_FUNCTION("number?", ProcedureFixed1);
304
return (INTP(obj)) ? SCM_TRUE : SCM_FALSE;
307
ScmObj ScmOp_equal(ScmObj left, ScmObj right, enum ScmReductionState *state)
309
DECLARE_FUNCTION("=", ReductionOperator);
310
#define COMPARATOR_BODY(op) \
314
ERR("at least 2 arguments required"); \
315
case SCM_REDUCE_PARTWAY: \
316
case SCM_REDUCE_LAST: \
318
ASSERT_INTP(right); \
319
if (SCM_INT_VALUE(left) op SCM_INT_VALUE(right)) \
320
return *state == SCM_REDUCE_LAST ? SCM_TRUE : right; \
321
*state = SCM_REDUCE_STOP; \
324
ERR("(internal error) unrecognized state specifier: %d", *state); \
331
ScmObj ScmOp_less(ScmObj left, ScmObj right, enum ScmReductionState *state)
333
DECLARE_FUNCTION("<", ReductionOperator);
337
ScmObj ScmOp_less_eq(ScmObj left, ScmObj right, enum ScmReductionState *state)
339
DECLARE_FUNCTION("<=", ReductionOperator);
343
ScmObj ScmOp_greater(ScmObj left, ScmObj right, enum ScmReductionState *state)
345
DECLARE_FUNCTION(">", ReductionOperator);
349
ScmObj ScmOp_greater_eq(ScmObj left, ScmObj right, enum ScmReductionState *state)
351
DECLARE_FUNCTION(">=", ReductionOperator);
353
#undef COMPARATOR_BODY
356
ScmObj ScmOp_zerop(ScmObj scm_num)
358
DECLARE_FUNCTION("zero?", ProcedureFixed1);
359
ASSERT_INTP(scm_num);
360
return (SCM_INT_VALUE(scm_num) == 0) ? SCM_TRUE : SCM_FALSE;
363
ScmObj ScmOp_positivep(ScmObj scm_num)
365
DECLARE_FUNCTION("positive?", ProcedureFixed1);
366
ASSERT_INTP(scm_num);
367
return (SCM_INT_VALUE(scm_num) > 0) ? SCM_TRUE : SCM_FALSE;
370
ScmObj ScmOp_negativep(ScmObj scm_num)
372
DECLARE_FUNCTION("negative?", ProcedureFixed1);
373
ASSERT_INTP(scm_num);
374
return (SCM_INT_VALUE(scm_num) < 0) ? SCM_TRUE : SCM_FALSE;
377
ScmObj ScmOp_oddp(ScmObj scm_num)
379
DECLARE_FUNCTION("odd?", ProcedureFixed1);
380
ASSERT_INTP(scm_num);
381
return (SCM_INT_VALUE(scm_num) & 0x1) ? SCM_TRUE : SCM_FALSE;
384
ScmObj ScmOp_evenp(ScmObj scm_num)
386
DECLARE_FUNCTION("even?", ProcedureFixed1);
387
ASSERT_INTP(scm_num);
388
return (SCM_INT_VALUE(scm_num) & 0x1) ? SCM_FALSE : SCM_TRUE;
391
ScmObj ScmOp_max(ScmObj left, ScmObj right, enum ScmReductionState *state)
393
DECLARE_FUNCTION("max", ReductionOperator);
394
if (*state == SCM_REDUCE_0)
395
ERR("at least 1 argument required");
399
return SCM_INT_VALUE(left) > SCM_INT_VALUE(right) ? left : right;
402
ScmObj ScmOp_min(ScmObj left, ScmObj right, enum ScmReductionState *state)
404
DECLARE_FUNCTION("min", ReductionOperator);
405
if (*state == SCM_REDUCE_0)
406
ERR("at least 1 argument required");
410
return SCM_INT_VALUE(left) < SCM_INT_VALUE(right) ? left : right;
414
ScmObj ScmOp_abs(ScmObj scm_num)
417
DECLARE_FUNCTION("abs", ProcedureFixed1);
419
ASSERT_INTP(scm_num);
421
num = SCM_INT_VALUE(scm_num);
423
return (num < 0) ? Scm_NewInt(-num) : scm_num;
426
ScmObj ScmOp_quotient(ScmObj scm_n1, ScmObj scm_n2)
430
DECLARE_FUNCTION("quotient", ProcedureFixed2);
435
n1 = SCM_INT_VALUE(scm_n1);
436
n2 = SCM_INT_VALUE(scm_n2);
439
ERR("division by zero");
441
return Scm_NewInt((int)(n1 / n2));
444
ScmObj ScmOp_modulo(ScmObj scm_n1, ScmObj scm_n2)
449
DECLARE_FUNCTION("modulo", ProcedureFixed2);
454
n1 = SCM_INT_VALUE(scm_n1);
455
n2 = SCM_INT_VALUE(scm_n2);
458
ERR("division by zero");
461
if (n1 < 0 && n2 > 0) {
463
} else if (n1 > 0 && n2 < 0) {
467
return Scm_NewInt(rem);
470
ScmObj ScmOp_remainder(ScmObj scm_n1, ScmObj scm_n2)
474
DECLARE_FUNCTION("remainder", ProcedureFixed2);
479
n1 = SCM_INT_VALUE(scm_n1);
480
n2 = SCM_INT_VALUE(scm_n2);
483
ERR("division by zero");
485
return Scm_NewInt(n1 % n2);
488
/*==============================================================================
489
R5RS : 6.2 Numbers : 6.2.6 Numerical input and output
490
==============================================================================*/
491
ScmObj ScmOp_number2string(ScmObj num, ScmObj args)
493
char buf[sizeof(int)*CHAR_BIT + 1];
497
DECLARE_FUNCTION("number->string", ProcedureVariadic1);
500
n = SCM_INT_VALUE(num);
503
if (NO_MORE_ARG(args))
506
radix = POP_ARG(args);
507
ASSERT_NO_MORE_ARG(args);
510
r = SCM_INT_VALUE(radix);
512
if (!(r == 2 || r == 8 || r == 10 || r == 16))
514
if (!(2 <= r && r <= 16))
516
ERR_OBJ("invalid or unsupported radix", radix);
519
/* no signs for nondecimals */
523
/* initialize buffer */
524
p = &buf[sizeof(buf)-1];
529
*--p = 'A' + n % r - 10;
533
if (r == 10 && SCM_INT_VALUE (num) < 0)
536
return Scm_NewStringCopying(p);
539
/* TODO : support radix */
540
ScmObj ScmOp_string2number(ScmObj string)
545
DECLARE_FUNCTION("string->number", ProcedureFixed1);
547
ASSERT_STRINGP(string);
549
str = SCM_STRING_STR(string);
551
for (p = str; p < str + len; p++) {
552
if (isdigit(*p) == 0)
556
return Scm_NewInt((int)atoi(SCM_STRING_STR(string)));
559
/*===================================
560
R5RS : 6.3 Other data types
561
===================================*/
562
/*==============================================================================
563
R5RS : 6.3 Other data types : 6.3.1 Booleans
564
==============================================================================*/
565
ScmObj ScmOp_not(ScmObj obj)
567
DECLARE_FUNCTION("not", ProcedureFixed1);
568
return (FALSEP(obj)) ? SCM_TRUE : SCM_FALSE;
571
ScmObj ScmOp_booleanp(ScmObj obj)
573
DECLARE_FUNCTION("boolean?", ProcedureFixed1);
574
return (EQ(obj, SCM_FALSE) || EQ(obj, SCM_TRUE)) ? SCM_TRUE : SCM_FALSE;
577
/*==============================================================================
578
R5RS : 6.3 Other data types : 6.3.2 Pairs and lists
579
==============================================================================*/
580
ScmObj ScmOp_car(ScmObj obj)
582
DECLARE_FUNCTION("car", PocedureFixed1);
583
#if SCM_COMPAT_SIOD_BUGS
593
ScmObj ScmOp_cdr(ScmObj obj)
595
DECLARE_FUNCTION("cdr", ProcedureFixed1);
596
#if SCM_COMPAT_SIOD_BUGS
606
ScmObj ScmOp_pairp(ScmObj obj)
608
DECLARE_FUNCTION("pair?", ProcedureFixed1);
609
return (CONSP(obj)) ? SCM_TRUE : SCM_FALSE;
612
ScmObj ScmOp_cons(ScmObj car, ScmObj cdr)
614
DECLARE_FUNCTION("cons", ProcedureFixed1);
615
return CONS(car, cdr);
618
ScmObj ScmOp_setcar(ScmObj pair, ScmObj car)
620
DECLARE_FUNCTION("set-car!", SyntaxFixed2);
632
ScmObj ScmOp_setcdr(ScmObj pair, ScmObj cdr)
634
DECLARE_FUNCTION("set-cdr!", SyntaxFixed2);
646
ScmObj ScmOp_caar(ScmObj lst)
648
DECLARE_FUNCTION("caar", ProcedureFixed1);
649
return ScmOp_car( ScmOp_car(lst) );
651
ScmObj ScmOp_cadr(ScmObj lst)
653
DECLARE_FUNCTION("cadr", ProcedureFixed1);
654
return ScmOp_car( ScmOp_cdr(lst) );
656
ScmObj ScmOp_cdar(ScmObj lst)
658
DECLARE_FUNCTION("cdar", ProcedureFixed1);
659
return ScmOp_cdr( ScmOp_car(lst) );
661
ScmObj ScmOp_cddr(ScmObj lst)
663
DECLARE_FUNCTION("cddr", ProcedureFixed1);
664
return ScmOp_cdr( ScmOp_cdr(lst) );
666
ScmObj ScmOp_caddr(ScmObj lst)
668
DECLARE_FUNCTION("caddr", ProcedureFixed1);
669
return ScmOp_car( ScmOp_cdr( ScmOp_cdr(lst) ));
671
ScmObj ScmOp_cdddr(ScmObj lst)
673
DECLARE_FUNCTION("cdddr", ProcedureFixed1);
674
return ScmOp_cdr( ScmOp_cdr( ScmOp_cdr(lst) ));
677
#if SCM_USE_DEEP_CADRS
678
ScmObj ScmOp_caaar(ScmObj lst)
680
DECLARE_FUNCTION("caaar", ProcedureFixed1);
681
return ScmOp_car( ScmOp_car( ScmOp_car(lst) ));
683
ScmObj ScmOp_caadr(ScmObj lst)
685
DECLARE_FUNCTION("caadr", ProcedureFixed1);
686
return ScmOp_car( ScmOp_car( ScmOp_cdr(lst) ));
688
ScmObj ScmOp_cadar(ScmObj lst)
690
DECLARE_FUNCTION("cadar", ProcedureFixed1);
691
return ScmOp_car( ScmOp_cdr( ScmOp_car(lst) ));
693
ScmObj ScmOp_cdaar(ScmObj lst)
695
DECLARE_FUNCTION("cdaar", ProcedureFixed1);
696
return ScmOp_cdr( ScmOp_car( ScmOp_car(lst) ));
698
ScmObj ScmOp_cdadr(ScmObj lst)
700
DECLARE_FUNCTION("cdadr", ProcedureFixed1);
701
return ScmOp_cdr( ScmOp_car( ScmOp_cdr(lst) ));
703
ScmObj ScmOp_cddar(ScmObj lst)
705
DECLARE_FUNCTION("cddar", ProcedureFixed1);
706
return ScmOp_cdr( ScmOp_cdr( ScmOp_car(lst) ));
708
ScmObj ScmOp_caaaar(ScmObj lst)
710
DECLARE_FUNCTION("caaaar", ProcedureFixed1);
711
return ScmOp_car( ScmOp_car( ScmOp_car( ScmOp_car(lst) )));
713
ScmObj ScmOp_caaadr(ScmObj lst)
715
DECLARE_FUNCTION("caaadr", ProcedureFixed1);
716
return ScmOp_car( ScmOp_car( ScmOp_car( ScmOp_cdr(lst) )));
718
ScmObj ScmOp_caadar(ScmObj lst)
720
DECLARE_FUNCTION("caadar", ProcedureFixed1);
721
return ScmOp_car( ScmOp_car( ScmOp_cdr( ScmOp_car(lst) )));
723
ScmObj ScmOp_caaddr(ScmObj lst)
725
DECLARE_FUNCTION("caaddr", ProcedureFixed1);
726
return ScmOp_car( ScmOp_car( ScmOp_cdr( ScmOp_cdr(lst) )));
728
ScmObj ScmOp_cadaar(ScmObj lst)
730
DECLARE_FUNCTION("cadaar", ProcedureFixed1);
731
return ScmOp_car( ScmOp_cdr( ScmOp_car( ScmOp_car(lst) )));
733
ScmObj ScmOp_cadadr(ScmObj lst)
735
DECLARE_FUNCTION("cadadr", ProcedureFixed1);
736
return ScmOp_car( ScmOp_cdr( ScmOp_car( ScmOp_cdr(lst) )));
738
ScmObj ScmOp_caddar(ScmObj lst)
740
DECLARE_FUNCTION("caddar", ProcedureFixed1);
741
return ScmOp_car( ScmOp_cdr( ScmOp_cdr( ScmOp_car(lst) )));
743
ScmObj ScmOp_cadddr(ScmObj lst)
745
DECLARE_FUNCTION("cadddr", ProcedureFixed1);
746
return ScmOp_car( ScmOp_cdr( ScmOp_cdr( ScmOp_cdr(lst) )));
748
ScmObj ScmOp_cdaaar(ScmObj lst)
750
DECLARE_FUNCTION("cdaaar", ProcedureFixed1);
751
return ScmOp_cdr( ScmOp_car( ScmOp_car( ScmOp_car(lst) )));
753
ScmObj ScmOp_cdaadr(ScmObj lst)
755
DECLARE_FUNCTION("cdaadr", ProcedureFixed1);
756
return ScmOp_cdr( ScmOp_car( ScmOp_car( ScmOp_cdr(lst) )));
758
ScmObj ScmOp_cdadar(ScmObj lst)
760
DECLARE_FUNCTION("cdadar", ProcedureFixed1);
761
return ScmOp_cdr( ScmOp_car( ScmOp_cdr( ScmOp_car(lst) )));
763
ScmObj ScmOp_cdaddr(ScmObj lst)
765
DECLARE_FUNCTION("cdaddr", ProcedureFixed1);
766
return ScmOp_cdr( ScmOp_car( ScmOp_cdr( ScmOp_cdr(lst) )));
768
ScmObj ScmOp_cddaar(ScmObj lst)
770
DECLARE_FUNCTION("cddaar", ProcedureFixed1);
771
return ScmOp_cdr( ScmOp_cdr( ScmOp_car( ScmOp_car(lst) )));
773
ScmObj ScmOp_cddadr(ScmObj lst)
775
DECLARE_FUNCTION("cddadr", ProcedureFixed1);
776
return ScmOp_cdr( ScmOp_cdr( ScmOp_car( ScmOp_cdr(lst) )));
778
ScmObj ScmOp_cdddar(ScmObj lst)
780
DECLARE_FUNCTION("cdddar", ProcedureFixed1);
781
return ScmOp_cdr( ScmOp_cdr( ScmOp_cdr( ScmOp_car(lst) )));
783
ScmObj ScmOp_cddddr(ScmObj lst)
785
DECLARE_FUNCTION("cddddr", ProcedureFixed1);
786
return ScmOp_cdr( ScmOp_cdr( ScmOp_cdr( ScmOp_cdr(lst) )));
788
#endif /* SCM_USE_DEEP_CADRS */
790
ScmObj ScmOp_list(ScmObj args)
792
DECLARE_FUNCTION("list", ProcedureVariadic0);
796
ScmObj ScmOp_nullp(ScmObj obj)
798
DECLARE_FUNCTION("null?", ProcedureFixed1);
799
return (NULLP(obj)) ? SCM_TRUE : SCM_FALSE;
802
ScmObj ScmOp_listp(ScmObj obj)
805
DECLARE_FUNCTION("list?", ProcedureFixed1);
812
len = ScmOp_c_length(obj);
814
return (len != -1) ? SCM_TRUE : SCM_FALSE;
820
* This function is ported from Gauche, by Shiro Kawai(shiro@acm.org)
823
* - Rename to Scm_c_length() since it isn't a Scheme procedure
824
* - Insert its copyright and license into this file properly
826
int ScmOp_c_length(ScmObj lst)
832
if (NULLP(lst)) break;
833
if (!CONSP(lst)) return -1;
834
if (len != 0 && lst == slow) return -1; /* circular */
838
if (NULLP(lst)) break;
839
if (!CONSP(lst)) return -1;
840
if (lst == slow) return -1; /* circular */
850
ScmObj ScmOp_length(ScmObj obj)
852
int len = ScmOp_c_length(obj);
853
DECLARE_FUNCTION("length", ProcedureFixed1);
856
ERR_OBJ("list required but got", obj);
858
return Scm_NewInt(len);
862
* FIXME: Invalid direct cdr part referencing as lvalue. Don't assume such
863
* specific storage model. It breaks the abstract storage API. For example,
864
* base pointer + offset representation will not work under the lvalue
865
* assumption. Use SET_CDR properly. -- YamaKen 2005-09-23
867
ScmObj ScmOp_append(ScmObj args)
869
ScmObj ret_lst = SCM_NULL;
870
ScmObj *ret_tail = &ret_lst;
872
ScmObj obj = SCM_NULL;
873
DECLARE_FUNCTION("append", ProcedureVariadic0);
878
/* duplicate and merge all but the last argument */
879
for (; !NULLP(CDR(args)); args = CDR(args)) {
880
for (ls = CAR(args); CONSP(ls); ls = CDR(ls)) {
882
*ret_tail = CONS(obj, SCM_NULL);
883
ret_tail = &CDR(*ret_tail);
886
ERR_OBJ("proper list required but got: ", CAR(args));
889
/* append the last argument */
890
*ret_tail = CAR(args);
895
ScmObj ScmOp_reverse(ScmObj lst)
897
ScmObj ret_lst = SCM_NULL;
898
DECLARE_FUNCTION("reverse", ProcedureFixed1);
900
for (; CONSP(lst); lst = CDR(lst))
901
ret_lst = CONS(CAR(lst), ret_lst);
904
ERR_OBJ("got improper list: ", lst);
909
static ScmObj ScmOp_listtail_internal(ScmObj lst, int k)
920
ScmObj ScmOp_list_tail(ScmObj lst, ScmObj scm_k)
923
DECLARE_FUNCTION("list-tail", ProcedureFixed2);
927
ret = ScmOp_listtail_internal(lst, SCM_INT_VALUE(scm_k));
928
if (EQ(ret, SCM_INVALID))
929
ERR_OBJ("out of range or bad list, arglist is: ", CONS(lst, scm_k));
934
ScmObj ScmOp_list_ref(ScmObj lst, ScmObj scm_k)
936
ScmObj tail = SCM_NULL;
937
DECLARE_FUNCTION("list-ref", ProcedureFixed2);
941
tail = ScmOp_listtail_internal(lst, SCM_INT_VALUE(scm_k));
942
if (EQ(tail, SCM_INVALID) || NULLP(tail))
943
ERR_OBJ("out of range or bad list, arglist is: ", CONS(lst, scm_k));
948
#define MEM_OPERATION_BODY(obj, lst, cmpop) \
950
for (; CONSP(lst); lst = CDR(lst)) \
951
if (cmpop(obj, CAR(lst))) \
954
} while (/* CONSTCOND */ 0)
956
ScmObj ScmOp_memq(ScmObj obj, ScmObj lst)
958
DECLARE_FUNCTION("memq", ProcedureFixed2);
960
for (; CONSP(lst); lst = CDR(lst))
961
if (EQ(obj, CAR(lst)))
967
ScmObj ScmOp_memv(ScmObj obj, ScmObj lst)
969
DECLARE_FUNCTION("memv", ProcedureFixed2);
971
for (; CONSP(lst); lst = CDR(lst))
972
if (NFALSEP(ScmOp_eqvp(obj, CAR(lst))))
978
ScmObj ScmOp_member(ScmObj obj, ScmObj lst)
980
DECLARE_FUNCTION("member", ProcedureFixed2);
982
for (; CONSP(lst); lst = CDR(lst))
983
if (NFALSEP(ScmOp_equalp(obj, CAR(lst))))
989
ScmObj ScmOp_assq(ScmObj obj, ScmObj alist)
991
ScmObj tmp_lst = SCM_NULL;
992
ScmObj tmpobj = SCM_NULL;
994
DECLARE_FUNCTION("assq", ProcedureFixed2);
996
for (tmp_lst = alist; CONSP(tmp_lst); tmp_lst = CDR(tmp_lst)) {
997
tmpobj = CAR(tmp_lst);
1000
ASSERT_CONSP(tmpobj);
1001
if (EQ(CAR(tmpobj), obj))
1004
if (CONSP(tmpobj) && EQ(CAR(tmpobj), obj))
1012
ScmObj ScmOp_assv(ScmObj obj, ScmObj alist)
1014
ScmObj tmp_lst = SCM_NULL;
1015
ScmObj tmpobj = SCM_NULL;
1017
DECLARE_FUNCTION("assv", ProcedureFixed2);
1019
for (tmp_lst = alist; CONSP(tmp_lst); tmp_lst = CDR(tmp_lst)) {
1020
tmpobj = CAR(tmp_lst);
1023
ASSERT_CONSP(tmpobj);
1024
if (NFALSEP(ScmOp_eqvp(car, obj)))
1027
if (CONSP(tmpobj) && NFALSEP(ScmOp_eqvp(car, obj)))
1035
ScmObj ScmOp_assoc(ScmObj obj, ScmObj alist)
1037
ScmObj tmp_lst = SCM_NULL;
1038
ScmObj tmpobj = SCM_NULL;
1040
DECLARE_FUNCTION("assoc", ProcedureFixed2);
1042
for (tmp_lst = alist; CONSP(tmp_lst); tmp_lst = CDR(tmp_lst)) {
1043
tmpobj = CAR(tmp_lst);
1046
ASSERT_CONSP(tmpobj);
1047
if (NFALSEP(ScmOp_equalp(car, obj)))
1050
if (CONSP(tmpobj) && NFALSEP(ScmOp_equalp(car, obj)))
1059
/*==============================================================================
1060
R5RS : 6.3 Other data types : 6.3.3 Symbols
1061
==============================================================================*/
1062
ScmObj ScmOp_symbolp(ScmObj obj)
1064
DECLARE_FUNCTION("symbol?", ProcedureFixed1);
1065
return (SYMBOLP(obj)) ? SCM_TRUE : SCM_FALSE;
1068
ScmObj ScmOp_symbol2string(ScmObj obj)
1070
DECLARE_FUNCTION("symbol->string", ProcedureFixed1);
1071
ASSERT_SYMBOLP(obj);
1072
return Scm_NewStringCopying(SCM_SYMBOL_NAME(obj));
1075
ScmObj ScmOp_string2symbol(ScmObj str)
1077
DECLARE_FUNCTION("string->symbol", ProcedureFixed1);
1078
ASSERT_STRINGP(str);
1079
return Scm_Intern(SCM_STRING_STR(str));
1082
/*==============================================================================
1083
R5RS : 6.3 Other data types : 6.3.4 Characters
1084
==============================================================================*/
1085
ScmObj ScmOp_charp(ScmObj obj)
1087
DECLARE_FUNCTION("char?", ProcedureFixed1);
1088
return (CHARP(obj)) ? SCM_TRUE : SCM_FALSE;
1091
ScmObj ScmOp_char_equal(ScmObj ch1, ScmObj ch2)
1093
DECLARE_FUNCTION("char=?", ProcedureFixed2);
1097
if (strcmp(SCM_CHAR_VALUE(ch1), SCM_CHAR_VALUE(ch2)) == 0)
1103
ScmObj ScmOp_char_alphabeticp(ScmObj obj)
1105
DECLARE_FUNCTION("char-alphabetic?", ProcedureFixed1);
1108
/* check multibyte */
1109
if (strlen(SCM_CHAR_VALUE(obj)) != 1)
1112
/* check alphabet */
1113
if (isalpha(SCM_CHAR_VALUE(obj)[0]) != 0)
1119
ScmObj ScmOp_char_numericp(ScmObj obj)
1121
DECLARE_FUNCTION("char-numeric?", ProcedureFixed1);
1124
/* check multibyte */
1125
if (strlen(SCM_CHAR_VALUE(obj)) != 1)
1129
if (isdigit(SCM_CHAR_VALUE(obj)[0]) != 0)
1135
ScmObj ScmOp_char_whitespacep(ScmObj obj)
1137
DECLARE_FUNCTION("char-whitespace?", ProcedureFixed1);
1140
/* check multibyte */
1141
if (strlen(SCM_CHAR_VALUE(obj)) != 1)
1145
if (isspace(SCM_CHAR_VALUE(obj)[0]) != 0)
1151
ScmObj ScmOp_char_upper_casep(ScmObj obj)
1153
DECLARE_FUNCTION("char-upper-case?", ProcedureFixed1);
1156
/* check multibyte */
1157
if (strlen(SCM_CHAR_VALUE(obj)) != 1)
1160
/* check uppercase */
1161
if (isupper(SCM_CHAR_VALUE(obj)[0]) != 0)
1167
ScmObj ScmOp_char_lower_casep(ScmObj obj)
1169
DECLARE_FUNCTION("char-lower-case?", ProcedureFixed1);
1172
/* check multibyte */
1173
if (strlen(SCM_CHAR_VALUE(obj)) != 1)
1176
/* check lowercase */
1177
if (islower(SCM_CHAR_VALUE(obj)[0]) != 0)
1183
ScmObj ScmOp_char_upcase(ScmObj obj)
1185
DECLARE_FUNCTION("char-upcase", ProcedureFixed1);
1188
/* check multibyte */
1189
if (strlen(SCM_CHAR_VALUE(obj)) != 1)
1193
SCM_CHAR_VALUE(obj)[0] = toupper(SCM_CHAR_VALUE(obj)[0]);
1198
ScmObj ScmOp_char_downcase(ScmObj obj)
1200
DECLARE_FUNCTION("char-downcase", ProcedureFixed1);
1203
/* check multibyte */
1204
if (strlen(SCM_CHAR_VALUE(obj)) != 1)
1208
SCM_CHAR_VALUE(obj)[0] = tolower(SCM_CHAR_VALUE(obj)[0]);
1213
/*==============================================================================
1214
R5RS : 6.3 Other data types : 6.3.5 Strings
1215
==============================================================================*/
1216
ScmObj ScmOp_stringp(ScmObj obj)
1218
DECLARE_FUNCTION("string?", ProcedureFixed1);
1219
return (STRINGP(obj)) ? SCM_TRUE : SCM_FALSE;
1222
ScmObj ScmOp_make_string(ScmObj length, ScmObj args)
1225
ScmObj str = SCM_FALSE;
1226
ScmObj filler = SCM_FALSE;
1227
DECLARE_FUNCTION("make-string", ProcedureVariadic1);
1229
ASSERT_INTP(length);
1230
len = SCM_INT_VALUE(length);
1232
return Scm_NewStringCopying("");
1234
/* specify filler */
1235
if (NO_MORE_ARG(args)) {
1236
filler = Scm_NewChar(strdup(" "));
1238
filler = POP_ARG(args);
1239
ASSERT_CHARP(filler);
1243
str = Scm_NewStringWithLen(NULL, len);
1246
ScmOp_string_fill(str, filler);
1251
ScmObj ScmOp_string(ScmObj args)
1253
DECLARE_FUNCTION("string", ProcedureVariadic0);
1254
return ScmOp_list2string(args);
1257
ScmObj ScmOp_string_length(ScmObj str)
1259
DECLARE_FUNCTION("string-length", ProcedureFixed1);
1260
ASSERT_STRINGP(str);
1261
return Scm_NewInt(Scm_mb_bare_c_strlen(SCM_STRING_STR(str)));
1264
ScmObj ScmOp_string_ref(ScmObj str, ScmObj k)
1267
char *new_ch = NULL;
1268
ScmMultibyteString mbs;
1269
DECLARE_FUNCTION("string-ref", ProcedureFixed2);
1271
ASSERT_STRINGP(str);
1275
/* get start_ptr and end_ptr */
1276
c_index = SCM_INT_VALUE(k);
1277
SCM_MBS_SET_STR(mbs, SCM_STRING_STR(str));
1279
/* FIXME: This strlen() can be eliminated. */
1280
SCM_MBS_SET_SIZE(mbs, strlen(SCM_STRING_STR(str)));
1281
mbs = Scm_mb_strref(mbs, c_index);
1283
/* copy from start_ptr to end_ptr */
1284
new_ch = (char*)malloc(SCM_MBS_GET_SIZE(mbs) + 1);
1285
memcpy(new_ch, SCM_MBS_GET_STR(mbs), SCM_MBS_GET_SIZE(mbs));
1286
new_ch[SCM_MBS_GET_SIZE(mbs)] = 0;
1288
return Scm_NewChar(new_ch);
1291
ScmObj ScmOp_string_set(ScmObj str, ScmObj k, ScmObj ch)
1293
int c_start_index = 0;
1294
int prefix_size = 0;
1296
int postfix_size = 0;
1298
char *new_str = NULL;
1299
ScmMultibyteString mbs;
1300
const char *string_str = NULL;
1301
DECLARE_FUNCTION("string-set!", ProcedureFixed3);
1303
ASSERT_STRINGP(str);
1308
c_start_index = SCM_INT_VALUE(k);
1309
string_str = SCM_STRING_STR(str);
1310
/* FIXME: can string_str be NULL at this point or not? */
1311
if (!string_str) string_str = "";
1313
/* FIXME: strlen() can be eliminiated. */
1315
SCM_MBS_SET_STR(mbs, string_str);
1316
SCM_MBS_SET_SIZE(mbs, strlen(string_str));
1317
mbs = Scm_mb_strref(mbs, c_start_index);
1319
/* calculate total size */
1320
prefix_size = SCM_MBS_GET_STR(mbs) - string_str;
1321
newch_size = strlen(SCM_CHAR_VALUE(ch));
1322
postfix_size = strlen(SCM_MBS_GET_STR(mbs) + SCM_MBS_GET_SIZE(mbs));
1323
total_size = prefix_size + newch_size + postfix_size;
1325
/* copy each part */
1326
new_str = (char*)malloc(total_size + 1);
1327
memcpy(new_str, string_str, prefix_size);
1328
memcpy(new_str+prefix_size, SCM_CHAR_VALUE(ch), newch_size);
1329
memcpy(new_str+prefix_size+newch_size,
1330
SCM_MBS_GET_STR(mbs)+SCM_MBS_GET_SIZE(mbs), postfix_size);
1332
if (SCM_STRING_STR(str))
1333
free(SCM_STRING_STR(str));
1335
SCM_STRING_SET_STR(str, new_str);
1340
ScmObj ScmOp_string_equal(ScmObj str1, ScmObj str2)
1342
DECLARE_FUNCTION("string=", ProcedureFixed2);
1344
ASSERT_STRINGP(str1);
1345
ASSERT_STRINGP(str2);
1347
if (strcmp(SCM_STRING_STR(str1), SCM_STRING_STR(str2)) == 0)
1353
ScmObj ScmOp_string_substring(ScmObj str, ScmObj start, ScmObj end)
1355
int c_start_index = 0;
1356
int c_end_index = 0;
1357
char *new_str = NULL;
1358
ScmMultibyteString mbs;
1359
const char *string_str = NULL;
1360
DECLARE_FUNCTION("substring", ProcedureFixed3);
1362
ASSERT_STRINGP(str);
1366
/* get start_ptr and end_ptr */
1367
c_start_index = SCM_INT_VALUE(start);
1368
c_end_index = SCM_INT_VALUE(end);
1371
if (c_start_index > c_end_index)
1372
ERR("substring: start index is greater than end index.");
1373
if (c_end_index > SCM_STRING_LEN(str))
1374
ERR_OBJ("index out of range", end);
1376
/* FIXME: strlen() can be eliminated. */
1377
string_str = SCM_STRING_STR(str);
1379
SCM_MBS_SET_STR(mbs, string_str);
1380
SCM_MBS_SET_SIZE(mbs, strlen(string_str));
1381
mbs = Scm_mb_substring(mbs, c_start_index, c_end_index - c_start_index);
1383
/* copy from start_ptr to end_ptr */
1384
new_str = (char*)malloc(SCM_MBS_GET_SIZE(mbs) + 1);
1385
memcpy(new_str, SCM_MBS_GET_STR(mbs), SCM_MBS_GET_SIZE(mbs));
1386
new_str[SCM_MBS_GET_SIZE(mbs)] = 0;
1388
return Scm_NewString(new_str);
1391
ScmObj ScmOp_string_append(ScmObj args)
1393
/* FIXME: transition to new arg extraction mechanism incomplete. */
1396
ScmObj strings = SCM_NULL;
1397
ScmObj obj = SCM_NULL;
1398
char *new_str = NULL;
1400
DECLARE_FUNCTION("string-append", ProcedureFixed1);
1402
if (NO_MORE_ARG(args))
1403
return Scm_NewStringCopying("");
1405
/* count total size of the new string */
1406
for (strings = args; !NULLP(strings); strings = CDR(strings)) {
1408
ASSERT_STRINGP(obj);
1410
total_size += strlen(SCM_STRING_STR(obj));
1411
total_len += SCM_STRING_LEN(obj);
1414
/* allocate new string */
1415
new_str = (char*)malloc(sizeof(char) * total_size + 1);
1417
/* copy string by string */
1419
for (strings = args; !NULLP(strings); strings = CDR(strings)) {
1422
strcpy(p, SCM_STRING_STR(obj));
1423
p += strlen(SCM_STRING_STR(obj));
1426
return Scm_NewStringWithLen(new_str, total_len);
1429
ScmObj ScmOp_string2list(ScmObj string)
1431
ScmObj head = SCM_NULL;
1432
ScmObj tail = SCM_NULL;
1433
ScmObj next = SCM_NULL;
1434
ScmMultibyteString mbs;
1435
ScmMultibyteCharInfo ch;
1437
DECLARE_FUNCTION("string->list", string);
1439
ASSERT_STRINGP(string);
1442
SCM_MBS_SET_STR(mbs, SCM_STRING_STR(string));
1443
SCM_MBS_SET_SIZE(mbs, strlen(SCM_STRING_STR(string)));
1445
while (SCM_MBS_GET_SIZE(mbs)) {
1446
ch = Scm_mb_scan_char(mbs);
1447
buf = malloc(SCM_MBCINFO_GET_SIZE(ch)+1);
1448
memcpy(buf, SCM_MBS_GET_STR(mbs), SCM_MBCINFO_GET_SIZE(ch));
1449
buf[SCM_MBCINFO_GET_SIZE(ch)] = 0;
1450
next = LIST_1(Scm_NewChar(buf));
1455
SET_CDR(tail, next);
1459
SCM_MBS_SKIP_CHAR(mbs, ch);
1465
ScmObj ScmOp_list2string(ScmObj lst)
1469
ScmObj chars = SCM_NULL;
1470
ScmObj obj = SCM_NULL;
1471
char *new_str = NULL;
1474
DECLARE_FUNCTION("list->string", ProcedureFixed1);
1476
if (FALSEP(ScmOp_listp(lst)))
1477
ERR_OBJ("list required but got ", lst);
1480
return Scm_NewStringCopying("");
1482
/* count total size of the string */
1483
for (chars = lst; !NULLP(chars); chars = CDR(chars)) {
1487
total_size += strlen(SCM_CHAR_VALUE(obj));
1490
/* allocate new string */
1491
new_str = (char*)malloc(sizeof(char) * total_size + 1);
1493
/* copy char by char */
1495
for (chars = lst; !NULLP(chars); chars = CDR(chars)) {
1497
ch = SCM_CHAR_VALUE(obj);
1498
len = strlen(SCM_CHAR_VALUE(obj));
1504
return Scm_NewString(new_str);
1507
ScmObj ScmOp_string_copy(ScmObj string)
1509
DECLARE_FUNCTION("string-copy", ProcedureFixed1);
1510
ASSERT_STRINGP(string);
1511
return Scm_NewStringCopying(SCM_STRING_STR(string));
1514
ScmObj ScmOp_string_fill(ScmObj string, ScmObj ch)
1518
char *new_str = NULL;
1521
DECLARE_FUNCTION("string-fill!", ProcedureFixed2);
1523
ASSERT_STRINGP(string);
1526
/* create new str */
1527
char_size = strlen(SCM_CHAR_VALUE(ch));
1528
str_len = SCM_STRING_LEN(string);
1529
new_str = (char*)realloc(SCM_STRING_STR(string),
1530
sizeof(char) * str_len * char_size + 1);
1531
for (i = 0, p = new_str; i < char_size * str_len;) {
1532
strcpy(p, SCM_CHAR_VALUE(ch));
1538
SCM_STRING_SET_STR(string, new_str);
1543
/*==============================================================================
1544
R5RS : 6.3 Other data types : 6.3.6 Vectors
1545
==============================================================================*/
1546
ScmObj ScmOp_vectorp(ScmObj obj)
1548
DECLARE_FUNCTION("vector?", ProcedureFixed1);
1549
return (VECTORP(obj)) ? SCM_TRUE : SCM_FALSE;
1552
ScmObj ScmOp_make_vector(ScmObj vector_len, ScmObj args)
1555
ScmObj filler = SCM_FALSE;
1558
DECLARE_FUNCTION("make-vector", ProcedureVariadic1);
1560
ASSERT_INTP(vector_len);
1562
/* allocate vector */
1563
len = SCM_INT_VALUE(vector_len);
1564
vec = (ScmObj*)malloc(sizeof(ScmObj) * len);
1571
for (i = 0; i < len; i++)
1574
return Scm_NewVector(vec, len);
1577
ScmObj ScmOp_vector(ScmObj args)
1579
int len = SCM_INT_VALUE(ScmOp_length(args));
1581
ScmObj *vec = (ScmObj*)malloc(sizeof(ScmObj) * len); /* allocate vector */
1582
DECLARE_FUNCTION("vector", ProcedureVariadic0);
1585
for (i = 0; i < len; i++)
1586
SCM_SHIFT_RAW_1(vec[i], args);
1588
return Scm_NewVector(vec, len);
1591
ScmObj ScmOp_vector_length(ScmObj vec)
1593
DECLARE_FUNCTION("vector-length", ProcedureFixed1);
1595
ASSERT_VECTORP(vec);
1596
return Scm_NewInt(SCM_VECTOR_LEN(vec));
1599
ScmObj ScmOp_vector_ref(ScmObj vec, ScmObj scm_k)
1601
DECLARE_FUNCTION("vector-ref", ProcedureFixed2);
1603
ASSERT_VECTORP(vec);
1606
return SCM_VECTOR_REF(vec, scm_k);
1609
ScmObj ScmOp_vector_set(ScmObj vec, ScmObj scm_k, ScmObj obj)
1611
DECLARE_FUNCTION("vector-set!", ProcedureFixed3);
1612
ASSERT_VECTORP(vec);
1615
SCM_VECTOR_SET_REF(vec, scm_k, obj);
1620
ScmObj ScmOp_vector2list(ScmObj vec)
1628
DECLARE_FUNCTION("vector->list", ProcedureFixed1);
1630
ASSERT_VECTORP(vec);
1632
v = SCM_VECTOR_VEC(vec);
1633
c_len = SCM_VECTOR_LEN(vec);
1637
for (i = 0; i < c_len; i++) {
1638
next = CONS(v[i], SCM_NULL);
1641
SET_CDR(prev, next);
1652
ScmObj ScmOp_list2vector(ScmObj lst)
1654
ScmObj scm_len = SCM_NULL;
1658
DECLARE_FUNCTION("list->vector", ProcedureFixed1);
1660
/* TOOD : canbe optimized. scanning list many times */
1661
if (FALSEP(ScmOp_listp(lst)))
1662
ERR_OBJ("list required but got ", lst);
1664
scm_len = ScmOp_length(lst);
1665
c_len = SCM_INT_VALUE(scm_len);
1666
v = (ScmObj*)malloc(sizeof(ScmObj) * c_len);
1667
for (i = 0; i < c_len; i++) {
1672
return Scm_NewVector(v, c_len);
1675
ScmObj ScmOp_vector_fill(ScmObj vec, ScmObj fill)
1679
DECLARE_FUNCTION("vector-fill!", ProcedureFixed2);
1681
ASSERT_VECTORP(vec);
1683
c_len = SCM_VECTOR_LEN(vec);
1684
for (i = 0; i < c_len; i++) {
1685
SCM_VECTOR_VEC(vec)[i] = fill;
1691
/*=======================================
1692
R5RS : 6.4 Control Features
1693
=======================================*/
1694
ScmObj ScmOp_procedurep(ScmObj obj)
1696
DECLARE_FUNCTION("procedure?", ProcedureFixed1);
1697
return (PROCEDUREP(obj)) ? SCM_TRUE : SCM_FALSE;
1700
ScmObj ScmOp_map(ScmObj proc, ScmObj args)
1702
DECLARE_FUNCTION("map", ProcedureVariadic1);
1705
SigScm_Error("map : wrong number of arguments");
1707
/* fast path for single arg case */
1708
if (NULLP(CDR(args)))
1709
return map_single_arg(proc, CAR(args));
1711
/* multiple args case */
1712
return map_multiple_args(proc, args);
1715
static ScmObj map_single_arg(ScmObj proc, ScmObj lst)
1717
ScmObj ret = SCM_FALSE;
1718
ScmObj ret_last = SCM_FALSE;
1719
ScmObj mapped_elm = SCM_FALSE;
1724
for (; !NULLP(lst); lst = CDR(lst)) {
1727
mapped_elm = CONS(Scm_call(proc, LIST_1(CAR(lst))), SCM_NULL);
1728
SET_CDR(ret_last, mapped_elm);
1729
ret_last = mapped_elm;
1732
ret = CONS(Scm_call(proc, LIST_1(CAR(lst))), SCM_NULL);
1742
* - Simplify and make names appropriate as like as map_singular_arg()
1744
static ScmObj map_multiple_args(ScmObj proc, ScmObj args)
1746
ScmObj map_arg = SCM_FALSE;
1747
ScmObj map_arg_last = SCM_FALSE;
1748
ScmObj tmp_lsts = SCM_FALSE;
1749
ScmObj lst = SCM_FALSE;
1750
ScmObj ret = SCM_FALSE;
1751
ScmObj ret_last = SCM_FALSE;
1754
/* construct "map_arg" */
1755
map_arg = SCM_FALSE;
1757
for (; !NULLP(tmp_lsts); tmp_lsts = CDR(tmp_lsts)) {
1758
lst = CAR(tmp_lsts);
1762
if (NFALSEP(map_arg)) {
1764
SET_CDR(map_arg_last, CONS(CAR(lst), SCM_NULL));
1765
map_arg_last = CDR(map_arg_last);
1768
map_arg = CONS(CAR(lst), SCM_NULL);
1769
map_arg_last = map_arg;
1772
/* update tmp_lsts */
1773
SET_CAR(tmp_lsts, CDR(lst));
1776
/* construct "ret" by applying proc to each map_arg */
1779
SET_CDR(ret_last, CONS(Scm_call(proc, map_arg), SCM_NULL));
1780
ret_last = CDR(ret_last);
1783
ret = CONS(Scm_call(proc, map_arg), SCM_NULL);
1788
SigScm_Error("map : invalid argument ", args);
1792
ScmObj ScmOp_for_each(ScmObj proc, ScmObj args)
1794
DECLARE_FUNCTION("for-each", ProcedureVariadic1);
1795
ScmOp_map(proc, args);
1800
ScmObj ScmOp_force(ScmObj closure)
1802
DECLARE_FUNCTION("force", ProcedureFixed1);
1804
ASSERT_CLOSUREP(closure);
1806
return Scm_call(closure, SCM_NULL);
1809
ScmObj ScmOp_call_with_current_continuation(ScmObj proc, ScmEvalState *eval_state)
1811
DECLARE_FUNCTION("call-with-current-continuation", ProcedureFixedTailRec1);
1813
ASSERT_PROCEDUREP(proc);
1815
return Scm_CallWithCurrentContinuation(proc, eval_state);
1818
ScmObj ScmOp_values(ScmObj args)
1820
DECLARE_FUNCTION("values", ProcedureVariadic0);
1821
/* Values with one arg must return something that fits an ordinary
1823
if (CONSP(args) && NULLP(CDR(args)))
1826
/* Otherwise, we'll return the values in a packet. */
1827
return SCM_MAKE_VALUEPACKET(args);
1830
ScmObj ScmOp_call_with_values(ScmObj producer, ScmObj consumer,
1831
ScmEvalState *eval_state)
1834
DECLARE_FUNCTION("call-with-values", ProcedureFixedTailRec2);
1836
ASSERT_PROCEDUREP(producer);
1837
ASSERT_PROCEDUREP(consumer);
1839
vals = Scm_call(producer, SCM_NULL);
1841
if (!VALUEPACKETP(vals)) {
1842
/* got back a single value */
1843
vals = CONS(vals, SCM_NULL);
1846
vals = SCM_VALUEPACKET_VALUES(vals);
1849
return Scm_tailcall(consumer, vals, eval_state);
1852
ScmObj ScmOp_dynamic_wind(ScmObj before, ScmObj thunk, ScmObj after)
1854
DECLARE_FUNCTION("dynamic-wind", ProcedureFixed3);
1856
ASSERT_PROCEDUREP(before);
1857
ASSERT_PROCEDUREP(thunk);
1858
ASSERT_PROCEDUREP(after);
1860
return Scm_DynamicWind(before, thunk, after);
1863
/*============================================================================
1864
SigScheme-Specific Non-R5RS Standard Procedures
1865
============================================================================*/
1866
#if SCM_USE_NONSTD_FEATURES
1869
* - describe compatibility with de facto standard of other Scheme
1870
* implementations (accept env as optional arg, etc)
1872
/* The implementation is fully compatible with SIOD */
1873
ScmObj ScmOp_symbol_boundp(ScmObj sym, ScmObj rest)
1875
ScmObj env = SCM_INVALID;
1876
DECLARE_FUNCTION("symbol-bound?", ProcedureVariadic1);
1878
ASSERT_SYMBOLP(sym);
1880
env = POP_ARG(rest);
1884
env = SCM_INTERACTION_ENV;
1886
return (!NULLP(Scm_LookupEnvironment(sym, env))
1887
|| SCM_SYMBOL_BOUNDP(sym)) ? SCM_TRUE : SCM_FALSE;
1889
#endif /* SCM_USE_NONSTD_FEATURES */
1892
#include "operations-srfi1.c"
1895
#include "operations-srfi2.c"
1898
#include "operations-srfi6.c"
1901
#include "operations-srfi8.c"
1904
#include "operations-srfi23.c"
1907
#include "operations-srfi34.c"
1910
#include "operations-srfi38.c"
1913
#include "operations-srfi60.c"
1916
#include "operations-siod.c"