]> granicus.if.org Git - jq/commitdiff
Initial add of math functions. 302/head
authorMike McCabe <mccabe@archive.org>
Fri, 21 Feb 2014 08:46:56 +0000 (08:46 +0000)
committerMike McCabe <mccabe@archive.org>
Fri, 21 Feb 2014 08:46:56 +0000 (08:46 +0000)
builtin.c
libm.h [new file with mode: 0644]

index e60fa85b36672b2c4dbe5f7e00eef5f2c344fa81..61a9fedd31d5e03557e6e76a23c03dd9ec970074 100644 (file)
--- a/builtin.c
+++ b/builtin.c
@@ -50,23 +50,17 @@ static jv f_plus(jv input, jv a, jv b) {
   }
 }
 
-static jv f_floor(jv input) {
-  if (jv_get_kind(input) != JV_KIND_NUMBER) {
-    return type_error(input, "cannot be floored");
-  }
-  jv ret = jv_number(floor(jv_number_value(input)));
-  jv_free(input);
-  return ret;
-}
-
-static jv f_sqrt(jv input) {
-  if (jv_get_kind(input) != JV_KIND_NUMBER) {
-    return type_error(input, "has no square root");
-  }
-  jv ret = jv_number(sqrt(jv_number_value(input)));
-  jv_free(input);
-  return ret;
-}
+#define LIBM_DD(name) \
+static jv f_ ## name(jv input) { \
+  if (jv_get_kind(input) != JV_KIND_NUMBER) { \
+    return type_error(input, "number required"); \
+  } \
+  jv ret = jv_number(name(jv_number_value(input))); \
+  jv_free(input); \
+  return ret; \
+}
+#include "libm.h"
+#undef LIBM_DD
 
 static jv f_negate(jv input) {
   if (jv_get_kind(input) != JV_KIND_NUMBER) {
@@ -569,9 +563,11 @@ static jv f_error(jv input, jv msg) {
   return jv_invalid_with_msg(msg);
 }
 
+#define LIBM_DD(name) \
+  {(cfunction_ptr)f_ ## name, "_" #name, 1},
+   
 static const struct cfunction function_list[] = {
-  {(cfunction_ptr)f_floor, "_floor", 1},
-  {(cfunction_ptr)f_sqrt, "_sqrt", 1},
+#include "libm.h"
   {(cfunction_ptr)f_plus, "_plus", 3},
   {(cfunction_ptr)f_negate, "_negate", 1},
   {(cfunction_ptr)f_minus, "_minus", 3},
@@ -613,6 +609,7 @@ static const struct cfunction function_list[] = {
   {(cfunction_ptr)f_error, "error", 2},
   {(cfunction_ptr)f_format, "format", 2},
 };
+#undef LIBM_DD
 
 struct bytecoded_builtin { const char* name; block code; };
 static block bind_bytecoded_builtins(block b) {
@@ -657,6 +654,8 @@ static block bind_bytecoded_builtins(block b) {
   return block_bind_referenced(builtins, b, OP_IS_CALL_PSEUDO);
 }
 
+#define LIBM_DD(name) "def " #name ": _" #name ";",
+
 static const char* const jq_builtins[] = {
   "def map(f): [.[] | f];",
   "def select(f): if f then . else empty end;",
@@ -665,8 +664,7 @@ static const char* const jq_builtins[] = {
   "def unique: group_by(.) | map(.[0]);",
   "def max_by(f): _max_by_impl(map([f]));",
   "def min_by(f): _min_by_impl(map([f]));",
-  "def floor: _floor;",
-  "def sqrt: _sqrt;",
+#include "libm.h"
   "def add: reduce .[] as $x (null; . + $x);",
   "def del(f): delpaths([path(f)]);",
   "def _assign(paths; value): value as $v | reduce path(paths) as $p (.; setpath($p; $v));",
@@ -684,6 +682,7 @@ static const char* const jq_builtins[] = {
   "def any: reduce .[] as $i (false; . or $i);",
   "def all: reduce .[] as $i (true; . and $i);",
 };
+#undef LIBM_DD
 
 
 static int builtins_bind_one(jq_state *jq, block* bb, const char* code) {
diff --git a/libm.h b/libm.h
new file mode 100644 (file)
index 0000000..e31c172
--- /dev/null
+++ b/libm.h
@@ -0,0 +1,27 @@
+LIBM_DD(acos)
+LIBM_DD(acosh)
+LIBM_DD(asin)
+LIBM_DD(atanh)
+LIBM_DD(cosh)
+LIBM_DD(exp10)
+LIBM_DD(exp2)
+LIBM_DD(exp)
+LIBM_DD(floor)
+LIBM_DD(j0)
+LIBM_DD(j1)
+LIBM_DD(log10)
+LIBM_DD(log2)
+LIBM_DD(log)
+LIBM_DD(sinh)
+LIBM_DD(sqrt)
+LIBM_DD(tgamma)
+LIBM_DD(y0)
+LIBM_DD(y1)
+/* LIBM_DID(jn) */
+/* LIBM_DID(yn) */
+/* LIBM_DDD(pow) */
+/* LIBM_DDD(atan2) */
+/* LIBM_DDD(hypot) */
+/* LIBM_DDD(remainder) */
+/* LIBM_DDI(scalbn) */
+/* LIBM_DDIP(lgamma_r) */