Skip to content
This repository was archived by the owner on May 19, 2025. It is now read-only.

Commit c69db04

Browse files
andrzejwalczakcommon-lisp-dev
authored andcommitted
Internal change
PiperOrigin-RevId: 313584484
1 parent 3d3d1c2 commit c69db04

File tree

2 files changed

+155
-9
lines changed

2 files changed

+155
-9
lines changed

etc.lisp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#:ace.core.once-only)
1515
(:import-from #:ace.core.type #:variable-information)
1616
(:export
17+
#:one-of
1718
#:orf #:andf
1819
#:define-constant
1920
#:define-numerals
@@ -121,6 +122,14 @@
121122
:collect
122123
`(defconstant ,n (%set-constant-value ',n ,o #'%numeral-eq)))))
123124

125+
;;;
126+
;;; one-of shortcut
127+
128+
(defmacro one-of (e &rest members)
129+
"True if element E compares EQL with at least one of the MEMBERS."
130+
(once-only (e)
131+
`(or ,@(lmap (m members) `(eql ,e ,m)))))
132+
124133
;;;
125134
;;; SETF forms for OR and AND.
126135
;;; TODO(czak): Move to an own module.
@@ -186,15 +195,22 @@ This is different from a potential DEFINE-MODIFY-MACRO operator which
186195
would always set the place even in the case where its first value is non-NIL."
187196
(multiple-value-bind (vars vals places setter getter)
188197
(get-setf-expansion place env)
189-
(let* ((place (if (cdr places) `(values ,@places) (car places)))
190-
(setfs (lmap (form rest) `(setf ,place ,form))))
191-
`(let* (,@(mapcar #'list vars vals)
192-
,@places)
193-
(cond ((setf ,place ,getter)
194-
,place)
195-
(,@(and (cdr places) '(t))
196-
(or ,@setfs)
197-
,setter))))))
198+
`(let* (,@(mapcar #'list vars vals)
199+
,@places)
200+
,(if (cdr places)
201+
;; multiple value places
202+
(let ((store-vars `(values ,@places)))
203+
`(cond ((setf ,store-vars ,getter)
204+
,store-vars)
205+
(t
206+
(or ,@(lmap (form rest) `(setf ,store-vars ,form)))
207+
,setter)))
208+
;; single value place
209+
(let* ((place (car places)))
210+
`(or ,getter
211+
(progn
212+
(setf ,place (or ,@rest))
213+
,setter)))))))
198214

199215
(defmacro andf (place &rest rest &environment env)
200216
"The ANDF modifying macro has a similar short-cut semantics as AND.

list.lisp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@
4545
#:remove #:remove-if #:remove-if-not
4646
#:delete #:delete-if #:delete-if-not
4747
#:delete-adjacent
48+
49+
#:removef
50+
#:removef-if
51+
#:removef-if-not
52+
#:deletef
53+
#:deletef-if
54+
#:deletef-if-not
55+
4856
#:partition
4957
#:npartition
5058
#:dolist*
@@ -970,6 +978,128 @@ Parameters:
970978
(define-compiler-macro copy-if-not (&whole whole &rest args)
971979
(apply #'%remove-if-form whole args))
972980

981+
;;;
982+
;;; Modifying macros.
983+
;;;
984+
985+
(defmacro removef (item list &rest rest
986+
&key from-end test test-not start end count key
987+
&environment env)
988+
"Remove all elements from the LIST that match the ITEM.
989+
LIST needs to be a place and is assigned the new returned LIST.
990+
991+
The REST parameters are:
992+
FROM-END - if true, will start deleting from the end,
993+
TEST - the equality test used to compare ITEM with the elements in the list,
994+
TEST-NOT - the complement of the TEST,
995+
START - the START index (default 0),
996+
END - the END index (default is NIL, the end of list),
997+
COUNT - the maximum count of elements to be deleted,
998+
KEY - a function that derives values to be compared with the ITEM."
999+
(declare (ignore from-end test test-not start end count key))
1000+
(multiple-value-bind (vars vals places setter getter) (get-setf-expansion list env)
1001+
`(let* (,@(mapcar #'list vars vals)
1002+
(,(first places) (remove ,item ,getter ,@rest))
1003+
,@(rest places))
1004+
,setter)))
1005+
1006+
(defmacro removef-if (predicate list &rest rest
1007+
&key from-end start end count key
1008+
&environment env)
1009+
"Remove all elements from the LIST that match the PREDICATE.
1010+
LIST needs to be a place and is assigned the new returned LIST.
1011+
1012+
The REST parameters are:
1013+
FROM-END - if true, will start deleting from the end,
1014+
START - the START index (default 0),
1015+
END - the END index (default is NIL, the end of list),
1016+
COUNT - the maximum count of elements to be deleted,
1017+
KEY - a function that derives values to be tested by the predicate."
1018+
(declare (ignore from-end start end count key))
1019+
(multiple-value-bind (vars vals places setter getter) (get-setf-expansion list env)
1020+
`(let* (,@(mapcar #'list vars vals)
1021+
(,(first places) (remove-if ,predicate ,getter ,@rest))
1022+
,@(rest places))
1023+
,setter)))
1024+
1025+
(defmacro removef-if-not (predicate list &rest rest
1026+
&key from-end start end count key
1027+
&environment env)
1028+
"Remove all elements from the LIST that does NOT match the PREDICATE.
1029+
LIST needs to be a place and is assigned the new returned LIST.
1030+
1031+
The REST parameters are:
1032+
FROM-END - if true, will start deleting from the end,
1033+
START - the START index (default 0),
1034+
END - the END index (default is NIL, the end of list),
1035+
COUNT - the maximum count of elements to be deleted,
1036+
KEY - a function that derives values to be tested by the predicate."
1037+
(declare (ignore from-end start end count key))
1038+
(multiple-value-bind (vars vals places setter getter) (get-setf-expansion list env)
1039+
`(let* (,@(mapcar #'list vars vals)
1040+
(,(first places) (remove-if-not ,predicate ,getter ,@rest))
1041+
,@(rest places))
1042+
,setter)))
1043+
1044+
(defmacro deletef (item list &rest rest
1045+
&key from-end test test-not start end count key
1046+
&environment env)
1047+
"Destructively delete all elements from the LIST that match the ITEM.
1048+
LIST needs to be a place and is assigned the returned modified LIST.
1049+
1050+
The REST parameters are:
1051+
FROM-END - if true, will start deleting from the end,
1052+
TEST - the equality test used to compare ITEM with the elements in the list,
1053+
TEST-NOT - the complement of the TEST,
1054+
START - the START index (default 0),
1055+
END - the END index (default is NIL, the end of list),
1056+
COUNT - the maximum count of elements to be deleted,
1057+
KEY - a function that derives values to be compared with the ITEM."
1058+
(declare (ignore from-end test test-not start end count key))
1059+
(multiple-value-bind (vars vals places setter getter) (get-setf-expansion list env)
1060+
`(let* (,@(mapcar #'list vars vals)
1061+
(,(first places) (delete ,item ,getter ,@rest))
1062+
,@(rest places))
1063+
,setter)))
1064+
1065+
(defmacro deletef-if (predicate list &rest rest
1066+
&key from-end start end count key
1067+
&environment env)
1068+
"Destructively delete all elements from the LIST that match the PREDICATE.
1069+
LIST needs to be a place and is assigned the returned modified LIST.
1070+
1071+
The REST parameters are:
1072+
FROM-END - if true, will start deleting from the end,
1073+
START - the START index (default 0),
1074+
END - the END index (default is NIL, the end of list),
1075+
COUNT - the maximum count of elements to be deleted,
1076+
KEY - a function that derives values to be tested by the predicate."
1077+
(declare (ignore from-end start end count key))
1078+
(multiple-value-bind (vars vals places setter getter) (get-setf-expansion list env)
1079+
`(let* (,@(mapcar #'list vars vals)
1080+
(,(first places) (delete-if ,predicate ,getter ,@rest))
1081+
,@(rest places))
1082+
,setter)))
1083+
1084+
(defmacro deletef-if-not (predicate list &rest rest
1085+
&key from-end start end count key
1086+
&environment env)
1087+
"Destructively delete all elements from the LIST that does NOT match the PREDICATE.
1088+
LIST needs to be a place and is assigned the returned modified LIST.
1089+
1090+
The REST parameters are:
1091+
FROM-END - if true, will start deleting from the end,
1092+
START - the START index (default 0),
1093+
END - the END index (default is NIL, the end of list),
1094+
COUNT - the maximum count of elements to be deleted,
1095+
KEY - a function that derives values to be tested by the predicate."
1096+
(declare (ignore from-end start end count key))
1097+
(multiple-value-bind (vars vals places setter getter) (get-setf-expansion list env)
1098+
`(let* (,@(mapcar #'list vars vals)
1099+
(,(first places) (delete-if-not ,predicate ,getter ,@rest))
1100+
,@(rest places))
1101+
,setter)))
1102+
9731103
;;;
9741104
;;; etc ...
9751105
;;;

0 commit comments

Comments
 (0)