4cd3e167a1ebaa7128d0c243d3d90a0a6c081986
[fw/altos] / src / scheme / ao_scheme_basic_syntax.scheme
1 ;
2 ; Copyright © 2018 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 ; Basic syntax placed in ROM
15
16 (def (quote list) (lambda l l))
17
18 (def (quote def!)
19      (macro (a b)
20             (list
21              def
22              (list quote a)
23              b)
24             )
25      )
26
27 (begin
28  (def! append
29    (lambda a
30           (def! _a
31             (lambda (a b)
32               (cond ((null? a) b)
33                     (else (cons (car a) (_a (cdr a) b)))
34                     )
35               )
36             )
37             
38           (def! _b
39             (lambda (l)
40               (cond ((null? l) l)
41                     ((null? (cdr l)) (car l))
42                     (else (_a (car l) (_b (cdr l))))
43                     )
44               )
45             )
46           (_b a)
47           )
48    )
49  'append)
50
51 (append '(a) '(b))
52
53
54                                         ;
55                                         ; Define a variable without returning the value
56                                         ; Useful when defining functions to avoid
57                                         ; having lots of output generated.
58                                         ;
59                                         ; Also accepts the alternate
60                                         ; form for defining lambdas of
61                                         ; (define (name x y z) sexprs ...) 
62                                         ;
63
64 (begin
65  (def! define
66    (macro (a . b)
67                                         ; check for alternate lambda definition form
68
69           (cond ((pair? a)
70                  (set! b
71                        (cons
72                         lambda
73                         (cons (cdr a) b)))
74                  (set! a (car a))
75                  )
76                 (else
77                  (set! b (car b))
78                  )
79                 )
80           (cons begin
81                 (cons
82                  (cons def
83                        (cons (cons quote (cons a '()))
84                              (cons b '())
85                              )
86                        )
87                  (cons
88                   (cons quote (cons a '()))
89                   '())
90                  )
91                 )
92           )
93    )
94  'define
95  )
96                                         ; boolean operators
97
98 (define or
99   (macro a
100     (def! b
101       (lambda (a)
102         (cond ((null? a) #f)
103               ((null? (cdr a))
104                (car a))
105               (else
106                (list
107                 cond
108                 (list
109                  (car a))
110                 (list
111                  'else
112                  (b (cdr a))
113                  )
114                 )
115                )
116               )
117         )
118       )
119     (b a)))
120
121                                         ; execute to resolve macros
122
123 (or #f #t)
124
125 (define and
126   (macro a
127     (def! b
128       (lambda (a)
129         (cond ((null? a) #t)
130               ((null? (cdr a))
131                (car a))
132               (else
133                (list
134                 cond
135                 (list
136                  (car a)
137                  (b (cdr a))
138                  )
139                 )
140                )
141               )
142         )
143       )
144     (b a)
145     )
146   )
147
148                                         ; execute to resolve macros
149
150 (and #t #f)
151
152                                         ; (if <condition> <if-true>)
153                                         ; (if <condition> <if-true> <if-false)
154
155 (define if
156   (macro (a . b)
157     (cond ((null? (cdr b))
158            (list cond (list a (car b)))
159                 )
160           (else
161            (list cond
162                  (list a (car b))
163                  (list 'else (car (cdr b)))
164                  )
165            )
166           )
167     )
168   )
169
170 (if (> 3 2) 'yes)
171 (if (> 3 2) 'yes 'no)
172 (if (> 2 3) 'no 'yes)
173 (if (> 2 3) 'no)
174
175 (define letrec
176   (macro (a . b)
177
178                                         ;
179                                         ; make the list of names in the let
180                                         ;
181
182          (define (_a a)
183            (cond ((not (null? a))
184                   (cons (car (car a))
185                         (_a (cdr a))))
186                  (else ())
187                  )
188            )
189
190                                         ; the set of expressions is
191                                         ; the list of set expressions
192                                         ; pre-pended to the
193                                         ; expressions to evaluate
194
195          (define (_b a b)
196            (cond ((null? a) b)
197                  (else
198                   (cons
199                    (list set
200                          (list quote
201                                (car (car a))
202                                )
203                          (cond ((null? (cdr (car a)))
204                                 ()
205                                 )
206                                (else
207                                 (car (cdr (car a)))
208                                 )
209                                )
210                          )
211                    (_b (cdr a) b)
212                    )
213                   )
214                  )
215            )
216
217                                         ; the parameters to the lambda is a list
218                                         ; of nils of the right length
219
220          (define (_c a)
221            (cond ((null? a) ())
222                  (else (cons () (_c (cdr a))))
223                  )
224            )
225                                         ; build the lambda.
226
227          (cons (cons lambda (cons (_a a) (_b a b))) (_c a))
228          )
229      )
230
231 (letrec ((a 1) (b a)) (+ a b))
232
233                                         ; letrec is sufficient for let*
234
235 (define let* letrec)
236
237                                         ; use letrec for let in basic
238                                         ; syntax
239
240 (define let letrec)
241
242                                         ; Basic recursive
243                                         ; equality. Replaced with
244                                         ; vector-capable version in
245                                         ; advanced syntax
246
247 (define (equal? a b)
248   (cond ((eq? a b) #t)
249         ((pair? a)
250          (cond ((pair? b)
251                 (cond ((equal? (car a) (car b))
252                        (equal? (cdr a) (cdr b)))
253                       )
254                 )
255                )
256          )
257         )
258   )
259
260 (equal? '(a b c) '(a b c))
261
262                                         ; basic list accessors
263
264 (define (caar a) (car (car a)))
265
266 (define (cadr a) (car (cdr a)))
267
268 (define (list-ref a b)
269   (car (list-tail a b))
270   )
271
272 (list-ref '(1 2 3) 2)
273
274 (define (member a b . t?)
275   (cond ((null? b)
276          #f
277          )
278         (else
279          (if (null? t?) (set! t? equal?) (set! t? (car t?)))
280          (if (t? a (car b))
281              b
282              (member a (cdr b) t?))
283          )
284         )
285   )
286
287 (member '(2) '((1) (2) (3)))
288 (member '(4) '((1) (2) (3)))
289
290 (define (memq a b) (member a b eq?))
291
292 (memq 2 '(1 2 3))
293 (memq 4 '(1 2 3))
294 (memq '(2) '((1) (2) (3)))
295
296 (define (assoc a b . t?)
297   (if (null? t?)
298       (set! t? equal?)
299       (set! t? (car t?))
300       )
301   (if (null? b)
302       #f
303     (if (t? a (caar b))
304         (car b)
305       (assoc a (cdr b) t?)
306       )
307     )
308   )
309
310 (assoc '(c) '((a 1) (b 2) ((c) 3)))
311
312 (define (assq a b) (assoc a b eq?))
313
314 (assq 'a '((a 1) (b 2) (c 3)))
315
316 (define map
317   (lambda (proc . lists)
318          (define (_a lists)
319            (cond ((null? lists) ())
320                  (else
321                   (cons (caar lists) (_a (cdr lists)))
322                   )
323                  )
324            )
325          (define (_n lists)
326            (cond ((null? lists) ())
327                  (else
328                   (cons (cdr (car lists)) (_n (cdr lists)))
329                   )
330                  )
331            )
332          (define (_m lists)
333            (cond ((null? (car lists)) ())
334                  (else
335                   (cons (apply proc (_a lists)) (_m (_n lists)))
336                   )
337                  )
338            )
339          (_m lists)
340          )
341   )
342
343 (map cadr '((a b) (d e) (g h)))
344
345                                         ; use map as for-each in basic
346                                         ; mode
347
348 (define for-each map)
349                                         ; simple math operators
350
351 (define zero? (macro (value) (list eq? value 0)))
352
353 (zero? 1)
354 (zero? 0)
355 (zero? "hello")
356
357 (define positive? (macro (value) (list > value 0)))
358
359 (positive? 12)
360 (positive? -12)
361
362 (define negative? (macro (value) (list < value 0)))
363
364 (negative? 12)
365 (negative? -12)
366
367 (define (abs a) (if (>= a 0) a (- a)))
368
369 (abs 12)
370 (abs -12)
371
372 (define max (lambda (a . b)
373                    (while (not (null? b))
374                      (cond ((< a (car b))
375                             (set! a (car b)))
376                            )
377                      (set! b (cdr b))
378                      )
379                    a)
380   )
381
382 (max 1 2 3)
383 (max 3 2 1)
384
385 (define min (lambda (a . b)
386                    (while (not (null? b))
387                      (cond ((> a (car b))
388                             (set! a (car b)))
389                            )
390                      (set! b (cdr b))
391                      )
392                    a)
393   )
394
395 (min 1 2 3)
396 (min 3 2 1)
397
398 (define (even? a) (zero? (% a 2)))
399
400 (even? 2)
401 (even? -2)
402 (even? 3)
403 (even? -1)
404
405 (define (odd? a) (not (even? a)))
406
407 (odd? 2)
408 (odd? -2)
409 (odd? 3)
410 (odd? -1)
411
412 (define (newline) (write-char #\newline))
413
414 (newline)