Skip to content

Commit 9974cb1

Browse files
committed
Finish lexical address interpreter.
1 parent b5d0bca commit 9974cb1

1 file changed

Lines changed: 53 additions & 5 deletions

File tree

www/notes/fraud/interp-lexical.rkt

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
(provide (all-defined-out))
33
(require (only-in "interp.rkt" prim? value? interp-prim))
44

5+
;; type LEnv = (Listof Variable)
6+
;; type VEnv = (Listof Value)
7+
8+
;; Expr -> Answer
9+
(define (interp e)
10+
(interp-env (translate e) '()))
11+
512
;; Expr -> IExpr
613
(define (translate e)
714
(translate-e e '()))
@@ -17,16 +24,57 @@
1724
,(translate-e e1)
1825
,(translate-e e2))]
1926
[(? symbol? x)
20-
(lexical-address x r)]
27+
`(address ,(lexical-address x r))]
2128
[`(let ((,x ,e0)) ,e1)
22-
`(let ((_ ,(translate e0 r)))
23-
,(translate e1 (cons x r)))]))
29+
`(let ((_ ,(translate-e e0 r)))
30+
,(translate-e e1 (cons x r)))]))
31+
32+
;; IExpr VEnv -> Answer
33+
(define (interp-env e r)
34+
(match e
35+
[(? value? v) v]
36+
[(list (? prim? p) e)
37+
(let ((a (interp-env e r)))
38+
(interp-prim p a))]
39+
[`(if ,e0 ,e1 ,e2)
40+
(match (interp-env e0 r)
41+
['err 'err]
42+
[v
43+
(if v
44+
(interp-env e1 r)
45+
(interp-env e2 r))])]
46+
[`(address ,i)
47+
(list-ref r i)]
48+
[`(let ((_ ,e0)) ,e1)
49+
(match (interp-env e0 r)
50+
['err 'err]
51+
[v
52+
(interp-env e1 (cons v r))])]))
2453

2554
;; Variable LEnv -> Natural
2655
(define (lexical-address x r)
2756
(match r
2857
['() (error "unbound variable")]
2958
[(cons y r)
3059
(match (symbol=? x y)
31-
[#t (length r)]
32-
[#f (lexical-address x r)])]))
60+
[#t 0]
61+
[#f (add1 (lexical-address x r))])]))
62+
63+
(module+ test
64+
(require rackunit)
65+
(check-equal? (translate '(let ((x 0)) x))
66+
'(let ((_ 0)) (address 0)))
67+
(check-equal? (translate '(let ((x 0)) (let ((y 1)) x)))
68+
'(let ((_ 0)) (let ((_ 1)) (address 1))))
69+
(check-equal? (translate '(let ((x 0)) (let ((y 1)) y)))
70+
'(let ((_ 0)) (let ((_ 1)) (address 0))))
71+
(check-equal? (translate '(let ((x 0))
72+
(let ((y x))
73+
y)))
74+
'(let ((_ 0)) (let ((_ (address 0))) (address 0))))
75+
76+
(check-equal? (interp 5) 5)
77+
(check-equal? (interp '(let ((x 0)) x)) 0)
78+
(check-equal? (interp '(let ((x 0)) (let ((y 1)) x))) 0)
79+
(check-equal? (interp '(let ((x 0)) (let ((y 1)) y))) 1)
80+
(check-equal? (interp '(let ((x 0)) (let ((y x)) y))) 0))

0 commit comments

Comments
 (0)