12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- #lang racket
- (require racket/match)
- (define builtins
- `((car . ,car)
- (cdr . ,cdr)
- (cons . ,cons)
- (list . ,list)
- (list . ,list?)
- (null? . ,null?)
- (+ . ,+)
- (- . ,-)
- (* . ,*)
- (/ . ,/)
- (= . ,=)
- (eq? . ,eq?)
- (equal? . ,equal?)
- (not . ,not)))
- (define special-forms
- '(lambda if quote and or))
- (define (i exp env spec)
- (match exp
- ((? number? n) n)
- ((? boolean? b) b)
- ((? symbol? s)
- (cond ((assoc s env) => cdr)
- (else (error "unbound variable" s))))
- ((? list? l)
- (if (member (car l) spec)
- (i-special l env spec)
- (apply (i (car l) env spec)
- (map (lambda (exp) (i exp env spec)) (cdr l)))))
- (else (error "unknown expression type" exp))))
- (define (i-special exp env spec)
- (match exp
- (`(if ,t ,c ,a)
- (if (i t env spec)
- (i c env spec)
- (i a env spec))
- (`(lambda (,x) ,b)
- (lambda (y)
- (i b (cons (cons x y) env) (remove x spec))))
- (`(quote ,d)
- d)
- (`(and . ,things)
- (let loop (things things)
- (if (null? things)
- #t
- (if (i (car things) env spec)
- (loop (cdr things))
- #f))))
- (`(or . ,things)
- (let loop (things things)
- (if (null? things)
- #f
- (if (i (car things) env spec)
- #t
- (loop (cdr things))))))
- (else (error "Unimplemented special form:" exp))))
|