Not bad.
One thing to remember about ASH (the "Advanced Script Handler") is that it is, like the CLI, a "scripting language". Such languages execute commands or statements sequentially (modulo loops, function calls, and other control structures) until they either finish by "falling off the bottom of the script" or abort when any command or statement fails to "do the right thing".
Now, since ASH is a full programming language, we allow programs to "capture" requests to KoL that failed and continue execution. But library calls or operations that fail because of errors in the script - accessing a negative index in a string, dividing by zero, taking the square root of a negative number, and so on - throw runtime exceptions which will unwind the call stack, executing "finally" blocks, and exit the script with an error message, pointing out the erroneous file and line number.
It is not the "style" of ASH to simply print an error message and return a usable value to the script, allowing it continue executing with some arbitrary result.
Note the distinction between "capturing" an unexpected error from an interaction with KoL to avoid aborting the script and programming errors in the script that abort with no recourse. If a script aborts with a runtime error, the expectation is that the script needs to be fixed, rather than allowed to continue executing after a coding error generated an arbitrary or unreliable result.
The issue with modifier_eval/expression_eval is that their argument is, itself, a little program written in a specialized programming language, with the possibility of both syntax errors in the expression itself and runtime errors during the evaluation of the expression. Those functions are coded - and documented on the Wiki - as "always returning something, regardless of syntax errors or runtime errors."
I think it's time to revisit that, since both kinds of errors are, essentially, runtime errors in the script that calls modifier_eval/expression_eval, and should behave like other runtime errors caused by script errors, rather than failed interactions with KoL: they should throw a runtime error and require the script author to fix it.
THAT would be in the "style" of ASH.
My opinion. Which, I hope, counts for something. Not that KoLmafia is a democracy.
Not the style of ASH, but the style of modifier_eval. It already prints warnings when you do a malformed expression like "(", and returns 0.0. Are you going to change that behaviour also?
I'm leaning in that direction.