diff options
author | Stas Boukarev <stassats@gmail.com> | 2016-04-01 12:46:11 +0300 |
---|---|---|
committer | Stas Boukarev <stassats@gmail.com> | 2016-04-01 12:46:11 +0300 |
commit | 26aa9b68fb59cc18d216efe0f15d535eb11a2d5a (patch) | |
tree | 4efd9425e8ebc4ddaed49cc7b7c0eef1cf40b6fb | |
parent | 35c5266061d365afc78d9640e9e17c3f891fea91 (diff) |
Fix compiler-macro interaction with LOAD-TIME-VALUE and CONSTANTP.
When CONSTANTP is supplied an &environment object from the compiler
macro it can determine forms involving MACROLET to be constant, but
such forms are problematic for LOAD-TIME-VALUE and its null lexical
environment execution requirements.
-rw-r--r-- | api.lisp | 60 | ||||
-rw-r--r-- | test/simple | 8 |
2 files changed, 39 insertions, 29 deletions
@@ -277,11 +277,13 @@ internal purposes.")) (values (car match) (cdr match) reg-starts reg-ends)))))) #-:cormanlisp -(define-compiler-macro scan (&whole form &environment env regex target-string &rest rest) +(define-compiler-macro scan (&whole form regex target-string &rest rest) "Make sure that constant forms are compiled into scanners at compile time." - (cond ((constantp regex env) - `(scan (load-time-value (create-scanner ,regex)) - ,target-string ,@rest)) + ;; Don't pass &environment to CONSTANTP, it may not be digestable by + ;; LOAD-TIME-VALUE, e.g., MACROLETs. + (cond ((constantp regex) + `(scan (load-time-value (create-scanner ,regex)) + ,target-string ,@rest)) (t form))) (defun scan-to-strings (regex target-string &key (start 0) @@ -311,11 +313,11 @@ share structure with TARGET-STRING." #-:cormanlisp (define-compiler-macro scan-to-strings - (&whole form &environment env regex target-string &rest rest) + (&whole form regex target-string &rest rest) "Make sure that constant forms are compiled into scanners at compile time." - (cond ((constantp regex env) - `(scan-to-strings (load-time-value (create-scanner ,regex)) - ,target-string ,@rest)) + (cond ((constantp regex) + `(scan-to-strings (load-time-value (create-scanner ,regex)) + ,target-string ,@rest)) (t form))) (defmacro register-groups-bind (var-list (regex target-string @@ -524,12 +526,12 @@ the scan is continued one position behind this match." (push match-end result-list)))) #-:cormanlisp -(define-compiler-macro all-matches (&whole form &environment env regex &rest rest) +(define-compiler-macro all-matches (&whole form regex &rest rest) "Make sure that constant forms are compiled into scanners at compile time." - (cond ((constantp regex env) - `(all-matches (load-time-value (create-scanner ,regex)) - ,@rest)) + (cond ((constantp regex) + `(all-matches (load-time-value (create-scanner ,regex)) + ,@rest)) (t form))) (defun all-matches-as-strings (regex target-string @@ -547,13 +549,13 @@ share structure with TARGET-STRING." (push match result-list)))) #-:cormanlisp -(define-compiler-macro all-matches-as-strings (&whole form &environment env regex &rest rest) +(define-compiler-macro all-matches-as-strings (&whole form regex &rest rest) "Make sure that constant forms are compiled into scanners at compile time." - (cond ((constantp regex env) - `(all-matches-as-strings - (load-time-value (create-scanner ,regex)) - ,@rest)) + (cond ((constantp regex) + `(all-matches-as-strings + (load-time-value (create-scanner ,regex)) + ,@rest)) (t form))) (defun split (regex target-string @@ -628,11 +630,11 @@ structure with TARGET-STRING." nil))))) #-:cormanlisp -(define-compiler-macro split (&whole form &environment env regex target-string &rest rest) +(define-compiler-macro split (&whole form regex target-string &rest rest) "Make sure that constant forms are compiled into scanners at compile time." - (cond ((constantp regex env) - `(split (load-time-value (create-scanner ,regex)) - ,target-string ,@rest)) + (cond ((constantp regex) + `(split (load-time-value (create-scanner ,regex)) + ,target-string ,@rest)) (t form))) (defun string-case-modifier (str from to start end) @@ -996,11 +998,11 @@ match. #-:cormanlisp (define-compiler-macro regex-replace - (&whole form &environment env regex target-string replacement &rest rest) + (&whole form regex target-string replacement &rest rest) "Make sure that constant forms are compiled into scanners at compile time." - (cond ((constantp regex env) - `(regex-replace (load-time-value (create-scanner ,regex)) - ,target-string ,replacement ,@rest)) + (cond ((constantp regex) + `(regex-replace (load-time-value (create-scanner ,regex)) + ,target-string ,replacement ,@rest)) (t form))) (defun regex-replace-all (regex target-string replacement &key @@ -1060,11 +1062,11 @@ match. #-:cormanlisp (define-compiler-macro regex-replace-all - (&whole form &environment env regex target-string replacement &rest rest) + (&whole form regex target-string replacement &rest rest) "Make sure that constant forms are compiled into scanners at compile time." - (cond ((constantp regex env) - `(regex-replace-all (load-time-value (create-scanner ,regex)) - ,target-string ,replacement ,@rest)) + (cond ((constantp regex) + `(regex-replace-all (load-time-value (create-scanner ,regex)) + ,target-string ,replacement ,@rest)) (t form))) #-:cormanlisp diff --git a/test/simple b/test/simple index 8c86c34..632301c 100644 --- a/test/simple +++ b/test/simple @@ -364,3 +364,11 @@ characters if there's a match." (regex-replace-all (create-scanner "\\p{even}") "abcd" "+") (regex-replace-all (create-scanner "\\p{true}") "abcd" "+"))) '("+b+d" "a+c+" "++++"))) + +(macrolet ((z () "(a)*b")) + (equalp (multiple-value-list (scan (z) "xaaabd")) + (list 1 5 #(3) #(4)))) + +(macrolet ((z () "[^b]*b")) + (equalp (multiple-value-list (scan-to-strings (z) "aaabd")) + (list "aaab" #()))) |