-
Notifications
You must be signed in to change notification settings - Fork 19
/
startup
141 lines (118 loc) · 3.11 KB
/
startup
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
; Syntax and shorthands
(define = eq?)
(define not null?)
(define caar (lambda (lst) (car (car lst))))
(define cdar (lambda (lst) (cdr (car lst))))
(define caddr (lambda (lst) (car (cddr lst))))
(define cadddr (lambda (lst) (cadr (cddr lst))))
; I/O
(define print
(lambda (object)
(write object)
(newline)))
; The least dispensable list operations
(define equal?
(lambda (x1 x2)
(if (eq? x1 x2)
t
(if (pair? x1)
(if (pair? x2)
(if (equal? (car x1) (car x2))
(equal? (cdr x1) (cdr x2))))))))
(define length
(lambda (lst)
((lambda (n)
(while lst
(set! n (+ n 1))
(set! lst (cdr lst)))
n)
0)))
(define append
(lambda (L1 L2)
(if (null? L1)
L2
(cons (car L1)
(append (cdr L1) L2)))))
(define map
(lambda (proc lst)
((lambda (result)
(while lst
(set! result (cons (proc (car lst)) result))
(set! lst (cdr lst)))
(reverse! result))
'())))
(define for-each
(lambda (proc lst)
(while lst
(proc (car lst))
(set! lst (cdr lst)))))
; Macros
(define macroexpand
(lambda (exp)
(if (atom? exp)
exp
(if (get (car exp) 'special-form)
((get (car exp) 'special-form) exp)
(if (get (car exp) 'macro)
(macroexpand ((get (car exp) 'macro) (cdr exp)))
(map macroexpand exp))))))
(put 'quote 'special-form
(lambda (exp) exp))
(put 'lambda 'special-form
(lambda (exp)
(cons 'lambda
(cons (cadr exp)
(map macroexpand (cddr exp))))))
; Other special forms don't need special treatment, but you might want
; to add syntax-checking.
(define define-macro
(lambda (keyword expander)
(put keyword 'macro expander)))
(define-macro 'and
(lambda (args)
(if (null? args)
t
(if (null? (cdr args))
(car args)
(list 'if (car args) (cons 'and (cdr args)))))))
(define-macro 'or
(lambda (args)
(if (null? args)
nil
(if (null? (cdr args))
(car args)
(list
((lambda (test-var)
(list 'lambda (list test-var)
(list 'if test-var test-var (cons 'or (cdr args)))))
(gensym))
(car args))))))
(define-macro 'let
(lambda (args)
(cons
(cons 'lambda (cons (map car (car args)) (cdr args)))
(map cadr (car args)))))
(define make-begin
(lambda (lst)
(if (null? (cdr lst))
(car lst)
(cons 'begin lst))))
(define-macro 'cond
(lambda (clauses)
(if (null? clauses)
nil
(if (eq? (caar clauses) 'else)
(make-begin (cdar clauses))
(list 'if
(caar clauses)
(make-begin (cdar clauses))
(cons 'cond (cdr clauses)))))))
; This procedure replaces the system default read-eval-print loop:
(define top-level-driver
(lambda ()
(write '>)
((lambda (exp)
(if (eq? the-eof-object exp)
(set! top-level-driver nil)
(print (eval (macroexpand exp)))))
(read))))