<commit_before>(in-package :serapeum)

(export '(parse-number
          parse-real-number
          parse-positive-real-number
          invalid-number
          invalid-number-reason
          invalid-number-value))

(export '(parse-float
          bits unbits
          round-to
          finc fdec
          shrink grow
          shrinkf growf
          random-in-range))

(defmacro finc (place &optional (delta 1))
  "Like `incf', but returns the old value instead of the new.

An alternative to using -1 as the starting value of a counter, which
can prevent optimization."
  (with-gensyms (old)
    `(let ((,old ,place))
       (setf ,place (+ ,old ,delta))
       ,old)))

(defmacro fdec (place &optional (delta 1))
  "Like `decf', but returns the old value instead of the new."
  (with-gensyms (old)
    `(let ((,old ,place))
       (setf ,place (- ,old ,delta))
       ,old)))

(defun parse-float (string &key (start 0) (end (length string)) junk-allowed)
  "Based on the venerable `parse-float' from the CMU Lisp repository.
Of course you could just use `parse-number', but sometimes only a
float will do."
  (declare (string string) (array-length start end))
  (let ((index (or (position-if-not #'whitespacep string
                                    :start start :end end)
                   (return-from parse-float (values 0.0 end))))
        (minusp nil) (decimalp nil) (found-digit nil)
        (before-decimal 0) (after-decimal 0) (decimal-counter 0)
        (exponent 0)
        (result 0)
        (radix 10))
    (declare (array-length index))
    (let ((char (char string index)))
      (cond ((char= char #\-)
             (setq minusp t)
             (incf index))
            ((char= char #\+)
             (incf index))))
    (loop
      until (= index end)
      for char = (char string index)
      as weight = (digit-char-p char radix)
      do (cond ((and weight (not decimalp))
                (setq before-decimal (+ weight (* before-decimal radix))
                      found-digit t))
               ((and weight decimalp)
                (setq after-decimal (+ weight (* after-decimal radix))
                      found-digit t)
                (incf decimal-counter))
               ((and (char= char #\.) (not decimalp))
                (setq decimalp t))
               ((and (case char ((#\e #\d #\f #\s #\l) t))
                     (= radix 10))
                (multiple-value-bind (num idx)
                    (parse-integer string :start (1+ index) :end end
                                          :radix radix :junk-allowed junk-allowed)
                  (setq exponent (or num 0)
                        index idx)
                  (when (= index end) (return nil))))
               ((whitespacep char)
                (when (position-if-not #'whitespacep string
                                       :start (1+ index) :end end)
                  (if junk-allowed
                      (loop-finish)
                      (error "There's junk in this string: ~s." string)))
                (return nil))
               (t (if junk-allowed
                      (loop-finish)
                      (error "There's junk in this string: ~s." string))))
         (incf index))
    (setq result (coerce (* (+ before-decimal
                               (* after-decimal
                                  (coerce (expt radix (- decimal-counter))
                                          'float)))
                            (coerce (expt radix exponent)
                                    'float))
                         'float))
    (values
     (if found-digit
         (if minusp (- result) result)
         0.0)
     index)))

(defsubst round-to (number &optional (divisor 1))
  "Like `round', but return the resulting number.

     (round 15 10) => 2
     (round-to 15 10) => 20"
  (* (round number divisor) divisor))

(defun bits (int &key big-endian)
  "Return a bit vector of the bits in INT.
Defaults to little-endian."
  (lret ((bits (make-array (integer-length int)
                           :element-type 'bit)))
    (if big-endian
        (loop for i below (integer-length int)
              for j downfrom (1- (integer-length int)) to 0
              do (setf (sbit bits j)
                       (if (logbitp i int)
                           1
                           0)))
        (loop for i below (integer-length int)
              do (setf (sbit bits i)
                       (if (logbitp i int)
                           1
                           0))))))

(defun unbits (bits &key big-endian)
  "Turn a sequence of BITS into an integer.
Defaults to little-endian."
  (declare (bit-vector bits))
  (if big-endian
      (reduce (lambda (x y)
                (+ (ash x 1) y))
              bits)
      (loop with int = 0
            for bit across bits
            for i from 0
            do (setf int (logior int (ash bit i)))
            finally (return int))))

(assert (let ((n (random most-positive-fixnum)))
          (= n (unbits (bits n)))))

(defun shrink (n by)
  "Decrease N by a factor."
  (- n (* n by)))

(defun grow (n by)
  "Increase N by a factor."
  (+ n (* n by)))

(define-modify-macro shrinkf (n) shrink
  "Shrink the value in a place by a factor.")

(define-modify-macro growf (n) shrink
  "Grow the value in a place by a factor.")
(defsubst random-in-range (low high)
  "Random number in the range [low,high).

From Zetalisp."
  (+ low (random (- high low))))<commit_msg>Fix growf.<commit_after>(in-package :serapeum)

(export '(parse-number
          parse-real-number
          parse-positive-real-number
          invalid-number
          invalid-number-reason
          invalid-number-value))

(export '(parse-float
          bits unbits
          round-to
          finc fdec
          shrink grow
          shrinkf growf
          random-in-range))

(defmacro finc (place &optional (delta 1))
  "Like `incf', but returns the old value instead of the new.

An alternative to using -1 as the starting value of a counter, which
can prevent optimization."
  (with-gensyms (old)
    `(let ((,old ,place))
       (setf ,place (+ ,old ,delta))
       ,old)))

(defmacro fdec (place &optional (delta 1))
  "Like `decf', but returns the old value instead of the new."
  (with-gensyms (old)
    `(let ((,old ,place))
       (setf ,place (- ,old ,delta))
       ,old)))

(defun parse-float (string &key (start 0) (end (length string)) junk-allowed)
  "Based on the venerable `parse-float' from the CMU Lisp repository.
Of course you could just use `parse-number', but sometimes only a
float will do."
  (declare (string string) (array-length start end))
  (let ((index (or (position-if-not #'whitespacep string
                                    :start start :end end)
                   (return-from parse-float (values 0.0 end))))
        (minusp nil) (decimalp nil) (found-digit nil)
        (before-decimal 0) (after-decimal 0) (decimal-counter 0)
        (exponent 0)
        (result 0)
        (radix 10))
    (declare (array-length index))
    (let ((char (char string index)))
      (cond ((char= char #\-)
             (setq minusp t)
             (incf index))
            ((char= char #\+)
             (incf index))))
    (loop
      until (= index end)
      for char = (char string index)
      as weight = (digit-char-p char radix)
      do (cond ((and weight (not decimalp))
                (setq before-decimal (+ weight (* before-decimal radix))
                      found-digit t))
               ((and weight decimalp)
                (setq after-decimal (+ weight (* after-decimal radix))
                      found-digit t)
                (incf decimal-counter))
               ((and (char= char #\.) (not decimalp))
                (setq decimalp t))
               ((and (case char ((#\e #\d #\f #\s #\l) t))
                     (= radix 10))
                (multiple-value-bind (num idx)
                    (parse-integer string :start (1+ index) :end end
                                          :radix radix :junk-allowed junk-allowed)
                  (setq exponent (or num 0)
                        index idx)
                  (when (= index end) (return nil))))
               ((whitespacep char)
                (when (position-if-not #'whitespacep string
                                       :start (1+ index) :end end)
                  (if junk-allowed
                      (loop-finish)
                      (error "There's junk in this string: ~s." string)))
                (return nil))
               (t (if junk-allowed
                      (loop-finish)
                      (error "There's junk in this string: ~s." string))))
         (incf index))
    (setq result (coerce (* (+ before-decimal
                               (* after-decimal
                                  (coerce (expt radix (- decimal-counter))
                                          'float)))
                            (coerce (expt radix exponent)
                                    'float))
                         'float))
    (values
     (if found-digit
         (if minusp (- result) result)
         0.0)
     index)))

(defsubst round-to (number &optional (divisor 1))
  "Like `round', but return the resulting number.

     (round 15 10) => 2
     (round-to 15 10) => 20"
  (* (round number divisor) divisor))

(defun bits (int &key big-endian)
  "Return a bit vector of the bits in INT.
Defaults to little-endian."
  (lret ((bits (make-array (integer-length int)
                           :element-type 'bit)))
    (if big-endian
        (loop for i below (integer-length int)
              for j downfrom (1- (integer-length int)) to 0
              do (setf (sbit bits j)
                       (if (logbitp i int)
                           1
                           0)))
        (loop for i below (integer-length int)
              do (setf (sbit bits i)
                       (if (logbitp i int)
                           1
                           0))))))

(defun unbits (bits &key big-endian)
  "Turn a sequence of BITS into an integer.
Defaults to little-endian."
  (declare (bit-vector bits))
  (if big-endian
      (reduce (lambda (x y)
                (+ (ash x 1) y))
              bits)
      (loop with int = 0
            for bit across bits
            for i from 0
            do (setf int (logior int (ash bit i)))
            finally (return int))))

(assert (let ((n (random most-positive-fixnum)))
          (= n (unbits (bits n)))))

(defun shrink (n by)
  "Decrease N by a factor."
  (- n (* n by)))

(defun grow (n by)
  "Increase N by a factor."
  (+ n (* n by)))

(define-modify-macro shrinkf (n) shrink
  "Shrink the value in a place by a factor.")

(define-modify-macro growf (n) grow
  "Grow the value in a place by a factor.")
(defsubst random-in-range (low high)
  "Random number in the range [low,high).

From Zetalisp."
  (+ low (random (- high low))))
{'fraction_non_alphanumeric': 0.11742666544823174, 'fraction_numerical': 0.007493374760120625, 'mean_word_length': 1.4799456152277362, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7337797', 'n_tokens_mistral': 3286, 'n_tokens_neox': 3100, 'n_words': 1104}