altos/lisp: More schemisms
[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 cadr (l) (car (cdr l)))
58
59 (defun caddr (l) (car (cdr (cdr l))))
60
61 (defun nth (list n)
62   (cond ((= n 0) (car list))
63         ((nth (cdr list) (1- n)))
64         )
65   )
66
67                                         ; simple math operators
68
69 (defun 1+ (x) (+ x 1))
70 (defun 1- (x) (- x 1))
71
72 (define if (macro (test args)
73                (cond ((null? (cdr args))
74                       (list
75                        cond
76                        (list test (car args)))
77                       )
78                      (else
79                       (list
80                        cond
81                        (list test (car args))
82                        (list 'else (cadr args))
83                        )
84                       )
85                      )
86                )
87      )
88
89 (if (> 3 2) 'yes)
90 (if (> 3 2) 'yes 'no)
91 (if (> 2 3) 'no 'yes)
92 (if (> 2 3) 'no)
93
94                                         ; define a set of local
95                                         ; variables and then evaluate
96                                         ; a list of sexprs
97                                         ;
98                                         ; (let (var-defines) sexprs)
99                                         ;
100                                         ; where var-defines are either
101                                         ;
102                                         ; (name value)
103                                         ;
104                                         ; or
105                                         ;
106                                         ; (name)
107                                         ;
108                                         ; e.g.
109                                         ;
110                                         ; (let ((x 1) (y)) (set! y (+ x 1)) y)
111
112 (define let (macro (vars exprs)
113                 ((lambda (make-names make-exprs make-nils)
114
115                                         ;
116                                         ; make the list of names in the let
117                                         ;
118
119                    (set! make-names (lambda (vars)
120                                       (cond ((not (null? vars))
121                                              (cons (car (car vars))
122                                                    (make-names (cdr vars))))
123                                             )
124                                       )
125                          )
126
127                                         ; the set of expressions is
128                                         ; the list of set expressions
129                                         ; pre-pended to the
130                                         ; expressions to evaluate
131
132                    (set! make-exprs (lambda (vars exprs)
133                                       (cond ((not (null? vars)) (cons
134                                                    (list set
135                                                          (list quote
136                                                                (car (car vars))
137                                                                )
138                                                          (cadr (car vars))
139                                                          )
140                                                    (make-exprs (cdr vars) exprs)
141                                                    )
142                                                   )
143                                             (exprs)
144                                             )
145                                       )
146                          )
147
148                                         ; the parameters to the lambda is a list
149                                         ; of nils of the right length
150
151                    (set! make-nils (lambda (vars)
152                                      (cond ((not (null? vars)) (cons () (make-nils (cdr vars))))
153                                            )
154                                      )
155                          )
156                                         ; prepend the set operations
157                                         ; to the expressions
158
159                    (set! exprs (make-exprs vars exprs))
160
161                                         ; build the lambda.
162
163                    (cons (cons 'lambda (cons (make-names vars) exprs))
164                          (make-nils vars)
165                          )
166                    )
167                  ()
168                  ()
169                  ()
170                  )
171                 )
172      )
173
174 (let ((x 1)) x)
175
176                                         ; boolean operators
177
178 (define or (lexpr (l)
179                (let ((ret #f))
180                  (while (not (null? l))
181                    (cond ((car l) (set! ret #t) (set! l ()))
182                          ((set! l (cdr l)))))
183                  ret
184                  )
185                )
186      )
187
188                                         ; execute to resolve macros
189
190 (or #f #t)
191
192 (define and (lexpr (l)
193                (let ((ret #t))
194                  (while (not (null? l))
195                    (cond ((car l)
196                           (set! l (cdr l)))
197                          (#t
198                           (set! ret #f)
199                           (set! l ()))
200                          )
201                    )
202                  ret
203                  )
204                )
205      )
206
207                                         ; execute to resolve macros
208
209 (and #t #f)
210
211 (defun equal? (a b)
212   (cond ((eq? a b) #t)
213         ((and (pair? a) (pair? b))
214          (and (equal? (car a) (car b))
215               (equal? (cdr a) (cdr b)))
216          )
217         (else #f)
218         )
219   )
220
221 (equal? '(a b c) '(a b c))
222 (equal? '(a b c) '(a b b))