summaryrefslogtreecommitdiff
path: root/functions.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-22 15:25:48 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-22 15:25:48 +0000
commitba15cb00a35e3b95d698177ca6f88173097593a1 (patch)
tree4c3eddd5957ddfc931aaa4cf6e023b1fbe47ebd4 /functions.c
parent43419663c65fa8ab27c8bad6aa583efb513c303e (diff)
Implement dyadic ∨∧⍲⍱
Diffstat (limited to 'functions.c')
-rw-r--r--functions.c78
1 files changed, 74 insertions, 4 deletions
diff --git a/functions.c b/functions.c
index 9f23a43..d9b2eb4 100644
--- a/functions.c
+++ b/functions.c
@@ -87,10 +87,10 @@ fndyad dyadfunctiondefs[] = {
fnGreaterEqual, /* ≥ */
fnMatch, /* ≡ */
0, /* ≢ */
- 0, /* ∨ */
- 0, /* ∧ */
- 0, /* ⍲ */
- 0, /* ⍱ */
+ fnOr, /* ∨ */
+ fnAnd, /* ∧ */
+ fnNand, /* ⍲ */
+ fnNor, /* ⍱ */
fnTake, /* ↑ */
0, /* ↓ */
0, /* ⊂ */
@@ -116,6 +116,9 @@ fndyad dyadfunctiondefs[] = {
0, /* ⍕ */
};
+vlong gcd_int(vlong, vlong);
+double gcd_float(double, double);
+
/* Runner function */
Array *
runfunc(Function f, Array *left, Array *right)
@@ -705,6 +708,54 @@ fnMatch(Array *left, Array *right)
return mkscalarint(cmp == 0);
}
+SCALAR_FUNCTION_2(fnOr, 0, left->type,
+ case AtypeInt:
+ if((left->intdata[i] == 0 || left->intdata[i] == 1) && (right->intdata[i] == 0 || right->intdata[i] == 1))
+ res->intdata[i] = left->intdata[i] || right->intdata[i];
+ else
+ res->intdata[i] = gcd_int(left->intdata[i], right->intdata[i]);
+ break;
+ case AtypeFloat:
+ res->floatdata[i] = gcd_float(left->floatdata[i], right->floatdata[i]);
+ break;
+)
+
+SCALAR_FUNCTION_2(fnAnd, 0, left->type,
+ case AtypeInt:
+ if((left->intdata[i] == 0 || left->intdata[i] == 1) && (right->intdata[i] == 0 || right->intdata[i] == 1))
+ res->intdata[i] = left->intdata[i] && right->intdata[i];
+ else{
+ vlong p = left->intdata[i] * right->intdata[i];
+ if(p < 0)
+ p = -p;
+ res->intdata[i] = p / gcd_int(left->intdata[i], right->intdata[i]);
+ }
+ break;
+ case AtypeFloat:
+ res->floatdata[i] = fabs(left->floatdata[i] * right->floatdata[i]) / gcd_float(left->floatdata[i], right->floatdata[i]);
+ break;
+)
+
+SCALAR_FUNCTION_2(fnNand, 0, AtypeInt,
+ case AtypeInt:
+ if(left->intdata[i] != 0 && left->intdata[i] != 1)
+ throwerror(nil, EType);
+ if(right->intdata[i] != 0 && right->intdata[i] != 1)
+ throwerror(nil, EType);
+ res->intdata[i] = !(left->intdata[i] && right->intdata[i]);
+ break;
+)
+
+SCALAR_FUNCTION_2(fnNor, 0, AtypeInt,
+ case AtypeInt:
+ if(left->intdata[i] != 0 && left->intdata[i] != 1)
+ throwerror(nil, EType);
+ if(right->intdata[i] != 0 && right->intdata[i] != 1)
+ throwerror(nil, EType);
+ res->intdata[i] = !(left->intdata[i] || right->intdata[i]);
+ break;
+)
+
Array *
fnTake(Array *left, Array *right)
{
@@ -989,4 +1040,23 @@ fnReshape(Array *left, Array *right)
for(i = 0; i < res->size; i++)
incref(res->arraydata[i]);
return res;
+}
+
+/* helper functions */
+vlong
+gcd_int(vlong a, vlong b)
+{
+ if(b == 0)
+ return a;
+ else
+ return gcd_int(b, a % b);
+}
+
+double
+gcd_float(double a, double b)
+{
+ if(b < 0.0000000001 && b > -0.0000000001) /* Some error tolerance */
+ return a;
+ else
+ return gcd_float(b, fmod(a,b));
} \ No newline at end of file