Integrate defhsx package into hsx package

This commit is contained in:
Akira Tempaku 2024-06-06 14:59:46 +09:00
commit 693e6704f9
8 changed files with 98 additions and 108 deletions

View file

@ -1,6 +1,6 @@
(uiop:define-package #:hsx/builtin
(:use #:cl)
(:import-from #:hsx/defhsx
(:import-from #:hsx/hsx
#:deftag))
(in-package #:hsx/builtin)

View file

@ -1,48 +0,0 @@
(defpackage #:hsx/defhsx
(:use #:cl)
(:import-from #:alexandria
#:make-keyword
#:symbolicate)
(:import-from #:hsx/element
#:create-element)
(:export #:deftag
#:defcomp))
(in-package #:hsx/defhsx)
(defmacro defhsx (name element-type)
`(defmacro ,name (&body body)
`(%create-element ,',element-type ,@body)))
(defun %create-element (type &rest body)
(multiple-value-bind (props children)
(parse-body body)
(create-element type props children)))
(defun parse-body (body)
(cond ((and (listp (first body))
(keywordp (first (first body))))
(values (first body) (rest body)))
((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))))
(t (values nil body))))
(defmacro deftag (name)
`(eval-when (:compile-toplevel :load-toplevel :execute)
(defhsx ,name ,(make-keyword name))))
(defmacro defcomp (name props &body body)
(unless (or (null props)
(member '&key props)
(member '&rest props))
(error "Component properties must be declared with either &key, &rest, or both."))
(let ((%name (symbolicate '% name)))
`(eval-when (:compile-toplevel :load-toplevel :execute)
(defun ,%name ,props
,@body)
(defhsx ,name (fdefinition ',%name)))))

View file

@ -1,9 +1,17 @@
(defpackage #:hsx/hsx
(:use #:cl)
(:import-from #:hsx/builtin)
(:export #:hsx))
(:import-from #:alexandria
#:make-keyword
#:symbolicate)
(:import-from #:hsx/element
#:create-element)
(:export #:hsx
#:deftag
#:defcomp))
(in-package #:hsx/hsx)
;;;; hsx macro
(defmacro hsx (form)
(find-builtin-symbols form))
@ -19,3 +27,43 @@
(find-builtin-symbols n)
n))
(cdr node)))))
;;;; defhsx macro
(defmacro defhsx (name element-type)
`(defmacro ,name (&body body)
`(%create-element ,',element-type ,@body)))
(defun %create-element (type &rest body)
(multiple-value-bind (props children)
(parse-body body)
(create-element type props children)))
(defun parse-body (body)
(cond ((and (listp (first body))
(keywordp (first (first body))))
(values (first body) (rest body)))
((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))))
(t (values nil body))))
(defmacro deftag (name)
`(eval-when (:compile-toplevel :load-toplevel :execute)
(defhsx ,name ,(make-keyword name))))
(defmacro defcomp (name props &body body)
(unless (or (null props)
(member '&key props)
(member '&rest props))
(error "Component properties must be declared with either &key, &rest, or both."))
(let ((%name (symbolicate '% name)))
`(eval-when (:compile-toplevel :load-toplevel :execute)
(defun ,%name ,props
,@body)
(defhsx ,name (fdefinition ',%name)))))

View file

@ -2,8 +2,8 @@
(:nicknames #:hsx/main)
(:use #:cl
#:hsx/element
#:hsx/defhsx
#:hsx/hsx)
(:import-from #:hsx/builtin)
(:export #:hsx
#:defcomp
#:render-to-string