summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apl9.h1
-rw-r--r--functions.c29
2 files changed, 29 insertions, 1 deletions
diff --git a/apl9.h b/apl9.h
index 3b77423..e9a6cb7 100644
--- a/apl9.h
+++ b/apl9.h
@@ -357,6 +357,7 @@ Array *fnIndex(Array *, Array *);
Array *fnIndexOf(Array *, Array *);
Array *fnIntervalIndex(Array *, Array *);
Array *fnMembership(Array *, Array *);
+Array *fnFind(Array *, Array *);
Array *fnUnion(Array *, Array *);
Array *fnIntersection(Array *, Array *);
Array *fnExcluding(Array *, Array *);
diff --git a/functions.c b/functions.c
index e3020f9..f1c4b0d 100644
--- a/functions.c
+++ b/functions.c
@@ -103,7 +103,7 @@ fndyad dyadfunctiondefs[] = {
fnIndexOf, /* ⍳ */
fnIntervalIndex, /* ⍸ */
fnMembership, /* ∊ */
- 0, /* ⍷ */
+ fnFind, /* ⍷ */
fnUnion, /* ∪ */
fnIntersection, /* ∩ */
fnExcluding, /* ~ */
@@ -1586,6 +1586,33 @@ fnMembership(Array *left, Array *right)
}
Array *
+fnFind(Array *left, Array *right)
+{
+ int i,j;
+ if(left->rank > right->rank){
+ print("Left rank larger\n");
+ return rundfn(L"(⍴⍵)⍴0", nil, nil, nil, right);
+ }
+
+ if(left->rank < right->rank){
+ Array *newleft = allocarray(left->type, right->rank, left->size);
+ for(i = 0; i < right->rank - left->rank; i++)
+ newleft->shape[i] = 1;
+ for(j = 0; j < left->rank; j++)
+ newleft->shape[i+j] = left->shape[j];
+ memcpy(newleft->rawdata, left->rawdata, datasizes[left->type] * left->size);
+ if(left->type == AtypeArray)
+ for(i = 0; i < left->size; i++)
+ incref(newleft->arraydata[i]);
+ left = newleft;
+ }else
+ left = fnSame(left);
+ Array *result = rundfn(L"⎕io←0 ⋄ (⍴⍵)↑(⍺{⍶≡(⍴⍶)↑⍵↓⍹}⍵)¨⍳1+⍵-⍥⍴⍺", nil, nil, left, right);
+ freearray(left);
+ return result;
+}
+
+Array *
fnUnion(Array *left, Array *right)
{
if(left->rank > 1 || right->rank > 1)