Writing a plugin
Pegase has a plugin system that allows you to extend the base functionalities. A plugin is a simple object with four optional properties:
name: the name of your plugin.castParser: A function to convert custom tag argument types intoParserinstances.directives: Custom directive definitions.resolve: A string toParsermap that will be used as a fallback resolver for undefined non-terminals in your peg expressions. Think of it as global rules.
For the exact type signature of these properties, please refer to API > Types. Plugins then have to be added to the peg tag's plugins array. Order matters: in case of conflict (a conflicting resolve rule, directive definition or castParser behavior), the first will win. Let's add two directives @min and @max, that transform the children of the wrapped parser to only keep respectively the minimum and the maximum value and emit it as a single child:
peg.plugins.push({
name: "my-plugin",
directives: {
min: parser => peg`${parser} ${() => Math.min(...$children())}`,
max: parser => peg`${parser} ${() => Math.max(...$children())}`
}
});
Testing it:
const max = peg`
list: $int+ @max
$int: \d+ @number
`;
max.value("36 12 42 3"); // 42
To remove a plugin, you can manipulate the plugins array just like any other array: splice it, or replace it entirely:
peg.plugins = peg.plugins.filter(({ name }) => name !== "my-plugin");