extended-sequence.lisp - clic - Clic is an command line interactive client for gopher written in Common LISP (HTM) git clone git://bitreich.org/clic/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/clic/ (DIR) Log (DIR) Files (DIR) Refs (DIR) Tags (DIR) README (DIR) LICENSE --- extended-sequence.lisp (5232B) --- 1 ;;;; -*- Mode: Lisp; indent-tabs-mode: nil -*- 2 3 (in-package :split-sequence) 4 5 ;;; For extended sequences, we make the assumption that all extended sequences 6 ;;; can be at most ARRAY-DIMENSION-LIMIT long. This seems to match what SBCL 7 ;;; assumes about them. 8 9 ;;; TODO test this code. This will require creating such an extended sequence. 10 11 (deftype extended-sequence () 12 '(and sequence (not list) (not vector))) 13 14 (declaim (inline 15 split-extended-sequence split-extended-sequence-if split-extended-sequence-if-not 16 split-extended-sequence-from-end split-extended-sequence-from-start)) 17 18 (declaim (ftype (function (&rest t) (values list unsigned-byte)) 19 split-extended-sequence split-extended-sequence-if split-extended-sequence-if-not)) 20 21 (declaim (ftype (function (function extended-sequence array-index 22 (or null fixnum) (or null fixnum) boolean) 23 (values list fixnum)) 24 split-extended-sequence-from-start split-extended-sequence-from-end)) 25 26 (defun split-extended-sequence 27 (delimiter sequence start end from-end count remove-empty-subseqs test test-not key) 28 (cond 29 ((and (not from-end) (null test-not)) 30 (split-extended-sequence-from-start (lambda (sequence start) 31 (position delimiter sequence :start start :key key :test test)) 32 sequence start end count remove-empty-subseqs)) 33 ((and (not from-end) test-not) 34 (split-extended-sequence-from-start (lambda (sequence start) 35 (position delimiter sequence :start start :key key :test-not test-not)) 36 sequence start end count remove-empty-subseqs)) 37 ((and from-end (null test-not)) 38 (split-extended-sequence-from-end (lambda (sequence end) 39 (position delimiter sequence :end end :from-end t :key key :test test)) 40 sequence start end count remove-empty-subseqs)) 41 (t 42 (split-extended-sequence-from-end (lambda (sequence end) 43 (position delimiter sequence :end end :from-end t :key key :test-not test-not)) 44 sequence start end count remove-empty-subseqs)))) 45 46 (defun split-extended-sequence-if 47 (predicate sequence start end from-end count remove-empty-subseqs key) 48 (if from-end 49 (split-extended-sequence-from-end (lambda (sequence end) 50 (position-if predicate sequence :end end :from-end t :key key)) 51 sequence start end count remove-empty-subseqs) 52 (split-extended-sequence-from-start (lambda (sequence start) 53 (position-if predicate sequence :start start :key key)) 54 sequence start end count remove-empty-subseqs))) 55 56 (defun split-extended-sequence-if-not 57 (predicate sequence start end from-end count remove-empty-subseqs key) 58 (if from-end 59 (split-extended-sequence-from-end (lambda (sequence end) 60 (position-if-not predicate sequence :end end :from-end t :key key)) 61 sequence start end count remove-empty-subseqs) 62 (split-extended-sequence-from-start (lambda (sequence start) 63 (position-if-not predicate sequence :start start :key key)) 64 sequence start end count remove-empty-subseqs))) 65 66 (defun split-extended-sequence-from-end (position-fn sequence start end count remove-empty-subseqs) 67 (declare (optimize (speed 3) (debug 0)) 68 (type (function (extended-sequence fixnum) (or null fixnum)) position-fn)) 69 (loop 70 :with length = (length sequence) 71 :with end = (or end length) 72 :for right := end :then left 73 :for left := (max (or (funcall position-fn sequence right) -1) 74 (1- start)) 75 :unless (and (= right (1+ left)) remove-empty-subseqs) 76 :if (and count (>= nr-elts count)) 77 :return (values (nreverse subseqs) right) 78 :else 79 :collect (subseq sequence (1+ left) right) into subseqs 80 :and :sum 1 :into nr-elts :of-type fixnum 81 :until (< left start) 82 :finally (return (values (nreverse subseqs) (1+ left))))) 83 84 (defun split-extended-sequence-from-start (position-fn sequence start end count remove-empty-subseqs) 85 (declare (optimize (speed 3) (debug 0)) 86 (type (function (extended-sequence fixnum) (or null fixnum)) position-fn)) 87 (loop 88 :with length = (length sequence) 89 :with end = (or end length) 90 :for left := start :then (1+ right) 91 :for right := (min (or (funcall position-fn sequence left) length) 92 end) 93 :unless (and (= right left) remove-empty-subseqs) 94 :if (and count (>= nr-elts count)) 95 :return (values subseqs left) 96 :else 97 :collect (subseq sequence left right) :into subseqs 98 :and :sum 1 :into nr-elts :of-type fixnum 99 :until (>= right end) 100 :finally (return (values subseqs right))))