2024-05-25 16:26:26 +00:00
|
|
|
(uiop:define-package #:hsx/hsx
|
|
|
|
(:use #:cl)
|
|
|
|
(:import-from #:alexandria
|
2024-05-27 06:51:32 +00:00
|
|
|
#:symbolicate)
|
2024-05-25 16:26:26 +00:00
|
|
|
(:import-from #:hsx/element
|
|
|
|
#:create-element)
|
2024-05-27 02:10:11 +00:00
|
|
|
(:export #:defhsx
|
|
|
|
#:defcomp
|
2024-05-26 10:48:09 +00:00
|
|
|
#:hsx))
|
2024-05-25 16:26:26 +00:00
|
|
|
(in-package #:hsx/hsx)
|
|
|
|
|
2024-05-26 14:29:30 +00:00
|
|
|
|
|
|
|
;;;; hsx definitions
|
|
|
|
|
2024-05-27 02:10:11 +00:00
|
|
|
(defmacro defhsx (name element-type)
|
2024-05-27 09:33:55 +00:00
|
|
|
(eval-when (:compile-toplevel :load-toplevel :execute)
|
|
|
|
`(defmacro ,name (&body body)
|
|
|
|
(multiple-value-bind (props children)
|
|
|
|
(parse-body body)
|
|
|
|
`(create-element ,',element-type (list ,@props) ,@children)))))
|
2024-05-27 02:10:11 +00:00
|
|
|
|
2024-05-27 03:24:38 +00:00
|
|
|
(defun parse-body (body)
|
|
|
|
(if (keywordp (first body))
|
|
|
|
(loop :for thing :on body :by #'cddr
|
|
|
|
:for (k v) := thing
|
|
|
|
:when (and (keywordp k) v)
|
|
|
|
:append (list k v) :into props
|
|
|
|
:when (not (keywordp k))
|
|
|
|
:return (values props thing)
|
|
|
|
:finally (return (values props nil)))
|
|
|
|
(values nil body)))
|
|
|
|
|
2024-05-25 16:26:26 +00:00
|
|
|
(defmacro defcomp (name props &body body)
|
|
|
|
(let ((%name (symbolicate '% name)))
|
|
|
|
`(eval-when (:compile-toplevel :load-toplevel :execute)
|
|
|
|
(defun ,%name ,props
|
|
|
|
,@body)
|
2024-05-27 02:10:11 +00:00
|
|
|
(defhsx ,name (fdefinition ',%name)))))
|
2024-05-26 10:48:09 +00:00
|
|
|
|
2024-05-26 14:29:30 +00:00
|
|
|
|
|
|
|
;;;; hsx macro to find hsx symbols
|
|
|
|
|
2024-05-27 08:00:58 +00:00
|
|
|
(defmacro hsx (&body form)
|
|
|
|
(when (not (= (length form) 1))
|
|
|
|
(error "The body of the hsx macro must be a single form."))
|
|
|
|
(find-builtin-symbols (car form)))
|
2024-05-26 10:48:09 +00:00
|
|
|
|
2024-05-27 06:51:32 +00:00
|
|
|
(defun find-builtin-symbols (tree)
|
2024-05-26 10:48:09 +00:00
|
|
|
(if tree
|
|
|
|
(cons (let ((first-node (first tree)))
|
2024-05-27 06:51:32 +00:00
|
|
|
(if (listp first-node)
|
|
|
|
(find-builtin-symbols first-node)
|
|
|
|
(or (find-symbol (string first-node) :hsx/builtin)
|
|
|
|
first-node)))
|
2024-05-26 10:48:09 +00:00
|
|
|
(mapcar (lambda (node)
|
|
|
|
(if (listp node)
|
2024-05-27 06:51:32 +00:00
|
|
|
(find-builtin-symbols node)
|
2024-05-26 10:48:09 +00:00
|
|
|
node))
|
|
|
|
(rest tree)))))
|