美文网首页
clojure 宏

clojure 宏

作者: onedam | 来源:发表于2021-06-01 23:00 被阅读0次

    宏的本质是fn* 函数. 该函数有个meta 说明是宏. 则clojure compiler 在编译的时候需要先展开后编译.

    (def
     ^{:doc "Like defn, but the resulting function name is declared as a
      macro and will be used as a macro by the compiler when it is
      called."
       :arglists '([name doc-string? attr-map? [params*] body]
                     [name doc-string? attr-map? ([params*] body)+ attr-map?])
       :added "1.0"}
     defmacro (fn [&form &env 
                    name & args]
                 (let [prefix (loop [p (list name) args args]
                                (let [f (first args)]
                                  (if (string? f)
                                    (recur (cons f p) (next args))
                                    (if (map? f)
                                      (recur (cons f p) (next args))
                                      p))))
                       fdecl (loop [fd args]
                               (if (string? (first fd))
                                 (recur (next fd))
                                 (if (map? (first fd))
                                   (recur (next fd))
                                   fd)))
                       fdecl (if (vector? (first fdecl))
                               (list fdecl)
                               fdecl)
                       add-implicit-args (fn [fd]
                                 (let [args (first fd)]
                                   (cons (vec (cons '&form (cons '&env args))) (next fd))))
                       add-args (fn [acc ds]
                                  (if (nil? ds)
                                    acc
                                    (let [d (first ds)]
                                      (if (map? d)
                                        (conj acc d)
                                        (recur (conj acc (add-implicit-args d)) (next ds))))))
                       fdecl (seq (add-args [] fdecl))
                       decl (loop [p prefix d fdecl]
                              (if p
                                (recur (next p) (cons (first p) d))
                                d))]
                   (list 'do
                         (cons `defn decl)
                         (list '. (list 'var name) '(setMacro))  ; 这里定义的fn也被设置为宏
                         (list 'var name)))))
    
    
    (. (var defmacro) (setMacro))  ;defmacro 本身是宏. 在上面展开后 继续对用户自定义的宏展开编译. 生成jvm可加载运行的bytecode.
    

    相关文章

      网友评论

          本文标题:clojure 宏

          本文链接:https://www.haomeiwen.com/subject/gnzgsltx.html