See declarations/docs below. There's obviously a bit of a near-name-clash with h_bind_indirect - I'll leave it to you to decide whether anything needs to be done about that.
One item of note is the HArena wrapped in an HAllocator I made so I can have parsers, via the __m function variants, allocated in a temporary arena that I destroy before leaving the outer parser. Consider h_bind(p, k, NULL); Obviously I don't want allocations from the second argument to stick around after the continuation has run, so k is passed an ArenaAllocator (as a pointer to HAllocator) that it is supposed to use.
Please have a look how I extend the HAllocator struct to add the pointer to the HArena. I'm fuzzy on whether this trick is portable.
This arena allocator could be useful to users in other circumstances so maybe we should expose it; it's private to the h_bind implementation right now.
/**
* Type of a parser that depends on the result of a previous parser,
* used in h_bind(). The void* argument is passed through from h_bind() and can
* be used to arbitrarily parameterize the function further.
*
* The HAllocator* argument gives access to temporary memory and is to be used
* for any allocations inside the function. Specifically, construction of any
* HParsers should use the '__m' combinator variants with the given allocator.
* Anything allocated thus will be freed by 'h_bind'.
*/
typedef HParser* (*HContinuation)(HAllocator *mm__, const HParsedToken *x, void *env);
/**
* Monadic bind for HParsers, i.e.:
* Sequencing where later parsers may depend on the result(s) of earlier ones.
*
* Run p and call the result x. Then run k(env,x). Fail if p fails or if
* k(env,x) fails or if k(env,x) is NULL.
*
* Result: the result of k(x,env).
*/
HAMMER_FN_DECL(HParser*, h_bind, const HParser *p, HContinuation k, void *env);
See declarations/docs below. There's obviously a bit of a near-name-clash with
h_bind_indirect
- I'll leave it to you to decide whether anything needs to be done about that.One item of note is the
HArena
wrapped in anHAllocator
I made so I can have parsers, via the__m
function variants, allocated in a temporary arena that I destroy before leaving the outer parser. Considerh_bind(p, k, NULL)
; Obviously I don't want allocations from the second argument to stick around after the continuation has run, sok
is passed anArenaAllocator
(as a pointer toHAllocator
) that it is supposed to use.Please have a look how I extend the
HAllocator
struct to add the pointer to theHArena
. I'm fuzzy on whether this trick is portable.This arena allocator could be useful to users in other circumstances so maybe we should expose it; it's private to the
h_bind
implementation right now.