summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apl9.h10
-rw-r--r--functions.c127
2 files changed, 125 insertions, 12 deletions
diff --git a/apl9.h b/apl9.h
index 2399eb3..dc38112 100644
--- a/apl9.h
+++ b/apl9.h
@@ -233,6 +233,15 @@ void throwerror(Rune *, int);
}
/* Monadic functions from function.c */
+Array *fnNegate(Array *);
+Array *fnSign(Array *);
+Array *fnRecip(Array *);
+Array *fnExponent(Array *);
+Array *fnNaturalLog(Array *);
+Array *fnPiTimes(Array *);
+Array *fnMagnitude(Array *);
+Array *fnCeiling(Array *);
+Array *fnFloor(Array *);
Array *fnSame(Array *);
Array *fnTally(Array *);
Array *fnMix(Array *);
@@ -242,6 +251,7 @@ Array *fnNest(Array *);
Array *fnGradeUp(Array *);
Array *fnGradeDown(Array *);
Array *fnIndexGenerator(Array *);
+Array *fnNot(Array *);
Array *fnRavel(Array *);
Array *fnTable(Array *);
Array *fnShape(Array *);
diff --git a/functions.c b/functions.c
index d9b2eb4..870ee17 100644
--- a/functions.c
+++ b/functions.c
@@ -7,19 +7,19 @@
Rune primfuncnames[] = L"+-×÷*⍟⌹○!?|⌈⌊⊥⊤⊣⊢=≠≤<>≥≡≢∨∧⍲⍱↑↓⊂⊃⊆⌷⍋⍒⍳⍸∊⍷∪∩~,⍪⍴⌽⊖⍉⍎⍕";
fnmonad monadfunctiondefs[] = {
- 0, /* + */
- 0, /* - */
- 0, /* × */
- 0, /* ÷ */
- 0, /* * */
- 0, /* ⍟ */
+ fnSame, /* + */
+ fnNegate, /* - */
+ fnSign, /* × */
+ fnRecip, /* ÷ */
+ fnExponent, /* * */
+ fnNaturalLog, /* ⍟ */
0, /* ⌹ */
- 0, /* ○ */
+ fnPiTimes, /* ○ */
0, /* ! */
0, /* ? */
- 0, /* | */
- 0, /* ⌈ */
- 0, /* ⌊ */
+ fnMagnitude, /* | */
+ fnCeiling, /* ⌈ */
+ fnFloor, /* ⌊ */
0, /* ⊥ */
0, /* ⊤ */
fnSame, /* ⊣ */
@@ -50,7 +50,7 @@ fnmonad monadfunctiondefs[] = {
0, /* ⍷ */
0, /* ∪ */
0, /* ∩ */
- 0, /* ~ */
+ fnNot, /* ~ */
fnRavel, /* , */
fnTable, /* ⍪ */
fnShape, /* ⍴ */
@@ -222,6 +222,87 @@ rundfn(Rune *code, Array *left, Array *right)
/* Monadic functions */
Array *
+fnNegate(Array *right)
+{
+ return rundfn(L"0-⍵", nil, right);
+}
+
+Array *
+fnSign(Array *right)
+{
+ return rundfn(L"(¯1×⍵<0)+⍵>0", nil, right);
+}
+
+Array *
+fnRecip(Array *right)
+{
+ return rundfn(L"1÷⍵", nil, right);
+}
+
+Array *
+fnExponent(Array *right)
+{
+ Array *e = mkscalarfloat(2.7182818284590452353602);
+ Array *res = fnPower(e, right);
+ freearray(e);
+ return res;
+}
+
+Array *
+fnNaturalLog(Array *right)
+{
+ Array *e = mkscalarfloat(2.7182818284590452353602);
+ Array *res = fnLogarithm(e, right);
+ freearray(e);
+ return res;
+}
+
+Array *
+fnPiTimes(Array *right)
+{
+ Array *pi = mkscalarfloat(PI);
+ Array *res = fnTimes(pi, right);
+ freearray(pi);
+ return res;
+}
+
+Array *
+fnMagnitude(Array *right)
+{
+ return rundfn(L"⍵××⍵", nil, right);
+}
+
+Array *
+fnCeiling(Array *right)
+{
+ return rundfn(L"-⌊-⍵", nil, right);
+}
+
+Array *
+fnFloor(Array *right)
+{
+ Array *res = nil;
+ switch(right->type){
+ case AtypeInt:
+ res = fnSame(right);
+ break;
+ case AtypeFloat:
+ res = duparrayshape(right, AtypeInt);
+ for(int i = 0; i < right->size; i++)
+ res->intdata[i] = floor(right->floatdata[i]);
+ break;
+ case AtypeArray:
+ res = duparrayshape(right, AtypeArray);
+ for(int i = 0; i < right->size; i++)
+ res->arraydata[i] = fnFloor(right->arraydata[i]);
+ break;
+ default:
+ throwerror(nil, EType);
+ }
+ return res;
+}
+
+Array *
fnSame(Array *right)
{
incref(right);
@@ -421,6 +502,25 @@ fnNest(Array *right)
}
Array *
+fnNot(Array *right)
+{
+ if(right->type != AtypeInt)
+ throwerror(nil, EType);
+ Array *res = duparray(right);
+ for(int i = 0; i < res->size; i++){
+ if(res->intdata[i] == 0)
+ res->intdata[i] = 1;
+ else if(res->intdata[i] == 1)
+ res->intdata[i] = 0;
+ else{
+ freearray(res);
+ throwerror(nil, EType);
+ }
+ }
+ return res;
+}
+
+Array *
fnRavel(Array *right)
{
Array *res = duparray(right);
@@ -580,7 +680,10 @@ SCALAR_FUNCTION_2(fnTimes, 0, left->type,
SCALAR_FUNCTION_2(fnDivide, 1, left->type,
case AtypeFloat:
- res->floatdata[i] /= right->floatdata[i];
+ if(right->floatdata[i] == 0)
+ throwerror(nil, EDomain);
+ else
+ res->floatdata[i] /= right->floatdata[i];
break;
)