Demote "contains" to a built-in function rather than an operator.
This commit is contained in:
1 parent
63d10433c9
commit
ed7f95a492
5 files changed
+42
-48
No files matched your search
@@ -161,8 +161,7 @@ static jv f_greatereq(jv input, jv a, jv b) {
|
||||
return order_cmp(input, a, b, CMP_OP_GREATEREQ);
|
||||
}
|
||||
|
||||
static jv f_contains(jv input, jv a, jv b) {
|
||||
jv_free(input);
|
||||
static jv f_contains(jv a, jv b) {
|
||||
jv_kind akind = jv_get_kind(a);
|
||||
|
||||
if (akind == jv_get_kind(b)) {
|
||||
@@ -242,7 +241,7 @@ static struct cfunction function_list[] = {
|
||||
{(cfunction_ptr)f_greater, "_greater", 3},
|
||||
{(cfunction_ptr)f_lesseq, "_lesseq", 3},
|
||||
{(cfunction_ptr)f_greatereq, "_greatereq", 3},
|
||||
{(cfunction_ptr)f_contains, "_contains", 3},
|
||||
{(cfunction_ptr)f_contains, "contains", 2},
|
||||
{(cfunction_ptr)f_length, "length", 1},
|
||||
{(cfunction_ptr)f_type, "type", 1},
|
||||
{(cfunction_ptr)f_add, "add", 1},
|
||||
|
||||
@@ -487,6 +487,35 @@ sections:
|
||||
input: '[1, "1", [1]]'
|
||||
output: ['"1"', '"1"', '"[1]"']
|
||||
|
||||
- title: `contains`
|
||||
body: |
|
||||
|
||||
The filter `contains(b)` will produce true if b is
|
||||
completely contained within the input. A string B is
|
||||
contained in a string A if B is a substring of A. An array B
|
||||
is contained in an array A is all elements in B are
|
||||
contained in any element in A. An object B is contained in
|
||||
object A if all of the values in B are contained in the
|
||||
value in A with the same key. All other types are assumed to
|
||||
be contained in each other if they are equal.
|
||||
|
||||
examples:
|
||||
- program: 'contains("bar")'
|
||||
input: '"foobar"'
|
||||
output: ['true']
|
||||
- program: 'contains(["baz", "bar"])'
|
||||
input: '["foobar", "foobaz", "blarp"]'
|
||||
output: ['true']
|
||||
- program: 'contains(["bazzzzz", "bar"])'
|
||||
input: '["foobar", "foobaz", "blarp"]'
|
||||
output: ['false']
|
||||
- program: 'contains({foo: 12, bar: [{barp: 12}]})'
|
||||
input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}'
|
||||
output: ['true']
|
||||
- program: 'contains({foo: 12, bar: [{barp: 15}]})'
|
||||
input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}'
|
||||
output: ['false']
|
||||
|
||||
- title: "String interpolation - `\(foo)`"
|
||||
body: |
|
||||
|
||||
@@ -522,33 +551,6 @@ sections:
|
||||
- program: '.[] == 1'
|
||||
input: '[1, 1.0, "1", "banana"]'
|
||||
output: ['[true, true, false, false]']
|
||||
- title: `contains`
|
||||
body: |
|
||||
|
||||
The expression 'a contains b' will produce true if b is completely
|
||||
contained within a. A string B is contained in a string A if B is a
|
||||
substring of A. An array B is contained in an array A is all elements
|
||||
in B are contained in any element in A. An object B is contained in
|
||||
object A if all of the values in B are contained in the value in A with
|
||||
the same key. All other types are assumed to be contained in each other
|
||||
if they are equal.
|
||||
|
||||
examples:
|
||||
- program: '. == contains "bar"'
|
||||
input: '"foobar"'
|
||||
output: ['true']
|
||||
- program: '. contains ["baz", "bar"]'
|
||||
input: '["foobar", "foobaz", "blarp"]'
|
||||
output: ['true']
|
||||
- program: '. contains ["bazzzzz", "bar"]'
|
||||
input: '["foobar", "foobaz", "blarp"]'
|
||||
output: ['false']
|
||||
- program: '. contains {foo: 12, bar: [{barp: 12}]}'
|
||||
input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}'
|
||||
output: ['true']
|
||||
- program: '. contains {foo: 12, bar: [{barp: 15}]}'
|
||||
input: '{foo: 12, bar:[1,2,{barp:12, blip:13}]}'
|
||||
output: ['false']
|
||||
- title: if-then-else
|
||||
body: |
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ struct lexer_param;
|
||||
"//=" { return SETDEFINEDOR; }
|
||||
"<=" { return LESSEQ; }
|
||||
">=" { return GREATEREQ; }
|
||||
"contains" { return CONTAINS; }
|
||||
"."|"="|";"|","|":"|"|"|"+"|"-"|"*"|"/"|"\$"|"<"|">" { return yytext[0];}
|
||||
|
||||
"["|"{"|"(" {
|
||||
|
||||
@@ -65,7 +65,6 @@ struct lexer_param;
|
||||
%token SETDEFINEDOR "//="
|
||||
%token LESSEQ "<="
|
||||
%token GREATEREQ ">="
|
||||
%token CONTAINS "contains"
|
||||
|
||||
%token QQSTRING_START
|
||||
%token <literal> QQSTRING_TEXT
|
||||
@@ -81,7 +80,7 @@ struct lexer_param;
|
||||
%nonassoc '=' SETPIPE SETPLUS SETMINUS SETMULT SETDIV SETDEFINEDOR
|
||||
%left OR
|
||||
%left AND
|
||||
%nonassoc NEQ EQ '<' '>' LESSEQ GREATEREQ CONTAINS
|
||||
%nonassoc NEQ EQ '<' '>' LESSEQ GREATEREQ
|
||||
%left '+' '-'
|
||||
%left '*' '/'
|
||||
|
||||
@@ -150,7 +149,6 @@ static block gen_binop(block a, block b, int op) {
|
||||
case '>': funcname = "_greater"; break;
|
||||
case LESSEQ: funcname = "_lesseq"; break;
|
||||
case GREATEREQ: funcname = "_greatereq"; break;
|
||||
case CONTAINS: funcname = "_contains"; break;
|
||||
}
|
||||
assert(funcname);
|
||||
|
||||
@@ -295,10 +293,6 @@ Exp ">=" Exp {
|
||||
$$ = gen_binop($1, $3, GREATEREQ);
|
||||
} |
|
||||
|
||||
Exp "contains" Exp {
|
||||
$$ = gen_binop($1, $3, CONTAINS);
|
||||
} |
|
||||
|
||||
Term {
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
@@ -406,27 +406,27 @@ def inc(x): x |= .+1; inc(.[].a)
|
||||
[true,false]
|
||||
|
||||
# containment operator
|
||||
["foo" contains "foo", "foobar" contains "foo", "foo" contains "foobar"]
|
||||
[("foo" | contains("foo")), ("foobar" | contains("foo")), ("foo" | contains("foobar"))]
|
||||
{}
|
||||
[true, true, false]
|
||||
|
||||
[[] contains [], [1,2,3] contains [1,2], [1,2,3] contains [3,1], [1,2,3] contains [4], [1,2,3] contains [1,4]]
|
||||
{}
|
||||
map(.[1] as $needle | .[0] | contains($needle))
|
||||
[[[],[]], [[1,2,3], [1,2]], [[1,2,3], [3,1]], [[1,2,3], [4]], [[1,2,3], [1,4]]]
|
||||
[true, true, true, false, false]
|
||||
|
||||
[["foobar", "foobaz"] contains ["baz", "bar"], ["foobar", "foobaz"] contains ["foo"], ["foobar", "foobaz"] contains ["blap"]]
|
||||
map(.[1] as $needle | .[0] | contains($needle))
|
||||
[[["foobar", "foobaz"], ["baz", "bar"]], [["foobar", "foobaz"], ["foo"]], [["foobar", "foobaz"], ["blap"]]]
|
||||
[true, true, false]
|
||||
|
||||
[({foo: 12, bar:13} | contains({foo: 12})), ({foo: 12} | contains({})), ({foo: 12, bar:13} | contains({baz:14}))]
|
||||
{}
|
||||
[true, true, false]
|
||||
|
||||
[{foo: 12, bar:13} contains {foo: 12}, {foo: 12} contains {}, {foo: 12, bar:13} contains {baz:14}]
|
||||
{}
|
||||
[true, true, false]
|
||||
|
||||
{foo: {baz: 12, blap: {bar: 13}}, bar: 14} contains {bar: 14, foo: {blap: {}}}
|
||||
{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {}}})
|
||||
{}
|
||||
true
|
||||
|
||||
{foo: {baz: 12, blap: {bar: 13}}, bar: 14} contains {bar: 14, foo: {blap: {bar: 14}}}
|
||||
{foo: {baz: 12, blap: {bar: 13}}, bar: 14} | contains({bar: 14, foo: {blap: {bar: 14}}})
|
||||
{}
|
||||
false
|
||||
|
||||
|
||||
Reference in new issue
Block a user