git.fiddlerwoaroof.com
Browse code

chore: add new demos

Ed Langley authored on 20/11/2019 18:32:16
Showing 11 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,11 @@
1
+(progn
2
+  (defparameter *loads* ())
3
+  (defparameter *load-depth* 0)
4
+  (ccl:advise asdf:operate
5
+              (let ((current-load (list)))
6
+                (incf *load-depth*)
7
+                (push (cons *load-depth* arglist)
8
+                      *loads*)
9
+                (unwind-protect (:do-it)
10
+                  (decf *load-depth*)))
11
+              :when :around))
0 12
new file mode 100644
... ...
@@ -0,0 +1,48 @@
1
+(defun homedir-translation (input dd)
2
+  (declare (ignore dd))
3
+  (merge-pathnames
4
+   (make-pathname :directory
5
+                  (list* :relative
6
+                         "build-cache"
7
+                         "homedir"
8
+                         (cdr
9
+                          (pathname-directory
10
+                           (parse-namestring
11
+                            (enough-namestring input
12
+                                               (user-homedir-pathname))))))
13
+                  :defaults input)
14
+   (merge-pathnames "asdf-corral/Contents/Resources/"
15
+                    (user-homedir-pathname))))
16
+
17
+(defun do-translation (input dd)
18
+  (declare (ignore dd))
19
+  (merge-pathnames
20
+   (make-pathname :directory
21
+                  (list :relative
22
+                        "build-cache"
23
+                        "root"
24
+                        (format nil "~{~a~^-~}"(cdr (pathname-directory input))))
25
+                  :defaults input)
26
+   (merge-pathnames "asdf-corral/Contents/Resources/"
27
+                    (user-homedir-pathname))))
28
+
29
+(defun in-homedir ()
30
+  (merge-pathnames (make-pathname :directory (list :relative :wild-inferiors)
31
+                                  :name :wild
32
+                                  :type :wild
33
+                                  :version :wild)
34
+                   (user-homedir-pathname)))
35
+
36
+(asdf:initialize-output-translations
37
+ `(:output-translations
38
+   :ignore-inherited-configuration
39
+   :disable-cache
40
+   (,(in-homedir) (:function homedir-translation))
41
+   ("/" (:function do-translation))))
42
+
43
+(load "~/quicklisp/setup.lisp")
44
+
45
+(eval-when (:compile-toplevel :load-toplevel :execute)
46
+  (trace homedir-translation do-translation))
47
+
48
+(ql:quickload :data-lens)
0 49
new file mode 100644
... ...
@@ -0,0 +1,142 @@
1
+(defpackage :fwoar.bodge-like
2
+  (:use :cl )
3
+  (:export ))
4
+(in-package :fwoar.bodge-like)
5
+
6
+(defclass feature ()
7
+  ((%sym :reader sym :initarg sym)))
8
+
9
+(defclass monster (feature)
10
+  ((%position :accessor pos :initform (gamekit:vec2 (random 12)
11
+                                                    (random 12)))))
12
+
13
+(defclass dog (monster)
14
+  ()
15
+  (:default-initargs sym "d"))
16
+
17
+(defun monster (sym)
18
+  (make-instance 'monster 'sym sym))
19
+
20
+(defclass player (feature)
21
+  ((%position :accessor pos :initform (gamekit:vec2 0 0)))
22
+  (:default-initargs sym "@"))
23
+
24
+(defparameter *white* (gamekit:vec4 1 1 1 1))
25
+(defparameter *black* (gamekit:vec4 0 0 0 0.8))
26
+(defparameter *tile-size* 32)
27
+
28
+(gamekit:defgame bodgelike ()
29
+  ((%player :reader player :initform (make-instance 'player))
30
+   (%monsters :accessor monsters :initform ()))
31
+  (:viewport-title "@")
32
+  (:viewport-height (* 12 *tile-size*))
33
+  (:viewport-width (* 12 *tile-size*)))
34
+
35
+(defun draw-tile (row col &optional (size *tile-size*))
36
+  (gamekit:draw-rect (gamekit:vec2 (* row size)
37
+                                   (* col size))
38
+                     size size
39
+                     :fill-paint *black*))
40
+
41
+(defvar *my-font*)
42
+(defun draw-feature (feature &optional pos (tile-size *tile-size*))
43
+  (let* ((pos (if pos
44
+                  pos
45
+                  (pos feature)))
46
+         (row (gamekit:x pos))
47
+         (col (gamekit:y pos))
48
+         (tile-origin (gamekit:vec2 (* row tile-size)
49
+                                    (* col tile-size)))
50
+         (feature-text (etypecase feature
51
+                         (string feature)
52
+                         (feature (sym feature)))))
53
+    (multiple-value-bind (text-origin text-width text-height)
54
+        (gamekit:calc-text-bounds feature-text *my-font*)
55
+      (let ((text-origin
56
+              (gamekit:add tile-origin
57
+                           (gamekit:mult -1 text-origin)
58
+                           (gamekit:mult 0.5
59
+                                         (gamekit:subt (gamekit:vec2 tile-size tile-size)
60
+                                                       (gamekit:vec2 text-width text-height))))))
61
+        (gamekit:draw-text feature-text text-origin
62
+                           :fill-color *white*
63
+                           :font *my-font*)))))
64
+
65
+
66
+(gamekit:define-font :fantasy "/tmp/foo/font.ttf")
67
+
68
+
69
+(defgeneric interact2 (game obj1 obj2)
70
+  (:method (game obj1 obj2) nil)
71
+  (:method (game obj1 obj2) t)
72
+  (:method (game (obj1 player) (obj2 dog))
73
+    (format t "~&Ruff! ~s~%" (gamekit:subt (pos obj2)
74
+                                           (pos obj1)))
75
+    (setf (pos obj2)
76
+          (gamekit:add (pos obj2)
77
+                       (gamekit:subt (pos obj2)
78
+                                     (pos obj1))))
79
+    nil))
80
+
81
+(defun find-in-space (pos obj-list)
82
+  (find pos obj-list 
83
+        :key 'pos 
84
+        :test 'bodge-math:vec=))
85
+
86
+(defun update (thing fun &rest args)
87
+  (apply fun thing args))
88
+
89
+(define-modify-macro updatef (fun &rest args)
90
+  update)
91
+
92
+(defun move-handler (delta)
93
+  (lambda (game player)
94
+    (updatef (pos player)
95
+             (lambda (old-pos)
96
+               (let* ((new-pos (gamekit:add old-pos delta))
97
+                      (feature-in-space (find-in-space new-pos (monsters game))))
98
+                 (if (and feature-in-space (interact2 game player feature-in-space))
99
+                     old-pos
100
+                     new-pos))))) )
101
+
102
+(defun move-left (game player)
103
+  (let ((handler (move-handler (gamekit:vec2 -1 0))))
104
+    (lambda ()
105
+      (funcall handler game player))))
106
+
107
+(defun move-right (game player)
108
+  (let ((handler (move-handler (gamekit:vec2 1 0)))) 
109
+    (lambda ()
110
+      (funcall handler game player))))
111
+
112
+(defun move-up (game player)
113
+  (let ((handler (move-handler (gamekit:vec2 0 1)))) 
114
+    (lambda ()
115
+      (funcall handler game player))))
116
+
117
+(defun move-down (game player)
118
+  (let ((handler (move-handler (gamekit:vec2 0 -1)))) 
119
+    (lambda ()
120
+      (funcall handler game player))))
121
+
122
+
123
+(defmethod gamekit:post-initialize ((game bodgelike))
124
+  (gamekit:bind-button :h :pressed
125
+                       (move-left game (player game)))
126
+  (gamekit:bind-button :j :pressed
127
+                       (move-down game (player game)))
128
+  (gamekit:bind-button :k :pressed
129
+                       (move-up game (player game)))
130
+  (gamekit:bind-button :l :pressed
131
+                       (move-right game (player game))))
132
+
133
+(defmethod style )
134
+
135
+(defmethod gamekit:draw ((system bodgelike))
136
+  (dotimes (row 16)
137
+    (dotimes (col 16)
138
+      (draw-tile row col)))
139
+  (let ((*my-font* (gamekit:make-font :fantasy (* 0.8 *tile-size*))))
140
+    (mapcar 'draw-feature
141
+            (monsters system))
142
+    (draw-feature (player system))))
0 143
new file mode 100644
... ...
@@ -0,0 +1,30 @@
1
+(defpackage :fwoar.condorcet
2
+  (:use :cl )
3
+  (:export ))
4
+(in-package :fwoar.condorcet)
5
+
6
+(defmacro define-data-class (name (&rest super-classes) &body slots)
7
+  `(defclass ,name ,super-classes
8
+     ,(mapcar
9
+       (lambda (slot-name)
10
+         `(,slot-name :initarg ,(alexandria:make-keyword slot-name) :reader ,slot-name))
11
+       slots)))
12
+
13
+(define-data-class ballot ()
14
+  voter-name confirmation rankings)
15
+
16
+(define-data-class ranking ()
17
+  rank candidates)
18
+
19
+(define-data-class secret-ballot ()
20
+  confirmation rankings)
21
+
22
+(define-data-class tally-election-request ()
23
+  election candidates eligible-voters ballots)
24
+
25
+(define-data-class tally-election-response ()
26
+  election candidates voted did-not-vote rankings ballots preference-matrix strongest-path-matrix)
27
+
28
+(define-data-class tally-election-response ()
29
+  election candidates voted did-not-vote rankings ballots)
30
+
0 31
new file mode 100644
... ...
@@ -0,0 +1,30 @@
1
+(defpackage :fwoar.docstrings
2
+  (:use :cl )
3
+  (:export ))
4
+(in-package :fwoar.docstrings)
5
+
6
+(eval-when (:load-toplevel :compile-toplevel :execute)
7
+  (defun docstring (name &key signature return summary examples doc)
8
+    (format nil "(~s ~{~s~^ ~}) => ~s ~a~%~%~:[~;~:*~a~%~%~]~{(~/pprint-linear/)~%~}"
9
+            name signature return summary
10
+            doc
11
+            examples)))
12
+
13
+(defmacro document (definition (=> return) &body (doc &rest examples))
14
+  (assert (eql => '=>))
15
+  (ecase (car definition)
16
+    (defun (destructuring-bind (_ name arguments summary &rest __) definition
17
+             (declare (ignore _ __))
18
+             `(progn ,definition
19
+                     (setf (documentation ',name 'function)
20
+                           ,(docstring name :signature arguments :return return :summary summary :examples examples :doc doc)))))))
21
+
22
+(document
23
+    (defun this-is-a-test (a b c)
24
+      "this is a test"
25
+      (declare (ignore a b c))
26
+      (values))
27
+    (=> values)
28
+  "don't do nothin"
29
+  (this-is-a-test 1 2 3)
30
+  (this-is-a-test 'a 2 3))
0 31
new file mode 100644
... ...
@@ -0,0 +1,133 @@
1
+(defpackage :fwoar.graphql
2
+  (:import-from :data-lens :key :over :juxt)
3
+  (:import-from :serapeum :defalias)
4
+  (:use :cl )
5
+  (:export ))
6
+(in-package :fwoar.graphql)
7
+
8
+#|
9
+;; query {
10
+;;   search(query: "topic:common-lisp", type: REPOSITORY, first: 100) {
11
+;;     edges {
12
+;;       node {
13
+;;         ... on Repository {
14
+;;           owner {
15
+;;             login
16
+;;           }
17
+;;           name
18
+;;           description 
19
+;;           pushedAt
20
+;;         }
21
+;;       }
22
+;;     }
23
+;;   }
24
+;; }
25
+|#
26
+
27
+(defun camelize (name)
28
+  (fw.lu:with (parts (fwoar.string-utils:split #\- (string-downcase name)))
29
+    (format nil "~a~{~:(~a~)~}"
30
+            (elt parts 0)
31
+            (map 'list #'string-capitalize (subseq parts 1)))))
32
+
33
+(defun handle-term (term)
34
+  (typecase term
35
+    (symbol (camelize term))
36
+    (t term)))
37
+
38
+(defun sexp->query (s expr)
39
+  (destructuring-bind (op &rest body) expr
40
+    (pprint-logical-block (s nil)
41
+      (pprint-logical-block (s nil)
42
+        (pprint-indent :block 4 s)
43
+        (if (listp op)
44
+            (format s "~a(~{~a~^, ~})"
45
+                    (handle-term (car op))
46
+                    (loop for (key value) on (cdr op) by #'cddr
47
+                          collect (format nil "~a:~a" (handle-term key) value)))
48
+            (princ (handle-term op) s))
49
+        (princ " {" s)
50
+        (loop for expr in body
51
+              do
52
+                 (pprint-newline :mandatory s)
53
+              if (listp expr) do
54
+                (sexp->query s expr)
55
+              else do
56
+                (princ (handle-term expr)
57
+                       s)))
58
+      (pprint-newline :mandatory s)
59
+      (format s "}"))))
60
+
61
+(defun dive (&rest keys)
62
+  (lambda (map)
63
+    (declare (dynamic-extent map))
64
+    (fw.lu:dive keys map)))
65
+
66
+(defalias <>
67
+  'alexandria:compose)
68
+
69
+(defun %jq (&rest query)
70
+  (lambda (map)
71
+    (reduce (lambda (acc next)
72
+              (typecase next
73
+                (list (ecase (car next)
74
+                        (:juxt (funcall (apply 'juxt
75
+                                               (mapcar '%jq
76
+                                                       (cdr next)))
77
+                                        acc))
78
+                        (:dive (funcall (apply '%jq (cdr next))
79
+                                        acc))
80
+                        (:map (funcall (over (apply '%jq (cdr next)))
81
+                                       acc))))
82
+                (t (gethash next acc))))
83
+            query
84
+            :initial-value map)))
85
+
86
+(defmacro jq (&rest query)
87
+  `(%jq ,@(mapcar (lambda (v) `',v)
88
+                  query)))
89
+
90
+(defun format-results (results)
91
+  (format t "~:{* ~a/~a ~a~%~2t~a~%~%~}"
92
+          results))
93
+
94
+
95
+;; .data.search.edges[]
96
+;; | .node
97
+;; | "* "+ .owner.login + "/" + .name + " " + .pushedAt + "\n  " + .description + "\n"'
98
+
99
+(defalias extract-data
100
+  (jq "data"
101
+      "search"
102
+      "edges"
103
+      (:map "node"
104
+            (:juxt (:dive "owner"
105
+                          "login")
106
+                   "name"
107
+                   "pushedAt"
108
+                   "description"))))
109
+
110
+(defun search-for-topic-repos (topic)
111
+  `(query ((search query ,(format nil "\"topic:~a\"" topic)
112
+                   type "REPOSITORY"
113
+                   first "100")
114
+           (edges
115
+            (node
116
+             ("... on Repository"
117
+              (owner login)
118
+              name
119
+              description
120
+              pushed-at))))))
121
+
122
+(defun github-graphql (token query)
123
+  (let ((drakma:*text-content-types* (acons "application" "json"
124
+                                            drakma:*text-content-types*)))
125
+    (yason:parse (drakma:http-request "https://api.github.com/graphql"
126
+                                      :method :post 
127
+                                      :content   (yason:with-output-to-string* ()
128
+                                                   (yason:with-object ()
129
+                                                     (yason:encode-object-element
130
+                                                      "query"
131
+                                                      (with-output-to-string (s)
132
+                                                        (sexp->query s query)))))
133
+                                      :additional-headers `(("Authorization" . ,(format nil "bearer ~a" token)))))))
0 134
new file mode 100644
... ...
@@ -0,0 +1,29 @@
1
+(defpackage :paredit
2
+  (:use :cl)
3
+  (:export ))
4
+(in-package :paredit)
5
+
6
+(defclass cursor ()
7
+  ((%pos :initarg :pos :reader pos)))
8
+
9
+(defun make-cursor (&rest path)
10
+  (make-instance 'cursor
11
+                 :pos (copy-seq path)))
12
+
13
+(defun get-exp-at-cursor (cursor exp)
14
+  (reduce (lambda (acc next-pos)
15
+            (elt acc next-pos))
16
+          (pos cursor)
17
+          :initial-value exp))
18
+
19
+(defun barf-backward (cursor exp)
20
+  (let* ((parent-exp-cursor (apply 'make-cursor
21
+                                   (butlast (pos cursor))))
22
+         (parent-exp (get-exp-at-cursor parent-exp-cursor exp))
23
+         (grandparent-exp-cursor (apply 'make-cursor
24
+                                        (butlast (pos parent-exp-cursor)))))
25
+    
26
+
27
+
28
+
29
+    ))
0 30
new file mode 100644
... ...
@@ -0,0 +1,57 @@
1
+;; from Rosetta code, with modifications https://rosettacode.org/wiki/Password_generator#Common_Lisp
2
+(defpackage :fwoar.password-gen
3
+  (:use :cl )
4
+  (:export ))
5
+(in-package :fwoar.password-gen)
6
+
7
+(defparameter *lowercase*
8
+  '(#\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p
9
+    #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z))
10
+
11
+(defparameter *uppercase*
12
+  '(#\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P
13
+    #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z))
14
+
15
+(defparameter *numbers*
16
+  '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
17
+
18
+(defparameter *special-characters*
19
+  '(#\! #\\ #\# #\% #\& #\* #\+ #\, #\- #\. #\: #\< #\= #\>
20
+    #\? #\^ #\_ #\| #\~))
21
+
22
+(defparameter *similar-characters*
23
+  '(#\I #\l #\1 #\| #\O #\0 #\5 #\S #\2 #\Z))
24
+
25
+(defun make-readable (s)
26
+  (remove-if (lambda (x) (member x *similar-characters*)) s))
27
+
28
+(defun shuffle-list (input-list)
29
+  (loop with l = (length input-list)
30
+        for i below l
31
+        do (rotatef (nth i input-list)
32
+                    (nth (random l) input-list)))
33
+  input-list)
34
+
35
+(defun generate-password (len human-readable)
36
+  (let*
37
+      ((upper (if human-readable (make-readable *uppercase*) *uppercase*))
38
+       (lower (if human-readable (make-readable *lowercase*) *lowercase*))
39
+       (number (if human-readable (make-readable *numbers*) *numbers*))
40
+       (special (if human-readable (make-readable *special-characters*) *special-characters*))
41
+       (character-groups (list upper lower number special))
42
+       (initial-password (reduce (lambda (acc x)
43
+                                   (cons (nth (random (length x)) x) acc))
44
+                                 character-groups :initial-value NIL)))
45
+    
46
+    (coerce (shuffle-list (reduce (lambda (acc x)
47
+                                    (declare (ignore x))
48
+                                    (let ((group (nth (random (length character-groups)) character-groups)))
49
+                                      (cons (nth (random (length group)) group) acc)))
50
+                                  (make-list (- len 4)) :initial-value initial-password)) 'string)))
51
+
52
+(defun main (len count &optional human-readable)
53
+  (if (< len 4)
54
+      (print "Length must be at least 4~%")
55
+      (loop for x from 1 to count do
56
+        (princ (generate-password len human-readable))
57
+        (terpri))))
0 58
new file mode 100644
... ...
@@ -0,0 +1,52 @@
1
+(defpackage :fwoar.recursion-schemes
2
+  (:use :cl)
3
+  (:export ))
4
+(in-package :fwoar.recursion-schemes)
5
+
6
+(defun cdr* (cons)
7
+  (funcall (cdr cons)))
8
+
9
+;; cata :: (a -> b -> b) -> b -> [a] -> b
10
+(defun cata (fun init as)
11
+  (if (null as)
12
+      init
13
+      (funcall fun
14
+               (car as)
15
+               (cata fun init
16
+                     (cdr as)))))
17
+
18
+;; para :: (a -> [a] -> b -> b) -> b -> [a] -> b
19
+(defun para (fun init as)
20
+  (if (null as)
21
+      init
22
+      (funcall fun (car as) (cdr as)
23
+               (para fun init (cdr as)))))
24
+
25
+;; ana :: (v -> (a, () -> b)) -> b -> [a]
26
+(defun ana (fun init)
27
+  (destructuring-bind (a init*)
28
+      (funcall fun init)
29
+    (cons a (lambda () (ana fun init*)))))
30
+
31
+;; ana :: (v -> Maybe (a, b)) -> b -> [a]
32
+(defun ana* (fun init)
33
+  (let ((v (funcall fun init)))
34
+    (when v
35
+      (cons (car v)
36
+            (ana* fun (cadr v))))))
37
+
38
+;; hylo  :: (a -> c -> c) -> c -> (b -> Maybe (a, b)) -> b -> c
39
+(defun hylo (reducer reducer-init generator generator-seed)
40
+  (flet ((partial-ana (init)
41
+           (ana* generator init)))
42
+    (cata reducer reducer-init
43
+          (partial-ana generator-seed))))
44
+
45
+;; zygo (a -> b -> b) -> (a -> b -> c -> c) -> b -> c -> [a] -> c
46
+(defun zygo (fold-1 fold-2 fold-1-init fold-2-init as)
47
+  (second
48
+   (cata (fw.lu:destructuring-lambda (x (p q))
49
+           (list (funcall fold-1 x p)
50
+                 (funcall fold-2 x p q)))
51
+         (list fold-1-init fold-2-init)
52
+         as)))
0 53
new file mode 100644
... ...
@@ -0,0 +1,16 @@
1
+(defpackage :sqlite-environment
2
+  (:use :cl )
3
+  (:export ))
4
+(in-package :sqlite-environment)
5
+
6
+(defparameter *sqlite-env* (list))
7
+
8
+(defmacro defun* (name (&rest args) &body body)
9
+  `(progn
10
+     (push '(list ,name ,args ,body)
11
+           *sqlite-env*)
12
+     (defun ,name ,args
13
+       ,@body)))
14
+
15
+(defun* do-thing ()
16
+  (asdf))
0 17
new file mode 100644
... ...
@@ -0,0 +1,33 @@
1
+(defpackage :fwoar.triangle
2
+  (:use :cl )
3
+  (:export ))
4
+(in-package :fwoar.triangle)
5
+
6
+(defun alternate-source ()
7
+  (let ((alternator t))
8
+    (lambda ()
9
+      (prog1 alternator
10
+        (setf alternator (not alternator))))))
11
+
12
+(defun print-triangle (size)
13
+  (let ((alt (alternate-source)))
14
+    (dotimes (n size)
15
+      (let ((count (1+ n)))
16
+        (dotimes (i count)
17
+          (format t "~:[0~;1~] " (funcall alt)))
18
+        (terpri)))))
19
+
20
+#|
21
+TRIANGLE> (print-triangle 11)
22
+1
23
+0 1
24
+0 1 0
25
+1 0 1 0
26
+1 0 1 0 1
27
+0 1 0 1 0 1
28
+0 1 0 1 0 1 0
29
+1 0 1 0 1 0 1 0
30
+1 0 1 0 1 0 1 0 1
31
+0 1 0 1 0 1 0 1 0 1
32
+0 1 0 1 0 1 0 1 0 1 0
33
+|#