aboutsummaryrefslogtreecommitdiff
path: root/ps/env.ps
blob: b8752affc2185dbda9663eaab8d8e9d1b4381b5d (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
48
49
50
51
52
53
54
55
56
57
58
59
60
(in env.ps\n) print

% outer binds exprs -> env_new -> new_env
/env_new { 3 dict begin
    %(in env_new\n) print
    /exprs exch dup _sequential? { /data get }{ pop [ ] } ifelse def
    /binds exch dup _sequential? { /data get }{ pop [ ] } ifelse def
    /outer exch def
    << 
        /__outer__ outer
        0 1 binds length 1 sub {
            /idx exch def
            binds idx get (&) eq { %if &
                binds idx 1 add get % key
                exprs idx   exprs length idx sub   getinterval % value
                _list_from_array
                exit
            } if
            binds idx get % key
            exprs idx get % value
        } for
    >>
end } def

/env_find { 2 dict begin
    /key exch def
    /env exch def
    env key known { %if key in env
        env
    }{ env /__outer__ get null ne { %elseif __outer__ not null
        env /__outer__ get   key env_find
    }{ %else
        null
    } ifelse } ifelse
end } def

/env_set { 4 dict begin
    dup
    /func? exch xcheck def % executable function
    /val exch cvlit def
    /key exch def
    /env exch def
    env key val func? { cvx } if put
    val func? { cvx } if
end } def

/env_get { 2 dict begin
    /key exch def
    /env exch def
    env key env_find
    dup null eq {
        (')
        key dup length string cvs
        (' not found)
        concatenate concatenate
        _throw
    }{
        key get
    } ifelse
end } def