aboutsummaryrefslogtreecommitdiff
path: root/clojure/src/reader.clj
blob: 8f14767519116c3599dacb04669bd2f8da4e900a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
(ns reader
    (:refer-clojure :exclude [read-string])
    (:require [clojure.tools.reader :as r]
              [clojure.tools.reader.reader-types :as rt]))

;; change tools.reader syntax-quote to quasiquote
(defn- wrap [sym]
  (fn [rdr _] (list sym (#'r/read rdr true nil true))))

(defn- wrap-with [sym]
  (fn [rdr arg _] (list sym (#'r/read rdr true nil true) arg)))

;; Override some tools.reader reader macros so that we can do our own
;; metadata and quasiquote handling
(alter-var-root #'r/macros
  (fn [f]
    (fn [ch]
      (case ch
        \` (wrap 'quasiquote)
        \~ (fn [rdr comma]
             (if-let [ch (rt/peek-char rdr)]
               (if (identical? \@ ch)
                 ((wrap 'splice-unquote) (doto rdr rt/read-char) \@)
                 ((wrap 'unquote) rdr \~))))
        \^ (fn [rdr comma]
             (let [m (#'r/read rdr)]
               ((wrap-with 'with-meta) rdr m \^)))
        \@ (wrap 'deref)
        (f ch)))))

(defn read-string [s]
  (r/read-string s))