1750904496af4ddd36c1ce03ec7eb57c25f5c3a8
[fw/altos] / src / lisp / ao_lisp_const.lisp
1 ;
2 ; Copyright © 2016 Keith Packard <keithp@keithp.com>
3 ;
4 ; This program is free software; you can redistribute it and/or modify
5 ; it under the terms of the GNU General Public License as published by
6 ; the Free Software Foundation, either version 2 of the License, or
7 ; (at your option) any later version.
8 ;
9 ; This program is distributed in the hope that it will be useful, but
10 ; WITHOUT ANY WARRANTY; without even the implied warranty of
11 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 ; General Public License for more details.
13 ;
14 ; Lisp code placed in ROM
15
16                                         ; return a list containing all of the arguments
17
18 (set (quote list) (lexpr (l) l))
19
20                                         ;
21                                         ; Define a variable without returning the value
22                                         ; Useful when defining functions to avoid
23                                         ; having lots of output generated
24                                         ;
25
26 (set (quote define) (macro (name val rest)
27                         (list
28                          'progn
29                          (list
30                           'set
31                           (list 'quote name)
32                           val)
33                          (list 'quote name)
34                          )
35                         )
36      )
37
38                                         ;
39                                         ; A slightly more convenient form
40                                         ; for defining lambdas.
41                                         ;
42                                         ; (defun <name> (<params>) s-exprs)
43                                         ;
44
45 (define defun (macro (name args exprs)
46                   (list
47                    define
48                    name
49                    (cons 'lambda (cons args exprs))
50                    )
51                   )
52      )
53
54                                         ; basic list accessors
55
56
57 (defun caar (l) (car (car l)))
58
59 (defun cadr (l) (car (cdr l)))
60
61 (defun caddr (l) (car (cdr (cdr l))))
62
63 (defun nth (list n)
64   (cond ((= n 0) (car list))
65         ((nth (cdr list) (1- n)))
66         )
67   )
68
69                                         ; simple math operators
70
71 (defun 1+ (x) (+ x 1))
72 (defun 1- (x) (- x 1))
73
74 (define zero? (macro (value rest)
75                      (list
76                       eq?
77                       value
78                       0)
79                      )
80   )
81
82 (zero? 1)
83 (zero? 0)
84 (zero? "hello")
85
86 (define positive? (macro (value rest)
87                          (list
88                           >
89                           value
90                           0)
91                          )
92   )
93
94 (positive? 12)
95 (positive? -12)
96
97 (define negative? (macro (value rest)
98                          (list
99                           <
100                           value
101                           0)
102                          )
103   )
104
105 (negative? 12)
106 (negative? -12)
107
108 (defun abs (x) (cond ((>= x 0) x)
109                      (else (- x)))
110        )
111
112 (abs 12)
113 (abs -12)
114
115 (define max (lexpr (first rest)
116                    (while (not (null? rest))
117                      (cond ((< first (car rest))
118                             (set! first (car rest)))
119                            )
120                      (set! rest (cdr rest))
121                      )
122                    first)
123   )
124
125 (max 1 2 3)
126 (max 3 2 1)
127
128 (define min (lexpr (first rest)
129                    (while (not (null? rest))
130                      (cond ((> first (car rest))
131                             (set! first (car rest)))
132                            )
133                      (set! rest (cdr rest))
134                      )
135                    first)
136   )
137
138 (min 1 2 3)
139 (min 3 2 1)
140
141 (defun even? (x) (zero? (% x 2)))
142
143 (even? 2)
144 (even? -2)
145 (even? 3)
146 (even? -1)
147
148 (defun odd? (x) (not (even? x)))
149
150 (odd? 2)
151 (odd? -2)
152 (odd? 3)
153 (odd? -1)
154
155 (define exact? number?)
156 (defun inexact? (x) #f)
157
158                                         ; (if <condition> <if-true>)
159                                         ; (if <condition> <if-true> <if-false)
160
161 (define if (macro (test args)
162                (cond ((null? (cdr args))
163                       (list
164                        cond
165                        (list test (car args)))
166                       )
167                      (else
168                       (list
169                        cond
170                        (list test (car args))
171                        (list 'else (cadr args))
172                        )
173                       )
174                      )
175                )
176      )
177
178 (if (> 3 2) 'yes)
179 (if (> 3 2) 'yes 'no)
180 (if (> 2 3) 'no 'yes)
181 (if (> 2 3) 'no)
182
183                                         ; define a set of local
184                                         ; variables and then evaluate
185                                         ; a list of sexprs
186                                         ;
187                                         ; (let (var-defines) sexprs)
188                                         ;
189                                         ; where var-defines are either
190                                         ;
191                                         ; (name value)
192                                         ;
193                                         ; or
194                                         ;
195                                         ; (name)
196                                         ;
197                                         ; e.g.
198                                         ;
199                                         ; (let ((x 1) (y)) (set! y (+ x 1)) y)
200
201 (define let (macro (vars exprs)
202                 ((lambda (make-names make-exprs make-nils)
203
204                                         ;
205                                         ; make the list of names in the let
206                                         ;
207
208                    (set! make-names (lambda (vars)
209                                       (cond ((not (null? vars))
210                                              (cons (car (car vars))
211                                                    (make-names (cdr vars))))
212                                             )
213                                       )
214                          )
215
216                                         ; the set of expressions is
217                                         ; the list of set expressions
218                                         ; pre-pended to the
219                                         ; expressions to evaluate
220
221                    (set! make-exprs (lambda (vars exprs)
222                                       (cond ((not (null? vars)) (cons
223                                                    (list set
224                                                          (list quote
225                                                                (car (car vars))
226                                                                )
227                                                          (cadr (car vars))
228                                                          )
229                                                    (make-exprs (cdr vars) exprs)
230                                                    )
231                                                   )
232                                             (exprs)
233                                             )
234                                       )
235                          )
236
237                                         ; the parameters to the lambda is a list
238                                         ; of nils of the right length
239
240                    (set! make-nils (lambda (vars)
241                                      (cond ((not (null? vars)) (cons () (make-nils (cdr vars))))
242                                            )
243                                      )
244                          )
245                                         ; prepend the set operations
246                                         ; to the expressions
247
248                    (set! exprs (make-exprs vars exprs))
249
250                                         ; build the lambda.
251
252                    (cons (cons 'lambda (cons (make-names vars) exprs))
253                          (make-nils vars)
254                          )
255                    )
256                  ()
257                  ()
258                  ()
259                  )
260                 )
261      )
262
263 (let ((x 1)) x)
264
265                                         ; boolean operators
266
267 (define or (lexpr (l)
268                (let ((ret #f))
269                  (while (not (null? l))
270                    (cond ((car l) (set! ret #t) (set! l ()))
271                          ((set! l (cdr l)))))
272                  ret
273                  )
274                )
275      )
276
277                                         ; execute to resolve macros
278
279 (or #f #t)
280
281 (define and (lexpr (l)
282                (let ((ret #t))
283                  (while (not (null? l))
284                    (cond ((car l)
285                           (set! l (cdr l)))
286                          (#t
287                           (set! ret #f)
288                           (set! l ()))
289                          )
290                    )
291                  ret
292                  )
293                )
294      )
295
296                                         ; execute to resolve macros
297
298 (and #t #f)
299
300
301 (define append (lexpr (args)
302                       (let ((append-list (lambda (a b)
303                                            (cond ((null? a) b)
304                                                  (else (cons (car a) (append-list (cdr a) b)))
305                                                  )
306                                            )
307                                          )
308                             (append-lists (lambda (lists)
309                                             (cond ((null? lists) lists)
310                                                   ((null? (cdr lists)) (car lists))
311                                                   (else (append-list (car lists) (append-lists (cdr lists))))
312                                                   )
313                                             )
314                                           )
315                             )
316                         (append-lists args)
317                         )
318                       )
319   )
320
321 (append '(a b c) '(d e f) '(g h i))
322
323 (defun reverse (list)
324   (let ((result ()))
325     (while (not (null? list))
326       (set! result (cons (car list) result))
327       (set! list (cdr list))
328       )
329     result)
330   )
331
332 (reverse '(1 2 3))
333
334 (define list-tail
335   (lambda (x k)
336     (if (zero? k)
337         x
338       (list-tail (cdr x) (- k 1)))))
339
340 (list-tail '(1 2 3) 2)
341
342 (defun list-ref (x k) (car (list-tail x k)))
343
344 (list-ref '(1 2 3) 2)
345
346     
347                                         ; recursive equality
348
349 (defun equal? (a b)
350   (cond ((eq? a b) #t)
351         ((and (pair? a) (pair? b))
352          (and (equal? (car a) (car b))
353               (equal? (cdr a) (cdr b)))
354          )
355         (else #f)
356         )
357   )
358
359 (equal? '(a b c) '(a b c))
360 (equal? '(a b c) '(a b b))
361
362 (defun _member (obj list test?)
363   (if (null? list)
364       #f
365     (if (test? obj (car list))
366         list
367       (memq obj (cdr list)))))
368
369 (defun memq (obj list) (_member obj list eq?))
370
371 (memq 2 '(1 2 3))
372
373 (memq 4 '(1 2 3))
374
375 (defun memv (obj list) (_member obj list eqv?))
376
377 (memv 2 '(1 2 3))
378
379 (memv 4 '(1 2 3))
380
381 (defun member (obj list) (_member obj list equal?))
382
383 (member '(2) '((1) (2) (3)))
384
385 (member '(4) '((1) (2) (3)))
386
387 (defun _assoc (obj list test?)
388   (if (null? list)
389       #f
390     (if (test? obj (caar list))
391         (car list)
392       (_assoc obj (cdr list) test?)
393       )
394     )
395   )
396
397 (defun assq (obj list) (_assoc obj list eq?))
398 (defun assv (obj list) (_assoc obj list eqv?))
399 (defun assoc (obj list) (_assoc obj list equal?))
400
401 (assq 'a '((a 1) (b 2) (c 3)))
402 (assv 'b '((a 1) (b 2) (c 3)))
403 (assoc '(c) '((a 1) (b 2) ((c) 3)))
404
405 (define char? integer?)
406
407 (char? #\q)
408 (char? "h")
409
410 (defun char-upper-case? (c) (<= #\A c #\Z))
411
412 (char-upper-case? #\a)
413 (char-upper-case? #\B)
414 (char-upper-case? #\0)
415 (char-upper-case? #\space)
416
417 (defun char-lower-case? (c) (<= #\a c #\a))
418
419 (char-lower-case? #\a)
420 (char-lower-case? #\B)
421 (char-lower-case? #\0)
422 (char-lower-case? #\space)
423
424 (defun char-alphabetic? (c) (or (char-upper-case? c) (char-lower-case? c)))
425
426 (char-alphabetic? #\a)
427 (char-alphabetic? #\B)
428 (char-alphabetic? #\0)
429 (char-alphabetic? #\space)
430
431 (defun char-numeric? (c) (<= #\0 c #\9))
432
433 (char-numeric? #\a)
434 (char-numeric? #\B)
435 (char-numeric? #\0)
436 (char-numeric? #\space)
437
438 (defun char-whitespace? (c) (or (<= #\tab c #\return) (= #\space c)))
439
440 (char-whitespace? #\a)
441 (char-whitespace? #\B)
442 (char-whitespace? #\0)
443 (char-whitespace? #\space)
444
445 (defun char->integer (c) c)
446 (defun integer->char (c) char-integer)
447
448 (defun char-upcase (c) (if (char-lower-case? c) (+ c (- #\A #\a)) c))
449
450 (char-upcase #\a)
451 (char-upcase #\B)
452 (char-upcase #\0)
453 (char-upcase #\space)
454
455 (defun char-downcase (c) (if (char-upper-case? c) (+ c (- #\a #\A)) c))
456
457 (char-downcase #\a)
458 (char-downcase #\B)
459 (char-downcase #\0)
460 (char-downcase #\space)
461
462 (define string (lexpr (chars) (list->string chars)))
463
464 ;(define number->string (lexpr (arg opt)
465 ;                             (let ((base (if (null? opt) 10 (car opt)))
466                                         ;
467 ;
468