Create code-like data structures dynamically

To my surprise I found an easy solution.

(defmacro q [code]
  (cond (symbol? code)                            (list 'quote code)
        (number? code)                            code
        (string? code)                            code
        (keyword? code)                           code
        (vector? code)                            (apply vector (map #(list `q %) code))
        (map? code)                               (update-keys (update-vals code #(list `q %)) #(list `q %))
        (and (list? code) (= (first code) 'uq))   (second code)
        (list? code)                              (apply list 'list (map #(list `q %) code))))

(comment
  (q 4) 
  (q b)
  (q "abc")
  (q ())
  (q [])
  (q (a))
  (q (a b))
  (q ({a b}))
  (q {a b})
  (q [a b c])
  (q (a [b c d] e))
  (q (a (b c d) e)) 
  (q (a (uq (+ 1 1)) b))
  (let [x 'b] (q 4))
  (let [x 'b] (q (uq x)))
  (let [x 'b] (q (a (uq x))))
  (let [x 'b] (q ({a (uq x)})))
  (let [x 'b] (q {a (uq x)}))
  (let [x 'b] (q [a (uq x) c]))
  (let [x 'b] (q (a [(uq x) c d] e)))
  (let [x 'b] (q (a ((uq x) c d) e)))
  (let [x 'b] (q ({a (uq x) c d} e)))
  (let [x 'b] (q (uq (map identity ['a (q ((uq x) c))])))))

The macro q quotes something and uq is unquote. It seems to work.