aboutsummaryrefslogtreecommitdiff
path: root/racket/env.rkt
blob: 8e47b634a79b84cce0402d8fd334d98f5553058c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#lang racket

(provide Env%)

(require "types.rkt")

(define Env%
  (class object%
    (init outer binds exprs)
    (super-new)
    (define _outer outer)
    (define _binds (_to_list binds))
    (define _exprs (_to_list exprs))
    (define data (make-hash))
    (let ([vargs (member '& _binds)])
      (if vargs
        (begin
          (map (lambda (b e) (hash-set! data b e))
               (drop-right _binds 2)
               (take _exprs (- (length _binds) 2)))
          (hash-set! data
                     (last _binds)
                     (drop _exprs (- (length _binds) 2))))
        (map (lambda (b e) (hash-set! data b e))
             _binds
             _exprs)))

    (define/public (set k v)
      (hash-set! data k v)
      v)
    (define/public (find k)
      (cond
        [(hash-has-key? data k) this]
        [(not (null? _outer)) (send _outer find k)]
        [else null]))
    (define/public (_get k)
      (hash-ref data k))
    (define/public (get k)
      (let ([e (find k)])
        (if (null? e)
          (raise (string-append "'"
                                (symbol->string k)
                                "' not found"))
          (send e _get k))))))