Change defcfn to use a fn-tail to allow multiple arity wrappers
This commit is contained in:
parent
fce3675a4b
commit
ada787a72b
1 changed files with 16 additions and 16 deletions
|
|
@ -701,8 +701,9 @@
|
||||||
:native-arglist (s/coll-of qualified-keyword? :kind vector?)
|
:native-arglist (s/coll-of qualified-keyword? :kind vector?)
|
||||||
:return-type qualified-keyword?
|
:return-type qualified-keyword?
|
||||||
:fn-tail (s/?
|
:fn-tail (s/?
|
||||||
(s/cat :arglist (s/coll-of simple-symbol? :kind vector?)
|
(s/nonconforming
|
||||||
:body (s/* any?)))))
|
(s/cat :arglist (s/coll-of simple-symbol? :kind vector?)
|
||||||
|
:body (s/* any?))))))
|
||||||
|
|
||||||
(defmacro defcfn
|
(defmacro defcfn
|
||||||
"Defines a Clojure function which maps to a native function.
|
"Defines a Clojure function which maps to a native function.
|
||||||
|
|
@ -711,23 +712,23 @@
|
||||||
`symbol` is a symbol or string naming the library symbol to link against.
|
`symbol` is a symbol or string naming the library symbol to link against.
|
||||||
`arg-types` is a vector of qualified keywords representing the argument types.
|
`arg-types` is a vector of qualified keywords representing the argument types.
|
||||||
`ret-type` is a single qualified keyword representing the return type.
|
`ret-type` is a single qualified keyword representing the return type.
|
||||||
`arglist` is a binding vector for the symbols used in the wrapping function.
|
`fn-tail` is the body of the function (potentially with multiple arities)
|
||||||
`body` is a function body referring to `arglist`. During the execution of the
|
which wraps the native one. Inside the function, `name` is bound to a function
|
||||||
body, `name` is bound to a function that will serialize its arguments, call
|
that will serialize its arguments, call the native function, and deserialize
|
||||||
the native function, and deserialize its return type. If any body is present,
|
its return type. If any body is present, you must call this function in order
|
||||||
you must call this function in order to call the native code.
|
to call the native code.
|
||||||
|
|
||||||
If no `arglist` and `body` is provided, then the resulting function will
|
If no `fn-tail` is provided, then the resulting function will simply serialize
|
||||||
simply serialize the arguments according to `arg-types`, call the native
|
the arguments according to `arg-types`, call the native function, and
|
||||||
function, and deserialize the return value.
|
deserialize the return value.
|
||||||
|
|
||||||
The number of args in `arglist` need not match the number of `arg-types` for
|
The number of args in the `fn-tail` need not match the number of `arg-types`
|
||||||
the native function. It need only call the native wrapper function with the
|
for the native function. It need only call the native wrapper function with
|
||||||
correct arguments.
|
the correct arguments.
|
||||||
|
|
||||||
See [[serialize]], [[deserialize]], [[make-downcall]]."
|
See [[serialize]], [[deserialize]], [[make-downcall]]."
|
||||||
{:arglists '([name docstring? attr-map? symbol arg-types ret-type]
|
{:arglists '([name docstring? attr-map? symbol arg-types ret-type]
|
||||||
[name docstring? attr-map? symbol arg-types ret-type arglist & body])}
|
[name docstring? attr-map? symbol arg-types ret-type & fn-tail])}
|
||||||
[& args]
|
[& args]
|
||||||
(let [args (s/conform ::defcfn-args args)
|
(let [args (s/conform ::defcfn-args args)
|
||||||
scope (gensym "scope")
|
scope (gensym "scope")
|
||||||
|
|
@ -757,8 +758,7 @@
|
||||||
arg-syms arg-types))
|
arg-syms arg-types))
|
||||||
~ret-type))))
|
~ret-type))))
|
||||||
fun# ~(if (:fn-tail args)
|
fun# ~(if (:fn-tail args)
|
||||||
`(fn ~(-> args :fn-tail :arglist)
|
`(fn ~@(:fn-tail args))
|
||||||
~@(-> args :fn-tail :body))
|
|
||||||
(:name args))]
|
(:name args))]
|
||||||
(def
|
(def
|
||||||
~(with-meta (:name args)
|
~(with-meta (:name args)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue