Commit | Line | Data |
---|---|---|
fa64b741 JM |
1 | /runlibfile where { pop }{ /runlibfile { run } def } ifelse % |
2 | (types.ps) runlibfile | |
3 | (reader.ps) runlibfile | |
4 | (printer.ps) runlibfile | |
5 | (env.ps) runlibfile | |
04517bc8 JM |
6 | |
7 | % read | |
406761e7 | 8 | /_readline { print flush (%stdin) (r) file 1024 string readline } def |
950e3c76 | 9 | |
04517bc8 JM |
10 | /READ { |
11 | /str exch def | |
12 | str read_str | |
13 | } def | |
14 | ||
15 | ||
16 | % eval | |
17 | /eval_ast { 2 dict begin | |
18 | /env exch def | |
19 | /ast exch def | |
20 | %(eval_ast: ) print ast == | |
8e7e339d | 21 | ast _symbol? { %if symbol |
04517bc8 | 22 | env ast env_get |
5ce65382 | 23 | }{ ast _sequential? { %elseif list or vector |
04517bc8 | 24 | [ |
5ce65382 | 25 | ast /data get { %forall items |
04517bc8 JM |
26 | env EVAL |
27 | } forall | |
5ce65382 JM |
28 | ] ast _list? { _list_from_array }{ _vector_from_array } ifelse |
29 | }{ ast _hash_map? { %elseif list or vector | |
30 | << | |
31 | ast /data get { %forall entries | |
32 | env EVAL | |
33 | } forall | |
34 | >> _hash_map_from_dict | |
04517bc8 JM |
35 | }{ % else |
36 | ast | |
5ce65382 | 37 | } ifelse } ifelse } ifelse |
04517bc8 JM |
38 | end } def |
39 | ||
46669c86 | 40 | /EVAL { 8 dict begin |
04517bc8 JM |
41 | /env exch def |
42 | /ast exch def | |
950e3c76 JM |
43 | |
44 | %(EVAL: ) print ast true _pr_str print (\n) print | |
8e7e339d | 45 | ast _list? not { %if not a list |
04517bc8 JM |
46 | ast env eval_ast |
47 | }{ %else apply the list | |
5ce65382 | 48 | /a0 ast 0 _nth def |
12e4facd DM |
49 | a0 _nil? { %if () |
50 | ast | |
51 | }{ /def! a0 eq { %if def! | |
5ce65382 JM |
52 | /a1 ast 1 _nth def |
53 | /a2 ast 2 _nth def | |
04517bc8 JM |
54 | env a1 a2 env EVAL env_set |
55 | }{ /let* a0 eq { %if let* | |
5ce65382 JM |
56 | /a1 ast 1 _nth def |
57 | /a2 ast 2 _nth def | |
58 | /let_env env null null env_new def | |
59 | 0 2 a1 _count 1 sub { %for each pair | |
04517bc8 JM |
60 | /idx exch def |
61 | let_env | |
5ce65382 JM |
62 | a1 idx _nth |
63 | a1 idx 1 add _nth let_env EVAL | |
04517bc8 | 64 | env_set |
3da90d39 | 65 | pop % discard the return value |
04517bc8 JM |
66 | } for |
67 | a2 let_env EVAL | |
68 | }{ | |
69 | /el ast env eval_ast def | |
950e3c76 JM |
70 | el _rest el _first % stack: ast function |
71 | exec % apply function to args | |
12e4facd | 72 | } ifelse } ifelse } ifelse |
04517bc8 JM |
73 | } ifelse |
74 | end } def | |
75 | ||
76 | ||
77 | ||
78 | /PRINT { | |
0a2c6954 | 79 | true _pr_str |
04517bc8 JM |
80 | } def |
81 | ||
82 | ||
83 | % repl | |
5ce65382 | 84 | /repl_env null null null env_new def |
04517bc8 JM |
85 | |
86 | /REP { READ repl_env EVAL PRINT } def | |
04517bc8 | 87 | |
8cb5cda4 | 88 | /_ref { repl_env 3 1 roll env_set pop } def |
5ce65382 JM |
89 | (+) { dup 0 _nth exch 1 _nth add } _ref |
90 | (-) { dup 0 _nth exch 1 _nth sub } _ref | |
91 | (*) { dup 0 _nth exch 1 _nth mul } _ref | |
92 | (/) { dup 0 _nth exch 1 _nth idiv } _ref | |
04517bc8 | 93 | |
86b689f3 JM |
94 | % repl loop |
95 | { %loop | |
950e3c76 | 96 | (user> ) _readline |
04517bc8 JM |
97 | not { exit } if % exit if EOF |
98 | ||
aef93ea3 JM |
99 | { %try |
100 | REP print (\n) print | |
101 | } stopped { | |
102 | (Error: ) print | |
0a2c6954 | 103 | get_error_data false _pr_str print (\n) print |
950e3c76 JM |
104 | $error /newerror false put |
105 | $error /errorinfo null put | |
aef93ea3 | 106 | clear |
950e3c76 | 107 | cleardictstack |
aef93ea3 | 108 | } if |
04517bc8 JM |
109 | } bind loop |
110 | ||
111 | (\n) print % final newline before exit for cleanliness | |
112 | quit |