我需要帮助解析为类生成代码的 Hy 宏中的参数。
我要完成的工作:一个将生成具有预定义属性的类的宏。属性名称是用于初始化类的变量。
这是我到目前为止所拥有的,
属性生成器
下面的函数生成属性 getter 的代码(约定是使用__variable__
名称作为私有/内部变量)
(eval-and-compile
(defn defproperty [attribute &optional docstring &rest body]
`(with-decorator property
(defn ~attribute [self]
~docstring
(do ~@body)
(return (getattr self (+ "__" (str '~attribute) "__")))))))
类生成器
下面的宏使用方法中传递的变量名生成类的代码__init__
。
(defmacro/g! defrecord [recname inherits properties
&optional docstring &rest body]
(setv g!properties% (-> (cut properties 1 (len properties) 2) (list)))
`(defclass ~recname [~@inherits]
~docstring
(defn __init__ [self ~@properties]
(for [prop% '~g!properties%]
(setattr self (+ "__" (str prop%) "__") (eval prop%))))
~@(lfor prop% g!properties% `(defproperty ~prop%))
(do ~@body)))
测试用例
上面的方法很好地适用于下面的简单案例,
(defrecord record [] (^(of float) data ^(of int) x ^(of str) doc))
(setv rec (record 2.0 3 "abc"))
(. rec doc) ;; => "abc"
(. rec info) ;; => 5.0
但对于更复杂的论证结构却失败了,
(^(of float) data ^(of int) x &optional ^(of str) doc)
(^(of float) data ^(of int) x &kwonly ^(of str) [doc None])
这是因为宏中的以下语句,
(setv g!properties% (-> (cut properties 1 (len properties) 2) (list)))
问题:如何推广宏以适应更复杂的用例?