summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-25 19:28:31 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-25 19:28:31 +0000
commit57a86f761605b6261d1045558c9cb7c83d723b60 (patch)
treec8b6d6c234156daafaafce9667932434496f6969
parent1bf60c0cfc8e26d4f9e92e044d37169f55ac170b (diff)
Add under ⍢ and obverse ⍫
Teach inverse() that the inverse of f⍫g is g⍫f 
-rw-r--r--apl9.h2
-rw-r--r--inverse.c9
-rw-r--r--operators.c23
3 files changed, 33 insertions, 1 deletions
diff --git a/apl9.h b/apl9.h
index 7c03918..b15b7e6 100644
--- a/apl9.h
+++ b/apl9.h
@@ -336,6 +336,8 @@ Array *opPower(Datum *, Datum *, Array *, Array *);
Array *opBind(Datum *, Datum *, Array *, Array *);
Array *opAtop(Datum *, Datum *, Array *, Array *);
Array *opOver(Datum *, Datum *, Array *, Array *);
+Array *opUnder(Datum *, Datum *, Array *, Array *);
+Array *opObverse(Datum *, Datum *, Array *, Array *);
Array *opSelfReference2(Datum *, Datum *, Array *, Array *);
/* Dyadic functions from hybrids.c */
diff --git a/inverse.c b/inverse.c
index b37664b..c20e78d 100644
--- a/inverse.c
+++ b/inverse.c
@@ -7,6 +7,15 @@
Function
inverse(Function f)
{
+ /* TODO figure out a good way to structure this code */
+ if(f.type == FunctypeOp && f.operator.type == OperatortypePrim && f.operator.code == 9 && f.operator.dyadic){
+ /* obverse */
+ Function newf = f;
+ newf.operator.left = f.operator.right;
+ newf.operator.right = f.operator.left;
+ return newf;
+ }
+
Rune *msg = runesmprint("No inverse defined for %S", ppfunction(f));
throwerror(msg, EDomain);
return f;
diff --git a/operators.c b/operators.c
index 1ecb8aa..2d26251 100644
--- a/operators.c
+++ b/operators.c
@@ -5,7 +5,7 @@
#include "apl9.h"
Rune primmonopnames[] = L"¨⍨⌸⌶&∆";
-Rune primdyadopnames[] = L"⍣.∘⍤⍥@⍠⌺⍙";
+Rune primdyadopnames[] = L"⍣.∘⍤⍥@⍠⌺⍢⍫⍙";
opmonad monadoperatordefs[] = {
opEach, /* ¨ */
@@ -25,6 +25,8 @@ opdyad dyadoperatordefs[] = {
0, /* @ */
0, /* ⍠ */
0, /* ⌺ */
+ opUnder, /* ⍢ */
+ opObverse, /* ⍫ */
opSelfReference2, /* ⍙ */
};
@@ -191,6 +193,25 @@ opAtop(Datum *lefto, Datum *righto, Array *left, Array *right)
}
Array *
+opUnder(Datum *lefto, Datum *righto, Array *left, Array *right)
+{
+ if(lefto->tag != FunctionTag || righto->tag != FunctionTag)
+ throwerror(L"⍢ operands must be functions", EDomain);
+ if(left)
+ return rundfn(L"⍹⍣¯1 ⊢ (⍹ ⍺) ⍶ ⍹ ⍵", lefto, righto, left, right);
+ else
+ return rundfn(L"⍹⍣¯1 ⍶ ⍹ ⍵", lefto, righto, left, right);
+}
+
+Array *
+opObverse(Datum *lefto, Datum *righto, Array *left, Array *right)
+{
+ if(lefto->tag != FunctionTag || righto->tag != FunctionTag)
+ throwerror(L"⍫ operands must be functions", EDomain);
+ return runfunc(lefto->func, left, right);
+}
+
+Array *
opOver(Datum *lefto, Datum *righto, Array *left, Array *right)
{
if(lefto->tag != FunctionTag || righto->tag != FunctionTag)