One problem I had with SELF's exit and exitValue was that it doesn't seem to work when an _Eval is on the stack.
This is indeed a bug, thanks for pointing it out. Non-local returns do not work across _Evals in the released system (i.e. if they should return to a frame above the Eval, they always terminate the entire program). I fixed that in our current system; we plan to release a new system sometime soon (hopefully January).
This makes it difficult to handle compile errors. The only approach I can think of is to actually parse the expression!
No; _Eval fails if there are parse errors, and you can catch the failure with a block as with any other primitive. For example,
')' _EvalIfFail: [ 'parse error' printLine]
produces the output
error: unexpected token on line 1, character 1 of "<a string>" found a ')' token expecting a token beginning a unary expression parse error
(The first three lines are printed by the VM.) BTW, the new system will have processes; this makes it much easier to handle run-time errors in evaluators since you can fork a new process to evaluate the expression. If an error occurs during evaluation, only that process dies (but not the evaluator itself).