Skip to content

Commit b40670a

Browse files
committed
Add namespaced maps, fix backquote implementation
Namespaced maps are parsed to a regular :map AST token, but with an extra `:map-prefix` key, which is the map-prefix lex token.
1 parent 49c715e commit b40670a

File tree

4 files changed

+41
-2
lines changed

4 files changed

+41
-2
lines changed

parseclj-ast.el

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ on available options."
137137
pos
138138
:children children)
139139
stack))
140+
(:map-prefix (cons (a-assoc (car children)
141+
:map-prefix opening-token)
142+
stack))
140143
(t (cons
141144
(parseclj-ast-node type pos :children children)
142145
stack)))))

parseclj-lex.el

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
:reader-conditional
5555
:reader-conditional-splice
5656
:var
57-
:deref)
57+
:deref
58+
:map-prefix)
5859
"Tokens that modify the form that follows.")
5960

6061
(defvar parseclj-lex--prefix-2-tokens '(:metadata)
@@ -406,6 +407,16 @@ See `parseclj-lex-symbol', `parseclj-lex-symbol-start-p'."
406407
(right-char))
407408
(parseclj-lex-token :comment (buffer-substring-no-properties pos (point)) pos)))
408409

410+
(defun parseclj-lex-map-prefix ()
411+
"Return a lex token representing a map prefix."
412+
(let ((pos (1- (point))))
413+
(right-char)
414+
(when (equal (char-after (point)) ?:)
415+
(right-char))
416+
(while (parseclj-lex-symbol-rest-p (char-after (point)))
417+
(right-char))
418+
(parseclj-lex-token :map-prefix (buffer-substring-no-properties pos (point)) pos)))
419+
409420
(defun parseclj-lex-next ()
410421
"Consume characters at point and return the next lexical token.
411422
@@ -448,7 +459,7 @@ See `parseclj-lex-token'."
448459

449460
((equal char ?`)
450461
(right-char)
451-
(parseclj-lex-token :backquote "'" pos))
462+
(parseclj-lex-token :backquote "`" pos))
452463

453464
((equal char ?~)
454465
(right-char)
@@ -502,6 +513,8 @@ See `parseclj-lex-token'."
502513
(parseclj-lex-token :var "#'" pos))
503514
((equal char ?\")
504515
(parseclj-lex-regex))
516+
((equal char ?:)
517+
(parseclj-lex-map-prefix))
505518
((equal char ?\?)
506519
(right-char)
507520
(if (eq ?@ (char-after (point)))

test/parseclj-lex-test.el

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,17 @@
326326
(goto-char 1)
327327
(should (equal (parseclj-lex-next) (parseclj-lex-token :tag "#foo/bar" 1)))))
328328

329+
(ert-deftest parseclj-lex-test-quote ()
330+
(with-temp-buffer
331+
(insert "'foo")
332+
(goto-char 1)
333+
(should (equal (parseclj-lex-next) (parseclj-lex-token :quote "'" 1))))
334+
335+
(with-temp-buffer
336+
(insert "`foo")
337+
(goto-char 1)
338+
(should (equal (parseclj-lex-next) (parseclj-lex-token :backquote "`" 1)))))
339+
329340
(provide 'parseclj-lex-test)
330341

331342
;;; parseclj-lex-test.el ends here

test/parseclj-test.el

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,18 @@
252252
(:form . "foo")
253253
(:value . foo)))))))))
254254

255+
(ert-deftest parseclj--parse-namespaced-map-test ()
256+
(should (equal
257+
(parseclj-parse-clojure "#:foo.bar{}")
258+
'((:node-type . :root)
259+
(:position . 1)
260+
(:children ((:map-prefix . ((:token-type . :map-prefix)
261+
(:form . "#:foo.bar")
262+
(:pos . 1)))
263+
(:node-type . :map)
264+
(:position . 10)
265+
(:children)))))))
266+
255267
(ert-deftest parseclj--take-token-test ()
256268
(should (equal
257269
(parseclj--take-token

0 commit comments

Comments
 (0)