lisp/defadt.lisp

34 lines
1.2 KiB
Common Lisp
Raw Normal View History

2024-12-16 14:34:52 -05:00
(load "utils.lisp")
(defmacro defadt (name &rest clauses)
`(prog1
(defclass ,name () ())
,@(loop for clause in clauses
nconcing
(begin
(= (cons clause-name slots) (mklist clause))
(= keywords (mapcar (lambda (x) (intern (string x) :keyword)) slots))
`((defclass ,clause-name (,name)
,(loop for slot in slots
for keyword in keywords
collecting `(,name :initarg ,keyword)))
,(if slots
`(defun ,clause-name ,slots
(make-instance ',clause-name
,@(loop for slot in slots
for keyword in keywords
nconcing
`(,keyword ,slot))))
`(defparameter ,clause-name
(make-instance ',clause-name))))))))
;; aaaaand match just works :P
(defadt NonEmpty (End x) (NCons hd tl))
(defun nlength (x)
(declare (type NonEmpty x))
(match x
((End (x _)) 1)
((NCons (hd _) tl) (+ 1 (nlength tl)))))