@okram, since you have Haskell experience I'll assume you're familiar with Parsec... I'd like to draw your attention to a current interesting design point..
I'm trying to transition PARSE from its ad-hoc C implementation into something based on parser combinators. While some combinators could be natives backed by a C implementation, others could be plain user functions. The effort is called UPARSE.
As with most parser combinators, this makes each one process both how far it gets on the input (or a failure signal)...which is separate from a generated value. The concept is distinct because the combinator for a SET-WORD! (and others that are "value gathering") triggers a demand for a generated value to the combinator. If that demand is not there, the combinator can run in "skip mode" and be faster.
Having the combinators return higher-level constructed values than merely having "how much input was consumed" is a much-needed aspect. But I think there's something interesting about how it accomplishes the effect of implicitly passing the parser input through a driver that does FRAME! specialization. It strikes me as a much easier-to-grasp mechanical concept vs. the more strict monadic approach, which could be used by other dialects.
It will be slow for a while as it is uses many unoptimized features (e.g. multi-return, which is prototyped as all usermode code... that's actually scanned and LOAD-ed on every SET-BLOCK! invocation right now!) and is all usermode. But it's just to hammer out the design.
I've been raising points in the PARSE category that could use informed opinions...!