matchPattern, projectObjects

This commit is contained in:
Tony Garnock-Jones 2014-07-24 20:18:51 -07:00
parent cfeb46ef62
commit e0b476cc0a
2 changed files with 67 additions and 20 deletions

View File

@ -145,6 +145,45 @@ function compilePattern(v, p) {
}
}
function matchPattern(v, p) {
var captureCount = 0;
var result = {};
try {
walk(v, p);
} catch (e) {
if (e.matchPatternFailed) return null;
throw e;
}
result.length = captureCount;
return result;
function walk(v, p) {
if (p === v) return;
if (p === __) return;
if (Array.isArray(p) && Array.isArray(v) && p.length === v.length) {
for (var i = 0; i < p.length; i++) {
walk(v[i], p[i]);
}
return;
}
if (isCapture(p)) {
var thisCapture = captureCount++;
walk(v, capturePattern(p));
result[captureName(p) || ('$' + thisCapture)] = v;
return;
}
if (p instanceof $Embedded) {
die("$Embedded patterns not supported in matchPattern()");
}
throw {matchPatternFailed: true};
}
}
function shallowCopyArray(s) {
return s.slice();
}
@ -1044,13 +1083,17 @@ function matcherKeysToObjects(matcherKeysResult, compiledProjection) {
var e = matcherKeysResult[i];
var d = {};
for (var j = 0; j < e.length; j++) {
d[compiledProjection.names[j] || j] = e[j];
d[compiledProjection.names[j] || ('$' + j)] = e[j];
}
result.push(d);
}
return result;
}
function projectObjects(m, compiledProjection) {
return matcherKeysToObjects(matcherKeys(project(m, compiledProjection)), compiledProjection);
}
function prettyMatcher(m, initialIndent) {
var acc = [];
walk(initialIndent || 0, m);
@ -1514,6 +1557,7 @@ module.exports.is_emptyMatcher = is_emptyMatcher;
module.exports.emptyMatcher = emptyMatcher;
module.exports.embeddedMatcher = embeddedMatcher;
module.exports.compilePattern = compilePattern;
module.exports.matchPattern = matchPattern;
module.exports.union = unionN;
module.exports.intersect = intersect;
module.exports.erasePath = erasePath;
@ -1526,6 +1570,7 @@ module.exports.projectionToPattern = projectionToPattern;
module.exports.project = project;
module.exports.matcherKeys = matcherKeys;
module.exports.matcherKeysToObjects = matcherKeysToObjects;
module.exports.projectObjects = projectObjects;
module.exports.matcherEquals = matcherEquals;
module.exports.prettyMatcher = prettyMatcher;
module.exports.serializeMatcher = serializeMatcher;

View File

@ -205,8 +205,8 @@ dumpM(r.union(r.compilePattern(r.arrayToSet('A'), [2]),
var M2 = r.project(M, proj);
dump(r.matcherKeys(M2));
dump(r.matcherKeys(r.project(M2, r.compileProjection(r._$, r._$))));
dump(r.matcherKeysToObjects(r.matcherKeys(r.project(M2, r.compileProjection(r._$, r._$))),
proj));
dump(r.matcherKeysToObjects(r.matcherKeys(M2), proj));
dump(r.projectObjects(M, proj));
})();
(function () {
@ -214,23 +214,9 @@ dumpM(r.union(r.compilePattern(r.arrayToSet('A'), [2]),
var M = r.union(r.compilePattern(r.arrayToSet(['A']), [1, 2]),
r.compilePattern(r.arrayToSet(['C']), [1, 3]),
r.compilePattern(r.arrayToSet(['B']), [3, 4]));
var proj = r.compileProjection([r._$("fst"), r._$("snd")]);
var M2 = r.project(M, proj);
dump(r.matcherKeys(M2));
dump(r.matcherKeysToObjects(r.matcherKeys(r.project(M2, r.compileProjection(r._$, r._$))),
proj));
})();
(function () {
console.log("matcherKeys using multiple-values in projections, with partial names");
var M = r.union(r.compilePattern(r.arrayToSet(['A']), [1, 2]),
r.compilePattern(r.arrayToSet(['C']), [1, 3]),
r.compilePattern(r.arrayToSet(['B']), [3, 4]));
var proj = r.compileProjection([r._$, r._$("snd")]);
var M2 = r.project(M, proj);
dump(r.matcherKeys(M2));
dump(r.matcherKeysToObjects(r.matcherKeys(r.project(M2, r.compileProjection(r._$, r._$))),
proj));
dump(r.projectObjects(M, r.compileProjection([r._$("fst"), r._$("snd")])));
dump(r.projectObjects(M, r.compileProjection([r._$, r._$("snd")])));
dump(r.projectObjects(M, r.compileProjection([r._$("fst"), r._$])));
})();
(function () {
@ -289,3 +275,19 @@ dumpM(r.union(r.compilePattern(r.arrayToSet('A'), [2]),
dump(r.matcherEquals(M1a, M1b) === true);
dump(r.matcherEquals(M2a, M2b) === true);
})();
(function () {
console.log("Calls to matchPattern");
dump(r.matchPattern([1, 2, 3], [r.__, 2, r._$]));
dump(r.matchPattern([1, 2, 3], [r.__, 2, r._$("three")]));
dump(r.matchPattern([1, 2, 3], [r._$, 2, r._$("three")]));
dump(r.matchPattern([1, 2, 3], [r._$("one"), 2, r._$]));
dump(r.matchPattern([1, 2, 3], [r._$("one"), 2, r._$("three")]));
dump(r.matchPattern([1, 2, 3], [r.__, 999, r._$("three")]) === null);
dump(r.matchPattern([1, 2, 3], [r.__, 2, r._$("three"), 4]) === null);
dump(r.matchPattern([1, [2, 999], 3], [r._$("one"), r._$(null, [2, r.__]), r._$("three")]));
dump(r.matchPattern([1, [2, 999], 3], [r._$("one"), r._$("two", [2, r.__]), r._$("three")]));
dump(r.matchPattern([1, [2, 999], 3], [r._$("one"), r._$(null, [2, r._$]), r._$("three")]));
dump(r.matchPattern([1, [2, 999], 3], [r._$("one"), r._$("two", [2, r._$]), r._$("three")]));
})();