]> git.rkrishnan.org Git - sicp.git/blob - src/sicp/metacircular2-test.rkt
Solution to 4.44. A bit too verbose. Can be improved by better
[sicp.git] / src / sicp / metacircular2-test.rkt
1 #lang racket
2
3 (require "metacircular2.rkt"
4          rackunit)
5
6 (require rackunit/text-ui)
7
8 (define metacircular2-tests
9   (test-suite "test suite for meta circular evaluator"
10    (let ([env1 (make-environment)])
11      (check-equal? (eval '(+ 1 1) env1) 2 "simple addition")
12      (check-equal? (eval '(- 2 1) env1) 1 "simple subtraction")
13      (check-equal? (eval '(quote x) env1) 'x "quote")
14      (eval '(define x 20) env1)
15      (check-equal? (eval 'x env1) 20 "definition of identifiers with simple values")
16      (eval '(set! x 42) env1) 
17      (check-equal? (eval 'x env1) 42 "set!")
18      (eval '(define (square x) (* x x)) env1)
19      (check-equal? (eval '(square 10) env1) 100 "simple function definition")
20      (eval '(define (square x) (let ([s (* x x)]) s)) env1)
21      (check-equal? (eval '(square 20) env1) 400 "different way to define square")
22      (eval '(define (absolute x)
23               (cond ((> x 0) x)
24                     ((= x 0) (display 'zero) 0)
25                     (else (- x))))
26            env1)
27      (check-equal? (eval '(absolute -2) env1) 2 "conditionals")
28      (check-equal? (eval '(absolute 2) env1) 2 "conditionals")
29      (eval '(define (foo) (let ((x 42) (y 100)) (list x y))) env1)
30      (check-equal? (eval '(foo) env1) '(42 100) "simple let")
31      (check-equal? (eval '(let* ((x 3)
32                                  (y (+ x 2))
33                                  (z (+ x y 5)))
34                             (* x z))
35                          env1)
36                    39
37                    "let* test")
38      (eval '(define (f x)
39               (define (even? n)
40                 (if (= n 0)
41                     true
42                     (odd? (- n 1))))
43               (define (odd? n)
44                 (if (= n 0)
45                     false
46                     (even? (- n 1))))
47               (odd? x))
48            env1)
49      (check-equal? (eval '(f 2) env1) false "internal definitions")
50      (check-equal? (eval '(f 3) env1) true "internal definitions")
51      (eval '(define (f1 x)
52               (letrec ((even?
53                         (lambda (n)
54                           (if (= n 0)
55                               true
56                               (odd? (- n 1)))))
57                        (odd?
58                         (lambda (n)
59                           (if (= n 0)
60                               false
61                               (even? (- n 1))))))
62                 (even? x)))
63            env1)
64      (check-equal? (eval '(f1 2) env1) true "internal definitions")
65      (check-equal? (eval '(f1 3) env1) false "internal definitions")
66      (eval '(define (fib n)
67               (let fib-iter ((a 1)
68                              (b 0)
69                              (count n))
70                 (if (= count 0)
71                     b
72                     (fib-iter (+ a b) a (- count 1)))))
73            env1)
74      (check-equal? (eval '(fib 10) env1) 55 "named let")
75      (eval '(define (factorial n)
76               (if (= n 1)
77                   1
78                   (* (factorial (- n 1)) n)))
79            env1)
80      (check-equal? (eval '(factorial 10) env1) 3628800 "factorial test")
81      (check-equal? (eval '(unless true "true" "false") env1) "false" "unless test 1")
82      (check-equal? (eval '(unless false "true" "false") env1) "true" "unless test 2"))))
83
84
85 (run-tests metacircular2-tests)