Browse code
Remove dependency on serapeum, as that tends to break
Ed Langley authored on 05/02/2018 06:39:29
Showing 3 changed files
Showing 3 changed files
... | ... |
@@ -6,14 +6,14 @@ |
6 | 6 |
|
7 | 7 |
(defmacro neither-null (&rest forms) |
8 | 8 |
`(neither ,@(loop for form |
9 |
- in forms |
|
10 |
- collecting `(null ,form)))) |
|
9 |
+ in forms |
|
10 |
+ collecting `(null ,form)))) |
|
11 | 11 |
|
12 | 12 |
|
13 | 13 |
(defmacro let-each ((&key (be '*)) &body forms) |
14 | 14 |
"Bind each element successively to the symbol specified via :be" |
15 | 15 |
`(let* ,(loop for form in forms |
16 |
- collect (list be form)) |
|
16 |
+ collect (list be form)) |
|
17 | 17 |
,be)) |
18 | 18 |
|
19 | 19 |
(defmacro let-first ((&key (be '*)) bound &body forms) |
... | ... |
@@ -34,7 +34,7 @@ |
34 | 34 |
"Make a lambda that wraps an call to if" |
35 | 35 |
`(lambda ,args |
36 | 36 |
(if (,test ,@args) |
37 |
- ,@body))) |
|
37 |
+ ,@body))) |
|
38 | 38 |
|
39 | 39 |
(defmacro lambda-cond ((&rest args) &body body) |
40 | 40 |
"Make a lambda that wraps an call to cond" |
... | ... |
@@ -52,73 +52,74 @@ |
52 | 52 |
(cond |
53 | 53 |
((null cons) '()) |
54 | 54 |
((consp (cdr cons)) (cons (funcall cb (car cons)) |
55 |
- (map-cons cb (cdr cons)))) |
|
55 |
+ (map-cons cb (cdr cons)))) |
|
56 | 56 |
(t (list (funcall cb (car cons)) |
57 |
- (funcall cb (cdr cons)))))) |
|
57 |
+ (funcall cb (cdr cons)))))) |
|
58 | 58 |
|
59 | 59 |
(defun generate-declarations-for (sym ignored ignorable) |
60 | 60 |
(let ((ignores (list)) |
61 |
- (ignorables (list))) |
|
62 |
- (map-cons (op (cond ((member _1 ignorable) |
|
63 |
- (push _1 ignorables)) |
|
64 |
- ((member _1 ignored) |
|
65 |
- (push _1 ignores)))) |
|
66 |
- (ensure-cons sym)) |
|
61 |
+ (ignorables (list))) |
|
62 |
+ (map-cons (lambda (_1) |
|
63 |
+ (cond ((member _1 ignorable) |
|
64 |
+ (push _1 ignorables)) |
|
65 |
+ ((member _1 ignored) |
|
66 |
+ (push _1 ignores)))) |
|
67 |
+ (alexandria:ensure-cons sym)) |
|
67 | 68 |
(if (or ignores ignorables) |
68 |
- `((declare |
|
69 |
- ,@(when ignores |
|
70 |
- `((ignore ,@ignores))) |
|
71 |
- ,@(when ignorables |
|
72 |
- `((ignorable ,@ignorables))))) |
|
73 |
- '()))) |
|
69 |
+ `((declare |
|
70 |
+ ,@(when ignores |
|
71 |
+ `((ignore ,@ignores))) |
|
72 |
+ ,@(when ignorables |
|
73 |
+ `((ignorable ,@ignorables))))) |
|
74 |
+ '()))) |
|
74 | 75 |
|
75 | 76 |
(defun find-ignored-vars (body) |
76 | 77 |
(let ((possible-declarations (car body)) |
77 |
- (ignored-vars nil) |
|
78 |
- (ignorable-vars nil)) |
|
78 |
+ (ignored-vars nil) |
|
79 |
+ (ignorable-vars nil)) |
|
79 | 80 |
(if (and (consp possible-declarations) |
80 |
- (eq (car possible-declarations) 'declare) |
|
81 |
- (consp (cadr possible-declarations))) |
|
82 |
- (let* ((declarations (cdr possible-declarations))) |
|
83 |
- (setf ignored-vars (cdr (assoc 'ignore declarations)) |
|
84 |
- ignorable-vars (cdr (assoc 'ignorable declarations)) |
|
85 |
- body (cdr body)))) |
|
81 |
+ (eq (car possible-declarations) 'declare) |
|
82 |
+ (consp (cadr possible-declarations))) |
|
83 |
+ (let* ((declarations (cdr possible-declarations))) |
|
84 |
+ (setf ignored-vars (cdr (assoc 'ignore declarations)) |
|
85 |
+ ignorable-vars (cdr (assoc 'ignorable declarations)) |
|
86 |
+ body (cdr body)))) |
|
86 | 87 |
(values ignored-vars |
87 |
- ignorable-vars |
|
88 |
- body))) |
|
88 |
+ ignorable-vars |
|
89 |
+ body))) |
|
89 | 90 |
|
90 | 91 |
(defun ensure-mapping (list) |
91 | 92 |
"Take a list and make sure that it's parseable as a let-style binding. |
92 | 93 |
Very handy for certain sorts of macros." |
93 | 94 |
(let ((symbols->mappings (lambda-cond (x) |
94 |
- ((symbolp x) `(,x ,x)) |
|
95 |
- ((null (cdr x)) `(,#1=(car x) ,#1#)) |
|
96 |
- (t x)))) |
|
95 |
+ ((symbolp x) `(,x ,x)) |
|
96 |
+ ((null (cdr x)) `(,#1=(car x) ,#1#)) |
|
97 |
+ (t x)))) |
|
97 | 98 |
(mapcar symbols->mappings list))) |
98 | 99 |
|
99 | 100 |
|
100 | 101 |
(defun rollup-list (list &optional body) |
101 | 102 |
(labels ((helper (list &optional accum start) |
102 |
- (tagbody |
|
103 |
- start |
|
104 |
- (cond |
|
105 |
- ((endp list) (return-from rollup-list accum)) |
|
106 |
- (t (psetf accum (cond |
|
107 |
- ((null accum) (car list)) |
|
108 |
- (start `(,@(car list) ,@accum)) |
|
109 |
- (t `(,@(car list) ,accum))) |
|
110 |
- list (cdr list) |
|
111 |
- start nil) |
|
112 |
- ;; NOTE: REMEMBER! This call to #'GO is the "tail call" |
|
113 |
- (go start)))))) |
|
103 |
+ (tagbody |
|
104 |
+ start |
|
105 |
+ (cond |
|
106 |
+ ((endp list) (return-from rollup-list accum)) |
|
107 |
+ (t (psetf accum (cond |
|
108 |
+ ((null accum) (car list)) |
|
109 |
+ (start `(,@(car list) ,@accum)) |
|
110 |
+ (t `(,@(car list) ,accum))) |
|
111 |
+ list (cdr list) |
|
112 |
+ start nil) |
|
113 |
+ ;; NOTE: REMEMBER! This call to #'GO is the "tail call" |
|
114 |
+ (go start)))))) |
|
114 | 115 |
(helper (reverse list) body t)))) |
115 | 116 |
|
116 | 117 |
(defmacro m-lambda (sym &rest args) |
117 | 118 |
(let ((arglist (loop for x in args |
118 |
- unless (member x (list '&optional '&key '&rest)) |
|
119 |
- collect (ctypecase x |
|
120 |
- (cons (car x)) |
|
121 |
- ((or symbol keyword string) x))))) |
|
119 |
+ unless (member x (list '&optional '&key '&rest)) |
|
120 |
+ collect (ctypecase x |
|
121 |
+ (cons (car x)) |
|
122 |
+ ((or symbol keyword string) x))))) |
|
122 | 123 |
`(lambda (,@args) |
123 | 124 |
(,sym ,@arglist)))) |
124 | 125 |
|
... | ... |
@@ -126,39 +127,39 @@ |
126 | 127 |
"A lambda whose arguments can be lambda-lists to be destructured" |
127 | 128 |
(multiple-value-bind (ignored ignorable body) (find-ignored-vars body) |
128 | 129 |
(let* ((args-syms (mapcar (lambda (_) (declare (ignore _)) (gensym "arg")) |
129 |
- args)) |
|
130 |
- (args (mapcar #'list args args-syms)) |
|
131 |
- (destructuring-expressions |
|
132 |
- (rollup-list |
|
133 |
- (loop for (arg arg-sym) in args |
|
134 |
- collect (if (consp arg) |
|
135 |
- `(destructuring-bind ,arg ,arg-sym |
|
136 |
- ,@(generate-declarations-for arg ignored ignorable)) |
|
137 |
- `(let ((,arg ,arg-sym)) |
|
138 |
- ,@(generate-declarations-for arg ignored ignorable)))) |
|
139 |
- body))) |
|
130 |
+ args)) |
|
131 |
+ (args (mapcar #'list args args-syms)) |
|
132 |
+ (destructuring-expressions |
|
133 |
+ (rollup-list |
|
134 |
+ (loop for (arg arg-sym) in args |
|
135 |
+ collect (if (consp arg) |
|
136 |
+ `(destructuring-bind ,arg ,arg-sym |
|
137 |
+ ,@(generate-declarations-for arg ignored ignorable)) |
|
138 |
+ `(let ((,arg ,arg-sym)) |
|
139 |
+ ,@(generate-declarations-for arg ignored ignorable)))) |
|
140 |
+ body))) |
|
140 | 141 |
`(lambda ,args-syms |
141 |
- ,destructuring-expressions)))) |
|
142 |
+ ,destructuring-expressions)))) |
|
142 | 143 |
|
143 | 144 |
|
144 | 145 |
;;; CASES::: |
145 | 146 |
#| |
146 | 147 |
(fw.lu::destructuring-lambda ((slot slot-keyword . r)) |
147 |
- (make-slot-spec slot slot-keyword)) |
|
148 |
+ (make-slot-spec slot slot-keyword)) |
|
148 | 149 |
|
149 | 150 |
(fw.lu::destructuring-lambda ((slot slot-keyword . r)) |
150 |
- (declare (ignore r)) |
|
151 |
- (make-slot-spec slot slot-keyword)) |
|
151 |
+ (declare (ignore r)) |
|
152 |
+ (make-slot-spec slot slot-keyword)) |
|
152 | 153 |
|
153 | 154 |
(fw.lu::destructuring-lambda ((slot slot-keyword . r) b c) |
154 |
- (make-slot-spec slot slot-keyword)) |
|
155 |
+ (make-slot-spec slot slot-keyword)) |
|
155 | 156 |
|
156 | 157 |
(fw.lu::destructuring-lambda ((slot slot-keyword . r) b) |
157 |
- (make-slot-spec slot slot-keyword)) |
|
158 |
+ (make-slot-spec slot slot-keyword)) |
|
158 | 159 |
|
159 | 160 |
(fw.lu::destructuring-lambda ((slot slot-keyword . r) b) |
160 |
- (declare (ignore r)) |
|
161 |
- (make-slot-spec slot slot-keyword)) |
|
161 |
+ (declare (ignore r)) |
|
162 |
+ (make-slot-spec slot slot-keyword)) |
|
162 | 163 |
|# |
163 | 164 |
|
164 | 165 |
(defun alist-string-hash-table (alist) |
... | ... |
@@ -213,7 +214,7 @@ |
213 | 214 |
`(funcall ,list-transform (transform-alist ,pair-transform ,@alist))) |
214 | 215 |
|
215 | 216 |
(defun make-pairs (symbols) |
216 |
- ;TODO: does this duplicate ensure-mapping? |
|
217 |
+ ;TODO: does this duplicate ensure-mapping? |
|
217 | 218 |
(cons 'list |
218 | 219 |
(iterate:iterate (iterate:for (key value) in symbols) |
219 | 220 |
(iterate:collect `(list* ,(symbol-name key) ,value))))) |
... | ... |
@@ -222,8 +223,8 @@ |
222 | 223 |
"Produce a alist from a set of object slots and their values" |
223 | 224 |
(once-only (obj) |
224 | 225 |
(let* ((slots (ensure-mapping slots)) |
225 |
- (bindings (iterate:iterate (iterate:for (slot v &key bind-from) in slots) |
|
226 |
- (iterate:collect (or bind-from slot))))) |
|
226 |
+ (bindings (iterate:iterate (iterate:for (slot v &key bind-from) in slots) |
|
227 |
+ (iterate:collect (or bind-from slot))))) |
|
227 | 228 |
`(with-slots ,bindings ,obj |
228 | 229 |
,(make-pairs slots))))) |
229 | 230 |
|
... | ... |
@@ -233,8 +234,8 @@ |
233 | 234 |
(with-output-to-string (ss) |
234 | 235 |
(prog1 ss |
235 | 236 |
(map 'vector |
236 |
- (lambda (x) (plump:serialize (plump:parse (plump:text x)) ss)) |
|
237 |
- html))))) |
|
237 |
+ (lambda (x) (plump:serialize (plump:parse (plump:text x)) ss)) |
|
238 |
+ html))))) |
|
238 | 239 |
|
239 | 240 |
(defmacro setfs (&body body) |
240 | 241 |
"Make setf a bit nicer to use with paredit" |
... | ... |
@@ -243,9 +244,9 @@ |
243 | 244 |
(defmacro prog2-let (first-form (&rest result-binding) &body body) |
244 | 245 |
"Execute a form, make a bunch of bindings and retern the bound values via prog1 after executing body" |
245 | 246 |
`(progn ,first-form |
246 |
- (let (,@result-binding) |
|
247 |
- (prog1 (list ,@(mapcar #'car result-binding)) |
|
248 |
- ,@body)))) |
|
247 |
+ (let (,@result-binding) |
|
248 |
+ (prog1 (list ,@(mapcar #'car result-binding)) |
|
249 |
+ ,@body)))) |
|
249 | 250 |
|
250 | 251 |
;; TODO: use multiple values . . . |
251 | 252 |
(defmacro prog1-let ((&rest result-binding) &body body) |
... | ... |
@@ -263,8 +264,8 @@ |
263 | 264 |
"Like if-let, but sets bindings sequentially. Doesn't short-circuit." |
264 | 265 |
`(let* ,bindings |
265 | 266 |
(if (and ,@(mapcar #'car bindings)) |
266 |
- ,then-form |
|
267 |
- ,else-form))) |
|
267 |
+ ,then-form |
|
268 |
+ ,else-form))) |
|
268 | 269 |
|
269 | 270 |
(defmacro with ((var val) &body body) |
270 | 271 |
"A stripped down let for binding a single name" |
... | ... |
@@ -275,11 +276,16 @@ |
275 | 276 |
(acons key datum alist))) |
276 | 277 |
(define-modify-macro aconsf (key datum) do-acons)) |
277 | 278 |
|
278 |
-;(defun ensure-list (val) |
|
279 |
-; (typecase val |
|
280 |
-; (list val) |
|
281 |
-; (t (list val)))) |
|
279 |
+ ;(defun ensure-list (val) |
|
280 |
+ ; (typecase val |
|
281 |
+ ; (list val) |
|
282 |
+ ; (t (list val)))) |
|
283 |
+ |
|
284 |
+(eval-when (:compile-toplevel :load-toplevel :execute) |
|
285 |
+ (when (find-package :serapeum) |
|
286 |
+ (pushnew :serapeum-present *features*))) |
|
282 | 287 |
|
288 |
+#+serapeum-present |
|
283 | 289 |
(defun map-tree* (fun tree &optional (tag nil tagp)) |
284 | 290 |
"Walk FUN over TREE and build a tree from the results. |
285 | 291 |
|
... | ... |
@@ -291,35 +297,35 @@ FUN can skip the current subtree with (throw TAG SUBTREE), in which |
291 | 297 |
case SUBTREE will be used as the value of the subtree." |
292 | 298 |
(let ((fun (ensure-function fun))) |
293 | 299 |
(labels ((map-tree (tree) |
294 |
- (let ((tree2 (funcall fun tree))) |
|
295 |
- (if (atom tree2) |
|
296 |
- tree2 |
|
297 |
- (serapeum::reuse-cons (map-tree (car tree2)) |
|
298 |
- (map-tree (cdr tree2)) |
|
299 |
- tree2)))) |
|
300 |
- (map-tree/tag (tree tag) |
|
301 |
- (catch tag |
|
302 |
- (let ((tree2 (funcall fun tree))) |
|
303 |
- (if (atom tree2) |
|
304 |
- tree2 |
|
305 |
- (serapeum::reuse-cons (map-tree/tag (car tree2) tag) |
|
306 |
- (map-tree/tag (cdr tree2) tag) |
|
307 |
- tree2)))))) |
|
300 |
+ (let ((tree2 (funcall fun tree))) |
|
301 |
+ (if (atom tree2) |
|
302 |
+ tree2 |
|
303 |
+ (serapeum::reuse-cons (map-tree (car tree2)) |
|
304 |
+ (map-tree (cdr tree2)) |
|
305 |
+ tree2)))) |
|
306 |
+ (map-tree/tag (tree tag) |
|
307 |
+ (catch tag |
|
308 |
+ (let ((tree2 (funcall fun tree))) |
|
309 |
+ (if (atom tree2) |
|
310 |
+ tree2 |
|
311 |
+ (serapeum::reuse-cons (map-tree/tag (car tree2) tag) |
|
312 |
+ (map-tree/tag (cdr tree2) tag) |
|
313 |
+ tree2)))))) |
|
308 | 314 |
(if tagp |
309 |
- (map-tree/tag tree tag) |
|
310 |
- (map-tree tree))))) |
|
315 |
+ (map-tree/tag tree tag) |
|
316 |
+ (map-tree tree))))) |
|
311 | 317 |
|
312 | 318 |
(defun replace-subtree (predicate value tree) |
313 | 319 |
(let ((spliced-value nil)) |
314 | 320 |
(flet ((mapper (x) |
315 |
- (typecase x |
|
316 |
- (cons |
|
317 |
- (if (funcall predicate x) |
|
318 |
- (progn |
|
319 |
- (setf spliced-value x) |
|
320 |
- (throw 'bail value)) |
|
321 |
- x)) |
|
322 |
- (t x)))) |
|
321 |
+ (typecase x |
|
322 |
+ (cons |
|
323 |
+ (if (funcall predicate x) |
|
324 |
+ (progn |
|
325 |
+ (setf spliced-value x) |
|
326 |
+ (throw 'bail value)) |
|
327 |
+ x)) |
|
328 |
+ (t x)))) |
|
323 | 329 |
(let ((result (map-tree* #'mapper tree 'bail))) |
324 |
- (values result spliced-value))))) |
|
330 |
+ (values result spliced-value))))) |
|
325 | 331 |
|
... | ... |
@@ -4,19 +4,18 @@ |
4 | 4 |
(:use :cl)) |
5 | 5 |
|
6 | 6 |
(defpackage :fwoar.anonymous-gf |
7 |
- (:use :cl :alexandria) |
|
7 |
+ (:use :cl) |
|
8 | 8 |
(:export :glambda)) |
9 | 9 |
|
10 | 10 |
(defpackage :patmatch |
11 |
- (:use :cl :alexandria :serapeum) |
|
11 |
+ (:use :cl) |
|
12 | 12 |
(:export :let-pat* |
13 | 13 |
:handle-pattern)) |
14 | 14 |
|
15 | 15 |
(defpackage #:fwoar.lisputils |
16 |
- (:use #:cl #:alexandria) |
|
16 |
+ (:use #:cl) |
|
17 | 17 |
(:nicknames #:fw.lu) |
18 | 18 |
(:shadow #:with) |
19 |
- (:import-from #:serapeum #:op) |
|
20 | 19 |
(:import-from :fwoar.anonymous-gf :glambda) |
21 | 20 |
(:import-from :patmatch :let-pat*) |
22 | 21 |
(:export #:lambda-if #:lambda-cond #:alambda #:rollup-list |