mirror of
https://github.com/janet-lang/janet
synced 2025-02-03 02:39:09 +00:00
Add varfn.
This commit is contained in:
parent
841b58042f
commit
e9f3dc7d5c
@ -2,6 +2,7 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Unreleased
|
||||
- Add `varfn` macro
|
||||
- Add compile time arity checking when function in function call is known.
|
||||
- Added `slice` to the core library.
|
||||
- The `*/slice` family of functions now can take nil as start or end to get
|
||||
|
@ -1538,6 +1538,30 @@
|
||||
(set current (macex1 current on-binding)))
|
||||
current)
|
||||
|
||||
(defmacro varfn
|
||||
"Create a function that can be rebound. varfn has the same signature
|
||||
as defn, but defines functions in the environment as vars. If a var 'name'
|
||||
already exists in the environment, it is rebound to the new function. Returns
|
||||
a function."
|
||||
[name & body]
|
||||
(def expansion (apply defn name body))
|
||||
(def fbody (last expansion))
|
||||
(def modifiers (tuple/slice expansion 2 -2))
|
||||
(def metadata @{})
|
||||
(each m modifiers
|
||||
(cond
|
||||
(keyword? m) (put metadata m true)
|
||||
(string? m) (put metadata :doc m)
|
||||
(error (string "invalid metadata " m))))
|
||||
(with-syms [entry old-entry f]
|
||||
~(let [,old-entry (,dyn ',name)]
|
||||
(def ,entry (or ,old-entry @{:ref @[nil]}))
|
||||
(,setdyn ',name ,entry)
|
||||
(def ,f ,fbody)
|
||||
(,put-in ,entry [:ref 0] ,f)
|
||||
(,merge-into ,entry ',metadata)
|
||||
,f)))
|
||||
|
||||
###
|
||||
###
|
||||
### Function shorthand
|
||||
|
Loading…
Reference in New Issue
Block a user