50 lines
1.3 KiB
Plaintext
50 lines
1.3 KiB
Plaintext
(defmacro clj-loop
|
|
``A drop-in replacement for Clojure's loop form. Useful for the current project of converting Clojure code to Janet.
|
|
``
|
|
[bindings & body]
|
|
(assert (even? (length bindings)) "Binding tuple must have an even number of terms")
|
|
(def names @[])
|
|
(def args @[])
|
|
(loop [i :range [0 (length bindings)]]
|
|
(if (even? i)
|
|
(array/push names (get bindings i))
|
|
(array/push args (get bindings i))))
|
|
~(do (defn recur [,;names] ,;body) (recur ,;args)))
|
|
|
|
(defmacro defn+
|
|
[name & clauses]
|
|
~(defn ,name [& args]
|
|
(print "before do")
|
|
(do
|
|
(def arities @{})
|
|
(def clauses ,clauses)
|
|
(def bindingses (map first clauses))
|
|
(def bodies (map |(slice $ 1) clauses))
|
|
(print "before loop")
|
|
(loop [i :range [0 (length clauses)]]
|
|
(def bindings (get bindingses i))
|
|
(def arity (length bindings))
|
|
(assert (not (get arities i)) "Clauses must have different arities")
|
|
(def body (get bodies i))
|
|
(def clause ~(fn ,name ,bindings ,;body))
|
|
(put $arities arity clause))
|
|
(print "before quasiquote")
|
|
(fn [& args]
|
|
(def arity (length args))
|
|
(def clause (get arities arity))
|
|
(assert clause "No clause with that arity")
|
|
(clause ;args)))))
|
|
|
|
(defn+ add
|
|
([] 0)
|
|
([x] x)
|
|
([x y] (+ x y)))
|
|
|
|
(macex1
|
|
'(defn+ add
|
|
([] 0)
|
|
([x] x)
|
|
([x y] (+ x y))))
|
|
|
|
|