;;; Ikarus Scheme -- A compiler for R6RS Scheme. ;;; Copyright (C) 2006,2007 Abdulaziz Ghuloum ;;; ;;; This program is free software: you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License version 3 as ;;; published by the Free Software Foundation. ;;; ;;; This program 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 ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program. If not, see . (library (ikarus.sort) (export list-sort vector-sort vector-sort!) (import (except (ikarus) list-sort vector-sort vector-sort!)) (define (list-sort proc ls) (unless (procedure? proc) (die 'list-sort "not a procedure" proc)) (unless (list? ls) (die 'list-sort "not a list" ls)) (let ([v (list->vector ls)]) (vector-sort! proc v) (vector->list v))) (module (vector-sort vector-sort!) (module UNSAFE (fx? fx>=? fx=? fx+ fx- fxarithmetic-shift-right vector-ref vector-set!) (import (rename (ikarus system $vectors) ($vector-ref vector-ref) ($vector-set! vector-set!)) (rename (ikarus system $fx) ($fxsra fxarithmetic-shift-right) ($fx+ fx+) ($fx- fx-) ($fx< fx fx>?) ($fx>= fx>=?) ($fx<= fx<=?) ($fx= fx=?)))) (import UNSAFE) (define (copy-subrange! src dst si di dj) (vector-set! dst di (vector-ref src si)) (let ([di (fx+ di 1)]) (when (fx<=? di dj) (copy-subrange! src dst (fx+ si 1) di dj)))) (define (do-merge-a! proc src skr ri rj ai aj bi bj b0) (let ([a0 (vector-ref skr ai)] [ai (fx+ ai 1)]) (cond [(proc b0 a0) (vector-set! src ri b0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? bi bj) (do-merge-b! proc src skr ri rj ai aj bi bj a0)] [else (vector-set! src ri a0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? ri rj) (copy-subrange! skr src ai ri rj)]))]))] [else (vector-set! src ri a0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? ai aj) (do-merge-a! proc src skr ri rj ai aj bi bj b0)] [else (vector-set! src ri b0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? ri rj) (copy-subrange! skr src bi ri rj)]))]))]))) (define (do-merge-b! proc src skr ri rj ai aj bi bj a0) (let ([b0 (vector-ref skr bi)] [bi (fx+ bi 1)]) (cond [(proc b0 a0) (vector-set! src ri b0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? bi bj) (do-merge-b! proc src skr ri rj ai aj bi bj a0)] [else (vector-set! src ri a0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? ri rj) (copy-subrange! skr src ai ri rj)]))]))] [else (vector-set! src ri a0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? ai aj) (do-merge-a! proc src skr ri rj ai aj bi bj b0)] [else (vector-set! src ri b0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? ri rj) (copy-subrange! skr src bi ri rj)]))]))]))) (define (do-merge! proc src skr ri rj ai aj bi bj) (let ([a0 (vector-ref skr ai)] [b0 (vector-ref skr bi)] [ai (fx+ ai 1)] [bi (fx+ bi 1)]) (cond [(proc b0 a0) (vector-set! src ri b0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? bi bj) (do-merge-b! proc src skr ri rj ai aj bi bj a0)] [else (vector-set! src ri a0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? ri rj) (copy-subrange! skr src ai ri rj)]))]))] [else (vector-set! src ri a0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? ai aj) (do-merge-a! proc src skr ri rj ai aj bi bj b0)] [else (vector-set! src ri b0) (let ([ri (fx+ ri 1)]) (cond [(fx<=? ri rj) (copy-subrange! skr src bi ri rj)]))]))]))) (define (do-sort! proc src skr i k) ; sort src[i .. k] inclusive in place (cond [(fx