Skip to content

Commit

Permalink
renamed qq to quasiquote
Browse files Browse the repository at this point in the history
  • Loading branch information
athos committed Apr 30, 2012
1 parent 103241f commit 3a2e6aa
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 38 deletions.
42 changes: 22 additions & 20 deletions src/syntactic_closure/quasiquote.clj
Expand Up @@ -12,31 +12,33 @@
(defn- unquote-splicing? [x]
(and (seq? x) (= (first x) UNQUOTE-SPLICING)))

(defn expand [xxs depth]
(cond (and (unquote? xxs) (= depth 0)) (second xxs)
(defn expand [xxs depth kwd on-unquote on-unquote-sp]
(letfn [(rec [xxs depth]
(cond (and (unquote? xxs) (= depth 0)) (on-unquote (second xxs))

(and (seq? xxs) (not (empty? xxs)))
(let [[x & [x' :as xs]] xxs]
(if (and (unquote-splicing? x) (= depth 0))
`(concat ~(second x) ~(expand xs depth))
(cond (= x 'qq)
`(list '~'qq ~(expand x' (inc depth)))
(and (seq? xxs) (not (empty? xxs)))
(let [[x & [x' :as xs]] xxs]
(if (and (unquote-splicing? x) (= depth 0))
`(concat ~(on-unquote-sp (second x)) ~(rec xs depth))
(cond (= x kwd)
`(list '~kwd ~(rec x' (inc depth)))

(and (= x UNQUOTE) (> depth 0))
`(list '~UNQUOTE ~(expand x' (dec depth)))
(and (= x UNQUOTE) (> depth 0))
`(list '~UNQUOTE ~(rec x' (dec depth)))

(and (= x UNQUOTE-SPLICING) (> depth 0))
`(list '~UNQUOTE-SPLICING ~(expand x' (dec depth)))
(and (= x UNQUOTE-SPLICING) (> depth 0))
`(list '~UNQUOTE-SPLICING ~(rec x' (dec depth)))

:else `(cons ~(expand x depth) ~(expand xs depth)))))
:else `(cons ~(rec x depth) ~(rec xs depth)))))

(vector? xxs)
`(vec ~(expand (seq xxs) depth))
(vector? xxs)
`(vec ~(rec (seq xxs) depth))

(map? xxs)
`(apply conj {} (map vec (partition 2 ~(expand (apply concat xxs) depth))))
(map? xxs)
`(apply conj {} (map vec (partition 2 ~(rec (apply concat xxs) depth))))

:else `'~xxs))
:else `'~xxs))]
(rec xxs depth)))

(defmacro qq [x]
(expand x 0))
(defmacro quasiquote [x]
(expand x 0 'quasiquote identity identity))
36 changes: 18 additions & 18 deletions test/syntactic_closure/test/quasiquote.clj
@@ -1,33 +1,33 @@
(ns syntactic-closure.test.quasiquote
(:use [syntactic-closure.core :only [qq]]
(:use [syntactic-closure.core :only [quasiquote]]
[clojure.test :only [deftest is]]))

(def x 101)
(def xs [102 103 104])

(deftest quasiquote
(is (= (qq ())
(deftest test-quasiquote
(is (= (quasiquote ())
'()))
(is (= (qq ~x)
(is (= (quasiquote ~x)
101))
(is (= (qq (0 1 2))
(is (= (quasiquote (0 1 2))
'(0 1 2)))
(is (= (qq (0 ~x 2))
(is (= (quasiquote (0 ~x 2))
'(0 101 2)))
(is (= (qq (~x))
(is (= (quasiquote (~x))
'(101)))
(is (= (qq (1 ~@xs 5))
(is (= (quasiquote (1 ~@xs 5))
'(1 102 103 104 5)))
(is (= (qq (~@xs))
(is (= (quasiquote (~@xs))
'(102 103 104)))
(is (= (qq [1 ~@xs 5])
(is (= (quasiquote [1 ~@xs 5])
[1 102 103 104 5]))
(is (= (qq {0 1 ~@xs 5})
(is (= (quasiquote {0 1 ~@xs 5})
{0 1 102 103 104 5}))
(is (= (qq (0 (qq (~x ~@xs))))
'(0 (qq (~x ~@xs)))))
(is (= (qq (0 (qq ~'(~x ~@xs))))
'(0 (qq (clojure.core/unquote (quote (101 102 103 104)))))))
(is (= (qq (0 (qq (~~x ~~@xs))))
'(0 (qq ((clojure.core/unquote 101)
(clojure.core/unquote (clojure.core/unquote-splicing xs))))))))
(is (= (quasiquote (0 (quasiquote (~x ~@xs))))
'(0 (quasiquote (~x ~@xs)))))
(is (= (quasiquote (0 (quasiquote ~'(~x ~@xs))))
'(0 (quasiquote (clojure.core/unquote (quote (101 102 103 104)))))))
(is (= (quasiquote (0 (quasiquote (~~x ~~@xs))))
'(0 (quasiquote ((clojure.core/unquote 101)
(clojure.core/unquote (clojure.core/unquote-splicing xs))))))))

0 comments on commit 3a2e6aa

Please sign in to comment.