Skip to content

Commit

Permalink
Add HAS and HAS NOT & better array support
Browse files Browse the repository at this point in the history
  • Loading branch information
florentsolt committed Jun 3, 2014
1 parent fda8463 commit d83e6cc
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
16 changes: 9 additions & 7 deletions filtrex.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ function filtrexParser() {
['or[^\\w]' , 'return "or";'],
['not[^\\w]', 'return "not";'],
['in[^\\w]', 'return "in";'],
['has[^\\w]', 'return "has";'],
['of[^\\w]', 'return "of";'],

['\\s+', ''], // skip whitespace
Expand All @@ -129,6 +130,7 @@ function filtrexParser() {
['left', 'or'],
['left', 'and'],
['left', 'in'],
['left', 'has'],
['left', 'of'],
['left', '==', '!='],
['left', '<', '<=', '>', '>='],
Expand Down Expand Up @@ -162,22 +164,22 @@ function filtrexParser() {
['e >= e' , code(['Number(', 1, '>=', 3, ')'])],
['e ? e : e', code([1, '?', 3, ':', 5])],
['( e )' , code([2])],
['( argsList , e )', code(['[', 2, ', ', 4, ']'])],
['NUMBER' , code([1])],
['STRING' , code(['"', 1, '"'])],
['SYMBOL' , code(['data["', 1, '"]'])],
['SYMBOL ( argsList )', code(['(functions.hasOwnProperty("', 1, '") ? functions.', 1, '(', 3, ') : unknown("', 1, '"))'])],
['e in ( inSet )', code([1, ' in (function(o) { ', 4, 'return o; })({})'])],
['e not in ( inSet )', code(['!(', 1, ' in (function(o) { ', 5, 'return o; })({}))'])],
['e in e', code([3, '.indexOf(', 1, ') !== -1'])],
['e has e', code([1, '.indexOf(', 3, ') !== -1'])],
['e not in e', code([4, '.indexOf(', 1, ') === -1'])],
['e has not e', code([1, '.indexOf(', 4, ') === -1'])],
['SYMBOL of e', code(['map(', 3, ',"', 1, '")'])],
],

argsList: [
['e', code([1], true)],
['argsList , e', code([1, ',', 3], true)],
],
inSet: [
['e', code(['o[', 1, '] = true; '], true)],
['inSet , e', code([1, 'o[', 3, '] = true; '], true)],
],
]
}
};
return new Jison.Parser(grammar);
Expand Down
16 changes: 9 additions & 7 deletions src/filtrex.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ function filtrexParser() {
['or[^\\w]' , 'return "or";'],
['not[^\\w]', 'return "not";'],
['in[^\\w]', 'return "in";'],
['has[^\\w]', 'return "has";'],
['of[^\\w]', 'return "of";'],

['\\s+', ''], // skip whitespace
Expand All @@ -129,6 +130,7 @@ function filtrexParser() {
['left', 'or'],
['left', 'and'],
['left', 'in'],
['left', 'has'],
['left', 'of'],
['left', '==', '!='],
['left', '<', '<=', '>', '>='],
Expand Down Expand Up @@ -162,22 +164,22 @@ function filtrexParser() {
['e >= e' , code(['Number(', 1, '>=', 3, ')'])],
['e ? e : e', code([1, '?', 3, ':', 5])],
['( e )' , code([2])],
['( argsList , e )', code(['[', 2, ', ', 4, ']'])],
['NUMBER' , code([1])],
['STRING' , code(['"', 1, '"'])],
['SYMBOL' , code(['data["', 1, '"]'])],
['SYMBOL ( argsList )', code(['(functions.hasOwnProperty("', 1, '") ? functions.', 1, '(', 3, ') : unknown("', 1, '"))'])],
['e in ( inSet )', code([1, ' in (function(o) { ', 4, 'return o; })({})'])],
['e not in ( inSet )', code(['!(', 1, ' in (function(o) { ', 5, 'return o; })({}))'])],
['e in e', code([3, '.indexOf(', 1, ') !== -1'])],
['e has e', code([1, '.indexOf(', 3, ') !== -1'])],
['e not in e', code([4, '.indexOf(', 1, ') === -1'])],
['e has not e', code([1, '.indexOf(', 4, ') === -1'])],
['SYMBOL of e', code(['map(', 3, ',"', 1, '")'])],
],

argsList: [
['e', code([1], true)],
['argsList , e', code([1, ',', 3], true)],
],
inSet: [
['e', code(['o[', 1, '] = true; '], true)],
['inSet , e', code([1, 'o[', 3, '] = true; '], true)],
],
]
}
};
return new Jison.Parser(grammar);
Expand Down
17 changes: 17 additions & 0 deletions test/filtrex-test.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@
eq(1, compileExpression('(0 and 1) or 1')());
eq(0, compileExpression('0 and (1 or 1)')());
eq(1, compileExpression('0 and 1 or 1')()); // or is higher precedence
eq(1, compileExpression('(0 and 1) or (1 and 1)')());
eq(1, compileExpression('1 or 1 and 0')()); // or is higher precedence
eq(0, compileExpression('not 1 and 0')()); // not is higher precedence
eq(0, compileExpression('not 1 and 1')()); // not is higher precedence
eq(0, compileExpression('not (1 and 1)')());
},

'comparisons': function() {
Expand Down Expand Up @@ -94,6 +97,15 @@
eq(0, compileExpression('3 not in (1, 2, 3, 4)')());
},

'has / has not': function() {
eq(0, compileExpression('(1, 2, 3, 4) has 5')());
eq(1, compileExpression('(1, 2, 3, 4) has 3')());
eq(0, compileExpression('not ((1, 2, 3, 4) has 3)')());
eq(1, compileExpression('(1, 2, 3, 4) has not 5')());
eq(0, compileExpression('(1, 2, 3, 4) has not 3')());
eq(1, compileExpression('(1, 2, 3, 4) has not 3 or 1')());
},

'string test': function() {
eq(1, compileExpression('foo == "hello"')({foo:'hello'}));
eq(0, compileExpression('foo == "hello"')({foo:'bye'}));
Expand Down Expand Up @@ -140,6 +152,11 @@
})({'objects':[
{'prop': 1},{'prop': 2},{'prop': 3}
]}));
eq(1, compileExpression('2 in prop of objects', {
max: function(o){ return Math.max.apply(null, o);}
})({'objects':[
{'prop': 1},{'prop': 2},{'prop': 3}
]}));
eq(3, compileExpression('max(foo.bar of objects)', {
max: function(o){ return Math.max.apply(null, o);}
})({'objects':[
Expand Down

0 comments on commit d83e6cc

Please sign in to comment.