summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStas Boukarev <stassats@gmail.com>2016-04-01 12:46:11 +0300
committerStas Boukarev <stassats@gmail.com>2016-04-01 12:46:11 +0300
commit26aa9b68fb59cc18d216efe0f15d535eb11a2d5a (patch)
tree4efd9425e8ebc4ddaed49cc7b7c0eef1cf40b6fb
parent35c5266061d365afc78d9640e9e17c3f891fea91 (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.lisp60
-rw-r--r--test/simple8
2 files changed, 39 insertions, 29 deletions
diff --git a/api.lisp b/api.lisp
index ea04405..1580fee 100644
--- a/api.lisp
+++ b/api.lisp
@@ -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" #())))