aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2019-10-22 17:02:23 +0200
committerMattias EngdegÄrd2019-10-24 10:23:00 +0200
commit539d0411bb04e5b3b32cd77ac3b3e4ad364589da (patch)
treeaf648e2b6719faf7dd9a310acdce692a8b11ca6e
parentb3b74514e98e2fc85c261a1444ce2db0cf23abfc (diff)
downloademacs-539d0411bb04e5b3b32cd77ac3b3e4ad364589da.tar.gz
emacs-539d0411bb04e5b3b32cd77ac3b3e4ad364589da.zip
rx.el: Refactor user-definition expansion
* lisp/emacs-lisp/rx.el (rx--translate-not): Simplify structure. * lisp/emacs-lisp/rx.el (rx--expand-def): New. (rx--translate-symbol, rx--translate-form): Use rx--expand-def.
-rw-r--r--lisp/emacs-lisp/rx.el97
1 files changed, 56 insertions, 41 deletions
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 2370948e81b..d7677f14443 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -122,9 +122,27 @@ Each entry is:
122 as the rx form DEF (which can contain members of ARGS).") 122 as the rx form DEF (which can contain members of ARGS).")
123 123
124(defsubst rx--lookup-def (name) 124(defsubst rx--lookup-def (name)
125 "Current definition of NAME: (DEF) or (ARGS DEF), or nil if none."
125 (or (cdr (assq name rx--local-definitions)) 126 (or (cdr (assq name rx--local-definitions))
126 (get name 'rx-definition))) 127 (get name 'rx-definition)))
127 128
129(defun rx--expand-def (form)
130 "FORM expanded (once) if a user-defined construct; otherwise nil."
131 (cond ((symbolp form)
132 (let ((def (rx--lookup-def form)))
133 (and def
134 (if (cdr def)
135 (error "Not an `rx' symbol definition: %s" form)
136 (car def)))))
137 ((consp form)
138 (let* ((op (car form))
139 (def (rx--lookup-def op)))
140 (and def
141 (if (cdr def)
142 (rx--expand-template
143 op (cdr form) (nth 0 def) (nth 1 def))
144 (error "Not an `rx' form definition: %s" op)))))))
145
128;; TODO: Additions to consider: 146;; TODO: Additions to consider:
129;; - A construct like `or' but without the match order guarantee, 147;; - A construct like `or' but without the match order guarantee,
130;; maybe `unordered-or'. Useful for composition or generation of 148;; maybe `unordered-or'. Useful for composition or generation of
@@ -155,11 +173,8 @@ Each entry is:
155 ((let ((class (cdr (assq sym rx--char-classes)))) 173 ((let ((class (cdr (assq sym rx--char-classes))))
156 (and class (cons (list (concat "[[:" (symbol-name class) ":]]")) t)))) 174 (and class (cons (list (concat "[[:" (symbol-name class) ":]]")) t))))
157 175
158 ((let ((definition (rx--lookup-def sym))) 176 ((let ((expanded (rx--expand-def sym)))
159 (and definition 177 (and expanded (rx--translate expanded))))
160 (if (cdr definition)
161 (error "Not an `rx' symbol definition: %s" sym)
162 (rx--translate (nth 0 definition))))))
163 178
164 ;; For compatibility with old rx. 179 ;; For compatibility with old rx.
165 ((let ((entry (assq sym rx-constituents))) 180 ((let ((entry (assq sym rx-constituents)))
@@ -446,21 +461,23 @@ If NEGATED, negate the sense (thus making it positive)."
446 (error "rx `not' form takes exactly one argument")) 461 (error "rx `not' form takes exactly one argument"))
447 (let ((arg (car body))) 462 (let ((arg (car body)))
448 (cond 463 (cond
449 ((consp arg) 464 ((and (consp arg)
450 (pcase (car arg) 465 (pcase (car arg)
451 ((or 'any 'in 'char) (rx--translate-any (not negated) (cdr arg))) 466 ((or 'any 'in 'char)
452 ('syntax (rx--translate-syntax (not negated) (cdr arg))) 467 (rx--translate-any (not negated) (cdr arg)))
453 ('category (rx--translate-category (not negated) (cdr arg))) 468 ('syntax
454 ('not (rx--translate-not (not negated) (cdr arg))) 469 (rx--translate-syntax (not negated) (cdr arg)))
455 (_ (error "Illegal argument to rx `not': %S" arg)))) 470 ('category
471 (rx--translate-category (not negated) (cdr arg)))
472 ('not
473 (rx--translate-not (not negated) (cdr arg))))))
474 ((let ((class (cdr (assq arg rx--char-classes))))
475 (and class
476 (rx--translate-any (not negated) (list class)))))
456 ((eq arg 'word-boundary) 477 ((eq arg 'word-boundary)
457 (rx--translate-symbol 478 (rx--translate-symbol
458 (if negated 'word-boundary 'not-word-boundary))) 479 (if negated 'word-boundary 'not-word-boundary)))
459 (t 480 (t (error "Illegal argument to rx `not': %S" arg)))))
460 (let ((class (cdr (assq arg rx--char-classes))))
461 (if class
462 (rx--translate-any (not negated) (list class))
463 (error "Illegal argument to rx `not': %s" arg)))))))
464 481
465(defun rx--atomic-regexp (item) 482(defun rx--atomic-regexp (item)
466 "ITEM is (REGEXP . PRECEDENCE); return a regexp of precedence t." 483 "ITEM is (REGEXP . PRECEDENCE); return a regexp of precedence t."
@@ -874,30 +891,28 @@ can expand to any number of values."
874 ((or 'regexp 'regex) (rx--translate-regexp body)) 891 ((or 'regexp 'regex) (rx--translate-regexp body))
875 892
876 (op 893 (op
877 (unless (symbolp op) 894 (cond
878 (error "Bad rx operator `%S'" op)) 895 ((not (symbolp op)) (error "Bad rx operator `%S'" op))
879 (let ((definition (rx--lookup-def op))) 896
880 (if definition 897 ((let ((expanded (rx--expand-def form)))
881 (if (cdr definition) 898 (and expanded
882 (rx--translate 899 (rx--translate expanded))))
883 (rx--expand-template 900
884 op body (nth 0 definition) (nth 1 definition))) 901 ;; For compatibility with old rx.
885 (error "Not an `rx' form definition: %s" op)) 902 ((let ((entry (assq op rx-constituents)))
886 903 (and (progn
887 ;; For compatibility with old rx. 904 (while (and entry (not (consp (cdr entry))))
888 (let ((entry (assq op rx-constituents))) 905 (setq entry
889 (if (progn 906 (if (symbolp (cdr entry))
890 (while (and entry (not (consp (cdr entry)))) 907 ;; Alias for another entry.
891 (setq entry 908 (assq (cdr entry) rx-constituents)
892 (if (symbolp (cdr entry)) 909 ;; Wrong type, try further down the list.
893 ;; Alias for another entry. 910 (assq (car entry)
894 (assq (cdr entry) rx-constituents) 911 (cdr (memq entry rx-constituents))))))
895 ;; Wrong type, try further down the list. 912 entry)
896 (assq (car entry) 913 (rx--translate-compat-form (cdr entry) form))))
897 (cdr (memq entry rx-constituents)))))) 914
898 entry) 915 (t (error "Unknown rx form `%s'" op)))))))
899 (rx--translate-compat-form (cdr entry) form)
900 (error "Unknown rx form `%s'" op)))))))))
901 916
902(defconst rx--builtin-forms 917(defconst rx--builtin-forms
903 '(seq sequence : and or | any in char not-char not 918 '(seq sequence : and or | any in char not-char not