diff options
-rw-r--r-- | apl9.h | 4 | ||||
-rw-r--r-- | array.c | 19 | ||||
-rw-r--r-- | memory.c | 3 | ||||
-rw-r--r-- | operators.c | 37 |
4 files changed, 62 insertions, 1 deletions
@@ -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 */ @@ -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 @@ -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, /* ⌶ */ @@ -28,6 +28,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) { if(lefto->tag == ArrayTag){ |