mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
Multiplication and division operators.
It is an error to use these on anything but numbers. Maybe later
implementing python/ruby-style ("a" * 100) might be handy.
This commit is contained in:
32
c/builtin.c
32
c/builtin.c
@@ -70,11 +70,43 @@ static void f_minus(jv input[], jv output[]) {
|
||||
}
|
||||
}
|
||||
|
||||
static void f_multiply(jv input[], jv output[]) {
|
||||
jv_free(input[0]);
|
||||
jv a = input[2];
|
||||
jv b = input[1];
|
||||
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
|
||||
output[0] = jv_number(jv_number_value(a) * jv_number_value(b));
|
||||
} else {
|
||||
output[0] = jv_invalid_with_msg(jv_string_fmt("Attempted to multiply %s and %s",
|
||||
jv_kind_name(jv_get_kind(a)),
|
||||
jv_kind_name(jv_get_kind(b))));
|
||||
jv_free(a);
|
||||
jv_free(b);
|
||||
}
|
||||
}
|
||||
|
||||
static void f_divide(jv input[], jv output[]) {
|
||||
jv_free(input[0]);
|
||||
jv a = input[2];
|
||||
jv b = input[1];
|
||||
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
|
||||
output[0] = jv_number(jv_number_value(a) / jv_number_value(b));
|
||||
} else {
|
||||
output[0] = jv_invalid_with_msg(jv_string_fmt("Attempted to divide %s by %s",
|
||||
jv_kind_name(jv_get_kind(a)),
|
||||
jv_kind_name(jv_get_kind(b))));
|
||||
jv_free(a);
|
||||
jv_free(b);
|
||||
}
|
||||
}
|
||||
|
||||
struct cfunction function_list[] = {
|
||||
{f_true, "true", CALL_BUILTIN_1_1},
|
||||
{f_false, "false", CALL_BUILTIN_1_1},
|
||||
{f_null, "null", CALL_BUILTIN_1_1},
|
||||
{f_plus, "_plus", CALL_BUILTIN_3_1},
|
||||
{f_minus, "_minus", CALL_BUILTIN_3_1},
|
||||
{f_multiply, "_multiply", CALL_BUILTIN_3_1},
|
||||
{f_divide, "_divide", CALL_BUILTIN_3_1},
|
||||
};
|
||||
struct symbol_table builtins = {function_list, sizeof(function_list)/sizeof(function_list[0])};
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"not" { return NOT; }
|
||||
"end" { return END; }
|
||||
"//" { return DEFINEDOR; }
|
||||
"."|"="|";"|"["|"]"|","|":"|"("|")"|"{"|"}"|"|"|"+"|"-"|"\$" { return yytext[0];}
|
||||
"."|"="|";"|"["|"]"|","|":"|"("|")"|"{"|"}"|"|"|"+"|"-"|"*"|"/"|"\$" { return yytext[0];}
|
||||
|
||||
\"(\\.|[^\\"])*\" |
|
||||
-?[0-9.]+([eE][+-]?[0-9]+)? {
|
||||
|
||||
11
c/parser.y
11
c/parser.y
@@ -43,6 +43,7 @@
|
||||
%left OR
|
||||
%left AND
|
||||
%left '+' '-'
|
||||
%left '*' '/'
|
||||
|
||||
|
||||
%type <blk> Exp Term MkDict MkDictPair ExpD ElseBody
|
||||
@@ -68,6 +69,8 @@ static block gen_binop(block a, block b, char op) {
|
||||
switch (op) {
|
||||
case '+': funcname = "_plus"; break;
|
||||
case '-': funcname = "_minus"; break;
|
||||
case '*': funcname = "_multiply"; break;
|
||||
case '/': funcname = "_divide"; break;
|
||||
}
|
||||
assert(funcname);
|
||||
|
||||
@@ -157,6 +160,14 @@ Exp '-' Exp {
|
||||
$$ = gen_binop($1, $3, '-');
|
||||
} |
|
||||
|
||||
Exp '*' Exp {
|
||||
$$ = gen_binop($1, $3, '*');
|
||||
} |
|
||||
|
||||
Exp '/' Exp {
|
||||
$$ = gen_binop($1, $3, '/');
|
||||
} |
|
||||
|
||||
Term {
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
@@ -175,6 +175,14 @@ null
|
||||
1
|
||||
[2,4]
|
||||
|
||||
[10 * 20, 20 / .]
|
||||
4
|
||||
[200, 5]
|
||||
|
||||
1 + 2 * 2 + 10 / 2
|
||||
null
|
||||
10
|
||||
|
||||
#
|
||||
# User-defined functions
|
||||
# Oh god.
|
||||
|
||||
Reference in New Issue
Block a user