<commit_before>(in-package #:first-class-lambda-lists)

(defclass parameter () ())

(defgeneric fcll:unparse (object))

(defmethod print-object ((parameter parameter) stream)
  (print-unreadable-object (parameter stream :type t)
    (prin1 (fcll:unparse parameter) stream)))

(defclass parameter-variable-mixin ()
  ((%variable :initarg :variable
              :reader variable)))

(defclass parameter-simple-variable-mixin (parameter-variable-mixin)
  ((%variable :type symbol)))

(defclass parameter-recursable-variable-mixin (parameter-variable-mixin)
  ((%variable :type (or symbol fcll:lambda-list))))

(defparameter *parse-recursable-variable*
  (lambda (variable)
    (declare (ignore variable))
    (error "Tried to parse a recursable variable in a non-recursive context.")))

(defun %parse-recursable-variable (variable)
  (etypecase variable
    (list (funcall *parse-recursable-variable* variable))
    (symbol variable)))

(defun %unparse-recursable-variable (variable-or-lambda-list)
  (etypecase variable-or-lambda-list
    (symbol variable-or-lambda-list)
    (fcll:lambda-list (unparse variable-or-lambda-list))))

(defclass parameter-initform-mixin ()
  ((%initform :initarg :initform
              :reader initform
              :type t)))

(defclass parameter-suppliedp-variable-mixin ()
  ((%suppliedp-variable :initarg :suppliedp-variable
                        :reader suppliedp-variable
                        :type symbol
                        :initform nil)))

(defclass simple-parameter (parameter parameter-simple-variable-mixin)
  ())

(defun %parse-simple-parameter (parameter)
  (check-type parameter symbol)
  (make-instance 'simple-parameter :variable parameter))

(defun %parse-simple-recursable-parameter (parameter)
  (make-instance 'simple-parameter :variable (%parse-recursable-variable parameter)))

(defmethod fcll:unparse ((parameter simple-parameter))
  (variable parameter))

(defclass required-parameter (parameter parameter-recursable-variable-mixin)
  ())

(defun %parse-required-parameter (parameter)
  (make-instance 'required-parameter :variable (%parse-recursable-variable parameter)))

(defmethod fcll:unparse ((parameter required-parameter))
  (%unparse-recursable-variable (variable parameter)))

(defclass specializable-parameter (required-parameter)
  ((%specializer :initarg :specializer
                 :reader specializer
                 :initform t)))

(defun %parse-specializable-parameter (parameter)
  (multiple-value-bind (variable specializer)
      (if (symbolp parameter)
          (values (or parameter (%parse-recursable-variable parameter))
                  t)
          (destructuring-bind (variable &optional (specializer t))
              parameter
            (values (%parse-recursable-variable variable) specializer)))
    (make-instance 'specializable-parameter
                   :variable variable
                   :specializer specializer)))

(defmethod fcll:unparse ((parameter specializable-parameter))
  (let ((variable (variable parameter))
        (specializer (specializer parameter)))
    (if (and (eq specializer t) (not (typep variable 'fcll:lambda-list)))
        variable
        (list (%unparse-recursable-variable variable) specializer))))

(defclass optional-parameter (parameter parameter-recursable-variable-mixin parameter-initform-mixin parameter-suppliedp-variable-mixin)
  ())

(defun %parse-optional-parameter (parameter)
  (multiple-value-bind (variable initform suppliedp-variable)
      (if (symbolp parameter)
          (values (or parameter (%parse-recursable-variable parameter))
                  nil
                  nil)
          (destructuring-bind (variable &optional initform suppliedp-variable)
              parameter
            (values (%parse-recursable-variable variable)
                    initform
                    suppliedp-variable)))
    (make-instance 'optional-parameter
                   :variable variable
                   :initform initform
                   :suppliedp-variable suppliedp-variable)))

(defmethod fcll:unparse ((parameter optional-parameter))
  (let ((variable (variable parameter))
        (initform (initform parameter))
        (suppliedp-variable (suppliedp-variable parameter)))
    (if (or initform suppliedp-variable (typep variable 'fcll:lambda-list))
        `(,(%unparse-recursable-variable variable)
          ,initform
          ,@(when suppliedp-variable (list suppliedp-variable)))
        variable)))

(defclass optional-no-defaulting-parameter (parameter parameter-simple-variable-mixin)
  ())

(defun %parse-optional-no-defaulting-parameter (parameter)
  (make-instance 'optional-no-defaulting-parameter
                 :variable (etypecase parameter
                             (symbol parameter)
                             ((cons symbol null)
                              (car parameter)))))

(defmethod fcll:unparse ((parameter optional-no-defaulting-parameter))
  (variable parameter))

(defclass parameter-keyword-name-mixin ()
  ((%keyword-name :initarg :keyword-name
                  :reader keyword-name
                  :type symbol)))

(defmethod shared-initialize :after ((instance parameter-keyword-name-mixin) slot-names &key)
  (unless (slot-boundp instance '%keyword-name)
    (setf (slot-value instance '%keyword-name)
          (%keywordize (variable instance)))))

(defclass key-parameter (parameter parameter-recursable-variable-mixin parameter-keyword-name-mixin
                                   parameter-initform-mixin parameter-suppliedp-variable-mixin)
  ())

(defun %keywordize (symbol)
  (intern (symbol-name symbol) '#:keyword))

(defun %parse-key-parameter (parameter)
  (multiple-value-bind (variable initform suppliedp-variable keyword-name)
      (if (symbolp parameter)
          (values (or parameter (%parse-recursable-variable parameter))
                  nil
                  nil
                  (%keywordize parameter))
          (destructuring-bind (variable-and/or-keyword-name &optional initform suppliedp-variable)
              parameter
            (multiple-value-bind (variable keyword-name)
                (if (symbolp variable-and/or-keyword-name)
                    (values (or variable-and/or-keyword-name
                                (%parse-recursable-variable variable-and/or-keyword-name))
                            (%keywordize variable-and/or-keyword-name))
                    (destructuring-bind (variable keyword-name) variable-and/or-keyword-name
                      (values (%parse-recursable-variable variable) keyword-name)))
              (values variable initform suppliedp-variable keyword-name))))
    (make-instance 'key-parameter
                   :variable variable
                   :initform initform
                   :suppliedp-variable suppliedp-variable
                   :keyword-name keyword-name)))

(defmethod fcll:unparse ((parameter key-parameter))
  (let ((variable (variable parameter))
        (keyword-name (keyword-name parameter))
        (initform (initform parameter))
        (suppliedp-variable (suppliedp-variable parameter)))
    (let ((custom-keyword-name-p (or (not (keywordp keyword-name))
                                     (string/= (symbol-name keyword-name)
                                               (symbol-name variable))))
          (recursivep :untested))
      ;; Do the "expensive" TYPEP only once, and only as a last resort.
      (if (or custom-keyword-name-p initform suppliedp-variable
              (setf recursivep (typep variable 'fcll:lambda-list)))
          `(,(if (or custom-keyword-name-p (if (eq recursivep :untested)
                                               (typep variable 'fcll:lambda-list)
                                               recursivep))
                 (list keyword-name (%unparse-recursable-variable variable))
                 variable)
             ,initform
             ,@(when suppliedp-variable (list suppliedp-variable)))
          variable))))

(defclass key-no-defaulting-parameter (parameter parameter-simple-variable-mixin parameter-keyword-name-mixin)
  ())

(defun %parse-key-no-defaulting-parameter (parameter)
  (multiple-value-bind (variable keyword-name)
      (if (symbolp parameter)
          (values parameter (%keywordize parameter))
          (destructuring-bind (variable-and/or-keyword-name)
              parameter
            (multiple-value-bind (variable keyword-name)
                (if (symbolp variable-and/or-keyword-name)
                    (values variable-and/or-keyword-name<commit_msg>Fix trivial unparsing canonicalization bugs.<commit_after>(in-package #:first-class-lambda-lists)

(defclass parameter () ())

(defgeneric fcll:unparse (object))

(defmethod print-object ((parameter parameter) stream)
  (print-unreadable-object (parameter stream :type t)
    (prin1 (fcll:unparse parameter) stream)))

(defclass parameter-variable-mixin ()
  ((%variable :initarg :variable
              :reader variable)))

(defclass parameter-simple-variable-mixin (parameter-variable-mixin)
  ((%variable :type symbol)))

(defclass parameter-recursable-variable-mixin (parameter-variable-mixin)
  ((%variable :type (or symbol fcll:lambda-list))))

(defparameter *parse-recursable-variable*
  (lambda (variable)
    (declare (ignore variable))
    (error "Tried to parse a recursable variable in a non-recursive context.")))

(defun %parse-recursable-variable (variable)
  (etypecase variable
    (list (funcall *parse-recursable-variable* variable))
    (symbol variable)))

(defun %unparse-recursable-variable (variable-or-lambda-list)
  (etypecase variable-or-lambda-list
    (symbol variable-or-lambda-list)
    (fcll:lambda-list (unparse variable-or-lambda-list))))

(defclass parameter-initform-mixin ()
  ((%initform :initarg :initform
              :reader initform
              :type t)))

(defclass parameter-suppliedp-variable-mixin ()
  ((%suppliedp-variable :initarg :suppliedp-variable
                        :reader suppliedp-variable
                        :type symbol
                        :initform nil)))

(defclass simple-parameter (parameter parameter-simple-variable-mixin)
  ())

(defun %parse-simple-parameter (parameter)
  (check-type parameter symbol)
  (make-instance 'simple-parameter :variable parameter))

(defun %parse-simple-recursable-parameter (parameter)
  (make-instance 'simple-parameter :variable (%parse-recursable-variable parameter)))

(defmethod fcll:unparse ((parameter simple-parameter))
  (variable parameter))

(defclass required-parameter (parameter parameter-recursable-variable-mixin)
  ())

(defun %parse-required-parameter (parameter)
  (make-instance 'required-parameter :variable (%parse-recursable-variable parameter)))

(defmethod fcll:unparse ((parameter required-parameter))
  (%unparse-recursable-variable (variable parameter)))

(defclass specializable-parameter (required-parameter)
  ((%specializer :initarg :specializer
                 :reader specializer
                 :initform t)))

(defun %parse-specializable-parameter (parameter)
  (multiple-value-bind (variable specializer)
      (if (symbolp parameter)
          (values (or parameter (%parse-recursable-variable parameter))
                  t)
          (destructuring-bind (variable &optional (specializer t))
              parameter
            (values (%parse-recursable-variable variable) specializer)))
    (make-instance 'specializable-parameter
                   :variable variable
                   :specializer specializer)))

(defmethod fcll:unparse ((parameter specializable-parameter))
  (let ((variable (variable parameter))
        (specializer (specializer parameter)))
    (if (and (eq specializer t) (not (typep variable 'fcll:lambda-list)))
        variable
        (list (%unparse-recursable-variable variable) specializer))))

(defclass optional-parameter (parameter parameter-recursable-variable-mixin parameter-initform-mixin parameter-suppliedp-variable-mixin)
  ())

(defun %parse-optional-parameter (parameter)
  (multiple-value-bind (variable initform suppliedp-variable)
      (if (symbolp parameter)
          (values (or parameter (%parse-recursable-variable parameter))
                  nil
                  nil)
          (destructuring-bind (variable &optional initform suppliedp-variable)
              parameter
            (values (%parse-recursable-variable variable)
                    initform
                    suppliedp-variable)))
    (make-instance 'optional-parameter
                   :variable variable
                   :initform initform
                   :suppliedp-variable suppliedp-variable)))

(defmethod fcll:unparse ((parameter optional-parameter))
  (let* ((variable (variable parameter))
         (initform (initform parameter))
         (suppliedp-variable (suppliedp-variable parameter))
         (initform-or-suppliedp (or initform suppliedp-variable)))
    (if (or initform-or-suppliedp (typep variable 'fcll:lambda-list))
        `(,(%unparse-recursable-variable variable)
          ,@(when initform-or-suppliedp (list initform))
          ,@(when suppliedp-variable (list suppliedp-variable)))
        variable)))

(defclass optional-no-defaulting-parameter (parameter parameter-simple-variable-mixin)
  ())

(defun %parse-optional-no-defaulting-parameter (parameter)
  (make-instance 'optional-no-defaulting-parameter
                 :variable (etypecase parameter
                             (symbol parameter)
                             ((cons symbol null)
                              (car parameter)))))

(defmethod fcll:unparse ((parameter optional-no-defaulting-parameter))
  (variable parameter))

(defclass parameter-keyword-name-mixin ()
  ((%keyword-name :initarg :keyword-name
                  :reader keyword-name
                  :type symbol)))

(defmethod shared-initialize :after ((instance parameter-keyword-name-mixin) slot-names &key)
  (unless (slot-boundp instance '%keyword-name)
    (setf (slot-value instance '%keyword-name)
          (%keywordize (variable instance)))))

(defclass key-parameter (parameter parameter-recursable-variable-mixin parameter-keyword-name-mixin
                                   parameter-initform-mixin parameter-suppliedp-variable-mixin)
  ())

(defun %keywordize (symbol)
  (intern (symbol-name symbol) '#:keyword))

(defun %parse-key-parameter (parameter)
  (multiple-value-bind (variable initform suppliedp-variable keyword-name)
      (if (symbolp parameter)
          (values (or parameter (%parse-recursable-variable parameter))
                  nil
                  nil
                  (%keywordize parameter))
          (destructuring-bind (variable-and/or-keyword-name &optional initform suppliedp-variable)
              parameter
            (multiple-value-bind (variable keyword-name)
                (if (symbolp variable-and/or-keyword-name)
                    (values (or variable-and/or-keyword-name
                                (%parse-recursable-variable variable-and/or-keyword-name))
                            (%keywordize variable-and/or-keyword-name))
                    (destructuring-bind (keyword-name variable) variable-and/or-keyword-name
                      (values (%parse-recursable-variable variable) keyword-name)))
              (values variable initform suppliedp-variable keyword-name))))
    (make-instance 'key-parameter
                   :variable variable
                   :initform initform
                   :suppliedp-variable suppliedp-variable
                   :keyword-name keyword-name)))

(defmethod fcll:unparse ((parameter key-parameter))
  (let ((variable (variable parameter))
        (keyword-name (keyword-name parameter))
        (initform (initform parameter))
        (suppliedp-variable (suppliedp-variable parameter)))
    (let ((custom-keyword-name-p (or (not (keywordp keyword-name))
                                     (string/= (symbol-name keyword-name)
                                               (symbol-name variable))))
          (recursivep :untested))
      ;; Do the "expensive" TYPEP only once, and only as a last resort.
      (if (or custom-keyword-name-p initform suppliedp-variable
              (setf recursivep (typep variable 'fcll:lambda-list)))
          `(,(if (or custom-keyword-name-p (if (eq recursivep :untested)
                                               (typep variable 'fcll:lambda-list)
                                               recursivep))
                 (list keyword-name (%unparse-recursable-variable variable))
                 variable)
             ,@(when (or initform suppliedp-variable) (list initform))
             ,@(when suppliedp-variable (list suppliedp-variable)))
          variable))))

(defclass key-no-defaulting-parameter (parameter parameter-simple-variable-mixin parameter-keyword-name-mixin)
  ())

(defun %parse-key-no-defaulting-parameter (parameter)
  (multiple-value-bind (variable keyword-name)
      (if (symbolp parameter)
          (values parameter (%keywordize parameter))
          (destructuring-bind (variable-and/or-keyword-name)
              parameter
            (multiple-value-bind (variable keyword-name)
                (if (symbolp variable-and/or-keyword-name)
                    (values variable-and/or-keyword-name
{'fraction_non_alphanumeric': 0.11089325875093708, 'fraction_numerical': 0.00011533360244507237, 'mean_word_length': 2.5587933511184073, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6171818', 'n_tokens_mistral': 4614, 'n_tokens_neox': 4461, 'n_words': 1046}