1
0
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:
Stephen Dolan
2012-09-10 16:57:17 +01:00
parent 6f3abbac62
commit aa3ebdfe9b
4 changed files with 52 additions and 1 deletions

View File

@@ -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])};

View File

@@ -22,7 +22,7 @@
"not" { return NOT; }
"end" { return END; }
"//" { return DEFINEDOR; }
"."|"="|";"|"["|"]"|","|":"|"("|")"|"{"|"}"|"|"|"+"|"-"|"\$" { return yytext[0];}
"."|"="|";"|"["|"]"|","|":"|"("|")"|"{"|"}"|"|"|"+"|"-"|"*"|"/"|"\$" { return yytext[0];}
\"(\\.|[^\\"])*\" |
-?[0-9.]+([eE][+-]?[0-9]+)? {

View File

@@ -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;
}

View File

@@ -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.