2002-12-01 13:09:26 +00:00
|
|
|
/* Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
|
2003-04-05 19:15:35 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
1999-01-10 07:57:58 +00:00
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
1999-01-10 07:57:58 +00:00
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
*/
|
1999-01-10 07:57:58 +00:00
|
|
|
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
/* Written in December 1998 by Roland Orre <orre@nada.kth.se>
|
|
|
|
|
* This implements the same sort interface as slib/sort.scm
|
|
|
|
|
* for lists and vectors where slib defines:
|
|
|
|
|
* sorted?, merge, merge!, sort, sort!
|
1999-08-20 00:19:01 +00:00
|
|
|
* For scsh compatibility sort-list and sort-list! are also defined.
|
1999-01-10 07:57:58 +00:00
|
|
|
* In cases where a stable-sort is required use stable-sort or
|
1999-08-20 00:19:01 +00:00
|
|
|
* stable-sort!. An additional feature is
|
1999-01-10 07:57:58 +00:00
|
|
|
* (restricted-vector-sort! vector less? startpos endpos)
|
1999-08-20 00:19:01 +00:00
|
|
|
* which allows you to sort part of a vector.
|
1999-01-10 07:57:58 +00:00
|
|
|
* Thanks to Aubrey Jaffer for the slib/sort.scm library.
|
|
|
|
|
* Thanks to Richard A. O'Keefe (based on Prolog code by D.H.D.Warren)
|
|
|
|
|
* for the merge sort inspiration.
|
|
|
|
|
* Thanks to Douglas C. Schmidt (schmidt@ics.uci.edu) for the
|
|
|
|
|
* quicksort code.
|
|
|
|
|
*/
|
|
|
|
|
|
2000-04-21 14:16:44 +00:00
|
|
|
#include "libguile/_scm.h"
|
|
|
|
|
#include "libguile/eval.h"
|
|
|
|
|
#include "libguile/unif.h"
|
|
|
|
|
#include "libguile/ramap.h"
|
|
|
|
|
#include "libguile/feature.h"
|
|
|
|
|
#include "libguile/vectors.h"
|
2002-01-22 23:31:39 +00:00
|
|
|
#include "libguile/lang.h"
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2000-04-21 14:16:44 +00:00
|
|
|
#include "libguile/validate.h"
|
|
|
|
|
#include "libguile/sort.h"
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
/* The routine quicksort was extracted from the GNU C Library qsort.c
|
|
|
|
|
written by Douglas C. Schmidt (schmidt@ics.uci.edu)
|
|
|
|
|
and adapted to guile by adding an extra pointer less
|
|
|
|
|
to quicksort by Roland Orre <orre@nada.kth.se>.
|
|
|
|
|
|
|
|
|
|
The reason to do this instead of using the library function qsort
|
|
|
|
|
was to avoid dependency of the ANSI-C extensions for local functions
|
|
|
|
|
and also to avoid obscure pool based solutions.
|
1999-08-20 00:19:01 +00:00
|
|
|
|
|
|
|
|
This sorting routine is not much more efficient than the stable
|
|
|
|
|
version but doesn't consume extra memory.
|
1999-01-10 07:57:58 +00:00
|
|
|
*/
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
#define SWAP(a, b) do { const SCM _tmp = a; a = b; b = _tmp; } while (0)
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Order size using quicksort. This implementation incorporates
|
|
|
|
|
four optimizations discussed in Sedgewick:
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
1. Non-recursive, using an explicit stack of pointer that store the next
|
|
|
|
|
array partition to sort. To save time, this maximum amount of space
|
|
|
|
|
required to store an array of MAX_SIZE_T is allocated on the stack.
|
|
|
|
|
Assuming a bit width of 32 bits for size_t, this needs only
|
|
|
|
|
32 * sizeof (stack_node) == 128 bytes. Pretty cheap, actually.
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
2. Chose the pivot element using a median-of-three decision tree. This
|
|
|
|
|
reduces the probability of selecting a bad pivot value and eliminates
|
|
|
|
|
certain extraneous comparisons.
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
3. Only quicksorts NR_ELEMS / MAX_THRESH partitions, leaving insertion sort
|
|
|
|
|
to order the MAX_THRESH items within each partition. This is a big win,
|
|
|
|
|
since insertion sort is faster for small, mostly sorted array segments.
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
4. The larger of the two sub-partitions is always pushed onto the
|
|
|
|
|
stack first, with the algorithm then concentrating on the
|
|
|
|
|
smaller partition. This *guarantees* no more than log (n)
|
|
|
|
|
stack size is needed (actually O(1) in this case)! */
|
|
|
|
|
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
/* Discontinue quicksort algorithm when partition gets below this size.
|
|
|
|
|
* This particular magic number was chosen to work best on a Sun 4/260. */
|
|
|
|
|
#define MAX_THRESH 4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Inline stack abstraction: The stack size for quicksorting at most as many
|
|
|
|
|
* elements as can be given by a value of type size_t is, as described above,
|
|
|
|
|
* log (MAX_SIZE_T), which is the number of bits of size_t. More accurately,
|
|
|
|
|
* we would only need ceil (log (MAX_SIZE_T / MAX_THRESH)), but this is
|
|
|
|
|
* ignored below. */
|
|
|
|
|
|
|
|
|
|
/* Stack node declarations used to store unfulfilled partition obligations. */
|
|
|
|
|
typedef struct {
|
|
|
|
|
size_t lo;
|
|
|
|
|
size_t hi;
|
|
|
|
|
} stack_node;
|
|
|
|
|
|
|
|
|
|
#define STACK_SIZE (8 * sizeof (size_t)) /* assume 8 bit char */
|
|
|
|
|
#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
|
|
|
|
|
#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
|
|
|
|
|
#define STACK_NOT_EMPTY (stack < top)
|
|
|
|
|
|
1999-08-19 23:02:00 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
static void
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
quicksort (SCM *const base_ptr, size_t nr_elems, scm_t_trampoline_2 cmp, SCM less)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
static const char s_buggy_less[] = "buggy less predicate used when sorting";
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
if (nr_elems == 0)
|
1999-01-10 07:57:58 +00:00
|
|
|
/* Avoid lossage with unsigned arithmetic below. */
|
|
|
|
|
return;
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
if (nr_elems > MAX_THRESH)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
size_t lo = 0;
|
|
|
|
|
size_t hi = nr_elems - 1;
|
|
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
stack_node stack[STACK_SIZE];
|
|
|
|
|
stack_node *top = stack + 1;
|
|
|
|
|
|
|
|
|
|
while (STACK_NOT_EMPTY)
|
|
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
size_t left;
|
|
|
|
|
size_t right;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
/* Select median value from among LO, MID, and HI. Rearrange
|
|
|
|
|
LO and HI so the three values are sorted. This lowers the
|
|
|
|
|
probability of picking a pathological pivot value and
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
skips a comparison for both the left and right. */
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
size_t mid = lo + (hi - lo) / 2;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, base_ptr[mid], base_ptr[lo])))
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
SWAP (base_ptr[mid], base_ptr[lo]);
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, base_ptr[hi], base_ptr[mid])))
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
SWAP (base_ptr[mid], base_ptr[hi]);
|
1999-01-10 07:57:58 +00:00
|
|
|
else
|
|
|
|
|
goto jump_over;
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, base_ptr[mid], base_ptr[lo])))
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
SWAP (base_ptr[mid], base_ptr[lo]);
|
1999-01-10 07:57:58 +00:00
|
|
|
jump_over:;
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
left = lo + 1;
|
|
|
|
|
right = hi - 1;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
/* Here's the famous ``collapse the walls'' section of quicksort.
|
|
|
|
|
Gotta like those tight inner loops! They are the main reason
|
|
|
|
|
that this algorithm runs much faster than others. */
|
|
|
|
|
do
|
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
while (scm_is_true ((*cmp) (less, base_ptr[left], base_ptr[mid])))
|
1999-08-19 23:02:00 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
left++;
|
1999-08-19 23:02:00 +00:00
|
|
|
/* The comparison predicate may be buggy */
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
if (left > hi)
|
* dynl.c, feature.c, filesys.c, fports.c, list.c, load.c,
net_db.c, sort.c, stacks.c, unif.c: Use SCM_WTA, SCM_MISC_ERROR
where possible.
* symbols.c (scm_sysintern0): Fixed the function name in a
scm_misc_error invocation.
* print.c (scm_simple_format): Do not need SCM_COERCE_SUBSTR, and
use scm_return_first to ward off latent GC bug that Mikael caught.
* async.c: Use SCM_VALIDATE_ASYNC_COPY one place where it wasn't
used before but should've been.
2000-01-11 23:56:47 +00:00
|
|
|
scm_misc_error (NULL, s_buggy_less, SCM_EOL);
|
1999-08-19 23:02:00 +00:00
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2004-07-06 10:59:25 +00:00
|
|
|
while (scm_is_true ((*cmp) (less, base_ptr[mid], base_ptr[right])))
|
1999-08-19 23:02:00 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
right--;
|
1999-08-19 23:02:00 +00:00
|
|
|
/* The comparison predicate may be buggy */
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
if (right < lo)
|
* dynl.c, feature.c, filesys.c, fports.c, list.c, load.c,
net_db.c, sort.c, stacks.c, unif.c: Use SCM_WTA, SCM_MISC_ERROR
where possible.
* symbols.c (scm_sysintern0): Fixed the function name in a
scm_misc_error invocation.
* print.c (scm_simple_format): Do not need SCM_COERCE_SUBSTR, and
use scm_return_first to ward off latent GC bug that Mikael caught.
* async.c: Use SCM_VALIDATE_ASYNC_COPY one place where it wasn't
used before but should've been.
2000-01-11 23:56:47 +00:00
|
|
|
scm_misc_error (NULL, s_buggy_less, SCM_EOL);
|
1999-08-19 23:02:00 +00:00
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
if (left < right)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
SWAP (base_ptr[left], base_ptr[right]);
|
|
|
|
|
left++;
|
|
|
|
|
right--;
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
else if (left == right)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
left++;
|
|
|
|
|
right--;
|
1999-01-10 07:57:58 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
while (left <= right);
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
/* Set up pointers for next iteration. First determine whether
|
|
|
|
|
left and right partitions are below the threshold size. If so,
|
|
|
|
|
ignore one or both. Otherwise, push the larger partition's
|
|
|
|
|
bounds on the stack and continue sorting the smaller one. */
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
if ((size_t) (right - lo) <= MAX_THRESH)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
if ((size_t) (hi - left) <= MAX_THRESH)
|
1999-01-10 07:57:58 +00:00
|
|
|
/* Ignore both small partitions. */
|
|
|
|
|
POP (lo, hi);
|
|
|
|
|
else
|
|
|
|
|
/* Ignore small left partition. */
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
lo = left;
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
else if ((size_t) (hi - left) <= MAX_THRESH)
|
1999-01-10 07:57:58 +00:00
|
|
|
/* Ignore small right partition. */
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
hi = right;
|
|
|
|
|
else if ((right - lo) > (hi - left))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
/* Push larger left partition indices. */
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
PUSH (lo, right);
|
|
|
|
|
lo = left;
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Push larger right partition indices. */
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
PUSH (left, hi);
|
|
|
|
|
hi = right;
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
/* Once the BASE_PTR array is partially sorted by quicksort the rest is
|
|
|
|
|
completely sorted using insertion sort, since this is efficient for
|
|
|
|
|
partitions below MAX_THRESH size. BASE_PTR points to the beginning of the
|
|
|
|
|
array to sort, and END idexes the very last element in the array (*not*
|
|
|
|
|
one beyond it!). */
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
size_t tmp = 0;
|
|
|
|
|
size_t end = nr_elems - 1;
|
|
|
|
|
size_t thresh = min (end, MAX_THRESH);
|
|
|
|
|
size_t run;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
/* Find smallest element in first threshold and place it at the
|
|
|
|
|
array's beginning. This is the smallest array element,
|
|
|
|
|
and the operation speeds up insertion sort's inner loop. */
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
for (run = tmp + 1; run <= thresh; run++)
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, base_ptr[run], base_ptr[tmp])))
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
tmp = run;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
if (tmp != 0)
|
|
|
|
|
SWAP (base_ptr[tmp], base_ptr[0]);
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
/* Insertion sort, running from left-hand-side up to right-hand-side. */
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
run = 1;
|
|
|
|
|
while (++run <= end)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
tmp = run - 1;
|
2004-07-06 10:59:25 +00:00
|
|
|
while (scm_is_true ((*cmp) (less, base_ptr[run], base_ptr[tmp])))
|
1999-08-19 23:02:00 +00:00
|
|
|
{
|
|
|
|
|
/* The comparison predicate may be buggy */
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
if (tmp == 0)
|
* dynl.c, feature.c, filesys.c, fports.c, list.c, load.c,
net_db.c, sort.c, stacks.c, unif.c: Use SCM_WTA, SCM_MISC_ERROR
where possible.
* symbols.c (scm_sysintern0): Fixed the function name in a
scm_misc_error invocation.
* print.c (scm_simple_format): Do not need SCM_COERCE_SUBSTR, and
use scm_return_first to ward off latent GC bug that Mikael caught.
* async.c: Use SCM_VALIDATE_ASYNC_COPY one place where it wasn't
used before but should've been.
2000-01-11 23:56:47 +00:00
|
|
|
scm_misc_error (NULL, s_buggy_less, SCM_EOL);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
|
|
|
|
tmp--;
|
1999-08-19 23:02:00 +00:00
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
tmp++;
|
|
|
|
|
if (tmp != run)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
SCM to_insert = base_ptr[run];
|
|
|
|
|
size_t hi, lo;
|
|
|
|
|
|
|
|
|
|
for (hi = lo = run; --lo >= tmp; hi = lo)
|
|
|
|
|
base_ptr[hi] = base_ptr[lo];
|
|
|
|
|
base_ptr[hi] = to_insert;
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
static scm_t_trampoline_2
|
|
|
|
|
compare_function (SCM less, unsigned int arg_nr, const char* fname)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = scm_trampoline_2 (less);
|
|
|
|
|
SCM_ASSERT_TYPE (cmp != NULL, less, arg_nr, fname, "less predicate");
|
|
|
|
|
return cmp;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Question: Is there any need to make this a more general array sort?
|
|
|
|
|
It is probably enough to manage the vector type. */
|
|
|
|
|
/* endpos equal as for substring, i.e. endpos is not included. */
|
2000-01-26 01:17:16 +00:00
|
|
|
/* More natural with length? */
|
1999-12-12 02:36:16 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_restricted_vector_sort_x, "restricted-vector-sort!", 4, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM vec, SCM less, SCM startpos, SCM endpos),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the vector @var{vec}, using @var{less} for comparing\n"
|
|
|
|
|
"the vector elements. @var{startpos} and @var{endpos} delimit\n"
|
|
|
|
|
"the range of the vector which gets sorted. The return value\n"
|
|
|
|
|
"is not specified.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_restricted_vector_sort_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
|
|
|
|
size_t vlen, spos, len;
|
1999-01-10 07:57:58 +00:00
|
|
|
SCM *vp;
|
|
|
|
|
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_VECTOR (1, vec);
|
|
|
|
|
vp = SCM_WRITABLE_VELTS (vec); /* vector pointer */
|
2000-10-10 09:22:31 +00:00
|
|
|
vlen = SCM_VECTOR_LENGTH (vec);
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* validate.h, deprecated.h (SCM_VALIDATE_INUM, SCM_VALIDATE_INUM_COPY,
SCM_VALIDATE_BIGINT, SCM_VALIDATE_INUM_MIN,
SCM_VALIDATE_INUM_MIN_COPY,
SCM_VALIDATE_INUM_MIN_DEF_COPY,SCM_VALIDATE_INUM_DEF,
SCM_VALIDATE_INUM_DEF_COPY, SCM_VALIDATE_INUM_RANGE,
SCM_VALIDATE_INUM_RANGE_COPY): Deprecated because they make the
fixnum/bignum distinction visible. Changed all uses to scm_to_size_t
or similar.
2004-07-10 14:35:36 +00:00
|
|
|
spos = scm_to_unsigned_integer (startpos, 0, vlen);
|
|
|
|
|
len = scm_to_unsigned_integer (endpos, 0, vlen) - spos;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
quicksort (&vp[spos], len, cmp, less);
|
|
|
|
|
scm_remember_upto_here_1 (vec);
|
2002-07-20 14:08:34 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return SCM_UNSPECIFIED;
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
|
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
/* (sorted? sequence less?)
|
|
|
|
|
* is true when sequence is a list (x0 x1 ... xm) or a vector #(x0 ... xm)
|
|
|
|
|
* such that for all 1 <= i <= m,
|
|
|
|
|
* (not (less? (list-ref list i) (list-ref list (- i 1)))). */
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sorted_p, "sorted?", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Return @code{#t} iff @var{items} is a list or a vector such that\n"
|
|
|
|
|
"for all 1 <= i <= m, the predicate @var{less} returns true when\n"
|
|
|
|
|
"applied to all elements i - 1 and i")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sorted_p
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2001-05-26 20:51:22 +00:00
|
|
|
long len, j; /* list/vector length, temp j */
|
1999-01-10 07:57:58 +00:00
|
|
|
SCM item, rest; /* rest of items loop variable */
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM const *vp;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
1999-01-10 07:57:58 +00:00
|
|
|
return SCM_BOOL_T;
|
1999-12-12 02:36:16 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
if (SCM_CONSP (items))
|
|
|
|
|
{
|
|
|
|
|
len = scm_ilength (items); /* also checks that it's a pure list */
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_ASSERT_RANGE (1, items, len >= 0);
|
1999-01-10 07:57:58 +00:00
|
|
|
if (len <= 1)
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
|
|
|
|
item = SCM_CAR (items);
|
|
|
|
|
rest = SCM_CDR (items);
|
|
|
|
|
j = len - 1;
|
|
|
|
|
while (j > 0)
|
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (rest), item)))
|
1999-01-10 07:57:58 +00:00
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
item = SCM_CAR (rest);
|
|
|
|
|
rest = SCM_CDR (rest);
|
|
|
|
|
j--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-10-10 09:22:31 +00:00
|
|
|
SCM_VALIDATE_VECTOR (1, items);
|
|
|
|
|
|
|
|
|
|
vp = SCM_VELTS (items); /* vector pointer */
|
|
|
|
|
len = SCM_VECTOR_LENGTH (items);
|
|
|
|
|
j = len - 1;
|
|
|
|
|
while (j > 0)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, vp[1], vp[0])))
|
2000-10-10 09:22:31 +00:00
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
vp++;
|
|
|
|
|
j--;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
2000-10-10 09:22:31 +00:00
|
|
|
return SCM_BOOL_T;
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
2000-10-10 09:22:31 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
return SCM_BOOL_F;
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
|
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
/* (merge a b less?)
|
|
|
|
|
takes two lists a and b such that (sorted? a less?) and (sorted? b less?)
|
|
|
|
|
and returns a new list in which the elements of a and b have been stably
|
|
|
|
|
interleaved so that (sorted? (merge a b less?) less?).
|
|
|
|
|
Note: this does _not_ accept vectors. */
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_merge, "merge", 3, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM alist, SCM blist, SCM less),
|
2001-11-16 15:04:17 +00:00
|
|
|
"Merge two already sorted lists into one.\n"
|
|
|
|
|
"Given two lists @var{alist} and @var{blist}, such that\n"
|
|
|
|
|
"@code{(sorted? alist less?)} and @code{(sorted? blist less?)},\n"
|
|
|
|
|
"return a new list in which the elements of @var{alist} and\n"
|
2001-01-30 14:53:20 +00:00
|
|
|
"@var{blist} have been stably interleaved so that\n"
|
|
|
|
|
"@code{(sorted? (merge alist blist less?) less?)}.\n"
|
|
|
|
|
"Note: this does _not_ accept vectors.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_merge
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
SCM build;
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (alist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return blist;
|
2002-01-22 23:31:39 +00:00
|
|
|
else if (SCM_NULL_OR_NIL_P (blist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return alist;
|
|
|
|
|
else
|
|
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 3, FUNC_NAME);
|
|
|
|
|
long alen, blen; /* list lengths */
|
|
|
|
|
SCM last;
|
|
|
|
|
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_NONEMPTYLIST_COPYLEN (1, alist, alen);
|
|
|
|
|
SCM_VALIDATE_NONEMPTYLIST_COPYLEN (2, blist, blen);
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (blist), SCM_CAR (alist))))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
build = scm_cons (SCM_CAR (blist), SCM_EOL);
|
|
|
|
|
blist = SCM_CDR (blist);
|
|
|
|
|
blen--;
|
|
|
|
|
}
|
1999-01-11 11:34:33 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
build = scm_cons (SCM_CAR (alist), SCM_EOL);
|
|
|
|
|
alist = SCM_CDR (alist);
|
|
|
|
|
alen--;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
last = build;
|
|
|
|
|
while ((alen > 0) && (blen > 0))
|
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (blist), SCM_CAR (alist))))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
SCM_SETCDR (last, scm_cons (SCM_CAR (blist), SCM_EOL));
|
|
|
|
|
blist = SCM_CDR (blist);
|
|
|
|
|
blen--;
|
|
|
|
|
}
|
1999-01-11 11:34:33 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SCM_SETCDR (last, scm_cons (SCM_CAR (alist), SCM_EOL));
|
|
|
|
|
alist = SCM_CDR (alist);
|
|
|
|
|
alen--;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
last = SCM_CDR (last);
|
|
|
|
|
}
|
|
|
|
|
if ((alen > 0) && (blen == 0))
|
|
|
|
|
SCM_SETCDR (last, alist);
|
|
|
|
|
else if ((alen == 0) && (blen > 0))
|
|
|
|
|
SCM_SETCDR (last, blist);
|
|
|
|
|
}
|
|
|
|
|
return build;
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
static SCM
|
|
|
|
|
scm_merge_list_x (SCM alist, SCM blist,
|
|
|
|
|
long alen, long blen,
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_t_trampoline_2 cmp, SCM less)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
SCM build, last;
|
|
|
|
|
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (alist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return blist;
|
2002-01-22 23:31:39 +00:00
|
|
|
else if (SCM_NULL_OR_NIL_P (blist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return alist;
|
|
|
|
|
else
|
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (blist), SCM_CAR (alist))))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
build = blist;
|
|
|
|
|
blist = SCM_CDR (blist);
|
|
|
|
|
blen--;
|
|
|
|
|
}
|
1999-01-11 11:34:33 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
build = alist;
|
|
|
|
|
alist = SCM_CDR (alist);
|
|
|
|
|
alen--;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
last = build;
|
|
|
|
|
while ((alen > 0) && (blen > 0))
|
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, SCM_CAR (blist), SCM_CAR (alist))))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
SCM_SETCDR (last, blist);
|
|
|
|
|
blist = SCM_CDR (blist);
|
|
|
|
|
blen--;
|
|
|
|
|
}
|
1999-01-11 11:34:33 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SCM_SETCDR (last, alist);
|
|
|
|
|
alist = SCM_CDR (alist);
|
|
|
|
|
alen--;
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
last = SCM_CDR (last);
|
|
|
|
|
}
|
|
|
|
|
if ((alen > 0) && (blen == 0))
|
|
|
|
|
SCM_SETCDR (last, alist);
|
|
|
|
|
else if ((alen == 0) && (blen > 0))
|
|
|
|
|
SCM_SETCDR (last, blist);
|
|
|
|
|
}
|
|
|
|
|
return build;
|
|
|
|
|
} /* scm_merge_list_x */
|
|
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_merge_x, "merge!", 3, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM alist, SCM blist, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Takes two lists @var{alist} and @var{blist} such that\n"
|
|
|
|
|
"@code{(sorted? alist less?)} and @code{(sorted? blist less?)} and\n"
|
|
|
|
|
"returns a new list in which the elements of @var{alist} and\n"
|
|
|
|
|
"@var{blist} have been stably interleaved so that\n"
|
|
|
|
|
" @code{(sorted? (merge alist blist less?) less?)}.\n"
|
|
|
|
|
"This is the destructive variant of @code{merge}\n"
|
|
|
|
|
"Note: this does _not_ accept vectors.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_merge_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (alist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return blist;
|
2002-01-22 23:31:39 +00:00
|
|
|
else if (SCM_NULL_OR_NIL_P (blist))
|
1999-01-10 07:57:58 +00:00
|
|
|
return alist;
|
|
|
|
|
else
|
|
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 3, FUNC_NAME);
|
|
|
|
|
long alen, blen; /* list lengths */
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_NONEMPTYLIST_COPYLEN (1, alist, alen);
|
|
|
|
|
SCM_VALIDATE_NONEMPTYLIST_COPYLEN (2, blist, blen);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_x (alist, blist, alen, blen, cmp, less);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
|
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
/* This merge sort algorithm is same as slib's by Richard A. O'Keefe.
|
|
|
|
|
The algorithm is stable. We also tried to use the algorithm used by
|
|
|
|
|
scsh's merge-sort but that algorithm showed to not be stable, even
|
|
|
|
|
though it claimed to be.
|
|
|
|
|
*/
|
|
|
|
|
static SCM
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_merge_list_step (SCM * seq, scm_t_trampoline_2 cmp, SCM less, long n)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
1999-01-11 11:34:33 +00:00
|
|
|
SCM a, b;
|
|
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
if (n > 2)
|
|
|
|
|
{
|
2001-05-26 20:51:22 +00:00
|
|
|
long mid = n / 2;
|
1999-01-11 11:34:33 +00:00
|
|
|
a = scm_merge_list_step (seq, cmp, less, mid);
|
|
|
|
|
b = scm_merge_list_step (seq, cmp, less, n - mid);
|
|
|
|
|
return scm_merge_list_x (a, b, mid, n - mid, cmp, less);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
else if (n == 2)
|
|
|
|
|
{
|
|
|
|
|
SCM p = *seq;
|
|
|
|
|
SCM rest = SCM_CDR (*seq);
|
|
|
|
|
SCM x = SCM_CAR (*seq);
|
|
|
|
|
SCM y = SCM_CAR (SCM_CDR (*seq));
|
|
|
|
|
*seq = SCM_CDR (rest);
|
|
|
|
|
SCM_SETCDR (rest, SCM_EOL);
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, y, x)))
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2000-06-05 12:09:35 +00:00
|
|
|
SCM_SETCAR (p, y);
|
|
|
|
|
SCM_SETCAR (rest, x);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
else if (n == 1)
|
|
|
|
|
{
|
|
|
|
|
SCM p = *seq;
|
|
|
|
|
*seq = SCM_CDR (p);
|
|
|
|
|
SCM_SETCDR (p, SCM_EOL);
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return SCM_EOL;
|
|
|
|
|
} /* scm_merge_list_step */
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sort_x, "sort!", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the sequence @var{items}, which may be a list or a\n"
|
|
|
|
|
"vector. @var{less} is used for comparing the sequence\n"
|
|
|
|
|
"elements. The sorting is destructive, that means that the\n"
|
|
|
|
|
"input sequence is modified to produce the sorted result.\n"
|
|
|
|
|
"This is not a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sort_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2001-05-26 20:51:22 +00:00
|
|
|
long len; /* list/vector length */
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
|
|
|
|
return items;
|
2000-10-10 09:22:31 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
if (SCM_CONSP (items))
|
|
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
else if (SCM_VECTORP (items))
|
|
|
|
|
{
|
2000-10-10 09:22:31 +00:00
|
|
|
len = SCM_VECTOR_LENGTH (items);
|
1999-01-10 07:57:58 +00:00
|
|
|
scm_restricted_vector_sort_x (items,
|
|
|
|
|
less,
|
2004-07-23 15:43:02 +00:00
|
|
|
scm_from_int (0),
|
|
|
|
|
scm_from_long (len));
|
1999-01-10 07:57:58 +00:00
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
else
|
2001-03-04 22:48:13 +00:00
|
|
|
SCM_WRONG_TYPE_ARG (1, items);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
1999-12-12 02:36:16 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sort, "sort", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the sequence @var{items}, which may be a list or a\n"
|
|
|
|
|
"vector. @var{less} is used for comparing the sequence\n"
|
|
|
|
|
"elements. This is not a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sort
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
|
|
|
|
return items;
|
2000-10-10 09:22:31 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
if (SCM_CONSP (items))
|
|
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2001-05-26 20:51:22 +00:00
|
|
|
long len;
|
2001-03-17 21:20:20 +00:00
|
|
|
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
items = scm_list_copy (items);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
2003-03-27 20:09:46 +00:00
|
|
|
#if SCM_HAVE_ARRAYS
|
* acconfig.h: add HAVE_ARRAYS.
* configure.in: add --disable-arrays option, probably temporary.
* the following changes allow guile to be built with the array
"module" omitted. some of this stuff is just tc7 type support,
which wouldn't be needed if uniform array types were converted
to smobs.
* tag.c (scm_utag_bvect ... scm_utag_cvect): don't define unless
HAVE_ARRAYS.
(scm_tag): don't check array types unless HAVE_ARRAYS.
* sort.c (scm_restricted_vector_sort_x, scm_sorted_p):
remove the unused array types.
* (scm_stable_sort, scm_sort): don't support vectors if not
HAVE_ARRAYS. a bit excessive.
* random.c (vector_scale, vector_sum_squares,
scm_random_solid_sphere_x, scm_random_hollow_sphere_x,
scm_random_normal_vector_x): don't define unless HAVE_ARRAYS.
* gh_data.c (makvect, gh_chars2byvect, gh_shorts2svect,
gh_longs2ivect, gh_ulongs2uvect, gh_floats2fvect, gh_doubles2dvect,
gh_uniform_vector_length, gh_uniform_vector_ref):
don't define unless HAVE_ARRAYS.
(gh_scm2chars, gh_scm2shorts, gh_scm2longs, gh_scm2floats,
gh_scm2doubles):
don't check vector types if not HAVE_ARRAYS.
* eq.c (scm_equal_p), eval.c (SCM_CEVAL), print.c (scm_iprin1),
gc.c (scm_gc_mark, scm_gc_sweep), objects.c (scm_class_of):
don't support the array types unless HAVE_ARRAYS is defined.
* tags.h: make nine tc7 types conditional on HAVE_ARRAYS.
* read.c (scm_lreadr): don't check for #* unless HAVE_ARRAYS is
defined (this should use read-hash-extend).
* ramap.c, unif.c: don't check whether ARRAYS is defined.
* vectors.c (scm_vector_set_length_x): moved here from unif.c. call
scm_uniform_element_size if HAVE_ARRAYS.
vectors.h: prototype too.
* unif.c (scm_uniform_element_size): new procedure.
* init.c (scm_boot_guile_1): don't call scm_init_ramap or
scm_init_unif unless HAVE_ARRAYS is defined.
* __scm.h: don't define ARRAYS.
* Makefile.am (EXTRA_libguile_la_SOURCES): unif.c and ramap.c
moved here from libguile_la_SOURCES.
* Makefile.am (ice9_sources): add arrays.scm.
* boot-9.scm: load arrays.scm if 'array is provided.
* arrays.scm: new file with stuff from boot-9.scm.
1999-11-19 18:16:19 +00:00
|
|
|
/* support ordinary vectors even if arrays not available? */
|
1999-01-10 07:57:58 +00:00
|
|
|
else if (SCM_VECTORP (items))
|
|
|
|
|
{
|
2001-05-26 20:51:22 +00:00
|
|
|
long len = SCM_VECTOR_LENGTH (items);
|
2001-03-17 21:20:20 +00:00
|
|
|
SCM sortvec = scm_make_uve (len, scm_array_prototype (items));
|
|
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
scm_array_copy_x (items, sortvec);
|
|
|
|
|
scm_restricted_vector_sort_x (sortvec,
|
|
|
|
|
less,
|
2004-07-23 15:43:02 +00:00
|
|
|
scm_from_int (0),
|
|
|
|
|
scm_from_long (len));
|
1999-01-10 07:57:58 +00:00
|
|
|
return sortvec;
|
|
|
|
|
}
|
* acconfig.h: add HAVE_ARRAYS.
* configure.in: add --disable-arrays option, probably temporary.
* the following changes allow guile to be built with the array
"module" omitted. some of this stuff is just tc7 type support,
which wouldn't be needed if uniform array types were converted
to smobs.
* tag.c (scm_utag_bvect ... scm_utag_cvect): don't define unless
HAVE_ARRAYS.
(scm_tag): don't check array types unless HAVE_ARRAYS.
* sort.c (scm_restricted_vector_sort_x, scm_sorted_p):
remove the unused array types.
* (scm_stable_sort, scm_sort): don't support vectors if not
HAVE_ARRAYS. a bit excessive.
* random.c (vector_scale, vector_sum_squares,
scm_random_solid_sphere_x, scm_random_hollow_sphere_x,
scm_random_normal_vector_x): don't define unless HAVE_ARRAYS.
* gh_data.c (makvect, gh_chars2byvect, gh_shorts2svect,
gh_longs2ivect, gh_ulongs2uvect, gh_floats2fvect, gh_doubles2dvect,
gh_uniform_vector_length, gh_uniform_vector_ref):
don't define unless HAVE_ARRAYS.
(gh_scm2chars, gh_scm2shorts, gh_scm2longs, gh_scm2floats,
gh_scm2doubles):
don't check vector types if not HAVE_ARRAYS.
* eq.c (scm_equal_p), eval.c (SCM_CEVAL), print.c (scm_iprin1),
gc.c (scm_gc_mark, scm_gc_sweep), objects.c (scm_class_of):
don't support the array types unless HAVE_ARRAYS is defined.
* tags.h: make nine tc7 types conditional on HAVE_ARRAYS.
* read.c (scm_lreadr): don't check for #* unless HAVE_ARRAYS is
defined (this should use read-hash-extend).
* ramap.c, unif.c: don't check whether ARRAYS is defined.
* vectors.c (scm_vector_set_length_x): moved here from unif.c. call
scm_uniform_element_size if HAVE_ARRAYS.
vectors.h: prototype too.
* unif.c (scm_uniform_element_size): new procedure.
* init.c (scm_boot_guile_1): don't call scm_init_ramap or
scm_init_unif unless HAVE_ARRAYS is defined.
* __scm.h: don't define ARRAYS.
* Makefile.am (EXTRA_libguile_la_SOURCES): unif.c and ramap.c
moved here from libguile_la_SOURCES.
* Makefile.am (ice9_sources): add arrays.scm.
* boot-9.scm: load arrays.scm if 'array is provided.
* arrays.scm: new file with stuff from boot-9.scm.
1999-11-19 18:16:19 +00:00
|
|
|
#endif
|
1999-01-10 07:57:58 +00:00
|
|
|
else
|
2001-03-04 22:48:13 +00:00
|
|
|
SCM_WRONG_TYPE_ARG (1, items);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
static void
|
2002-07-21 17:46:23 +00:00
|
|
|
scm_merge_vector_x (SCM vec,
|
|
|
|
|
SCM * temp,
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_t_trampoline_2 cmp,
|
1999-01-10 07:57:58 +00:00
|
|
|
SCM less,
|
2001-05-26 20:51:22 +00:00
|
|
|
long low,
|
|
|
|
|
long mid,
|
|
|
|
|
long high)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
2001-05-26 20:51:22 +00:00
|
|
|
long it; /* Index for temp vector */
|
|
|
|
|
long i1 = low; /* Index for lower vector segment */
|
|
|
|
|
long i2 = mid + 1; /* Index for upper vector segment */
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
/* Copy while both segments contain more characters */
|
|
|
|
|
for (it = low; (i1 <= mid) && (i2 <= high); ++it)
|
2002-07-21 17:46:23 +00:00
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
Every call of LESS might invoke GC. For full correctness, we
|
|
|
|
|
should reset the generation of vecbase and tempbase between
|
|
|
|
|
every call of less.
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2002-07-21 17:46:23 +00:00
|
|
|
*/
|
|
|
|
|
register SCM *vp = SCM_WRITABLE_VELTS(vec);
|
|
|
|
|
|
2004-07-06 10:59:25 +00:00
|
|
|
if (scm_is_true ((*cmp) (less, vp[i2], vp[i1])))
|
2002-07-21 17:46:23 +00:00
|
|
|
temp[it] = vp[i2++];
|
|
|
|
|
else
|
|
|
|
|
temp[it] = vp[i1++];
|
|
|
|
|
}
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2002-07-21 17:46:23 +00:00
|
|
|
{
|
|
|
|
|
register SCM *vp = SCM_WRITABLE_VELTS(vec);
|
|
|
|
|
|
|
|
|
|
/* Copy while first segment contains more characters */
|
|
|
|
|
while (i1 <= mid)
|
|
|
|
|
temp[it++] = vp[i1++];
|
|
|
|
|
|
|
|
|
|
/* Copy while second segment contains more characters */
|
|
|
|
|
while (i2 <= high)
|
|
|
|
|
temp[it++] = vp[i2++];
|
|
|
|
|
|
|
|
|
|
/* Copy back from temp to vp */
|
|
|
|
|
for (it = low; it <= high; ++it)
|
|
|
|
|
vp[it] = temp[it];
|
|
|
|
|
}
|
|
|
|
|
} /* scm_merge_vector_x */
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
static void
|
2002-07-21 17:46:23 +00:00
|
|
|
scm_merge_vector_step (SCM vp,
|
|
|
|
|
SCM * temp,
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_t_trampoline_2 cmp,
|
1999-01-10 07:57:58 +00:00
|
|
|
SCM less,
|
2001-05-26 20:51:22 +00:00
|
|
|
long low,
|
|
|
|
|
long high)
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
|
|
|
|
if (high > low)
|
|
|
|
|
{
|
2001-05-26 20:51:22 +00:00
|
|
|
long mid = (low + high) / 2;
|
1999-01-10 07:57:58 +00:00
|
|
|
scm_merge_vector_step (vp, temp, cmp, less, low, mid);
|
|
|
|
|
scm_merge_vector_step (vp, temp, cmp, less, mid+1, high);
|
|
|
|
|
scm_merge_vector_x (vp, temp, cmp, less, low, mid, high);
|
|
|
|
|
}
|
|
|
|
|
} /* scm_merge_vector_step */
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_stable_sort_x, "stable-sort!", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the sequence @var{items}, which may be a list or a\n"
|
|
|
|
|
"vector. @var{less} is used for comparing the sequence elements.\n"
|
|
|
|
|
"The sorting is destructive, that means that the input sequence\n"
|
|
|
|
|
"is modified to produce the sorted result.\n"
|
|
|
|
|
"This is a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_stable_sort_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2001-05-26 20:51:22 +00:00
|
|
|
long len; /* list/vector length */
|
1999-01-10 07:57:58 +00:00
|
|
|
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
|
|
|
|
return items;
|
2000-10-10 09:22:31 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
if (SCM_CONSP (items))
|
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
|
|
|
|
else if (SCM_VECTORP (items))
|
|
|
|
|
{
|
2002-07-21 17:46:23 +00:00
|
|
|
SCM *temp;
|
2000-10-10 09:22:31 +00:00
|
|
|
len = SCM_VECTOR_LENGTH (items);
|
2002-07-20 14:08:34 +00:00
|
|
|
|
|
|
|
|
/*
|
2002-07-21 17:46:23 +00:00
|
|
|
the following array does not contain any new references to
|
|
|
|
|
SCM objects, so we can get away with allocing it on the heap.
|
|
|
|
|
*/
|
2002-08-16 22:01:10 +00:00
|
|
|
temp = scm_malloc (len * sizeof(SCM));
|
2002-07-20 14:08:34 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_merge_vector_step (items, temp, cmp, less, 0, len - 1);
|
1999-01-10 07:57:58 +00:00
|
|
|
free(temp);
|
|
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
else
|
2001-03-04 22:48:13 +00:00
|
|
|
SCM_WRONG_TYPE_ARG (1, items);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_stable_sort, "stable-sort", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the sequence @var{items}, which may be a list or a\n"
|
|
|
|
|
"vector. @var{less} is used for comparing the sequence elements.\n"
|
|
|
|
|
"This is a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_stable_sort
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2002-07-21 17:46:23 +00:00
|
|
|
|
2002-01-22 23:31:39 +00:00
|
|
|
if (SCM_NULL_OR_NIL_P (items))
|
|
|
|
|
return items;
|
2000-10-10 09:22:31 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
if (SCM_CONSP (items))
|
|
|
|
|
{
|
2002-07-21 17:46:23 +00:00
|
|
|
long len; /* list/vector length */
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
items = scm_list_copy (items);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
}
|
2003-03-27 20:09:46 +00:00
|
|
|
#if SCM_HAVE_ARRAYS
|
* acconfig.h: add HAVE_ARRAYS.
* configure.in: add --disable-arrays option, probably temporary.
* the following changes allow guile to be built with the array
"module" omitted. some of this stuff is just tc7 type support,
which wouldn't be needed if uniform array types were converted
to smobs.
* tag.c (scm_utag_bvect ... scm_utag_cvect): don't define unless
HAVE_ARRAYS.
(scm_tag): don't check array types unless HAVE_ARRAYS.
* sort.c (scm_restricted_vector_sort_x, scm_sorted_p):
remove the unused array types.
* (scm_stable_sort, scm_sort): don't support vectors if not
HAVE_ARRAYS. a bit excessive.
* random.c (vector_scale, vector_sum_squares,
scm_random_solid_sphere_x, scm_random_hollow_sphere_x,
scm_random_normal_vector_x): don't define unless HAVE_ARRAYS.
* gh_data.c (makvect, gh_chars2byvect, gh_shorts2svect,
gh_longs2ivect, gh_ulongs2uvect, gh_floats2fvect, gh_doubles2dvect,
gh_uniform_vector_length, gh_uniform_vector_ref):
don't define unless HAVE_ARRAYS.
(gh_scm2chars, gh_scm2shorts, gh_scm2longs, gh_scm2floats,
gh_scm2doubles):
don't check vector types if not HAVE_ARRAYS.
* eq.c (scm_equal_p), eval.c (SCM_CEVAL), print.c (scm_iprin1),
gc.c (scm_gc_mark, scm_gc_sweep), objects.c (scm_class_of):
don't support the array types unless HAVE_ARRAYS is defined.
* tags.h: make nine tc7 types conditional on HAVE_ARRAYS.
* read.c (scm_lreadr): don't check for #* unless HAVE_ARRAYS is
defined (this should use read-hash-extend).
* ramap.c, unif.c: don't check whether ARRAYS is defined.
* vectors.c (scm_vector_set_length_x): moved here from unif.c. call
scm_uniform_element_size if HAVE_ARRAYS.
vectors.h: prototype too.
* unif.c (scm_uniform_element_size): new procedure.
* init.c (scm_boot_guile_1): don't call scm_init_ramap or
scm_init_unif unless HAVE_ARRAYS is defined.
* __scm.h: don't define ARRAYS.
* Makefile.am (EXTRA_libguile_la_SOURCES): unif.c and ramap.c
moved here from libguile_la_SOURCES.
* Makefile.am (ice9_sources): add arrays.scm.
* boot-9.scm: load arrays.scm if 'array is provided.
* arrays.scm: new file with stuff from boot-9.scm.
1999-11-19 18:16:19 +00:00
|
|
|
/* support ordinary vectors even if arrays not available? */
|
1999-01-10 07:57:58 +00:00
|
|
|
else if (SCM_VECTORP (items))
|
|
|
|
|
{
|
2002-07-21 17:46:23 +00:00
|
|
|
long len = SCM_VECTOR_LENGTH (items);
|
2002-08-16 22:01:10 +00:00
|
|
|
SCM *temp = scm_malloc (len * sizeof (SCM));
|
2002-07-21 17:46:23 +00:00
|
|
|
SCM retvec = scm_make_uve (len, scm_array_prototype (items));
|
1999-01-10 07:57:58 +00:00
|
|
|
scm_array_copy_x (items, retvec);
|
2002-07-20 14:08:34 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
scm_merge_vector_step (retvec, temp, cmp, less, 0, len - 1);
|
1999-01-10 07:57:58 +00:00
|
|
|
free (temp);
|
|
|
|
|
return retvec;
|
|
|
|
|
}
|
* acconfig.h: add HAVE_ARRAYS.
* configure.in: add --disable-arrays option, probably temporary.
* the following changes allow guile to be built with the array
"module" omitted. some of this stuff is just tc7 type support,
which wouldn't be needed if uniform array types were converted
to smobs.
* tag.c (scm_utag_bvect ... scm_utag_cvect): don't define unless
HAVE_ARRAYS.
(scm_tag): don't check array types unless HAVE_ARRAYS.
* sort.c (scm_restricted_vector_sort_x, scm_sorted_p):
remove the unused array types.
* (scm_stable_sort, scm_sort): don't support vectors if not
HAVE_ARRAYS. a bit excessive.
* random.c (vector_scale, vector_sum_squares,
scm_random_solid_sphere_x, scm_random_hollow_sphere_x,
scm_random_normal_vector_x): don't define unless HAVE_ARRAYS.
* gh_data.c (makvect, gh_chars2byvect, gh_shorts2svect,
gh_longs2ivect, gh_ulongs2uvect, gh_floats2fvect, gh_doubles2dvect,
gh_uniform_vector_length, gh_uniform_vector_ref):
don't define unless HAVE_ARRAYS.
(gh_scm2chars, gh_scm2shorts, gh_scm2longs, gh_scm2floats,
gh_scm2doubles):
don't check vector types if not HAVE_ARRAYS.
* eq.c (scm_equal_p), eval.c (SCM_CEVAL), print.c (scm_iprin1),
gc.c (scm_gc_mark, scm_gc_sweep), objects.c (scm_class_of):
don't support the array types unless HAVE_ARRAYS is defined.
* tags.h: make nine tc7 types conditional on HAVE_ARRAYS.
* read.c (scm_lreadr): don't check for #* unless HAVE_ARRAYS is
defined (this should use read-hash-extend).
* ramap.c, unif.c: don't check whether ARRAYS is defined.
* vectors.c (scm_vector_set_length_x): moved here from unif.c. call
scm_uniform_element_size if HAVE_ARRAYS.
vectors.h: prototype too.
* unif.c (scm_uniform_element_size): new procedure.
* init.c (scm_boot_guile_1): don't call scm_init_ramap or
scm_init_unif unless HAVE_ARRAYS is defined.
* __scm.h: don't define ARRAYS.
* Makefile.am (EXTRA_libguile_la_SOURCES): unif.c and ramap.c
moved here from libguile_la_SOURCES.
* Makefile.am (ice9_sources): add arrays.scm.
* boot-9.scm: load arrays.scm if 'array is provided.
* arrays.scm: new file with stuff from boot-9.scm.
1999-11-19 18:16:19 +00:00
|
|
|
#endif
|
1999-01-10 07:57:58 +00:00
|
|
|
else
|
2001-03-04 22:48:13 +00:00
|
|
|
SCM_WRONG_TYPE_ARG (1, items);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sort_list_x, "sort-list!", 2, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
(SCM items, SCM less),
|
2001-01-30 14:53:20 +00:00
|
|
|
"Sort the list @var{items}, using @var{less} for comparing the\n"
|
|
|
|
|
"list elements. The sorting is destructive, that means that the\n"
|
|
|
|
|
"input list is modified to produce the sorted result.\n"
|
|
|
|
|
"This is a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sort_list_x
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2001-05-26 20:51:22 +00:00
|
|
|
long len;
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
SCM_DEFINE (scm_sort_list, "sort-list", 2, 0, 0,
|
2001-01-30 14:53:20 +00:00
|
|
|
(SCM items, SCM less),
|
|
|
|
|
"Sort the list @var{items}, using @var{less} for comparing the\n"
|
|
|
|
|
"list elements. This is a stable sort.")
|
1999-12-12 02:36:16 +00:00
|
|
|
#define FUNC_NAME s_scm_sort_list
|
1999-01-10 07:57:58 +00:00
|
|
|
{
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
const scm_t_trampoline_2 cmp = compare_function (less, 2, FUNC_NAME);
|
2001-05-26 20:51:22 +00:00
|
|
|
long len;
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
2002-07-20 14:08:34 +00:00
|
|
|
SCM_VALIDATE_LIST_COPYLEN (1, items, len);
|
1999-01-10 07:57:58 +00:00
|
|
|
items = scm_list_copy (items);
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
return scm_merge_list_step (&items, cmp, less, len);
|
1999-12-12 02:36:16 +00:00
|
|
|
}
|
2000-01-11 21:47:57 +00:00
|
|
|
#undef FUNC_NAME
|
1999-01-10 07:57:58 +00:00
|
|
|
|
* test-suite/tests/sort.test: Added. Both tests in that file did
fail (one even with a segfault) with CVS guile before the recent
changes to libguile/sort.c.
* libguile/sort.c: Replaced hand-made trampline code by the new
official mechanism from eval.c. This fixes a segfault in the new
test file test-suite/tests/sort.test.
(quicksort, compare_function, scm_restricted_vector_sort_x,
scm_sorted_p, scm_merge, scm_merge_list_x, scm_merge_x,
scm_merge_list_step, scm_sort_x, scm_sort, scm_merge_vector_x,
scm_merge_vector_step, scm_stable_sort_x, scm_stable_sort,
scm_sort_list_x, scm_sort_list): Use trampoline mechanism from
eval.c.
(subr2less, lsubrless, closureless, applyless, scm_cmp_function,
cmp_fun_t): Removed.
(compare_function): Added.
* libguile/sort.c (quicksort, SWAP, stack_node): Replaced pointer
arithmetics with index arithmetics. Changed quicksort to work on
an array of SCM values instead of an array of characters. Avoid
bytewise copying of SCM elements. Avoid allocating memory on the
stack with alloca. Fixed some comments.
2003-04-22 23:32:40 +00:00
|
|
|
|
1999-01-10 07:57:58 +00:00
|
|
|
void
|
|
|
|
|
scm_init_sort ()
|
|
|
|
|
{
|
2000-04-21 14:16:44 +00:00
|
|
|
#include "libguile/sort.x"
|
1999-01-10 07:57:58 +00:00
|
|
|
|
|
|
|
|
scm_add_feature ("sort");
|
|
|
|
|
}
|
2000-03-19 19:01:16 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Local Variables:
|
|
|
|
|
c-file-style: "gnu"
|
|
|
|
|
End:
|
|
|
|
|
*/
|