diff options
Diffstat (limited to 'src/tg/type-macros.lisp')
| -rw-r--r-- | src/tg/type-macros.lisp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/tg/type-macros.lisp b/src/tg/type-macros.lisp index ea35f48..02437ec 100644 --- a/src/tg/type-macros.lisp +++ b/src/tg/type-macros.lisp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | (:use :c2cl :iterate) | 5 | (:use :c2cl :iterate) |
| 6 | (:import-from :alexandria :make-keyword :symbolicate :with-gensyms) | 6 | (:import-from :alexandria :make-keyword :symbolicate :with-gensyms) |
| 7 | (:import-from :com.dieggsy.f-string :enable-f-strings) | 7 | (:import-from :com.dieggsy.f-string :enable-f-strings) |
| 8 | (:import-from :serapeum :->) | ||
| 8 | (:import-from :str) | 9 | (:import-from :str) |
| 9 | (:import-from :ukkoclot/src/serializing :parse-value) | 10 | (:import-from :ukkoclot/src/serializing :parse-value) |
| 10 | (:import-from :ukkoclot/src/hash-tables :gethash-lazy) | 11 | (:import-from :ukkoclot/src/hash-tables :gethash-lazy) |
| @@ -22,6 +23,7 @@ | |||
| 22 | (defparameter +unique+ (gensym)) | 23 | (defparameter +unique+ (gensym)) |
| 23 | 24 | ||
| 24 | ;; TODO: Fix optional-and-key ! | 25 | ;; TODO: Fix optional-and-key ! |
| 26 | (-> make-field (symbol t &optional t &key (:skip-if-default boolean)) field) | ||
| 25 | (defun make-field (name type ; lint:suppress avoid-optional-and-key | 27 | (defun make-field (name type ; lint:suppress avoid-optional-and-key |
| 26 | &optional (default +unique+) | 28 | &optional (default +unique+) |
| 27 | &key (skip-if-default (not (eq default +unique+)))) | 29 | &key (skip-if-default (not (eq default +unique+)))) |
| @@ -33,28 +35,36 @@ | |||
| 33 | :default default | 35 | :default default |
| 34 | :skip-if-default skip-if-default))) | 36 | :skip-if-default skip-if-default))) |
| 35 | 37 | ||
| 38 | (-> type-constructor (symbol) symbol) | ||
| 36 | (defun type-constructor (name) | 39 | (defun type-constructor (name) |
| 37 | (symbolicate "MAKE-" name)) | 40 | (symbolicate "MAKE-" name)) |
| 38 | 41 | ||
| 42 | (-> field-accessor (symbol field) symbol) | ||
| 39 | (defun field-accessor (name field) | 43 | (defun field-accessor (name field) |
| 40 | (symbolicate name "-" (field-name field))) | 44 | (symbolicate name "-" (field-name field))) |
| 41 | 45 | ||
| 46 | (-> field-hash-key (field) string) | ||
| 42 | (defun field-hash-key (field) | 47 | (defun field-hash-key (field) |
| 43 | (str:snake-case (field-name field))) | 48 | (str:snake-case (field-name field))) |
| 44 | 49 | ||
| 50 | (-> field-keyword (field) keyword) | ||
| 45 | (defun field-keyword (field) | 51 | (defun field-keyword (field) |
| 46 | (make-keyword (field-name field))) | 52 | (make-keyword (field-name field))) |
| 47 | 53 | ||
| 54 | ;; TODO: list-of-fields, list-of-field-specs | ||
| 55 | (-> parse-field-specs (list) list) | ||
| 48 | (defun parse-field-specs (field-specs) | 56 | (defun parse-field-specs (field-specs) |
| 49 | (iter (for field-spec in field-specs) | 57 | (iter (for field-spec in field-specs) |
| 50 | (collect (apply #'make-field field-spec)))) | 58 | (collect (apply #'make-field field-spec)))) |
| 51 | 59 | ||
| 52 | (defun emit-append-to-pprint-args (field value pprint-args) | 60 | (-> emit-coerced-field (field (or symbol list)) list) |
| 53 | `(setf ,pprint-args (list* ',(field-name field) ,value ,pprint-args))) | ||
| 54 | |||
| 55 | (defun emit-coerced-field (field value) | 61 | (defun emit-coerced-field (field value) |
| 56 | `(list ,(field-hash-key field) ,value ',(field-type field))) | 62 | `(list ,(field-hash-key field) ,value ',(field-type field))) |
| 57 | 63 | ||
| 64 | ;; TODO: list-of-fields | ||
| 65 | (-> emit-collect-nondefault-fields | ||
| 66 | (symbol list symbol (function (field (or symbol list)) list)) | ||
| 67 | list) | ||
| 58 | (defun emit-collect-nondefault-fields (name fields obj collector) | 68 | (defun emit-collect-nondefault-fields (name fields obj collector) |
| 59 | (with-gensyms (value) | 69 | (with-gensyms (value) |
| 60 | (iter (for field in (reverse fields)) | 70 | (iter (for field in (reverse fields)) |
| @@ -65,12 +75,16 @@ | |||
| 65 | ,(funcall collector field value))) | 75 | ,(funcall collector field value))) |
| 66 | (funcall collector field (list (field-accessor name field) obj))))))) | 76 | (funcall collector field (list (field-accessor name field) obj))))))) |
| 67 | 77 | ||
| 78 | (-> emit-constructor-args (field) list) | ||
| 68 | (defun emit-constructor-args (field) | 79 | (defun emit-constructor-args (field) |
| 69 | `(,(field-keyword field) ,(field-name field))) | 80 | `(,(field-keyword field) ,(field-name field))) |
| 70 | 81 | ||
| 82 | (-> emit-gethash (field symbol) list) | ||
| 71 | (defun emit-gethash (field source) | 83 | (defun emit-gethash (field source) |
| 72 | `(gethash-lazy ,(field-hash-key field) ,source ,(field-default field))) | 84 | `(gethash-lazy ,(field-hash-key field) ,source ,(field-default field))) |
| 73 | 85 | ||
| 86 | ;; TODO: list-of-fields | ||
| 87 | (-> emit-jzon-coerced-fields (symbol list) list) | ||
| 74 | (defun emit-jzon-coerced-fields (name fields) | 88 | (defun emit-jzon-coerced-fields (name fields) |
| 75 | (with-gensyms (obj result) | 89 | (with-gensyms (obj result) |
| 76 | `(defmethod jzon:coerced-fields ((,obj ,name)) | 90 | `(defmethod jzon:coerced-fields ((,obj ,name)) |
| @@ -81,10 +95,13 @@ | |||
| 81 | `(push ,(emit-coerced-field field value) ,result))) | 95 | `(push ,(emit-coerced-field field value) ,result))) |
| 82 | ,result)))) | 96 | ,result)))) |
| 83 | 97 | ||
| 98 | (-> emit-let-gethash (field symbol) list) | ||
| 84 | (defun emit-let-gethash (field source) | 99 | (defun emit-let-gethash (field source) |
| 85 | `(,(field-name field) | 100 | `(,(field-name field) |
| 86 | (parse-value ',(field-type field) ,(emit-gethash field source)))) | 101 | (parse-value ',(field-type field) ,(emit-gethash field source)))) |
| 87 | 102 | ||
| 103 | ;; TODO: list-of-fields | ||
| 104 | (-> emit-parse-value (symbol list) list) | ||
| 88 | (defun emit-parse-value (name fields) | 105 | (defun emit-parse-value (name fields) |
| 89 | (with-gensyms (source type) | 106 | (with-gensyms (source type) |
| 90 | `(defmethod parse-value ((,type (eql ',name)) ,source) | 107 | `(defmethod parse-value ((,type (eql ',name)) ,source) |
| @@ -94,6 +111,8 @@ | |||
| 94 | ,@(iter (for field in fields) | 111 | ,@(iter (for field in fields) |
| 95 | (appending (emit-constructor-args field)))))))) | 112 | (appending (emit-constructor-args field)))))))) |
| 96 | 113 | ||
| 114 | ;; TODO: list-of-fields | ||
| 115 | (-> emit-printer (symbol symbol list) list) | ||
| 97 | (defun emit-printer (name printer-name fields) | 116 | (defun emit-printer (name printer-name fields) |
| 98 | (with-gensyms (depth obj pprint-args stream) | 117 | (with-gensyms (depth obj pprint-args stream) |
| 99 | `(defun ,printer-name (,obj ,stream ,depth) ; lint:suppress lambda-list-invalid | 118 | `(defun ,printer-name (,obj ,stream ,depth) ; lint:suppress lambda-list-invalid |
| @@ -105,11 +124,14 @@ | |||
| 105 | `(setf ,pprint-args (list* ',(field-name field) ,value ,pprint-args)))) | 124 | `(setf ,pprint-args (list* ',(field-name field) ,value ,pprint-args)))) |
| 106 | (format ,stream "~A~<[~;~@{~_~1I~W = ~W~^, ~}~;]~:>" ',name ,pprint-args))))) | 125 | (format ,stream "~A~<[~;~@{~_~1I~W = ~W~^, ~}~;]~:>" ',name ,pprint-args))))) |
| 107 | 126 | ||
| 127 | ;; TODO: list-of-fields | ||
| 128 | (-> emit-struct (symbol symbol list) list) | ||
| 108 | (defun emit-struct (name printer-name fields) | 129 | (defun emit-struct (name printer-name fields) |
| 109 | `(defstruct (,name (:print-function ,printer-name)) | 130 | `(defstruct (,name (:print-function ,printer-name)) |
| 110 | ,@(iter (for field in fields) | 131 | ,@(iter (for field in fields) |
| 111 | (collect (emit-struct-field field))))) | 132 | (collect (emit-struct-field field))))) |
| 112 | 133 | ||
| 134 | (-> emit-struct-field (field) list) | ||
| 113 | (defun emit-struct-field (field) | 135 | (defun emit-struct-field (field) |
| 114 | `(,(field-name field) ,(field-default field) :type ,(field-type field)))) | 136 | `(,(field-name field) ,(field-default field) :type ,(field-type field)))) |
| 115 | 137 | ||