-
Notifications
You must be signed in to change notification settings - Fork 0
/
scheme-standard-macros.scm
89 lines (84 loc) · 2.12 KB
/
scheme-standard-macros.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
(define-syntax and
(syntax-rules ()
((and)
#t)
((and e)
e)
((and e1 e2 ...)
(if e1 (and e2 ...) #f))))
(define-syntax or
(syntax-rules ()
((or)
#f)
((or e)
e)
((or (f ...) e ...)
(let ((t (f ...)))
(or t e ...)))
((or t e ...)
(if t t (or e ...)))))
(define-syntax cond
(syntax-rules (else =>)
((cond (else result1 result2 ...))
(begin result1 result2 ...))
((cond (test => result))
(let ((temp test))
(if temp (result temp))))
((cond (test => result) clause1 clause2 ...)
(let ((temp test))
(if temp
(result temp)
(cond clause1 clause2 ...))))
((cond (test))
test)
((cond (test) clause1 clause2 ...)
(or test (cond clause1 clause2 ...)))
((cond (test result1 result2 ...))
(if test (begin result1 result2 ...)))
((cond (test result1 result2 ...) clause1 clause2 ...)
(if test
(begin result1 result2 ...)
(cond clause1 clause2 ...)))))
(define-syntax case
(syntax-rules (else)
((case (key ...)
clauses ...)
(let ((atom-key (key ...)))
(case atom-key clauses ...)))
((case key
(else result1 result2 ...))
(begin result1 result2 ...))
((case key
((atom ...) result1 result2 ...))
(if (case "compare" key (atom ...))
(begin result1 result2 ...)))
((case key
((atom ...) result1 result2 ...) clause1 clause2 ...)
(if (case "compare" key (atom ...))
(begin result1 result2 ...)
(case key clause1 clause2 ...)))
((case "compare" key ())
#f)
((case "compare" key (atom))
(eqv? key 'atom))
((case "compare" key (atom ...))
(memv key '(atom ...)))))
(define-syntax let*
(syntax-rules ()
((let* () body ...)
(let () body ...))
((let* ((x e) rest ...) body ...)
(let ((x e))
(let* (rest ...) body ...)))))
(define-syntax do
(syntax-rules ()
((do ((var init step ...) ...) (test exp ...) cmd ...)
(let loop ((var init) ...)
(cond
(test exp ...)
(else cmd ...
(loop (do "step" var step ...) ...)))))
((do "step" x)
x)
((do "step" x y)
y)))