Generalize matchValue to permit wildcard messages (not yet used)
This commit is contained in:
parent
1f33039e28
commit
8256b56607
|
@ -403,36 +403,53 @@ function subtract(o1, o2, subtractSuccessesOpt) {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Returns failureResult on failed match, otherwise the appropriate success
|
||||
// value contained in the trie r.
|
||||
function matchValue(r, v, failureResult) {
|
||||
var vs = Immutable.List.of(v);
|
||||
// Returns failureResult on failed match, otherwise the appropriate
|
||||
// success value contained in the trie r. If wildcardUnionOpt
|
||||
// non-falsy, allows wildcards in "messages" v.
|
||||
function matchValue(r, v, failureResult, wildcardUnionOpt) {
|
||||
return walk(Immutable.List.of(v), r);
|
||||
|
||||
while (!is_emptyTrie(r)) {
|
||||
if (r instanceof $Success) {
|
||||
return vs.isEmpty() ? r.value : failureResult;
|
||||
function walk(vs, r) {
|
||||
while (!is_emptyTrie(r)) {
|
||||
if (r instanceof $Success) {
|
||||
return vs.isEmpty() ? r.value : failureResult;
|
||||
}
|
||||
|
||||
if (vs.isEmpty()) return failureResult;
|
||||
var v = vs.first();
|
||||
vs = vs.rest();
|
||||
|
||||
if (v === __) {
|
||||
if (!wildcardUnionOpt) {
|
||||
die("Cannot match wildcard in value unless wildcardUnionOpt non-falsy");
|
||||
}
|
||||
|
||||
var seed = walk(vs, r.wild);
|
||||
r.edges.forEach(function (keymap, arity) {
|
||||
keymap.forEach(function (k, key) {
|
||||
seed = wildcardUnionOpt(walk(Immutable.Repeat(__, arity).concat(vs), k), seed);
|
||||
});
|
||||
});
|
||||
return seed;
|
||||
}
|
||||
|
||||
if (typeof v === 'string' && v.substring(0, 2) === '__') {
|
||||
die("Cannot match special string starting with __");
|
||||
}
|
||||
|
||||
if (Array.isArray(v)) {
|
||||
r = rlookup(r, v.length, SOA);
|
||||
vs = Immutable.List(v).concat(vs);
|
||||
} else if (Struct.isStructure(v)) {
|
||||
r = rlookup(r, v.meta.arity, v.meta);
|
||||
vs = Immutable.List(v.fields).concat(vs);
|
||||
} else {
|
||||
r = rlookup(r, 0, v);
|
||||
}
|
||||
}
|
||||
|
||||
if (vs.isEmpty()) return failureResult;
|
||||
var v = vs.first();
|
||||
vs = vs.shift();
|
||||
|
||||
if (typeof v === 'string' && v.substring(0, 2) === '__') {
|
||||
die("Cannot match special string starting with __");
|
||||
}
|
||||
|
||||
if (Array.isArray(v)) {
|
||||
r = rlookup(r, v.length, SOA);
|
||||
vs = Immutable.List(v).concat(vs);
|
||||
} else if (Struct.isStructure(v)) {
|
||||
r = rlookup(r, v.meta.arity, v.meta);
|
||||
vs = Immutable.List(v.fields).concat(vs);
|
||||
} else {
|
||||
r = rlookup(r, 0, v);
|
||||
}
|
||||
return failureResult;
|
||||
}
|
||||
|
||||
return failureResult;
|
||||
}
|
||||
|
||||
function matchTrie(o1, o2, seed, combiner) {
|
||||
|
|
|
@ -40,19 +40,19 @@ describe("basic pattern compilation", function () {
|
|||
|
||||
describe("of wildcard", function () {
|
||||
it("should match anything", function () {
|
||||
expect(r.matchValue(mAny, 'hi')).to.eql(sAny);
|
||||
expect(r.matchValue(mAny, ['A', 'hi'])).to.eql(sAny);
|
||||
expect(r.matchValue(mAny, ['B', 'hi'])).to.eql(sAny);
|
||||
expect(r.matchValue(mAny, ['A', [['hi']]])).to.eql(sAny);
|
||||
expect(r.matchValue(mAny, 'hi', null)).to.eql(sAny);
|
||||
expect(r.matchValue(mAny, ['A', 'hi'], null)).to.eql(sAny);
|
||||
expect(r.matchValue(mAny, ['B', 'hi'], null)).to.eql(sAny);
|
||||
expect(r.matchValue(mAny, ['A', [['hi']]], null)).to.eql(sAny);
|
||||
});
|
||||
});
|
||||
|
||||
describe("of A followed by wildcard", function () {
|
||||
it("should match A followed by anything", function () {
|
||||
expect(r.matchValue(mAAny, 'hi')).to.be(null);
|
||||
expect(r.matchValue(mAAny, ['A', 'hi'])).to.eql(sAAny);
|
||||
expect(r.matchValue(mAAny, ['B', 'hi'])).to.be(null);
|
||||
expect(r.matchValue(mAAny, ['A', [['hi']]])).to.eql(sAAny);
|
||||
expect(r.matchValue(mAAny, 'hi', null)).to.be(null);
|
||||
expect(r.matchValue(mAAny, ['A', 'hi'], null)).to.eql(sAAny);
|
||||
expect(r.matchValue(mAAny, ['B', 'hi'], null)).to.be(null);
|
||||
expect(r.matchValue(mAAny, ['A', [['hi']]], null)).to.eql(sAAny);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -539,7 +539,7 @@ describe('makeConstructor', function () {
|
|||
var inst = ctor(123, 234);
|
||||
var x = r.compilePattern(sA, ctor(123, r.__));
|
||||
checkPrettyTrie(x, [' foo<2> 123 ★ {["A"]}']);
|
||||
expect(r.matchValue(x, ctor(123, 234))).to.eql(sA);
|
||||
expect(r.matchValue(x, ctor(234, 123))).to.eql(null);
|
||||
expect(r.matchValue(x, ctor(123, 234), null)).to.eql(sA);
|
||||
expect(r.matchValue(x, ctor(234, 123), null)).to.eql(null);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue