|
34 | 34 | ;; Is e a closed expression?
|
35 | 35 | (define (closed? e)
|
36 | 36 | ;; TODO
|
37 |
| - #f |
38 |
| - ;; SOLN |
39 |
| - (closed?/env e '())) |
| 37 | + #f) |
40 | 38 |
|
41 |
| -;; SOLN |
42 |
| -(define (closed?/env e bvs) |
43 |
| - (match e |
44 |
| - [(int-e i) #t] |
45 |
| - [(bool-e b) #t] |
46 |
| - [(char-e c) #t] |
47 |
| - [(string-e s) #t] |
48 |
| - [(var-e v) (and (memq v bvs) #t)] |
49 |
| - [(nil-e) #t] |
50 |
| - [(if-e p t f) (and |
51 |
| - (closed?/env p bvs) |
52 |
| - (closed?/env t bvs) |
53 |
| - (closed?/env f bvs))] |
54 |
| - [(prim-e (? prim1? p) (list e)) |
55 |
| - (closed?/env e bvs)] |
56 |
| - [(prim-e (? prim2? p) (list e0 e1)) |
57 |
| - (and (closed?/env e0 bvs) |
58 |
| - (closed?/env e1 bvs))] |
59 |
| - [(cond-e cs f) (and |
60 |
| - (closed-clauses?/env cs bvs) |
61 |
| - (closed?/env f bvs))] |
62 |
| - [(let-e bs e) (let ((vs (get-vars bs))) |
63 |
| - (and |
64 |
| - (closed-bindings?/env bs bvs) |
65 |
| - (closed?/env e (append vs bvs))))])) |
66 | 39 |
|
67 |
| -;; SOLN |
68 |
| -(define (closed-clauses?/env cs bvs) |
69 |
| - (match cs |
70 |
| - ['() #t] |
71 |
| - [(cons (clause e b) cs) (and |
72 |
| - (closed?/env e bvs) |
73 |
| - (closed?/env b bvs) |
74 |
| - (closed-clauses?/env cs bvs))])) |
75 |
| -;; SOLN |
76 |
| -(define (closed-bindings?/env bs bvs) |
77 |
| - (match bs |
78 |
| - ['() #t] |
79 |
| - [(cons (binding v def) bs) (and |
80 |
| - (closed?/env def bvs) |
81 |
| - (closed-bindings?/env bs bvs))])) |
82 | 40 |
|
83 | 41 |
|
84 | 42 | ;; Any -> Boolean
|
|
133 | 91 | [_ (error "bound name must be a symbol")]))
|
134 | 92 |
|
135 | 93 |
|
136 |
| -;; SOLN |
137 |
| -(module+ test |
138 |
| - (require rackunit) |
139 |
| - |
140 |
| - (check-true (expr? (sexpr->ast 1))) |
141 |
| - (check-true (expr? (sexpr->ast #\c))) |
142 |
| - (check-true (expr? (sexpr->ast #t))) |
143 |
| - (check-true (expr? (sexpr->ast '(add1 1)))) |
144 |
| - (check-true (expr? (sexpr->ast '(add1 #t)))) |
145 |
| - (check-true (expr? (sexpr->ast '(let () 1)))) |
146 |
| - (check-true (expr? (sexpr->ast '(let ((x 1)) 1)))) |
147 |
| - (check-true (expr? (sexpr->ast '(let ((x 1)) x)))) |
148 |
| - |
149 |
| - (check-false (expr? (sexpr->ast '(let ((x 1) (x 2)) x)))) |
150 |
| - |
151 |
| - (check-exn exn:fail? (lambda () (expr? (sexpr->ast '(let ((x)) 0))))) |
152 |
| - (check-exn exn:fail? (lambda () (expr? (sexpr->ast '(let 0 0))))) |
153 |
| - (check-exn exn:fail? (lambda () (expr? (sexpr->ast '(let (x) 0))))) |
154 |
| - (check-exn exn:fail? (lambda () (expr? (sexpr->ast '(let (()) 0))))) |
155 |
| - (check-exn exn:fail? (lambda () (expr? (sexpr->ast '(let x 0))))) |
156 |
| - (check-exn exn:fail? (lambda () (expr? (sexpr->ast '(let x))))) |
157 |
| - (check-exn exn:fail? (lambda () (expr? (sexpr->ast '(let ((x 0)))))))) |
0 commit comments