1
1
mirror of https://github.com/kanaka/mal.git synced 2024-11-11 00:52:44 +03:00
mal/ps/step2_eval.ps
Joel Martin efa2daef57 Fix empty list eval in step2 for most languages.
I think the only remaining ones are ada, elisp, factor, and rust.
2016-04-02 18:40:49 -05:00

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