aboutsummaryrefslogtreecommitdiff
path: root/ps/env.ps
diff options
context:
space:
mode:
Diffstat (limited to 'ps/env.ps')
-rw-r--r--ps/env.ps60
1 files changed, 60 insertions, 0 deletions
diff --git a/ps/env.ps b/ps/env.ps
new file mode 100644
index 0000000..b8752af
--- /dev/null
+++ b/ps/env.ps
@@ -0,0 +1,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