malachi

A domain specific pattern matching language made mainly for defining bot commands.

Crate Examples

Please check out the examples subdirectory of this repository.

Notes

Capture Syntax

You can define captures in 3 ways:

  1. <NAME[QUANTIFIER]>
  2. <NAME[QUANTIFIER]: FILTERS>
  3. <NAME[QUANTIFIER]: FILTERS1; FILTERS2; FILTERS3...>

Quantifiers: - ?: Match this capture 1 or 0 times. - *: Match this capture 0 or more times. The captures will be returned in a Vec. - +: Match this capture at least once. The values are returned in a Vec. - None: Match this exactly once.

If you use the first form, the default is to match on words (whitespace separated). Otherwise you must use a filter.

Filter Syntax

Filters are exactly like a function call in any mainstream language. They may take arguments. Arguments are always quoted strings.

Some examples:

Strings

Strings are always quoted with one of the ", ' or ```.

You can escape the quotation to include it in the string.

Some more escape patterns are recognized:

Capture Group Syntax

A capture group defines a list of patterns that will be matched out of order. There are two forms of capture groups: - Priority groups: These are delimited with [] and the match priority of the captures enclosed are unchanged. - Normal group: These groups are enclosed in {} and the enclosed captures may be re-ordered for potentially more matches.

The syntax is as follows:

Priority groups: [ CAPTURE1 CAPTURE2 ...CAPTURE_N ]

Normal groups: { CAPTURE1 CAPTURE2 ...CAPTURE_N }

Example:

[<first> <second> <maybe_third?>]

Some defaults

Examples

Run code

This example demonstrates a command for running code. The flags are optional but must start with -- The code block is not optional and must either start and end with: - "```" - "`" Or, - Starts with ```rust or ```rs and ends with ```.

.run <flags*: starts("--")> <code: starts("rust", "rs", ""), ends(""); starts("`"), ends("`"); >

Get a Bible Verse

This example command has 3 arguments: - book: required, must start with "book= - chapter: Optional, must start with either chapter= or ch=, case is not important. - verse: optional, must start with verse=.

Since the patterns are wrapped in [], they can be matched out of order.

.bible [ <book: starts("book=")> <chapter?: starts("chapter=", "ch="), nocase()> <verse?: starts("verse=")> ]

Bet some credits

This basic example command lets you bet some of your discord credits. The only required argument is the amount.

.bet <amount>

See a tag

This command takes 1 or more space separated arguments. It does not specify any pattern so the defaults apply: - Arguments are whitespace separated.

.tag <tags+:>

Filters

Every filter can be used any number of times, the arguments are combined into one filter.