Fennel, when used as a library, provides a number of functions in order to call various parts of the compiler. Most of these functions accept, inside an options table, an optional list of plugins that can affect the way the compiler works. Although plugins have the :parse-error hook that affects the way parsing works, the function
fennel.parser does not accept a list of plugins. This means the only way to pass an argument to affect the parser is via a function like
fennel.compileString which parses and compiles in the same call (I haven't actually verified if this option works), or by calling the compiler via command line and passing a plugin filename as an argument.
Ideally, fennel.parser would be able to simply use the :plugins key from its options table.
The reason this is slightly more complicated than it looks is that the plugins are accessed via the
utils.hookfunction. This function does not take the plugins as arguments; instead it looks for them in
utils.rootwhich acts as a kind of cheap version of dynamic scope where for every compilation we set and unset the root values (chunk, options, and scope) when we enter and exit the compilation process. (This is why plugins
assert-compilefunction has that final reset function arg; otherwise the root data doesn't get cleaned up.)
So when the parser calls
utils.hookduring the normal compilation process, it works fine. But when you call
fennel.parserdirectly, there is no such "enter/exit" cycle for the root to be set. However, the point of the root is to avoid having to pass these values around everywhere, and within the parser, "everywhere" is not so big of a problem.
So the first step would be to make
utils.hookaccept an optional argument to check for a plugins table instead of the root, because the root is simply not a viable concept in
fennel.parser. Problem is
...so we can't add an optional argument. Maybe we can create a separate
utils.hook-optsor something which takes options as an arg and change
utils.hookto call it? Or update all the calls to
utils.hookto pass in nil as its second argument before
Thanks for the fix!