From 3a2e6aa3cafd8ccd7f9192410961f9c520ff2b8a Mon Sep 17 00:00:00 2001 From: OHTA Shogo Date: Mon, 30 Apr 2012 17:39:33 +0900 Subject: [PATCH] renamed qq to quasiquote --- src/syntactic_closure/quasiquote.clj | 42 +++++++++++----------- test/syntactic_closure/test/quasiquote.clj | 36 +++++++++---------- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/syntactic_closure/quasiquote.clj b/src/syntactic_closure/quasiquote.clj index 562b5a5..3c122c7 100644 --- a/src/syntactic_closure/quasiquote.clj +++ b/src/syntactic_closure/quasiquote.clj @@ -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)) diff --git a/test/syntactic_closure/test/quasiquote.clj b/test/syntactic_closure/test/quasiquote.clj index 9762fdf..267aff3 100644 --- a/test/syntactic_closure/test/quasiquote.clj +++ b/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))))))))