aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMattias EngdegÄrd2019-09-25 14:29:50 -0700
committerPaul Eggert2019-09-25 14:29:50 -0700
commit07367e5b95fe31f3d4e994b42b081075501b9b60 (patch)
tree7d26251a300462083d971aa3aa9880cc23c423a1 /test
parent2ed71227c626c6cfdc684948644ccf3d9eaeb15b (diff)
downloademacs-07367e5b95fe31f3d4e994b42b081075501b9b60.tar.gz
emacs-07367e5b95fe31f3d4e994b42b081075501b9b60.zip
Add rx extension mechanism
Add a built-in set of extension macros: `rx-define', `rx-let' and `rx-let-eval'. * lisp/emacs-lisp/rx.el (rx-constituents, rx-to-string): Doc updates. (rx--builtin-symbols, rx--builtin-names, rx--local-definitions) (rx--lookup-def, rx--substitute, rx--expand-template) (rx--make-binding, rx--make-named-binding, rx--extend-local-defs) (rx-let-eval, rx-let, rx-define): New. (rx--translate-symbol, rx--translate-form): Use extensions if any. (rx): Use local definitions. * test/lisp/emacs-lisp/rx-tests.el (rx-let, rx-define) (rx-to-string-define, rx-let-define, rx-let-eval): New. * etc/NEWS (Changes in Specialized Modes and Packages): * doc/lispref/searching.texi (Rx Notation, Rx Functions, Extending Rx): Add node about rx extensions.
Diffstat (limited to 'test')
-rw-r--r--test/lisp/emacs-lisp/rx-tests.el98
1 files changed, 98 insertions, 0 deletions
diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el
index fec046dd991..11de4771dea 100644
--- a/test/lisp/emacs-lisp/rx-tests.el
+++ b/test/lisp/emacs-lisp/rx-tests.el
@@ -303,6 +303,104 @@
303 (should (equal (rx-to-string '(or nonl "\nx") t) 303 (should (equal (rx-to-string '(or nonl "\nx") t)
304 ".\\|\nx"))) 304 ".\\|\nx")))
305 305
306(ert-deftest rx-let ()
307 (rx-let ((beta gamma)
308 (gamma delta)
309 (delta (+ digit))
310 (epsilon (or gamma nonl)))
311 (should (equal (rx bol delta epsilon)
312 "^[[:digit:]]+\\(?:[[:digit:]]+\\|.\\)")))
313 (rx-let ((p () point)
314 (separated (x sep) (seq x (* sep x)))
315 (comma-separated (x) (separated x ","))
316 (semi-separated (x) (separated x ";"))
317 (matrix (v) (semi-separated (comma-separated v))))
318 (should (equal (rx (p) (matrix (+ "a")) eos)
319 "\\=a+\\(?:,a+\\)*\\(?:;a+\\(?:,a+\\)*\\)*\\'")))
320 (rx-let ((b bol)
321 (z "B")
322 (three (x) (= 3 x)))
323 (rx-let ((two (x) (seq x x))
324 (z "A")
325 (e eol))
326 (should (equal (rx b (two (three z)) e)
327 "^A\\{3\\}A\\{3\\}$"))))
328 (rx-let ((f (a b &rest r) (seq "<" a ";" b ":" r ">")))
329 (should (equal (rx bol (f ?x ?y) ?! (f ?u ?v ?w) ?! (f ?k ?l ?m ?n) eol)
330 "^<x;y:>!<u;v:w>!<k;l:mn>$")))
331
332 ;; Rest parameters are expanded by splicing.
333 (rx-let ((f (&rest r) (or bol r eol)))
334 (should (equal (rx (f "ab" nonl))
335 "^\\|ab\\|.\\|$")))
336
337 ;; Substitution is done in number positions.
338 (rx-let ((stars (n) (= n ?*)))
339 (should (equal (rx (stars 4))
340 "\\*\\{4\\}")))
341
342 ;; Substitution is done inside dotted pairs.
343 (rx-let ((f (x y z) (any x (y . z))))
344 (should (equal (rx (f ?* ?a ?t))
345 "[*a-t]")))
346
347 ;; Substitution is done in the head position of forms.
348 (rx-let ((f (x) (x "a")))
349 (should (equal (rx (f +))
350 "a+"))))
351
352(ert-deftest rx-define ()
353 (rx-define rx--a (seq "x" (opt "y")))
354 (should (equal (rx bol rx--a eol)
355 "^xy?$"))
356 (rx-define rx--c (lb rb &rest stuff) (seq lb stuff rb))
357 (should (equal (rx bol (rx--c "<" ">" rx--a nonl) eol)
358 "^<xy?.>$"))
359 (rx-define rx--b (* rx--a))
360 (should (equal (rx rx--b)
361 "\\(?:xy?\\)*"))
362 (rx-define rx--a "z")
363 (should (equal (rx rx--b)
364 "z*")))
365
366(defun rx--test-rx-to-string-define ()
367 ;; `rx-define' won't expand to code inside `ert-deftest' since we use
368 ;; `eval-and-compile'. Put it into a defun as a workaround.
369 (rx-define rx--d "Q")
370 (rx-to-string '(seq bol rx--d) t))
371
372(ert-deftest rx-to-string-define ()
373 "Check that `rx-to-string' uses definitions made by `rx-define'."
374 (should (equal (rx--test-rx-to-string-define)
375 "^Q")))
376
377(ert-deftest rx-let-define ()
378 "Test interaction between `rx-let' and `rx-define'."
379 (rx-define rx--e "one")
380 (rx-define rx--f "eins")
381 (rx-let ((rx--e "two"))
382 (should (equal (rx rx--e nonl rx--f) "two.eins"))
383 (rx-define rx--e "three")
384 (should (equal (rx rx--e) "two"))
385 (rx-define rx--f "zwei")
386 (should (equal (rx rx--f) "zwei")))
387 (should (equal (rx rx--e nonl rx--f) "three.zwei")))
388
389(ert-deftest rx-let-eval ()
390 (rx-let-eval '((a (* digit))
391 (f (x &rest r) (seq x nonl r)))
392 (should (equal (rx-to-string '(seq a (f bow a ?b)) t)
393 "[[:digit:]]*\\<.[[:digit:]]*b"))))
394
395(ert-deftest rx-redefine-builtin ()
396 (should-error (rx-define sequence () "x"))
397 (should-error (rx-define sequence "x"))
398 (should-error (rx-define nonl () "x"))
399 (should-error (rx-define nonl "x"))
400 (should-error (rx-let ((punctuation () "x")) nil))
401 (should-error (rx-let ((punctuation "x")) nil))
402 (should-error (rx-let-eval '((not-char () "x")) nil))
403 (should-error (rx-let-eval '((not-char "x")) nil)))
306 404
307(ert-deftest rx-constituents () 405(ert-deftest rx-constituents ()
308 (let ((rx-constituents 406 (let ((rx-constituents