GOOPS cosmetics
[bpt/guile.git] / libguile / srfi-1.c
index f67e600..353a746 100644 (file)
@@ -1,7 +1,7 @@
 /* srfi-1.c --- SRFI-1 procedures for Guile
  *
- * Copyright (C) 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2005, 2006,
- *   2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 1995-1997, 2000-2003, 2005, 2006, 2008-2011, 2013
+ *   2014 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
  */
 
 
-static long
-srfi1_ilength (SCM sx)
-{
-  long i = 0;
-  SCM tortoise = sx;
-  SCM hare = sx;
-
-  do {
-    if (SCM_NULL_OR_NIL_P(hare)) return i;
-    if (!scm_is_pair (hare)) return -2;
-    hare = SCM_CDR(hare);
-    i++;
-    if (SCM_NULL_OR_NIL_P(hare)) return i;
-    if (!scm_is_pair (hare)) return -2;
-    hare = SCM_CDR(hare);
-    i++;
-    /* For every two steps the hare takes, the tortoise takes one.  */
-    tortoise = SCM_CDR(tortoise);
-  }
-  while (! scm_is_eq (hare, tortoise));
-
-  /* If the tortoise ever catches the hare, then the list must contain
-     a cycle.  */
-  return -1;
-}
-
 static SCM
 equal_trampoline (SCM proc, SCM arg1, SCM arg2)
 {
@@ -284,7 +258,7 @@ SCM_DEFINE (scm_srfi1_count, "count", 2, 0, 1,
               SCM_SIMPLE_VECTOR_SET (vec, i, SCM_CDR (lst));  /* rest of lst */
             }
 
-          count += scm_is_true (scm_apply (pred, args, SCM_EOL));
+          count += scm_is_true (scm_apply_0 (pred, args));
         }
     }
 
@@ -594,28 +568,6 @@ SCM_DEFINE (scm_srfi1_delete_duplicates_x, "delete-duplicates!", 1, 1, 0,
 #undef FUNC_NAME
 
 
-SCM_DEFINE (scm_srfi1_drop_right, "drop-right", 2, 0, 0,
-            (SCM lst, SCM n),
-           "Return a new list containing all except the last @var{n}\n"
-           "elements of @var{lst}.")
-#define FUNC_NAME s_scm_srfi1_drop_right
-{
-  SCM tail = scm_list_tail (lst, n);
-  SCM ret = SCM_EOL;
-  SCM *rend = &ret;
-  while (scm_is_pair (tail))
-    {
-      *rend = scm_cons (SCM_CAR (lst), SCM_EOL);
-      rend = SCM_CDRLOC (*rend);
-      
-      lst = SCM_CDR (lst);
-      tail = SCM_CDR (tail);
-    }
-  SCM_ASSERT_TYPE (SCM_NULL_OR_NIL_P(tail), tail, SCM_ARG1, FUNC_NAME, "list");
-  return ret;
-}
-#undef FUNC_NAME
-
 SCM_DEFINE (scm_srfi1_find, "find", 2, 0, 0,
             (SCM pred, SCM lst),
            "Return the first element of @var{lst} which satisfies the\n"
@@ -662,8 +614,40 @@ SCM_DEFINE (scm_srfi1_length_plus, "length+", 1, 0, 0,
            "circular.")
 #define FUNC_NAME s_scm_srfi1_length_plus
 {
-  long len = scm_ilength (lst);
-  return (len >= 0 ? SCM_I_MAKINUM (len) : SCM_BOOL_F);
+  size_t i = 0;
+  SCM tortoise = lst;
+  SCM hare = lst;
+
+  do
+    {
+      if (!scm_is_pair (hare))
+        {
+          if (SCM_NULL_OR_NIL_P (hare))
+            return scm_from_size_t (i);
+          else
+            scm_wrong_type_arg_msg (FUNC_NAME, 1, lst,
+                                    "proper or circular list");
+        }
+      hare = SCM_CDR (hare);
+      i++;
+      if (!scm_is_pair (hare))
+        {
+          if (SCM_NULL_OR_NIL_P (hare))
+            return scm_from_size_t (i);
+          else
+            scm_wrong_type_arg_msg (FUNC_NAME, 1, lst,
+                                    "proper or circular list");
+        }
+      hare = SCM_CDR (hare);
+      i++;
+      /* For every two steps the hare takes, the tortoise takes one.  */
+      tortoise = SCM_CDR (tortoise);
+    }
+  while (!scm_is_eq (hare, tortoise));
+
+  /* If the tortoise ever catches the hare, then the list must contain
+     a cycle.  */
+  return SCM_BOOL_F;
 }
 #undef FUNC_NAME
 
@@ -760,206 +744,10 @@ SCM_DEFINE (scm_srfi1_lset_difference_x, "lset-difference!", 2, 0, 1,
 #undef FUNC_NAME
 
 
-/* Typechecking for multi-argument MAP and FOR-EACH.
-
-   Verify that each element of the vector ARGV, except for the first,
-   is a list and return minimum length.  Attribute errors to WHO,
-   and claim that the i'th element of ARGV is WHO's i+2'th argument.  */
-static inline int
-check_map_args (SCM argv,
-               long len,
-               SCM gf,
-               SCM proc,
-               SCM args,
-               const char *who)
-{
-  long i;
-  SCM elt;
-
-  for (i = SCM_SIMPLE_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
-    {
-      long elt_len;
-      elt = SCM_SIMPLE_VECTOR_REF (argv, i);
-
-      if (!(scm_is_null (elt) || scm_is_pair (elt)))
-       goto check_map_error;
-       
-      elt_len = srfi1_ilength (elt);
-      if (elt_len < -1)
-       goto check_map_error;
-
-      if (len < 0 || (elt_len >= 0 && elt_len < len))
-       len = elt_len;
-    }
-
-  if (len < 0)
-    {
-      /* i == 0 */
-      elt = SCM_EOL;
-    check_map_error:
-      if (gf)
-       scm_apply_generic (gf, scm_cons (proc, args));
-      else
-       scm_wrong_type_arg (who, i + 2, elt);
-    }
-
-  scm_remember_upto_here_1 (argv);
-  return len;
-}
-
-
-SCM_GPROC (s_srfi1_map, "map", 2, 0, 1, scm_srfi1_map, g_srfi1_map);
-
-/* Note: Currently, scm_srfi1_map applies PROC to the argument list(s)
-   sequentially, starting with the first element(s).  This is used in
-   the Scheme procedure `map-in-order', which guarantees sequential
-   behaviour, is implemented using scm_map.  If the behaviour changes,
-   we need to update `map-in-order'.
-*/
-
-SCM 
-scm_srfi1_map (SCM proc, SCM arg1, SCM args)
-#define FUNC_NAME s_srfi1_map
-{
-  long i, len;
-  SCM res = SCM_EOL;
-  SCM *pres = &res;
-
-  len = srfi1_ilength (arg1);
-  SCM_GASSERTn ((scm_is_null (arg1) || scm_is_pair (arg1)) && len >= -1,
-               g_srfi1_map,
-               scm_cons2 (proc, arg1, args), SCM_ARG2, s_srfi1_map);
-  SCM_VALIDATE_REST_ARGUMENT (args);
-  if (scm_is_null (args))
-    {
-      SCM_GASSERT2 (scm_is_true (scm_procedure_p (proc)), g_srfi1_map,
-                    proc, arg1, SCM_ARG1, s_srfi1_map);
-      SCM_GASSERT2 (len >= 0, g_srfi1_map, proc, arg1, SCM_ARG2, s_srfi1_map);
-      while (SCM_NIMP (arg1))
-       {
-         *pres = scm_list_1 (scm_call_1 (proc, SCM_CAR (arg1)));
-         pres = SCM_CDRLOC (*pres);
-         arg1 = SCM_CDR (arg1);
-       }
-      return res;
-    }
-  if (scm_is_null (SCM_CDR (args)))
-    {
-      SCM arg2 = SCM_CAR (args);
-      int len2 = srfi1_ilength (arg2);
-      SCM_GASSERTn (scm_is_true (scm_procedure_p (proc)), g_srfi1_map,
-                   scm_cons2 (proc, arg1, args), SCM_ARG1, s_srfi1_map);
-      if (len < 0 || (len2 >= 0 && len2 < len))
-       len = len2;
-      SCM_GASSERTn ((scm_is_null (arg2) || scm_is_pair (arg2))
-                   && len >= 0 && len2 >= -1,
-                   g_srfi1_map,
-                   scm_cons2 (proc, arg1, args),
-                   len2 >= 0 ? SCM_ARG2 : SCM_ARG3,
-                   s_srfi1_map);
-      while (len > 0)
-       {
-         *pres = scm_list_1 (scm_call_2 (proc, SCM_CAR (arg1), SCM_CAR (arg2)));
-         pres = SCM_CDRLOC (*pres);
-         arg1 = SCM_CDR (arg1);
-         arg2 = SCM_CDR (arg2);
-         --len;
-       }
-      return res;
-    }
-  args = scm_vector (arg1 = scm_cons (arg1, args));
-  len = check_map_args (args, len, g_srfi1_map, proc, arg1, s_srfi1_map);
-  while (len > 0)
-    {
-      arg1 = SCM_EOL;
-      for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
-       {
-         SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
-         arg1 = scm_cons (SCM_CAR (elt), arg1);
-         SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
-       }
-      *pres = scm_list_1 (scm_apply (proc, arg1, SCM_EOL));
-      pres = SCM_CDRLOC (*pres);
-      --len;
-    }
-  return res;
-}
-#undef FUNC_NAME
-
-SCM_REGISTER_PROC (s_srfi1_map_in_order, "map-in-order", 2, 0, 1, scm_srfi1_map);
-
-SCM_GPROC (s_srfi1_for_each, "for-each", 2, 0, 1, scm_srfi1_for_each, g_srfi1_for_each);
-
-SCM 
-scm_srfi1_for_each (SCM proc, SCM arg1, SCM args)
-#define FUNC_NAME s_srfi1_for_each
-{
-  long i, len;
-  len = srfi1_ilength (arg1);
-  SCM_GASSERTn ((scm_is_null (arg1) || scm_is_pair (arg1)) && len >= -1,
-               g_srfi1_for_each, scm_cons2 (proc, arg1, args),
-               SCM_ARG2, s_srfi1_for_each);
-  SCM_VALIDATE_REST_ARGUMENT (args);
-  if (scm_is_null (args))
-    {
-      SCM_GASSERT2 (scm_is_true (scm_procedure_p (proc)), g_srfi1_for_each,
-                    proc, arg1, SCM_ARG1, s_srfi1_for_each);
-      SCM_GASSERT2 (len >= 0, g_srfi1_for_each, proc, arg1,
-                   SCM_ARG2, s_srfi1_map);
-      while (SCM_NIMP (arg1))
-       {
-         scm_call_1 (proc, SCM_CAR (arg1));
-         arg1 = SCM_CDR (arg1);
-       }
-      return SCM_UNSPECIFIED;
-    }
-  if (scm_is_null (SCM_CDR (args)))
-    {
-      SCM arg2 = SCM_CAR (args);
-      int len2 = srfi1_ilength (arg2);
-      SCM_GASSERTn (scm_is_true (scm_procedure_p (proc)), g_srfi1_for_each,
-                   scm_cons2 (proc, arg1, args), SCM_ARG1, s_srfi1_for_each);
-      if (len < 0 || (len2 >= 0 && len2 < len))
-       len = len2;
-      SCM_GASSERTn ((scm_is_null (arg2) || scm_is_pair (arg2))
-                   && len >= 0 && len2 >= -1,
-                   g_srfi1_for_each,
-                   scm_cons2 (proc, arg1, args),
-                   len2 >= 0 ? SCM_ARG2 : SCM_ARG3,
-                   s_srfi1_for_each);
-      while (len > 0)
-       {
-         scm_call_2 (proc, SCM_CAR (arg1), SCM_CAR (arg2));
-         arg1 = SCM_CDR (arg1);
-         arg2 = SCM_CDR (arg2);
-         --len;
-       }
-      return SCM_UNSPECIFIED;
-    }
-  args = scm_vector (arg1 = scm_cons (arg1, args));
-  len = check_map_args (args, len, g_srfi1_for_each, proc, arg1,
-                       s_srfi1_for_each);
-  while (len > 0)
-    {
-      arg1 = SCM_EOL;
-      for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
-       {
-         SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
-         arg1 = scm_cons (SCM_CAR (elt), arg1);
-         SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
-       }
-      scm_apply (proc, arg1, SCM_EOL);
-      --len;
-    }
-  return SCM_UNSPECIFIED;
-}
-#undef FUNC_NAME
-
-
 SCM_DEFINE (scm_srfi1_assoc, "assoc", 2, 1, 0,
            (SCM key, SCM alist, SCM pred),
-           "Behaves like @code{assq} but uses third argument @var{pred?}\n"
-           "for key comparison.  If @var{pred?} is not supplied,\n"
+           "Behaves like @code{assq} but uses third argument @var{pred}\n"
+           "for key comparison.  If @var{pred} is not supplied,\n"
            "@code{equal?} is used.  (Extended from R5RS.)\n")
 #define FUNC_NAME s_scm_srfi1_assoc
 {
@@ -1088,9 +876,9 @@ SCM_DEFINE (scm_srfi1_partition_x, "partition!", 2, 0, 0,
 
 SCM_DEFINE (scm_srfi1_remove, "remove", 2, 0, 0,
            (SCM pred, SCM list),
-           "Return a list containing all elements from @var{lst} which do\n"
+           "Return a list containing all elements from @var{list} which do\n"
            "not satisfy the predicate @var{pred}.  The elements in the\n"
-           "result list have the same order as in @var{lst}.  The order in\n"
+           "result list have the same order as in @var{list}.  The order in\n"
            "which @var{pred} is applied to the list elements is not\n"
            "specified.")
 #define FUNC_NAME s_scm_srfi1_remove
@@ -1146,23 +934,6 @@ SCM_DEFINE (scm_srfi1_remove_x, "remove!", 2, 0, 0,
 }
 #undef FUNC_NAME
 
-SCM_DEFINE (scm_srfi1_take_right, "take-right", 2, 0, 0,
-            (SCM lst, SCM n),
-           "Return a list containing the @var{n} last elements of\n"
-           "@var{lst}.")
-#define FUNC_NAME s_scm_srfi1_take_right
-{
-  SCM tail = scm_list_tail (lst, n);
-  while (scm_is_pair (tail))
-    {
-      lst = SCM_CDR (lst);
-      tail = SCM_CDR (tail);
-    }
-  SCM_ASSERT_TYPE (SCM_NULL_OR_NIL_P(tail), tail, SCM_ARG1, FUNC_NAME, "list");
-  return lst;
-}
-#undef FUNC_NAME
-
 \f
 void
 scm_register_srfi_1 (void)
@@ -1175,16 +946,9 @@ scm_register_srfi_1 (void)
 void
 scm_init_srfi_1 (void)
 {
-  SCM the_root_module = scm_lookup_closure_module (SCM_BOOL_F);
 #ifndef SCM_MAGIC_SNARFER
 #include "libguile/srfi-1.x"
 #endif
-  scm_c_extend_primitive_generic
-    (SCM_VARIABLE_REF (scm_c_module_lookup (the_root_module, "map")),
-     SCM_VARIABLE_REF (scm_c_lookup ("map")));
-  scm_c_extend_primitive_generic
-    (SCM_VARIABLE_REF (scm_c_module_lookup (the_root_module, "for-each")),
-     SCM_VARIABLE_REF (scm_c_lookup ("for-each")));
 }
 
 /* End of srfi-1.c.  */