| integer (3) | | Matches a number of characters, and advances that many characters. If negative, matches if not that many characters and does not advance. For example, -1 will match the end of a string |
| `(range "az" "AZ")` | | Matches characters in a range and advances 1 character. Multiple ranges can be combined together. |
| `(set "abcd")` | | Match any character in the argument string. Advances 1 character. |
These primitive patterns are combined with a few specials to match a wide number of languages. These specials
can be thought of as the looping and branching forms in a traditional language
(that is how they are implemented when compiled to bytecode).
| Pattern | Alias | What it matches |
| ------- | ----- | --------------- |
| `(choice a b c ...)` | `(+ a b c ...)` | Tries to match a, then b, and so on. Will succeed on the first successful match, and fails if none of the arguments match the text. |
| `(sequence a b c)` | `(* a b c ...)` | Tries to match a, b, c and so on in sequence. If any of these arguments fail to match the text, the whole pattern fails. |
| `(any x)` | | Matches 0 or more repetitions of x. |
| `(some x)` | | Matches 1 or more repetitions of x. |
| `(between min max x)` | | Matches between min and max (inclusive) or more occurrences of x. |
| `(at-least n x)` | | Matches at least n occurrences of x. |
| `(at-most n x)` | | Matches at most n occurrences of x. |
| `(if cond patt)` | | | Tries to match patt only if cond matches as well. cond will not produce any captures. |
| `(if-not cond patt)` | | Tries to match only if cond does not match. cond will not produce any captures. |
| `(not patt)` | `(! patt)` | Matches only if patt does not match. Will not produce captures or advance any characters. |
| `(look offset patt)` | `(> offset patt)` | Matches only if patt matches at a fixed offset. offset can be any integer. patt will not produce captures and the peg will not advance any characters. |
## Captures
So far we have only been concerned with "does this text match this language?". This is useful, but
it is often more useful to extract data from text if it does match a peg. The `peg` module
uses that concept of a capture stack to extract data from text. As the PEG is trying to match
a piece of text, some forms may push Janet values onto the capture stack as a side effect. If the
text matches the main peg language, `(peg/match)` will return the final capture stack as an array.
Capture specials will only push captures to the capture stack if their child pattern matches the text.
Most captures specials will match the same text as their first argument pattern.
| `(capture patt)` | `(<- patt)` | Captures all of the text in patt if patt matches, If patt contains any captures, then those
captures will be pushed to the capture stack before the total text. |
| `(group patt) ` | | Pops all of the captures in patt off of the capture stack and pushes them in an array
if patt matches.
| `(replace patt subst)` | `(/ patt subst)` | Replaces the captures produced by patt by applying subst to them. If subst is a table or struct, will push `(get subst last-capture)` to the capture stack after removing the old captures. If a subst is a function, will call subst with the captures of patt as arguments and push the result to the capture stack. Otherwise, will push subst literally to the capture stack. |