<commit_before>(in-package :cl-user)
(defpackage sxql.operator
  (:use :cl
        :sxql.sql-type)
  (:import-from :sxql.sql-type
                :sql-statement-p))
(in-package :sxql.operator)

(cl-syntax:use-syntax :annot)

(defmacro define-op ((op-name struct-type &key sql-op-name include-slots) &body body)
  (check-type op-name symbol)
  (let ((struct-name (intern (concatenate 'string (symbol-name op-name) #.(string :-op)))))
    `(defstruct (,struct-name (:include ,struct-type
                               (name ,(or sql-op-name
                                          (with-output-to-string (s)
                                            (loop for c across (symbol-name op-name)
                                                  if (char= c #\-)
                                                    do (write-char #\Space s)
                                                  else
                                                    do (write-char c s)))))
                               ,@include-slots)
                              (:constructor ,(intern (concatenate 'string
                                                                  #.(string :make-)
                                                                  (symbol-name op-name)
                                                                  #.(string :-op)))
                                  ,(ecase struct-type
                                     ((unary-op
                                       unary-splicing-op
                                       unary-postfix-op) '(var))
                                     ((infix-op
                                       infix-splicing-op
                                       infix-list-op) '(left right))
                                     (conjunctive-op '(&rest expressions)))))
       ,@body)))

(define-op (:not unary-op))
(define-op (:is-null unary-op))
(define-op (:not-null unary-op))
(define-op (:desc unary-postfix-op))
(define-op (:asc unary-postfix-op))
(define-op (:distinct unary-splicing-op))
(defstruct (on-op (:include sql-op (name "ON"))
                  (:constructor make-on-op (var)))
  (var nil :type =-op))

(define-op (:= infix-op))
(define-op (:!= infix-op))
(define-op (:< infix-op))
(define-op (:> infix-op))
(define-op (:<= infix-op))
(define-op (:>= infix-op))
(define-op (:as infix-splicing-op))
(define-op (:in infix-list-op))
(define-op (:not-in infix-list-op))
(define-op (:like infix-op))

(define-op (:or conjunctive-op))
(define-op (:and conjunctive-op))
(define-op (:+ conjunctive-op))
(define-op (:- conjunctive-op :sql-op-name "-"))
(define-op (:* conjunctive-op))
(define-op (:/ conjunctive-op))
(define-op (:% conjunctive-op))
(define-op (:union conjunctive-op))
(define-op (:union-all conjunctive-op))

(defstruct (raw-op (:include sql-op (name ""))
                   (:constructor make-raw-op (var)))
  (var nil :type (or string
                    sql-variable)))

@export
(defun find-constructor (name suffix &key (package *package*) (errorp t))
  (check-type name symbol)
  (let ((func-symbol (intern
                      (concatenate 'string
                                   #.(string :make-)
                                   (symbol-name name)
                                   suffix)
                      package)))
    (if (or errorp (fboundp func-symbol))
        (symbol-function func-symbol)
        nil)))

(defun find-make-op (op-name &optional (package *package*))
  (or (find-constructor op-name #.(string :-op)
                        :package package
                        :errorp nil)
      #'(lambda (&rest expressions)
          (apply #'make-function-op (symbol-name op-name) expressions))))

@export
(defun make-op (op-name &rest args)
  (apply (find-make-op op-name #.*package*)
         (mapcar #'detect-and-convert args)))

(defun has-lower-case-letters-p (symbol)
  "Take in a symbol, convert to string, look for presences of lower
case letters."
  (let* ((string (symbol-name symbol))
         (chars (loop for i from 0 to (1- (length string)) collect (char string i))))
    (flet ((upper-or-alpha (c)
             (or (upper-case-p c) (not (alpha-char-p c)))))
      (remove-if #'upper-or-alpha chars))))

@export
(defun detect-and-convert (object)
  (etypecase object
    ((or number
         string
         (vector (unsigned-byte 8)))
     (make-sql-variable object))
    (boolean object)<commit_msg>Refactor has-lower-case-letters-p.<commit_after>(in-package :cl-user)
(defpackage sxql.operator
  (:use :cl
        :sxql.sql-type)
  (:import-from :sxql.sql-type
                :sql-statement-p))
(in-package :sxql.operator)

(cl-syntax:use-syntax :annot)

(defmacro define-op ((op-name struct-type &key sql-op-name include-slots) &body body)
  (check-type op-name symbol)
  (let ((struct-name (intern (concatenate 'string (symbol-name op-name) #.(string :-op)))))
    `(defstruct (,struct-name (:include ,struct-type
                               (name ,(or sql-op-name
                                          (with-output-to-string (s)
                                            (loop for c across (symbol-name op-name)
                                                  if (char= c #\-)
                                                    do (write-char #\Space s)
                                                  else
                                                    do (write-char c s)))))
                               ,@include-slots)
                              (:constructor ,(intern (concatenate 'string
                                                                  #.(string :make-)
                                                                  (symbol-name op-name)
                                                                  #.(string :-op)))
                                  ,(ecase struct-type
                                     ((unary-op
                                       unary-splicing-op
                                       unary-postfix-op) '(var))
                                     ((infix-op
                                       infix-splicing-op
                                       infix-list-op) '(left right))
                                     (conjunctive-op '(&rest expressions)))))
       ,@body)))

(define-op (:not unary-op))
(define-op (:is-null unary-op))
(define-op (:not-null unary-op))
(define-op (:desc unary-postfix-op))
(define-op (:asc unary-postfix-op))
(define-op (:distinct unary-splicing-op))
(defstruct (on-op (:include sql-op (name "ON"))
                  (:constructor make-on-op (var)))
  (var nil :type =-op))

(define-op (:= infix-op))
(define-op (:!= infix-op))
(define-op (:< infix-op))
(define-op (:> infix-op))
(define-op (:<= infix-op))
(define-op (:>= infix-op))
(define-op (:as infix-splicing-op))
(define-op (:in infix-list-op))
(define-op (:not-in infix-list-op))
(define-op (:like infix-op))

(define-op (:or conjunctive-op))
(define-op (:and conjunctive-op))
(define-op (:+ conjunctive-op))
(define-op (:- conjunctive-op :sql-op-name "-"))
(define-op (:* conjunctive-op))
(define-op (:/ conjunctive-op))
(define-op (:% conjunctive-op))
(define-op (:union conjunctive-op))
(define-op (:union-all conjunctive-op))

(defstruct (raw-op (:include sql-op (name ""))
                   (:constructor make-raw-op (var)))
  (var nil :type (or string
                    sql-variable)))

@export
(defun find-constructor (name suffix &key (package *package*) (errorp t))
  (check-type name symbol)
  (let ((func-symbol (intern
                      (concatenate 'string
                                   #.(string :make-)
                                   (symbol-name name)
                                   suffix)
                      package)))
    (if (or errorp (fboundp func-symbol))
        (symbol-function func-symbol)
        nil)))

(defun find-make-op (op-name &optional (package *package*))
  (or (find-constructor op-name #.(string :-op)
                        :package package
                        :errorp nil)
      #'(lambda (&rest expressions)
          (apply #'make-function-op (symbol-name op-name) expressions))))

@export
(defun make-op (op-name &rest args)
  (apply (find-make-op op-name #.*package*)
         (mapcar #'detect-and-convert args)))

(defun has-lower-case-letters-p (symbol)
  "Take in a symbol, convert to string, look for presences of lower
case letters."
  (flet ((upper-or-not-alpha (c)
           (or (upper-case-p c) (not (alpha-char-p c)))))
    (not (every #'upper-or-not-alpha (symbol-name symbol)))))

@export
(defun detect-and-convert (object)
  (etypecase object
    ((or number
         string
         (vector (unsigned-byte 8)))
     (make-sql-variable object))
    (boolean object)
{'fraction_non_alphanumeric': 0.14644160583941607, 'fraction_numerical': 0.0004562043795620438, 'mean_word_length': 1.4223756906077347, 'pattern_counts': {'":': 0, '<': 7, '<?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': 58, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '720019', 'n_tokens_mistral': 2614, 'n_tokens_neox': 2465, 'n_words': 606}