ref: 1da09c81867fc8416f99b8d7a24d73b2e3acf6e6
parent: f1e8a146075542d085cfb8e632849415d32eb2b0
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Sat Jul 27 08:40:39 EDT 2024
Implement dyadic ≡
--- a/array.c
+++ b/array.c
@@ -80,6 +80,12 @@
}
int
+gettype(Array *a)
+{
+ return a->type;
+}
+
+int
getrank(Array *a)
{
return a->rank;
@@ -89,6 +95,24 @@
getshape(Array *a, int dim)
{
return a->shape[dim];
+}
+
+vlong
+getint(Array *a, usize i)
+{
+ return a->intdata[i];
+}
+
+Rune
+getchar(Array *a, usize i)
+{
+ return a->chardata[i];
+}
+
+Array *
+getarray(Array *a, usize i)
+{
+ return a->arraydata[i];
}
static int printarraysub(char *, Array *, int);
--- a/fns.h
+++ b/fns.h
@@ -5,8 +5,12 @@
void setchar(Array *, usize, Rune);
void setarray(Array *, usize, Array *);
void setshape(Array *, int, usize);
+int gettype(Array *);
int getrank(Array *);
usize getshape(Array *, int);
+vlong getint(Array *, usize);
+Rune getchar(Array *, usize);
+Array *getarray(Array *, usize);
Array *simplifyarray(Array *);
char *printarray(Array *);
--- a/prim.c
+++ b/prim.c
@@ -14,6 +14,7 @@
/* dyadic functions */
static Array *primfn_left(Array *, Array *);
static Array *primfn_right(Array *, Array *);
+static Array *primfn_match(Array *, Array *);
struct {
char *spelling;
@@ -27,6 +28,7 @@
"+", NameclassFunc, nil, nil, nil,
"-", NameclassFunc, nil, nil, nil,
"⍴", NameclassFunc, nil, primfn_shape, nil,
+ "≡", NameclassFunc, nil, nil, primfn_match,
};
char *
@@ -121,4 +123,56 @@
primfn_right(Array *, Array *y)
{
return y;
+}
+
+static int
+matches(Array *x, Array *y)
+{
+ int res = 0;
+ usize size = 1;
+ int type = gettype(x);
+
+ if(gettype(x) != gettype(y))
+ goto no;
+ if(getrank(x) != getrank(y))
+ goto no;
+ for(int dim = 0; dim < getrank(x); dim++){
+ if(getshape(x, dim) != getshape(y, dim))
+ goto no;
+ size *= getshape(x, dim);
+ }
+
+ for(usize i = 0; i < size; i++){
+ switch(type){
+ case TypeNumber:
+ if(getint(x, i) != getint(y, i))
+ goto no;
+ break;
+ case TypeChar:
+ if(getchar(x, i) != getchar(y, i))
+ goto no;
+ break;
+ case TypeArray:
+ if(!matches(getarray(x, i), getarray(y, i))) /* TODO: RECURSION */
+ goto no;
+ /* TODO: that means we can save space by making them
+ * point to the same thing :)
+ */
+ break;
+ default:
+ error(EInternal, "unknown element type");
+ }
+ }
+
+ res = 1;
+no:
+ return res;
+}
+
+static Array *
+primfn_match(Array *x, Array *y)
+{
+ Array *z = allocarray(TypeNumber, 0, 1);
+ setint(z, 0, matches(x, y));
+ return z;
}
\ No newline at end of file