program-saver/mydefstruct.lisp
2025-01-25 19:01:15 +03:00

53 lines
1.4 KiB
Common Lisp

(defpackage :my-structures
(:use :cl)
(:export #:mydefstruct))
(in-package :my-structures)
(defun constructor-name (sym)
(intern (concatenate 'string "MAKE-" (string sym))))
(defun accessor-name (name sym)
(intern (concatenate 'string (string name) "-" (string sym))))
(defun setter-name (name sym)
(intern (concatenate 'string "SET-" (string name) "-" (string sym))))
(defun obj-type (obj)
(car obj))
(defun make-error-message (real expected)
(format nil "Accessor called on wrong type! Expected ~a but found ~a"
expected real))
(defun constructor (name slots)
`(defun ,(constructor-name name) ,slots
(list ',name ,@slots)))
(defun accessors (name slots)
(loop for slot in slots
for i upfrom 1 collect
`(defun ,(accessor-name name slot) (obj)
(if (eql (obj-type obj) ',name)
(nth ,i obj)
(error (make-error-message (obj-type obj) ',name))))))
(defun setters (name slots)
(loop for slot in slots
for i upfrom 1 collect
`(defun ,(setter-name name slot) (obj val)
(if (eql (obj-type obj) ',name)
(setf (nth ,i obj) val)
(error (make-error-message (obj-type obj) ',name))))))
(defun setfers (name slots)
(loop for slot in slots collect
`(defsetf ,(accessor-name name slot)
,(setter-name name slot))))
(defmacro mydefstruct (name &rest slots)
`(progn
,(constructor name slots)
,@ (accessors name slots)
,@ (setters name slots)
,@ (setfers name slots)))