Merge pull request #13 from euc/patch-1
[jackhill/mal.git] / ps / env.ps
1 % outer binds exprs -> env_new -> new_env
2 /env_new { 3 dict begin
3 %(in env_new\n) print
4 /exprs exch dup _sequential? { /data get }{ pop [ ] } ifelse def
5 /binds exch dup _sequential? { /data get }{ pop [ ] } ifelse def
6 /outer exch def
7 <<
8 /__outer__ outer
9 0 1 binds length 1 sub {
10 /idx exch def
11 binds idx get (&) eq { %if &
12 binds idx 1 add get % key
13 exprs idx exprs length idx sub getinterval % value
14 _list_from_array
15 exit
16 } if
17 binds idx get % key
18 exprs idx get % value
19 } for
20 >>
21 end } def
22
23 % env key -> env_find -> env
24 % env key -> env_find -> null
25 /env_find { 2 dict begin
26 /key exch def
27 /env exch def
28 env key known { %if key in env
29 env
30 }{ env /__outer__ get null ne { %elseif __outer__ not null
31 env /__outer__ get key env_find
32 }{ %else
33 null
34 } ifelse } ifelse
35 end } def
36
37 % env key val -> env_set -> val
38 /env_set {
39 dup 4 1 roll % stack: val env key val
40 put % stack: val
41 } def
42
43 /env_get {
44 dup 3 1 roll % stack: key env key
45 env_find % stack: key env/null
46 dup null eq {
47 pop % stack: key
48 (') exch % stack: (') key
49 dup length string cvs
50 (' not found)
51 concatenate concatenate
52 _throw
53 }{
54 exch % stack: env key
55 get
56 } ifelse
57 } def