~pmikkelsen/lpa

1da09c81867fc8416f99b8d7a24d73b2e3acf6e6 — Peter Mikkelsen a month ago f1e8a14
Implement dyadic ≡
3 files changed, 82 insertions(+), 0 deletions(-)

M array.c
M fns.h
M prim.c
M array.c => array.c +24 -0
@@ 80,6 80,12 @@ setshape(Array *a, int dim, usize size)
}

int
gettype(Array *a)
{
	return a->type;
}

int
getrank(Array *a)
{
	return a->rank;


@@ 91,6 97,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);
static int
printitem(char *p, Array *a, uvlong i, int depth)

M fns.h => fns.h +4 -0
@@ 5,8 5,12 @@ void setint(Array *, usize, vlong);
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 *);

M prim.c => prim.c +54 -0
@@ 14,6 14,7 @@ static Array *primfn_shape(Array *);
/* 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 @@ struct {
	"+", NameclassFunc, nil, nil, nil,
	"-", NameclassFunc, nil, nil, nil,
	"⍴", NameclassFunc, nil, primfn_shape, nil,
	"≡", NameclassFunc, nil, nil, primfn_match,
};

char *


@@ 121,4 123,56 @@ static Array *
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