mirror of
https://github.com/kanaka/mal.git
synced 2024-11-11 00:52:44 +03:00
efa2daef57
I think the only remaining ones are ada, elisp, factor, and rust.
98 lines
2.1 KiB
PostScript
98 lines
2.1 KiB
PostScript
/runlibfile where { pop }{ /runlibfile { run } def } ifelse %
|
|
(types.ps) runlibfile
|
|
(reader.ps) runlibfile
|
|
(printer.ps) runlibfile
|
|
|
|
% read
|
|
/_readline { print flush (%stdin) (r) file 1024 string readline } def
|
|
|
|
/READ {
|
|
/str exch def
|
|
str read_str
|
|
} def
|
|
|
|
|
|
% eval
|
|
/eval_ast { 2 dict begin
|
|
/env exch def
|
|
/ast exch def
|
|
%(eval_ast: ) print ast ==
|
|
ast _symbol? { %if symbol
|
|
env ast known {
|
|
env ast get
|
|
}{
|
|
(') ast false _pr_str (' not found)
|
|
concatenate concatenate _throw
|
|
} ifelse
|
|
}{ ast _sequential? { %elseif list or vector
|
|
[
|
|
ast /data get { %forall items
|
|
env EVAL
|
|
} forall
|
|
] ast _list? { _list_from_array }{ _vector_from_array } ifelse
|
|
}{ ast _hash_map? { %elseif list or vector
|
|
<<
|
|
ast /data get { %forall entries
|
|
env EVAL
|
|
} forall
|
|
>> _hash_map_from_dict
|
|
}{ % else
|
|
ast
|
|
} ifelse } ifelse } ifelse
|
|
end } def
|
|
|
|
/EVAL { 3 dict begin
|
|
/env exch def
|
|
/ast exch def
|
|
|
|
%(EVAL: ) print ast true _pr_str print (\n) print
|
|
ast _list? not { %if not a list
|
|
ast env eval_ast
|
|
}{ %else apply the list
|
|
ast _count 0 eq {
|
|
ast
|
|
}{
|
|
/el ast env eval_ast def
|
|
el _rest el _first % stack: ast function
|
|
exec % apply function to args
|
|
} ifelse
|
|
} ifelse
|
|
end } def
|
|
|
|
|
|
% print
|
|
/PRINT {
|
|
true _pr_str
|
|
} def
|
|
|
|
|
|
% repl
|
|
/repl_env <<
|
|
(+) { dup 0 _nth exch 1 _nth add }
|
|
(-) { dup 0 _nth exch 1 _nth sub }
|
|
(*) { dup 0 _nth exch 1 _nth mul }
|
|
(/) { dup 0 _nth exch 1 _nth idiv }
|
|
>> def
|
|
|
|
/REP { READ repl_env EVAL PRINT } def
|
|
|
|
% repl loop
|
|
{ %loop
|
|
(user> ) _readline
|
|
not { exit } if % exit if EOF
|
|
|
|
{ %try
|
|
REP print (\n) print
|
|
} stopped {
|
|
(Error: ) print
|
|
get_error_data false _pr_str print (\n) print
|
|
$error /newerror false put
|
|
$error /errorinfo null put
|
|
clear
|
|
cleardictstack
|
|
} if
|
|
} bind loop
|
|
|
|
(\n) print % final newline before exit for cleanliness
|
|
quit
|