From 396543790dc1c844c726b77a95c6180978232abd Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Fri, 14 Jan 2022 01:06:14 +0000 Subject: =?UTF-8?q?Add=20each=20(=C2=A8)=20operator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apl9.h | 4 ++++ array.c | 19 +++++++++++++++++++ memory.c | 3 +++ operators.c | 37 ++++++++++++++++++++++++++++++++++++- 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/apl9.h b/apl9.h index 72b8ca2..a2d0e3d 100644 --- a/apl9.h +++ b/apl9.h @@ -143,6 +143,7 @@ int simplearray(Array *); int simplescalar(Array *); Array *extend(Array *, Array *); int scalarextend(Array *, Array *, Array **, Array **); +Array *arrayitem(Array *, int); /* eval.c */ Datum *eval(Statement *); @@ -183,7 +184,10 @@ Array *fnCatenateFirst(Array *, Array *); Array *fnReshape(Array *, Array *); /* Monadic operators from operators.c */ +Array *opEach(Datum *, Array *, Array *); Array *opSwitch(Datum *, Array *, Array *); + +/* Dyadic operators from operators.c */ Array *opOver(Datum *, Datum *, Array *, Array *); /* Global variables */ diff --git a/array.c b/array.c index a2afc44..4a14ab9 100644 --- a/array.c +++ b/array.c @@ -78,4 +78,23 @@ scalarextend(Array *a, Array *b, Array **aa, Array **bb) }else return 0; return 1; +} + +Array * +arrayitem(Array *a, int index) +{ + Array *res = nil; + switch(a->type){ + case AtypeInt: + res = mkscalarint(a->intdata[index]); + break; + case AtypeArray: + res = a->arraydata[index]; + incref(res); + break; + default: + print("Unhandled case in arrayitem()\n"); + exits(nil); + } + return res; } \ No newline at end of file diff --git a/memory.c b/memory.c index adc0466..fd0fec6 100644 --- a/memory.c +++ b/memory.c @@ -9,6 +9,9 @@ int alloccounts = 0; void freearray(Array *a) { + if(a == nil) + return; + a->refs--; if(a->refs == 0){ /* print("Freeing array: %S (%p)\n", pparray(a), a); */ diff --git a/operators.c b/operators.c index ba999bd..226f27b 100644 --- a/operators.c +++ b/operators.c @@ -8,7 +8,7 @@ Rune primmonopnames[] = L"¨⍨⌸⌶&"; Rune primdyadopnames[] = L"⍣.∘⍤⍥@⍠⌺"; opmonad monadoperatordefs[] = { - 0, /* ¨ */ + opEach, /* ¨ */ opSwitch, /* ⍨ */ 0, /* ⌸ */ 0, /* ⌶ */ @@ -27,6 +27,41 @@ opdyad dyadoperatordefs[] = { }; /* Monadic operators */ +Array * +opEach(Datum *lefto, Array *left, Array *right) +{ + int i; + if(lefto->tag != FunctionTag) + return nil; + Array *leftarr; + Array *rightarr; + if(left){ + + int rankok = scalarextend(left, right, &leftarr, &rightarr); + if(!rankok){ + print("Ranks don't match lol\n"); + exits(nil); + } + }else{ + leftarr = nil; + rightarr = fnSame(right); + } + + Array *result = allocarray(AtypeArray, rightarr->rank, rightarr->size); + for(i = 0; i < rightarr->rank; i++) + result->shape[i] = rightarr->shape[i]; + for(i = 0; i < rightarr->size; i++){ + Array *elem1 = leftarr ? arrayitem(leftarr, i) : nil; + Array *elem2 = arrayitem(rightarr, i); + result->arraydata[i] = runfunc(lefto->func, elem1, elem2); + freearray(elem1); + freearray(elem2); + } + freearray(leftarr); + freearray(rightarr); + return result; +} + Array * opSwitch(Datum *lefto, Array *left, Array *right) { -- cgit v1.2.3