summaryrefslogtreecommitdiff
path: root/functions.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-20 22:53:30 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-20 22:53:30 +0000
commitb63ca926df347798ea113d7b197192bd28399f5a (patch)
tree18f4161678fe0d7239e4ebb735ab76cdb24745dd /functions.c
parent35f20421e7a4942b61c4a1910e8da0bf35f21fd9 (diff)
Implement guards, and start work on ↑ and ↓
Diffstat (limited to 'functions.c')
-rw-r--r--functions.c179
1 files changed, 176 insertions, 3 deletions
diff --git a/functions.c b/functions.c
index 9649e27..7d8b46c 100644
--- a/functions.c
+++ b/functions.c
@@ -36,8 +36,8 @@ fnmonad monadfunctiondefs[] = {
0, /* ∧ */
0, /* ⍲ */
0, /* ⍱ */
- 0, /* ↑ */
- 0, /* ↓ */
+ fnMix, /* ↑ */
+ fnSplit, /* ↓ */
fnEnclose, /* ⊂ */
0, /* ⊃ */
fnNest, /* ⊆ */
@@ -91,7 +91,7 @@ fndyad dyadfunctiondefs[] = {
0, /* ∧ */
0, /* ⍲ */
0, /* ⍱ */
- 0, /* ↑ */
+ fnTake, /* ↑ */
0, /* ↓ */
0, /* ⊂ */
0, /* ⊃ */
@@ -156,6 +156,15 @@ runfunc(Function f, Array *left, Array *right)
}
}
+Array *
+rundfn(Rune *code, Array *left, Array *right)
+{
+ Function dfn;
+ dfn.type = FunctypeDfn;
+ dfn.dfn = code;
+ return runfunc(dfn, left, right);
+}
+
/* Monadic functions */
Array *
@@ -172,6 +181,110 @@ fnTally(Array *right)
}
Array *
+fnMix(Array *right)
+{
+ if(right->type != AtypeArray || right->size == 0)
+ return fnSame(right);
+
+ int commonrank = 0;
+ int i,j;
+ for(i = 0; i < right->size; i++)
+ if(right->arraydata[i]->rank > commonrank)
+ commonrank = right->arraydata[i]->rank;
+
+ Array *commonshape = allocarray(AtypeInt, 1, commonrank);
+ commonshape->shape[0] = commonrank;
+ for(i = 0; i < commonrank; i++)
+ commonshape->intdata[i] = 0;
+
+ for(i = 0; i < right->size; i++){
+ Array *a = right->arraydata[i];
+ for(j = 0; j < a->rank; j++){
+ if(a->shape[a->rank-1-j] > commonshape->intdata[commonrank-1-j])
+ commonshape->intdata[commonrank-1-j] = a->shape[a->rank-1-j];
+ }
+ }
+
+ int size = 1;
+ int commonsize = 1;
+ for(i = 0; i < right->rank; i++)
+ size *= right->shape[i];
+ for(i = 0; i < commonshape->size; i++){
+ size *= commonshape->intdata[i];
+ commonsize *= commonshape->intdata[i];
+ }
+
+ /* TODO: think about types */
+ Array *result = allocarray(right->arraydata[0]->type, right->rank + commonrank, size);
+ for(i = 0; i < right->rank; i++)
+ result->shape[i] = right->shape[i];
+ for(j = 0; j < commonshape->size; j++)
+ result->shape[i+j] = commonshape->intdata[j];
+
+ int *index = malloc(sizeof(int) * commonrank);
+ int offset;
+ for(i = 0; i < size/commonsize; i++){
+ print("COPY CELL %d\n", i);
+ Array *a = right->arraydata[i];
+ Array *fill = fillelement(a);
+ if(a->rank == 0){
+ print("Copy scalar :-)\n");
+ memcpy(
+ result->rawdata + i * commonsize * datasizes[a->type],
+ a->rawdata, datasizes[a->type]);
+ if(a->type == AtypeArray)
+ incref(a->arraydata[0]);
+ for(j = 1; j < commonsize; j++){
+ memcpy(result->rawdata + (i * commonsize + j) * datasizes[a->type],
+ fill->rawdata, datasizes[a->type]);
+ if(fill->type == AtypeArray)
+ incref(fill->arraydata[0]);
+ }
+ }else{
+ for(j = 0; j < commonrank; j++)
+ index[j] = 0;
+ for(j = 0, offset = 0; offset < commonsize; j++){
+ for(int k = 0; index[commonrank-1-k] == a->shape[a->rank-1-k]; k++){
+ int nfill = commonshape->intdata[commonrank-1-k] - a->shape[a->rank-1-k];
+ if(nfill)
+ print("Adding %d fills\n", nfill);
+ while(nfill--){
+ memcpy(result->rawdata + (i * commonsize + offset) * datasizes[a->type],
+ fill->rawdata, datasizes[a->type]);
+ if(fill->type == AtypeArray)
+ incref(fill->arraydata[0]);
+ offset++;
+ }
+ index[commonrank-1-k] = 0;
+ index[commonrank-2-k]++;
+ }
+ if(offset < commonsize){
+ print("Copying from %d to %d\n", j, commonsize*i+offset);
+ memcpy(
+ result->rawdata + (i * commonsize + offset) * datasizes[a->type],
+ a->rawdata + j * datasizes[a->type], datasizes[a->type]);
+ if(a->type == AtypeArray)
+ incref(a->arraydata[j]);
+ offset++;
+ index[commonrank-1]++;
+ }
+ }
+ }
+ freearray(fill);
+ }
+ free(index);
+ free(commonshape);
+ return result;
+}
+
+Array *
+fnSplit(Array *right)
+{
+ Rune *code = L"0≡≢⍴⍵: ⍵ ⋄ (⊂⍵)⌷⍨¨⍳≢⍵";
+ return rundfn(code, nil, right);
+}
+
+Array *
fnEnclose(Array *right)
{
incref(right);
@@ -565,6 +678,66 @@ fnMatch(Array *left, Array *right)
}
Array *
+fnTake(Array *left, Array *right)
+{
+ if(left->type != AtypeInt || left->rank > 1 || left->size > right->rank){
+ print("Invalid left arg to ↑\n");
+ exits(nil);
+ }
+
+ int i;
+ if(left->size == right->rank)
+ left = fnSame(left);
+ else{
+ Array *old = left;
+ left = fnShape(right);
+ for(i = 0; i < old->size; i++)
+ left->intdata[i] = old->intdata[i];
+ }
+
+ if(right->rank == 0){
+ Array *leftshape = fnShape(left);
+ right = fnReshape(leftshape, right);
+ freearray(leftshape);
+ }
+ right = fnSame(right);
+
+ int *shape = malloc(sizeof(int) * left->size);
+ int size = 1;
+ for(i = 0; i < left->size; i++){
+ int s = left->intdata[i];
+ shape[i] = s < 0 ? -s : s;
+ size *= shape[i];
+ }
+
+ Array *result = allocarray(right->type, right->rank, size);
+ for(i = 0; i < right->rank; i++)
+ result->shape[i] = shape[i];
+
+ int *index = mallocz(sizeof(int) * left->size, 1);
+ int offset;
+ for(i = 0, offset = 0; offset < size; i++){
+ for(int j = left->size-1; index[j] == shape[j]; j--){
+ index[j] = 0;
+ index[j-1]++;
+ }
+ print("Result Index: ");
+ for(int j = 0; j < left->size; j++)
+ print("%d ", index[j]);
+ print("\n");
+
+ /* if index is part of left vector, select those places */
+
+ offset++;
+ index[left->size-1]++;
+ }
+
+ freearray(left);
+ freearray(right);
+ return result;
+}
+
+Array *
fnIndex(Array *left, Array *right)
{
int io = currentsymtab->io;