From f4b8d8e58b82b29b3cc765c44045b86d6ec44054 Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Sat, 18 Oct 2025 07:31:03 +0300 Subject: Utilise alexandria:with-gensyms --- src/enum.lisp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src/enum.lisp') diff --git a/src/enum.lisp b/src/enum.lisp index 8943a90..a047c1d 100644 --- a/src/enum.lisp +++ b/src/enum.lisp @@ -1,7 +1,9 @@ ;; SPDX-License-Identifier: EUPL-1.2 ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs (defpackage :ukkoclot/enum + (:documentation "Macro for generating an enum type.") (:use :c2cl :iterate) + (:import-from :alexandria :with-gensyms) (:import-from :ukkoclot/serializing :fixup-value :parse-value) (:import-from :string-case :string-case) (:local-nicknames @@ -13,33 +15,38 @@ (defstruct (field (:constructor make-field%)) name string) (defun make-field (name string) + "Better constructor for `field'." (make-field% :name name :string string)) (defun parse-field-specs (field-specs) + "Parse a list of field specs into a list of fields." (iter (for field-spec in field-specs) (collect (apply #'make-field field-spec)))) (defun emit-defconst (field) + "Emit the `defconstant' statement for a specific field." `(defconstant ,(field-name field) ',(field-name field))) (defun emit-deftype (name fields) + "Emit the `deftype' statement for the enum." `(deftype ,name () '(member ,@(iter (for field in fields) (collect (field-name field)))))) (defun emit-fixup-method (field) - (let ((arg (gensym "ARG"))) + "Emit the `fixup-value' specialization for the enum." + (with-gensyms (arg) `(defmethod fixup-value ((,arg (eql ',(field-name field)))) ,(field-string field)))) (defun emit-jzon-write-method (field) - (let ((writer (gensym "WRITER")) - (arg (gensym "ARG"))) + "Emit the `json:write-value' specialization for the enum." + (with-gensyms (arg writer) `(defmethod jzon:write-value ((,writer jzon:writer) (,arg (eql ',(field-name field)))) (jzon:write-value ,writer ,(field-string field))))) (defun emit-parse-value (name fields) - (let ((type (gensym "TYPE")) - (source (gensym "SOURCE"))) + "Emit the `parse-value' specialization for the enum." + (with-gensyms (source type) `(defmethod parse-value ((,type (eql ',name)) ,source) ;; nil in, nil out (when ,source @@ -48,6 +55,13 @@ (collect `(,(field-string field) ,(field-name field)))))))))) (defmacro define-enum (name &body field-specs) + "Define a new enumeration type. + +FIELD-SPECS := FIELD-SPEC* +FIELD-SPEC := (FIELD-NAME FIELD-SERIALIZATION) + +FIELD-NAME is the symbol name of the field. +FIELD-SERIALIZATION is the string serialization of the field." (let ((fields (parse-field-specs field-specs))) `(progn ,@(iter (for field in fields) -- cgit v1.2.3