Hejsil / mecha

A parser combinator library for Zig
MIT License
411 stars 17 forks source link

Document what `map` passes to functions with various parsers (`combine`, `oneOf`, ...) #53

Open ethindp opened 9 months ago

ethindp commented 9 months ago

From reading the code, it's unclear how I'm supposed to define a function as when I want to use map. For instance, if I have this parser:

const if_statement = combine(.{keyword_if, condition, keyword_then, statements});

I can't easily tell how my function in map will be called, i.e., will I get a call like fn x(kw_if: []u8, condition: Condition, kw_then: []u8, statements: Statements), or something else?

Hejsil commented 9 months ago

Looking at map, it is currently documented as this:

/// Constructs a parser that has its result converted with the
/// `conv` function. The ´conv` functions signature is
/// `*const fn (ParserResult(parser)) T`, so this function should only
/// be used for conversions that cannot fail. See `convert`.

So the conv function will be passed one argument, which is the result of the parser it maps over. For combine the result is a tuple, as documented:

/// Takes a tuple of `Parser(any)` and constructs a parser that
/// only succeeds if all parsers succeed to parse. The parsers
/// will be called in order and parser `N` will use the `rest`
/// from parser `N-1`. The parsers result will be a `Tuple` of
/// all parser not of type `Parser(void)`. If only one parser
/// is not of type `Parser(void)` then this parsers result is
/// returned instead of a tuple.

I'm unsure what is missing to make this more clear, but if you have any ideas I'm all ear.

ethindp commented 9 months ago

Thanks, I missed those parts, I understand now. I am wondering how map actually works though, like say I want to build an AST out of it and I use .map to do it. Would I return the AST nodes in the conversion function, add them to an external list, or something else?