0

我需要帮助解析为类生成代码的 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)))

问题:如何推广宏以适应更复杂的用例?

4

0 回答 0