To install this library, run:
bun install pmatcher
or
npm install pmatcher
The match_builder
function allows you to build and run custom pattern matchers. Here's a basic example of how to use it:
// Example usage of match_builder
import { build , P, run_matcher } from 'pmatcher/MatchBuilder';
import { MatchDict } from 'pmatcher/MatchDict';
// Define patterns using the builder function
const matcher = match_builder(["Hello", ["John",[P.segment, "details"], "Unrelated"]]);
// Example data array
const data = ["Hello", ["John", "age:30", "location:NY", "Unrelated"]];
// Define a success callback
// Run the matcher on the data
const result = run_matcher(matcher, data, {result: (matchDict, nEaten) => {
return {matchDict, nEaten}
}});
console.log(result);
output:
Matched Dictionary: {
"details": ["age:30", "location:NY"]
}
Number of elements processed: 2
This example demonstrates how to use the match_builder
and run_matcher
functions to create a matcher that matches a constant string "Hello" followed by a segment containing details. The onSuccess
callback is called when the matcher successfully matches the data, and it logs the matched dictionary and the number of elements processed.
The "..."
pattern is used to match any remaining elements in the data array. Here's an example:
// Example usage of "..." pattern
import { build, P, run_matcher } from 'pmatcher/MatchBuilder';
import { MatchDict } from 'pmatcher/MatchDict';
// Define patterns using the builder function
const matcher = build(["start","...", [P.element, "e"]]);
// Example data array
const data = ["start", 1, 2, 3, "end"];
// Define a success callback
// Run the matcher on the data
const result = run_matcher(matcher, data, {result: (matchDict, nEaten) => {
return {matchDict, nEaten}
}});
console.log(result);
output:
Matched Dictionary: {
"e": "end"
}
Number of elements processed: 5
// Example usage of matching nested arrays with match element
import { build, P, run_matcher } from 'pmatcher/MatchBuilder';
import { MatchDict } from 'pmatcher/MatchDict';
// Define patterns using the builder function
const nestedMatcherWithElement = build(["start", [ "subStart", [P.element, "key"], "subEnd"], "end"]);
// Example data array
const nestedDataWithElement = ["start", ["subStart", "actualValue", "subEnd"], "end"];
// Define a success callback
// Run the matcher on the data
const nestedResultWithElement = run_matcher(nestedMatcherWithElement, nestedDataWithElement, {result: (matchDict, nEaten) => {
return {matchDict, nEaten}
}});
console.log(nestedResultWithElement);
output:
Matched Dictionary: {
"key": "actualValue"
}
Number of elements processed: 3
The match_letrec
function allows you to define recursive patterns. Here's an example demonstrating how to handle tail recursive patterns:
// Example usage of match_letrec with tail recursion
import { build, P, run_matcher } from 'pmatcher/MatchBuilder';
import { emptyEnvironment, MatchEnvironment } from 'pmatcher/MatchEnvironment';
// Define recursive patterns using match_letrec
const matcher = build([P.letrec,
[["a", [P.choose, [], [ "1", [P.ref, "b"]]]],
["b", [P.choose, [], [ "2", [P.ref, "a"]]]]]
[P.ref, "a"]])
// Example data array
const data = [["1", ["2", ["1", ["2", []]]]]];
// Define a success callback
function onSuccess(environment: MatchEnvironment, nEaten: number) {
console.log("Matched Environment:", environment);
console.log("Number of elements processed:", nEaten);
}
// Run the matcher on the data
run_matcher(matcher, data, onSuccess);
output:
Matched Environment: MatchEnvironment { ... }
Number of elements processed: 1
i also tried to implemented an lexical scoping environment for match_letrec but it was not working as expected. btw, although the definition of environment do look like some sort of lexical scoping, it has some weird bug made it actually scoped dynamically, but who the hell needs a lexical scoped pattern matcher anyway.
In MatchBuilder.ts, we utilize functions from MatchCallback.ts and MatchCombinator.ts to construct complex pattern matchers.
MatchCallback.ts:
match_constant
: Matches a specific constant value in the data array.match_element
: Matches and binds a variable to a value in the data array based on a restriction function.match_segment
: Matches a sequence of elements in the data array and binds them to a variable.match_all_other_element
: Matches all remaining elements in the data array.match_segment_independently
: Matches a segment of the data array where each element satisfies a given restriction independently(means without element or segment or all_other_element in front ).These functions return a matcher_callback
, which is a function that takes the data array, a match dictionary, and a success callback, and either succeeds (calling the success callback) or fails (returning a match failure).
MatchCombinator.ts:
match_array
: Takes an array of matchers and applies them sequentially to the data array.match_choose
: Takes an array of matchers and tries each one until one succeeds.These combinators allow for building complex matching logic by combining simpler matchers from MatchCallback.ts.
Usage in MatchBuilder.ts:
match_builder
function uses these building blocks and combinators to construct a matcher from a pattern array. It interprets the pattern array, converts patterns to matchers using a recursive loop
function, and combines them using match_array
or other combinators as needed.run_matcher
function takes a matcher and data array, and executes the matcher, handling the match result.By leveraging the functions from MatchCallback.ts and MatchCombinator.ts, MatchBuilder.ts provides a flexible and powerful way to define and execute complex matching rules on data arrays. */