191ef00581ff2b602fa3a295cb1455fb2601a258
[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))
223                                              (cons
224                                               (list set
225                                                     (list quote
226                                                           (car (car vars))
227                                                           )
228                                                     (cond ((null? (cdr (car vars))) ())
229                                                           (else (cadr (car vars))))
230                                                     )
231                                               (make-exprs (cdr vars) exprs)
232                                               )
233                                              )
234                                             (exprs)
235                                             )
236                                       )
237                          )
238
239                                         ; the parameters to the lambda is a list
240                                         ; of nils of the right length
241
242                    (set! make-nils (lambda (vars)
243                                      (cond ((not (null? vars)) (cons () (make-nils (cdr vars))))
244                                            )
245                                      )
246                          )
247                                         ; prepend the set operations
248                                         ; to the expressions
249
250                    (set! exprs (make-exprs vars exprs))
251
252                                         ; build the lambda.
253
254                    (cons (cons 'lambda (cons (make-names vars) exprs))
255                          (make-nils vars)
256                          )
257                    )
258                  ()
259                  ()
260                  ()
261                  )
262                 )
263      )
264
265 (let ((x 1)) x)
266
267                                         ; boolean operators
268
269 (define or (lexpr (l)
270                (let ((ret #f))
271                  (while (not (null? l))
272                    (cond ((car l) (set! ret #t) (set! l ()))
273                          ((set! l (cdr l)))))
274                  ret
275                  )
276                )
277      )
278
279                                         ; execute to resolve macros
280
281 (or #f #t)
282
283 (define and (lexpr (l)
284                (let ((ret #t))
285                  (while (not (null? l))
286                    (cond ((car l)
287                           (set! l (cdr l)))
288                          (#t
289                           (set! ret #f)
290                           (set! l ()))
291                          )
292                    )
293                  ret
294                  )
295                )
296      )
297
298                                         ; execute to resolve macros
299
300 (and #t #f)
301
302
303 (define append (lexpr (args)
304                       (let ((append-list (lambda (a b)
305                                            (cond ((null? a) b)
306                                                  (else (cons (car a) (append-list (cdr a) b)))
307                                                  )
308                                            )
309                                          )
310                             (append-lists (lambda (lists)
311                                             (cond ((null? lists) lists)
312                                                   ((null? (cdr lists)) (car lists))
313                                                   (else (append-list (car lists) (append-lists (cdr lists))))
314                                                   )
315                                             )
316                                           )
317                             )
318                         (append-lists args)
319                         )
320                       )
321   )
322
323 (append '(a b c) '(d e f) '(g h i))
324
325 (defun reverse (list)
326   (let ((result ()))
327     (while (not (null? list))
328       (set! result (cons (car list) result))
329       (set! list (cdr list))
330       )
331     result)
332   )
333
334 (reverse '(1 2 3))
335
336 (define list-tail
337   (lambda (x k)
338     (if (zero? k)
339         x
340       (list-tail (cdr x) (- k 1)))))
341
342 (list-tail '(1 2 3) 2)
343
344 (defun list-ref (x k) (car (list-tail x k)))
345
346 (list-ref '(1 2 3) 2)
347
348     
349                                         ; recursive equality
350
351 (defun equal? (a b)
352   (cond ((eq? a b) #t)
353         ((and (pair? a) (pair? b))
354          (and (equal? (car a) (car b))
355               (equal? (cdr a) (cdr b)))
356          )
357         (else #f)
358         )
359   )
360
361 (equal? '(a b c) '(a b c))
362 (equal? '(a b c) '(a b b))
363
364 (defun _member (obj list test?)
365   (if (null? list)
366       #f
367     (if (test? obj (car list))
368         list
369       (memq obj (cdr list)))))
370
371 (defun memq (obj list) (_member obj list eq?))
372
373 (memq 2 '(1 2 3))
374
375 (memq 4 '(1 2 3))
376
377 (defun memv (obj list) (_member obj list eqv?))
378
379 (memv 2 '(1 2 3))
380
381 (memv 4 '(1 2 3))
382
383 (defun member (obj list) (_member obj list equal?))
384
385 (member '(2) '((1) (2) (3)))
386
387 (member '(4) '((1) (2) (3)))
388
389 (defun _assoc (obj list test?)
390   (if (null? list)
391       #f
392     (if (test? obj (caar list))
393         (car list)
394       (_assoc obj (cdr list) test?)
395       )
396     )
397   )
398
399 (defun assq (obj list) (_assoc obj list eq?))
400 (defun assv (obj list) (_assoc obj list eqv?))
401 (defun assoc (obj list) (_assoc obj list equal?))
402
403 (assq 'a '((a 1) (b 2) (c 3)))
404 (assv 'b '((a 1) (b 2) (c 3)))
405 (assoc '(c) '((a 1) (b 2) ((c) 3)))
406
407 (define char? integer?)
408
409 (char? #\q)
410 (char? "h")
411
412 (defun char-upper-case? (c) (<= #\A c #\Z))
413
414 (char-upper-case? #\a)
415 (char-upper-case? #\B)
416 (char-upper-case? #\0)
417 (char-upper-case? #\space)
418
419 (defun char-lower-case? (c) (<= #\a c #\a))
420
421 (char-lower-case? #\a)
422 (char-lower-case? #\B)
423 (char-lower-case? #\0)
424 (char-lower-case? #\space)
425
426 (defun char-alphabetic? (c) (or (char-upper-case? c) (char-lower-case? c)))
427
428 (char-alphabetic? #\a)
429 (char-alphabetic? #\B)
430 (char-alphabetic? #\0)
431 (char-alphabetic? #\space)
432
433 (defun char-numeric? (c) (<= #\0 c #\9))
434
435 (char-numeric? #\a)
436 (char-numeric? #\B)
437 (char-numeric? #\0)
438 (char-numeric? #\space)
439
440 (defun char-whitespace? (c) (or (<= #\tab c #\return) (= #\space c)))
441
442 (char-whitespace? #\a)
443 (char-whitespace? #\B)
444 (char-whitespace? #\0)
445 (char-whitespace? #\space)
446
447 (defun char->integer (c) c)
448 (defun integer->char (c) char-integer)
449
450 (defun char-upcase (c) (if (char-lower-case? c) (+ c (- #\A #\a)) c))
451
452 (char-upcase #\a)
453 (char-upcase #\B)
454 (char-upcase #\0)
455 (char-upcase #\space)
456
457 (defun char-downcase (c) (if (char-upper-case? c) (+ c (- #\a #\A)) c))
458
459 (char-downcase #\a)
460 (char-downcase #\B)
461 (char-downcase #\0)
462 (char-downcase #\space)
463
464 (define string (lexpr (chars) (list->string chars)))
465
466 (display "apply\n")
467 (apply cons '(a b))
468
469 (define map (lexpr (proc lists)
470                    (let ((args (lambda (lists)
471                                  (if (null? lists) ()
472                                    (cons (caar lists) (args (cdr lists))))))
473                          (next (lambda (lists)
474                                  (if (null? lists) ()
475                                    (cons (cdr (car lists)) (next (cdr lists))))))
476                          (domap (lambda (lists)
477                                   (if (null? (car lists)) ()
478                                     (cons (apply proc (args lists)) (domap (next lists)))
479                                         )))
480                          )
481                      (domap lists))))
482
483 (map cadr '((a b) (d e) (g h)))
484
485 (define for-each (lexpr (proc lists)
486                         (apply map proc lists)
487                         #t))
488
489 (for-each display '("hello" " " "world" "\n"))
490
491 (define -string-ml (lambda (strings)
492                              (if (null? strings) ()
493                                (cons (string->list (car strings)) (-string-ml (cdr strings))))))
494
495 (define string-map (lexpr (proc strings)
496                           (list->string (apply map proc (-string-ml strings))))))
497
498 (string-map 1+ "HAL")
499
500 (define string-for-each (lexpr (proc strings)
501                                (apply for-each proc (-string-ml strings))))
502
503 (string-for-each write-char "IBM\n")
504
505 (define newline (lambda () (write-char #\newline)))
506
507 (newline)
508
509 (call-with-current-continuation
510  (lambda (exit)
511    (for-each (lambda (x)
512                (write "test" x)
513                (if (negative? x)
514                    (exit x)))
515              '(54 0 37 -3 245 19))
516    #t))
517
518 ;(define number->string (lexpr (arg opt)
519 ;                             (let ((base (if (null? opt) 10 (car opt)))
520                                         ;
521 ;
522