Skip to content

Commit 65c3b93

Browse files
author
Yannick Scherer
authored
[#48] parse '#?@' into ':reader-macro' node.
2 parents cc5ff42 + d8969d3 commit 65c3b93

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

src/rewrite_clj/parser/core.clj

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,24 @@
119119
\' (node/var-node (parse-printables reader :var 1 true))
120120
\= (node/eval-node (parse-printables reader :eval 1 true))
121121
\_ (node/uneval-node (parse-printables reader :uneval 1 true))
122+
\? (do
123+
;; we need to examine the next character, so consume one (known \?)
124+
(reader/next reader)
125+
;; we will always have a reader-macro-node as the result
126+
(node/reader-macro-node
127+
(let [read1 (fn [] (parse-printables reader :reader-macro 1))]
128+
(cons (case (reader/peek reader)
129+
;; the easy case, just emit a token
130+
\( (node/token-node (symbol "?"))
131+
132+
;; the harder case, match \@, consume it and emit the token
133+
\@ (do (reader/next reader)
134+
(node/token-node (symbol "?@")))
135+
136+
;; otherwise no idea what we're reading but its \? prefixed
137+
(do (reader/unread reader \?)
138+
(first (read1))))
139+
(read1)))))
122140
(node/reader-macro-node (parse-printables reader :reader-macro 2))))
123141

124142
(defmethod parse-next* :deref

src/rewrite_clj/reader.clj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@
109109
[reader]
110110
(r/read-char reader))
111111

112+
(defn unread
113+
"Unreads a char. Puts the char back on the reader."
114+
[reader ch]
115+
(r/unread reader ch))
116+
112117
(defn peek
113118
"Peek next char."
114119
[reader]

test/rewrite_clj/parser_test.clj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
"#=sym" :eval [] '(eval 'sym)
8787
"#= sym" :eval [:whitespace] '(eval 'sym)
8888
"#'sym" :var [] '(var sym)
89-
"#'\nsym" :var [:newline]) '(var sym)
89+
"#'\nsym" :var [:newline])
9090

9191
(fact "about eval."
9292
(let [n (p/parse-string "#=(+ 1 2)")]
@@ -191,6 +191,9 @@
191191
"#=(+ 1 2)" :eval [:list]
192192
"#macro 1" :reader-macro [:token :whitespace :token]
193193
"#macro (* 2 3)" :reader-macro [:token :whitespace :list]
194+
"#?(:clj bar)" :reader-macro [:token :list]
195+
"#?@(:clj bar)" :reader-macro [:token :list]
196+
"#?foo baz" :reader-macro [:token :whitespace :token]
194197
"#_abc" :uneval [:token]
195198
"#_(+ 1 2)" :uneval [:list]
196199
"#(+ % 1)" :fn [:token :whitespace

0 commit comments

Comments
 (0)