diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-20 22:53:30 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-20 22:53:30 +0000 |
commit | b63ca926df347798ea113d7b197192bd28399f5a (patch) | |
tree | 18f4161678fe0d7239e4ebb735ab76cdb24745dd /functions.c | |
parent | 35f20421e7a4942b61c4a1910e8da0bf35f21fd9 (diff) |
Implement guards, and start work on ↑ and ↓
Diffstat (limited to 'functions.c')
-rw-r--r-- | functions.c | 179 |
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; |