/ ideas / env-tree
env-tree
  1  
  2    (define (env-binding env sym-or-term)
  3  
  4      (define (sym-ref alist sym)
  5        (assq sym alist))
  6  
  7      (define (term-ref pair-path-possibs term)
  8        (let ((t-env (term-env term)))
  9  
 10          (define (compare p o vars)
 11            (cond
 12              ((pair? p)
 13               (and (pair? o)
 14                    (let ((vars (compare (car p) (car o) vars)))
 15                      (and vars (compare (cdr p) (cdr o) vars)))))
 16              ((value? p)
 17               (let ((b (binding o t-env)))
 18                 (and b
 19                      (eqv? (value-value p) (binding-val b))
 20                      vars)))
 21              ((variable? p)
 22               (cond
 23                 ((assq p vars) => (lambda (a)
 24                                     (and (equal? o (cdr a))
 25                                          vars)))
 26                 (else
 27                  (let ((vty (variable-type p))
 28                        (oty (eval `(,$type ,o) t-env)))
 29                    (and (eval `((,$vau (oty vty) #F
 30                                   (,includes? oty vty))
 31                                 ,oty ,vty)
 32                               t-env)
 33                         (cons (cons p o) vars))))))
 34              ((symbol? p)
 35               (and (eq? p o)
 36                    (not (binding o t-env))
 37                    vars))
 38              (else
 39               (and (equal? p o)
 40                    vars))))
 41  
 42          (let recur ((ps pair-path-possibs)
 43                      (obj (term-expr term))
 44                      (vars '()))
 45            (and (pair? ps)
 46                 (let ((p (car ps)))
 47                   (cond ((and (pair? p) (pair? obj)
 48                               (compare (car p) (car obj) vars))
 49                          => (lambda (vars) (recur (cdr p) (cdr obj) vars)))
 50                         ((and (end? p)
 51                               (compare (end-possib p) obj vars))
 52                          (end-binding p))
 53                         (else
 54                          (recur (cdr ps) obj vars))))))))
 55  
 56      (if (symbol? sym-or-term)
 57        (sym-ref (environment-symbol-bindings env) sym-or-term)
 58        (term-ref (environment-term-bindings env) sym-or-term)))
 59  
 60  
 61    (define (bind env sym-or-term val)
 62  
 63      (define (sym-bind alist sym val)
 64        (cons (make-binding sym val) alist))
 65  
 66      (define (term-bind pair-path-possibs term val)
 67        (let ((t-env (term-env term)))
 68  
 69          (define (compare p o vars)
 70            (cond
 71              ((pair? p)
 72               (and (pair? o)
 73                    (let ((vars (compare (car p) (car o) vars)))
 74                      (and vars (compare (cdr p) (cdr o) vars)))))
 75              ((value? p)
 76               (and (symbol? o)
 77                    (let ((b (binding o t-env)))
 78                      (and b
 79                           (eqv? (value-value p) (binding-val b))
 80                           vars))))
 81              ((variable? p)
 82               (and (symbol? o)
 83                    (let ((b (binding o t-env)))
 84                      (and b
 85                           (let ((v (binding-val b)))
 86                             (and (variable? v)
 87                                  (eqv? (variable-type p) (variable-type v))
 88                                  (cond ((assq v vars)
 89                                         => (lambda (a) (and (eq? p (cdr a)) vars)))
 90                                        (else (cons (cons v p) vars)))))))))
 91              ((symbol? p)
 92               (and (eq? p o)
 93                    (not (binding o t-env))
 94                    vars))
 95              (else
 96               (and (equal? p o)
 97                    vars))))
 98  
 99          (define (compile o)
100            (cond ((pair? o)
101                   (cons (compile (car o)) (compile (cdr o))))
102                  ((and (symbol? o) (binding o t-env))
103                   => (lambda (b)
104                        (let ((v (binding-val b)))
105                          (if (variable? v) v (make-value v)))))
106                  (else o)))
107  
108          (let recur ((ps pair-path-possibs)
109                      (obj (term-expr term))
110                      (vars '())
111                      (rps '()))
112            (if (pair? ps)
113              (let ((p (car ps)))
114                (define (update np)
115                  (rappend rps (cons np (cdr ps))))
116                (cond
117                  ((and (pair? p) (pair? obj)
118                        (compare (car p) (car obj) vars))
119                   => (lambda (vars)
120                        (update (cons (car p)
121                                      (recur (cdr p) (cdr obj) vars '())))))
122                  ((and (end? p)
123                        (compare (end-possib p) obj vars))
124                   (update (make-end (end-possib p)
125                                     (make-binding term val))))
126                  (else
127                   (recur (cdr ps) obj vars (cons p rps)))))
128              (cons
129               (if (pair? obj)
130                 (cons (compile (car obj))
131                       (recur '() (cdr obj) '() '()))
132                 (make-end (compile obj)
133                           (make-binding term val)))
134               (reverse rps))))))
135  
136      (if (symbol? sym-or-term)
137        (make-environment
138         (sym-bind (environment-symbol-bindings env) sym-or-term val)
139         (environment-term-bindings env))
140        (make-environment
141         (environment-symbol-bindings env)
142         (term-bind (environment-term-bindings env) sym-or-term val))))
143  
144  
145  (define (rappend rl l)
146    (fold-left (lambda (a x) (cons x a)) l rl))
147  
148  (define (binding expr env)
149    (cond ((pair? expr) (env-binding env (make-term expr env)))
150          ((symbol? expr) (env-binding env expr))
151          (else (make-binding #F expr))))
152  
153  
154  
155  ($let ((a ($lambda ...))
156         (b ...))
157    ($let (('(a b c) ...))
158      (get-current-environment)))
159  =>
160  
161  [env symbols: ((a . ,A) (b . ,B))
162       terms:
163       (([val ,A] . (([val ,B] . ((c . ([end () ,VAL]))))
164                     ...))
165        ...)
166       ]