|
| 1 | +// ListLibrary.h - Version 1 - 8th February 2021 |
| 2 | +// execfile, member*, import, and dump added by dragoncoder047 |
| 3 | + |
| 4 | +const char LispLibrary[] PROGMEM = |
| 5 | + |
| 6 | +// count |
| 7 | +// Counts the number of items eq to x in lst. |
| 8 | + |
| 9 | +"(defun count (x lst)" |
| 10 | +" (if (null lst) 0" |
| 11 | +" (+ (if (eq x (car lst)) 1 0) (count x (cdr lst)))))" |
| 12 | + |
| 13 | +// count-if |
| 14 | +// Counts the number of items in lst for which tst is true. |
| 15 | + |
| 16 | +"(defun count-if (tst lst)" |
| 17 | +" (if (null lst) 0" |
| 18 | +" (+ (if (funcall tst (car lst)) 1 0) (count-if tst (cdr lst)))))" |
| 19 | + |
| 20 | +// count-if-not |
| 21 | +// Counts the number of items in lst for which tst is false. |
| 22 | + |
| 23 | +"(defun count-if-not (tst lst)" |
| 24 | +" (if (null lst) 0" |
| 25 | +" (+ (if (funcall tst (car lst)) 0 1) (count-if-not tst (cdr lst)))))" |
| 26 | + |
| 27 | +// eql |
| 28 | +// In uLisp eq and eql are equivalent. |
| 29 | + |
| 30 | +"(defvar eql eq)" |
| 31 | + |
| 32 | +// every |
| 33 | +// Returns t if tst is true for every item in lst, or returns nil on the first false item. |
| 34 | + |
| 35 | +"(defun every (tst lst)" |
| 36 | +" (if (null lst) t" |
| 37 | +" (and (funcall tst (car lst)) (every tst (cdr lst)))))" |
| 38 | + |
| 39 | +// find |
| 40 | +// Returns x if x is in lst, or nil otherwise. |
| 41 | + |
| 42 | +"(defun find (x lst) (car (member x lst)))" |
| 43 | + |
| 44 | +// find-if |
| 45 | +// Returns the first item for which tst is true in lst, or nil otherwise. |
| 46 | + |
| 47 | +"(defun find-if (tst lst)" |
| 48 | +" (cond" |
| 49 | +" ((null lst) nil)" |
| 50 | +" ((funcall tst (car lst)) (car lst))" |
| 51 | +" (t (find-if tst (cdr lst)))))" |
| 52 | + |
| 53 | +// find-if-not |
| 54 | +// Returns the first item for which tst is false in lst, or nil otherwise. |
| 55 | + |
| 56 | +"(defun find-if-not (tst lst)" |
| 57 | +" (cond" |
| 58 | +" ((null lst) nil)" |
| 59 | +" ((not (funcall tst (car lst))) (car lst))" |
| 60 | +" (t (find-if-not tst (cdr lst)))))" |
| 61 | + |
| 62 | +// fourth |
| 63 | +// Returns the fourth item in a list. |
| 64 | + |
| 65 | +"(defun fourth (lst) (car (cdddr lst)))" |
| 66 | + |
| 67 | +// identity |
| 68 | +// Simply returns its argument. |
| 69 | + |
| 70 | +"(defun identity (x) x)" |
| 71 | + |
| 72 | +// last |
| 73 | +// Returns the last cdr of lst. |
| 74 | + |
| 75 | +"(defun last (lst)" |
| 76 | +" (if (null (cdr lst)) lst" |
| 77 | +" (last (cdr lst))))" |
| 78 | + |
| 79 | +// mapl |
| 80 | +// Applies fn to successive cdrs of lst, and returns lst. |
| 81 | + |
| 82 | +"(defun mapl (fn lst)" |
| 83 | +" (require 'mapl2)" |
| 84 | +" (mapl2 fn lst)" |
| 85 | +" lst)" |
| 86 | + |
| 87 | +"(defun mapl2 (fn lst)" |
| 88 | +" (cond" |
| 89 | +" ((null lst) nil)" |
| 90 | +" (t (funcall fn lst)" |
| 91 | +" (mapl2 fn (cdr lst)))))" |
| 92 | + |
| 93 | +// maplist |
| 94 | +// Applies fn to successive cdrs of lst, and returns a list of the results. |
| 95 | + |
| 96 | +"(defun maplist (fn lst)" |
| 97 | +" (if (null lst) nil" |
| 98 | +" (cons (funcall fn lst) (maplist fn (cdr lst)))))" |
| 99 | + |
| 100 | +// nconc |
| 101 | +// Destructively appends its arguments together, which must be lists. |
| 102 | + |
| 103 | +"(defun nconc (&rest ls)" |
| 104 | +" (mapcan (lambda (x) x) ls))" |
| 105 | + |
| 106 | +// nthcdr |
| 107 | +// Returns the nth cdr of lst. |
| 108 | + |
| 109 | +"(defun nthcdr (n lst)" |
| 110 | +" (if (zerop n) lst" |
| 111 | +" (nthcdr (1- n) (cdr lst))))" |
| 112 | + |
| 113 | +// position |
| 114 | +// Returns the position of the first x in lst, or nil if it's not found. |
| 115 | + |
| 116 | +"(defun position (x lst &optional (n 0))" |
| 117 | +" (cond" |
| 118 | +" ((null lst) nil)" |
| 119 | +" ((eq x (car lst)) n)" |
| 120 | +" (t (position x (cdr lst) (1+ n)))))" |
| 121 | + |
| 122 | +// position-if |
| 123 | +// Returns the position of the first item in lst for which tst is true, or nil if none is found. |
| 124 | + |
| 125 | +"(defun position-if (tst lst &optional (n 0))" |
| 126 | +" (cond" |
| 127 | +" ((null lst) nil)" |
| 128 | +" ((funcall tst (car lst)) n)" |
| 129 | +" (t (position-if tst (cdr lst) (1+ n)))))" |
| 130 | + |
| 131 | +// position-if-not |
| 132 | +// Returns the position of the first item in lst for which tst is false, or nil if none is found. |
| 133 | + |
| 134 | +"(defun position-if-not (tst lst &optional (n 0))" |
| 135 | +" (cond" |
| 136 | +" ((null lst) nil)" |
| 137 | +" ((not (funcall tst (car lst))) n)" |
| 138 | +" (t (position-if-not tst (cdr lst) (1+ n)))))" |
| 139 | + |
| 140 | +// reduce |
| 141 | +// Returns the result of applying fn to successive pairs of items from lst. |
| 142 | + |
| 143 | +"(defun reduce (fn lst)" |
| 144 | +" (if (null (cdr lst)) (car lst)" |
| 145 | +" (funcall fn (car lst) (reduce fn (cdr lst)))))" |
| 146 | + |
| 147 | +// remove |
| 148 | +// Removes all occurrences of x from lst. |
| 149 | + |
| 150 | +"(defun remove (x lst)" |
| 151 | +" (mapcan (lambda (y) (unless (eq x y) (list y))) lst))" |
| 152 | + |
| 153 | +// remove-if |
| 154 | +// Removes all items from lst for which tst is true. |
| 155 | + |
| 156 | +"(defun remove-if (tst lst)" |
| 157 | +" (mapcan (lambda (x) (unless (funcall tst x) (list x))) lst))" |
| 158 | + |
| 159 | +// remove-if-not |
| 160 | +// Removes all items from lst for which tst is false. |
| 161 | + |
| 162 | +"(defun remove-if-not (tst lst)" |
| 163 | +" (mapcan (lambda (x) (when (funcall tst x) (list x))) lst))" |
| 164 | + |
| 165 | +// subseq (for lists) |
| 166 | +// Returns the subsequence of lst from item n to item m-1. |
| 167 | + |
| 168 | +"(defun subseq* (lst n m)" |
| 169 | +" (cond" |
| 170 | +" ((> n 0) (subseq* (cdr lst) (1- n) (1- m)))" |
| 171 | +" ((zerop m) nil)" |
| 172 | +" (t (cons (car lst) (subseq* (cdr lst) 0 (1- m))))))" |
| 173 | + |
| 174 | +// third |
| 175 | +// Returns the third item in a list. |
| 176 | + |
| 177 | +"(defvar third caddr)" |
| 178 | + |
| 179 | +// execfile |
| 180 | +// Loads the file off the SD card and runs it. |
| 181 | +// Does not resolve circular dependencies. |
| 182 | + |
| 183 | +"(defun execfile (filename)" |
| 184 | +" (with-sd-card (fp filename)" |
| 185 | +" (loop" |
| 186 | +" (let ((form (read fp)))" |
| 187 | +" (unless form (return))" |
| 188 | +" (eval form)))" |
| 189 | +" filename))" |
| 190 | + |
| 191 | +// member* |
| 192 | +// Returns t if lst has the element elem, using equal for comparison. |
| 193 | + |
| 194 | +"(defun member* (elem lst)" |
| 195 | +" (require 'equal)" |
| 196 | +" (let ((found nil))" |
| 197 | +" (dolist (x lst)" |
| 198 | +" (when (equal x elem) (setq found t) (return)))" |
| 199 | +" found))" |
| 200 | + |
| 201 | +// import |
| 202 | +// Runs the file, but only if it has not been run before. This allows circular dependencies. |
| 203 | + |
| 204 | +"(defun import (filename)" |
| 205 | +" (require 'execfile)" |
| 206 | +" (require 'member*)" |
| 207 | +" (require 'imported)" |
| 208 | +" (if (member* filename imported) nil" |
| 209 | +" (progn" |
| 210 | +" (push filename imported)" |
| 211 | +" (execfile filename))))" |
| 212 | + |
| 213 | +"(defvar imported nil)" |
| 214 | + |
| 215 | +// dump |
| 216 | +// Dumps the workspace into the specified file (default is "dump.lisp") |
| 217 | + |
| 218 | +"(defun dump (&optional (filename \"dump.lisp\"))" |
| 219 | +" (with-sd-card (fp filename)" |
| 220 | +" (pprintall fp)))" |
| 221 | + |
| 222 | +"\0" |
| 223 | + |
| 224 | +; |
0 commit comments