git.fiddlerwoaroof.com
Browse code

refactor: move patmatch to its own folder and reforma

Ed Langley authored on 03/11/2019 21:48:21
Showing 7 changed files
... ...
@@ -46,22 +46,14 @@
46 46
     :author "Ed L <edward@elangley.org>"
47 47
     :license "MIT"
48 48
     :depends-on (#:alexandria
49
+                 #:closer-mop
50
+                 #:parachute
51
+                 #:serapeum
49 52
                  #:uiop)
50
-    :serial t
51 53
     :components ((:module "patmatch"
52 54
                   :components ((:file "package")
53 55
                                (:file "patmatch" :depends-on ("package"))))))
54 56
 
55
-(defsystem :fwoar-lisputils/patmatch/test 
56
-    :description ""
57
-    :author "Ed L <edward@elangley.org>"
58
-    :license "MIT"
59
-    :depends-on (:fwoar-lisputils/patmatch
60
-                 :parachute)
61
-    :serial t
62
-    :components ((:module "patmatch"
63
-                  :components ((:file "test")))))
64
-
65 57
 (defsystem #:fwoar-lisputils/string-utils
66 58
     :description "A string splitter"
67 59
     :author "fiddlerwoaroof <fiddlerwoaroof@gmail.com"
... ...
@@ -1,17 +1,18 @@
1 1
 (in-package #:fwoar.lisputils)
2 2
 
3
-(defmacro neither (&rest forms) `(not (or ,@forms)))
3
+(defmacro neither (&rest forms)
4
+  `(not (or ,@forms)))
4 5
 
5 6
 (defmacro neither-null (&rest forms)
6 7
   `(neither ,@(loop for form
7
-                 in forms
8
-                 collecting `(null ,form))))
8
+                      in forms
9
+                    collecting `(null ,form))))
9 10
 
10 11
 
11 12
 (defmacro let-each ((&key (be '*)) &body forms)
12 13
   "Bind each element successively to the symbol specified via :be"
13 14
   `(let* ,(loop for form in forms
14
-             collect (list be form))
15
+                collect (list be form))
15 16
      ,be))
16 17
 
17 18
 (defmacro let-first ((&key (be '*)) bound &body forms)
... ...
@@ -114,10 +115,10 @@
114 115
 
115 116
 (defmacro m-lambda (sym &rest args)
116 117
   (let ((arglist (loop for x in args
117
-                    unless (member x (list '&optional '&key '&rest))
118
-                    collect (ctypecase x
119
-                              (cons                  (car x))
120
-                              ((or symbol keyword string) x)))))
118
+                       unless (member x (list '&optional '&key '&rest))
119
+                         collect (ctypecase x
120
+                                   (cons                  (car x))
121
+                                   ((or symbol keyword string) x)))))
121 122
     `(lambda (,@args)
122 123
        (,sym ,@arglist))))
123 124
 
... ...
@@ -133,14 +134,14 @@
133 134
                               args))
134 135
            (args (mapcar #'list args args-syms))
135 136
            (destructuring-expressions
136
-            (rollup-list
137
-             (loop for (arg arg-sym) in args
138
-                collect (if (consp arg)
139
-                            `(destructuring-bind ,arg ,arg-sym
140
-                               (declare (ignore ,@ignored) (ignorable ,@ignorable)))
141
-                            `(let ((,arg ,arg-sym))
142
-                               ,@(generate-declarations-for arg ignored ignorable))))
143
-             body)))
137
+             (rollup-list
138
+              (loop for (arg arg-sym) in args
139
+                    collect (if (consp arg)
140
+                                `(destructuring-bind ,arg ,arg-sym
141
+                                   (declare (ignore ,@ignored) (ignorable ,@ignorable)))
142
+                                `(let ((,arg ,arg-sym))
143
+                                   ,@(generate-declarations-for arg ignored ignorable))))
144
+              body)))
144 145
       `(lambda ,args-syms
145 146
          ,destructuring-expressions))))
146 147
 
... ...
@@ -176,8 +177,9 @@
176 177
   (alexandria:once-only (from to)
177 178
     `(progn
178 179
        (setf ,@(apply #'append
179
-                      (iterate:iterate (iterate:for (fro-slot to-slot) iterate:in (ensure-mapping slots))
180
-                                       (iterate:collect `((slot-value ,to ',to-slot) (slot-value ,from ',fro-slot))))))
180
+                      (iterate:iterate
181
+                        (iterate:for (fro-slot to-slot) iterate:in (ensure-mapping slots))
182
+                        (iterate:collect `((slot-value ,to ',to-slot) (slot-value ,from ',fro-slot))))))
181 183
        ,to)))
182 184
 
183 185
 (defun transform-alist (function alist)
... ...
@@ -207,7 +209,7 @@
207 209
              (typecase (cdr form)
208 210
                (symbol (list (cdr form)))
209 211
                (cons (loop for thing in (cdr form)
210
-                        append (find-nonoperator-symbols thing))))))))))
212
+                           append (find-nonoperator-symbols thing))))))))))
211 213
 
212 214
 (defmacro may ((op arg))
213 215
   (alexandria:once-only (arg)
... ...
@@ -237,16 +239,18 @@
237 239
 (defun make-pairs (symbols)
238 240
                                         ;TODO: does this duplicate ensure-mapping?
239 241
   (cons 'list
240
-        (iterate:iterate (iterate:for (key value) in symbols)
241
-                         (iterate:collect `(list* ,(symbol-name key) ,value)))))
242
+        (iterate:iterate
243
+          (iterate:for (key value) in symbols)
244
+          (iterate:collect `(list* ,(symbol-name key) ,value)))))
242 245
 
243 246
 (defmacro slots-to-pairs (obj (&rest slots))
244 247
   (declare (optimize (debug 3)))
245 248
   "Produce a alist from a set of object slots and their values"
246 249
   (alexandria:once-only (obj)
247 250
     (let* ((slots (ensure-mapping slots))
248
-           (bindings (iterate:iterate (iterate:for (slot v &key bind-from) in slots)
249
-                                      (iterate:collect (or bind-from slot)))))
251
+           (bindings (iterate:iterate
252
+                       (iterate:for (slot v &key bind-from) in slots)
253
+                       (iterate:collect (or bind-from slot)))))
250 254
       `(with-slots ,bindings ,obj
251 255
          ,(make-pairs slots)))))
252 256
 
... ...
@@ -6,3 +6,4 @@
6 6
 (defpackage :patmatch
7 7
   (:use :cl)
8 8
   (:export :let-pat* :handle-pattern :no-pattern))
9
+
9 10
new file mode 100644
... ...
@@ -0,0 +1,11 @@
1
+(in-package :asdf-user)
2
+
3
+(defsystem :fwoar-lisputils/patmatch/test 
4
+    :description ""
5
+    :author "Ed L <edward@elangley.org>"
6
+    :license "MIT"
7
+    :depends-on (#:fwoar-lisputils/patmatch
8
+                 #:parachute
9
+                 #:serapeum)
10
+    :components ((:file "test-fixtures")
11
+                 (:file "test" :depends-on ("test-fixtures"))))
... ...
@@ -42,4 +42,3 @@
42 42
   `(let* (,@ (loop for ((discriminator . args) val-form) in clauses
43 43
                    append (apply 'handle-pattern discriminator val-form args)))
44 44
      ,@body))
45
-
46 45
new file mode 100644
... ...
@@ -0,0 +1,36 @@
1
+(defpackage :patmatch/test
2
+  (:use :cl)
3
+  (:import-from :parachute
4
+                #:true #:false #:fail #:is #:isnt #:is-values #:isnt-values
5
+                #:of-type #:finish #:define-test)
6
+  (:import-from :patmatch :let-pat*)
7
+  (:export ))
8
+(in-package :patmatch/test)
9
+
10
+(defclass test-base ()
11
+  ((a :initform 1)))
12
+
13
+(defclass test-sub1 (test-base)
14
+  ())
15
+
16
+(defclass test-sub2 (test-base)
17
+  ((b :initform 2)))
18
+
19
+(eval-when (:compile-toplevel :load-toplevel :execute)
20
+  (closer-mop:ensure-class 'test-base)
21
+  (closer-mop:ensure-class 'test-sub1)
22
+  (closer-mop:ensure-class 'test-sub2))
23
+
24
+(defmethod patmatch:handle-pattern append ((pattern test-base) form &rest args)
25
+  (alexandria:when-let ((arg (getf args :a)))
26
+    (let ((val-sym (gensym "test-base-")))
27
+      `((,val-sym ,form)
28
+        ,@(serapeum:unsplice
29
+           `(,arg (slot-value ,val-sym 'a)))))))
30
+
31
+(defmethod patmatch:handle-pattern append ((pattern test-sub2) form &rest args)
32
+  (alexandria:when-let ((arg (getf args :b)))
33
+    (let ((val-sym (gensym "test-base-")))
34
+      `((,val-sym ,form)
35
+        ,@(serapeum:unsplice
36
+           `(,arg (slot-value ,val-sym 'b)))))))
... ...
@@ -1,118 +1,52 @@
1
-(defpackage :patmatch/test
2
-  (:use :cl)
3
-  (:import-from :parachute
4
-                #:true #:false #:fail #:is #:isnt #:is-values #:isnt-values
5
-                #:of-type #:finish #:define-test)
6
-  (:import-from :patmatch :let-pat*)
7
-  (:export ))
8 1
 (in-package :patmatch/test)
9 2
 
10
-(define-test add-stuff
11
-  (is =
12
-      (progn (sleep 2)
13
-             2)
14
-      2))
3
+(define-test let-pat*)
15 4
 
16 5
 (define-test let-pat*-handles-cons
17
-  (is =
18
-      2
19
-      (let-pat* (((cons a b) '(2 . 3)))
20
-        (declare (ignore b))
21
-        a)))
22
-
23
-#|
24
-(deftest let-pat*-handles-cons ()
25
-""
26
-(should be eql
27
-2
28
-(let-pat* (((cons a b) '(2 . 3)))
29
-(declare (ignore b))
30
-a))
31
-(should be eql
32
-3
33
-(let-pat* (((cons a b) '(2 . 3)))
34
-(declare (ignore a))
35
-b)))
36
-
37
-(deftest let-pat*-handles-vector ()
38
-  ""
39
-  (should be eql
40
-          2
41
-          (let-pat* (((vector a b) #(2 3)))
6
+  :parent let-pat*
7
+  (is = 2 (let-pat* (((cons a b) '(2 . 3)))
42 8
             (declare (ignore b))
43 9
             a))
44
-  (should be eql
45
-          3
46
-          (let-pat* (((vector a b) #(2 3)))
10
+
11
+  (is = 3 (let-pat* (((cons a b) '(2 . 3)))
47 12
             (declare (ignore a))
48 13
             b)))
49 14
 
50
-(deftest let-pat*-handles-hash-table ()
51
-  ""
52
-  (should be eql
53
-          2
54
-          (let-pat* (((hash-table (:a a) (:b b)) (alexandria:plist-hash-table '(:a 2 :b 3))))
15
+(define-test let-pat*-handles-vector
16
+  :parent let-pat*
17
+  (is = 2 (let-pat* (((vector a b) #(2 3)))
55 18
             (declare (ignore b))
56 19
             a))
57
-  (should be eql
58
-          3
59
-          (let-pat* (((hash-table (:a a) (:b b)) (alexandria:plist-hash-table '(:a 2 :b 3))))
20
+  (is = 3 (let-pat* (((vector a b) #(2 3)))
60 21
             (declare (ignore a))
61 22
             b)))
62 23
 
63
-(eval-when (:compile-toplevel :load-toplevel :execute)
64
-  (defclass test-base ()
65
-    ((a :initform 1)))
66
-  (defclass test-sub1 (test-base)
67
-    ())
68
-  (defclass test-sub2 (test-base)
69
-    ((b :initform 2)))
70
-  (closer-mop:ensure-class 'test-base)
71
-  (closer-mop:ensure-class 'test-sub1)
72
-  (closer-mop:ensure-class 'test-sub2)
73
-  )
74
-
75
-(defmethod patmatch:handle-pattern append ((pattern test-base) form &rest args)
76
-  (alexandria:when-let ((arg (getf args :a)))
77
-    (let ((val-sym (gensym "test-base-")))
78
-      `((,val-sym ,form)
79
-        ,@(serapeum:unsplice
80
-           `(,arg (slot-value ,val-sym 'a)))))))
24
+(define-test let-pat*-handles-hash-table
25
+  :parent let-pat*
26
+  (is = 2 (let-pat* (((hash-table (:a a) (:b b)) (alexandria:plist-hash-table '(:a 2 :b 3))))
27
+            (declare (ignore b))
28
+            a))
81 29
 
82
-(defmethod patmatch:handle-pattern append ((pattern test-sub2) form &rest args)
83
-  (alexandria:when-let ((arg (getf args :b)))
84
-    (let ((val-sym (gensym "test-base-")))
85
-      `((,val-sym ,form)
86
-        ,@(serapeum:unsplice
87
-           `(,arg (slot-value ,val-sym 'b)))))))
30
+  (is = 3 (let-pat* (((hash-table (:a a) (:b b)) (alexandria:plist-hash-table '(:a 2 :b 3))))
31
+            (declare (ignore a))
32
+            b)))
88 33
 
89 34
 
90
-(deftest let-pat*-handles-object-destructuring ()
91
-  ""
92
-  (should be eql
93
-          1
94
-          (let-pat* (((test-base :a a) (make-instance 'test-base)))
35
+(define-test let-pat*-handles-object-destructuring
36
+  :parent let-pat*
37
+  (is = 1 (let-pat* (((test-base :a a) (make-instance 'test-base)))
95 38
             a)))
96 39
 
97
-(deftest let-pat*-handles-inheritance ()
98
-""
99
-(should be eql
100
-1
101
-(let-pat* (((test-base :a a) (make-instance 'test-sub1)))
102
-a))
40
+(define-test let-pat*-handles-inheritance
41
+  :parent let-pat*
42
+  (is = 1 (let-pat* (((test-base :a a) (make-instance 'test-sub1)))
43
+            a))
103 44
 
104
-(should be eql
105
-1
106
-(let-pat* (((test-sub1 :a a) (make-instance 'test-sub1)))
107
-a))
45
+  (is = 1 (let-pat* (((test-sub1 :a a) (make-instance 'test-sub1)))
46
+            a))
108 47
 
109
-(should be eql
110
-1
111
-(let-pat* (((test-sub2 :a a) (make-instance 'test-sub2)))
112
-a))
48
+  (is = 1 (let-pat* (((test-sub2 :a a) (make-instance 'test-sub2)))
49
+            a))
113 50
 
114
-(should be equal
115
-'(1 2)
116
-(let-pat* (((test-sub2 :a a :b b) (make-instance 'test-sub2)))
117
-(list a b))))
118
-|#
51
+  (is equal '(1 2) (let-pat* (((test-sub2 :a a :b b) (make-instance 'test-sub2)))
52
+                     (list a b))))