summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apl9.h1
-rw-r--r--functions.c32
2 files changed, 32 insertions, 1 deletions
diff --git a/apl9.h b/apl9.h
index 83cee4a..0bfa6e9 100644
--- a/apl9.h
+++ b/apl9.h
@@ -344,6 +344,7 @@ Array *fnAnd(Array *, Array *);
Array *fnNand(Array *, Array *);
Array *fnNor(Array *, Array *);
Array *fnTake(Array *, Array *);
+Array *fnPick(Array *, Array *);
Array *fnIndex(Array *, Array *);
Array *fnIndexOf(Array *, Array *);
Array *fnMembership(Array *, Array *);
diff --git a/functions.c b/functions.c
index b72c2bd..1645e77 100644
--- a/functions.c
+++ b/functions.c
@@ -95,7 +95,7 @@ fndyad dyadfunctiondefs[] = {
fnTake, /* ↑ */
0, /* ↓ */
0, /* ⊂ */
- 0, /* ⊃ */
+ fnPick, /* ⊃ */
0, /* ⊆ */
fnIndex, /* ⌷ */
0, /* ⍋ */
@@ -1152,6 +1152,36 @@ fnTake(Array *left, Array *right)
}
Array *
+fnPick(Array *left, Array *right)
+{
+ if(left->rank > 1)
+ throwerror(nil, ERank);
+ if(left->size == 0)
+ return fnSame(right);
+
+ int io = globalIO();
+ Array *result = fnSame(right);
+ for(int i = 0; i < left->size; i++){
+ Array *ix = arrayitem(left, i);
+ if(ix->rank > 1)
+ throwerror(nil, ERank);
+ if(ix->size != result->rank)
+ throwerror(nil, ERank);
+ int index = 0;
+ for(int j = 0; j < ix->size; j++){
+ int add = ix->intdata[j] - io;
+ for(int k = j+1; k < ix->size; k++)
+ add *= result->shape[k];
+ index += add;
+ }
+ Array *tmp = result;
+ result = arrayitem(result, index);
+ freearray(tmp);
+ }
+ return result;
+}
+
+Array *
fnIndex(Array *left, Array *right)
{
int io = globalIO();