diff --git a/c/builtin.c b/c/builtin.c index 7943675d..375e3252 100644 --- a/c/builtin.c +++ b/c/builtin.c @@ -100,6 +100,11 @@ static void f_divide(jv input[], jv output[]) { } } +static void f_equal(jv input[], jv output[]) { + jv_free(input[0]); + output[0] = jv_bool(jv_equal(input[2], input[1])); +} + static void f_tonumber(jv input[], jv output[]) { if (jv_get_kind(input[0]) == JV_KIND_NUMBER) { output[0] = input[0]; @@ -133,5 +138,6 @@ struct cfunction function_list[] = { {f_multiply, "_multiply", CALL_BUILTIN_3_1}, {f_divide, "_divide", CALL_BUILTIN_3_1}, {f_tonumber, "tonumber", CALL_BUILTIN_1_1}, + {f_equal, "_equal", CALL_BUILTIN_3_1}, }; struct symbol_table builtins = {function_list, sizeof(function_list)/sizeof(function_list[0])}; diff --git a/c/parser.y b/c/parser.y index 225a324e..0f1e42c4 100644 --- a/c/parser.y +++ b/c/parser.y @@ -19,11 +19,6 @@ %token IDENT %token LITERAL - /* revolting hack */ -%left ';' - -%left '|' -%left ',' %token EQ "==" %token DEFINEDOR "//" %token AS "as" @@ -37,6 +32,12 @@ %token AND "and" %token OR "or" %token NOT "not" + + + /* revolting hack */ +%left ';' +%left '|' +%left ',' %right "//" %nonassoc '=' SETPIPE %nonassoc EQ @@ -64,13 +65,14 @@ static block gen_index(block obj, block key) { return block_join(obj, block_join(gen_subexp(key), gen_op_simple(INDEX))); } -static block gen_binop(block a, block b, char op) { +static block gen_binop(block a, block b, int op) { const char* funcname = 0; switch (op) { case '+': funcname = "_plus"; break; case '-': funcname = "_minus"; break; case '*': funcname = "_multiply"; break; case '/': funcname = "_divide"; break; + case EQ: funcname = "_equal"; break; } assert(funcname); @@ -129,6 +131,7 @@ Exp "and" Exp { $$ = gen_and($1, $3); } | + "not" Exp { $$ = gen_not($2); } | @@ -168,6 +171,10 @@ Exp '/' Exp { $$ = gen_binop($1, $3, '/'); } | +Exp "==" Exp { + $$ = gen_binop($1, $3, EQ); +} | + Term { $$ = $1; } diff --git a/c/testdata b/c/testdata index 45140242..bd1d7f25 100644 --- a/c/testdata +++ b/c/testdata @@ -183,10 +183,27 @@ null null 10 +[16 / 4 / 2, 16 / 4 * 2, 16 - 4 - 2, 16 - 4 + 2] +null +[2, 8, 10, 14] + 1 + tonumber + ("10" | tonumber) 4 15 +[{"a":42},.object,10,.num,false,true,null,"b",[1,4]] | .[] as $x | [$x == .[]] +{"object": {"a":42}, "num":10.0} +[true, true, false, false, false, false, false, false, false] +[true, true, false, false, false, false, false, false, false] +[false, false, true, true, false, false, false, false, false] +[false, false, true, true, false, false, false, false, false] +[false, false, false, false, true, false, false, false, false] +[false, false, false, false, false, true, false, false, false] +[false, false, false, false, false, false, true, false, false] +[false, false, false, false, false, false, false, true, false] +[false, false, false, false, false, false, false, false, true ] + + # # User-defined functions # Oh god.