% 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 key -> env_find -> env % env key -> env_find -> null /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 key val -> env_set -> val /env_set { dup 4 1 roll % stack: val env key val put % stack: val } def /env_get { dup 3 1 roll % stack: key env key env_find % stack: key env/null dup null eq { pop % stack: key (') exch % stack: (') key dup length string cvs (' not found) concatenate concatenate _throw }{ exch % stack: env key get } ifelse } def