For instance, a pattern written in the notation for complex numbers can be parsed as follows:
var m = matcher(Complex, "(%x+%yi)"); // m is the parsed pattern (a function) var s = m(new Complex(1, -1)); // matches the complex with the compiled pattern
In order for this to work with a custom notation for a type T, one must implement a method T.prototype.matcher(pattern, offset), which parses a sub-pattern starting at a given offset, and returns (1) an updated offset, indicating the sub-pattern that was consumed, and (2) a matcher function corresponding to the parsed pattern. The matcher method for the Complex type can be written as follows:
Complex.prototype.matcher = function(pat, off) { var m1, m2, res; off = matchChar("(", pat, off); res = parseType(Number, pat, off); off = res[0]; m1 = res[1]; if(pat.charAt(off) == "+") { off = matchChar("+", pat, off); res = parseType(Number, pat, off); off = res[0]; m2 = res[1]; off = matchChar("i", pat, off); } off = matchChar(")", pat, off); return [off, function(data, sub) { if(data == null) throw "fail"; m1(data.re, sub); if(m2 !== undefined) m2(data.im, sub); }]; }The parseType(type, pat, off) function above is predefined in myPatterns. It parses at the given offset either a variable occurrence or a sub-pattern written in the notation for the given type. In the case of complex numbers, the sub-patterns are all of type Number, so this function will use the predefined matcher() method for type Number to parse them. If some sub-pattern were written in a custom notation, the corresponding matcher method would have to be implemented.
Like in interpreted patterns, the outermost parentheses in a pattern can be omitted by using function pmatcher() instead of matcher(). Thus, pmatcher(Complex, "%x+%yi") gives the same result as matcher(Complex, "(%x+%yi)").