summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-14 01:06:14 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-14 01:06:14 +0000
commit396543790dc1c844c726b77a95c6180978232abd (patch)
treeb5051f5afba137e499b883b637ce6fc436805ec5
parent07082593ab4abfbf9a3dd6729cb2e548ec303115 (diff)
Add each (¨) operator
-rw-r--r--apl9.h4
-rw-r--r--array.c19
-rw-r--r--memory.c3
-rw-r--r--operators.c37
4 files changed, 62 insertions, 1 deletions
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, /* ⌶ */
@@ -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){