☻ 唐鳳 ☺
and 1 contributors

Result is the match state that is passed around. It essentially forms a linked list through the rule as it is executed, but the linked list is done in code (i.e. with closures). It has the following members:

    $.backtrack - Parsers tail-call this if they fail (see below)
    $.marks     - A hash that stores backtrack closures to various.
                  points earlier in the match.  This is used to
                  implement backtracking controls.  a*: ...
    $.pos       - The current position of the match (also holds the
                  string that is being matched against).
    $.match     - State that is scope-local.  A new match object gets
                  allocated when you enter a new rule or parenthesized
                  group.

A Parser is simply an object wrapper around a closure. The closure, $.parse, takes two parameters: a Result object and a continuation (which takes in turn a Result object as a parameter). If the parser succeeds, it tail-calls the continuation (i.e. returns whatever the continuation returns) with an updated Result object. If the parser fails, it tail-calls $result.backtrack()(). Backtracking parsers such as quantifiers are implemented by passing a Result object that has a $.backtrack closure that calls back into the parser.

$.Parser and $.Result are virtual classes within the strategy. They're done like this until pugs gets support for virtual classes.

Captures within quantified expressions are "parallelized". That is, /[ foo (bar) ]*/ will put an array in $1, and /[ [ foo (bar) ]* ]*/ will put an array of arrays in $1. This is done by setting $match.multidex to the index where captures should put themselves. In the former example, when (bar) runs, multidex will be, say, [3] (on the fourth match of the group). In the latter, it will be, say, [2,4] (on the third match of the outer group, and the fifth match of the inner group). XXX wrong; they should be "flat".