summaryrefslogtreecommitdiff
path: root/functions.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-28 21:49:14 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-28 21:49:14 +0000
commitc5d0ef8e53608da468f89837a12ab10ecc401978 (patch)
treead78251f2116ac884b4ccf474d01998ac0cad6df /functions.c
parent8ab9401c22502520bf3100f864a306a451e5d44a (diff)
Implement rotate first (⊖) and rotate last (⌽)
Diffstat (limited to 'functions.c')
-rw-r--r--functions.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/functions.c b/functions.c
index d96deb6..997c1b4 100644
--- a/functions.c
+++ b/functions.c
@@ -110,8 +110,8 @@ fndyad dyadfunctiondefs[] = {
fnCatenateLast, /* , */
fnCatenateFirst, /* ⍪ */
fnReshape, /* ⍴ */
- 0, /* ⌽ */
- 0, /* ⊖ */
+ fnRotateLast, /* ⌽ */
+ fnRotateFirst, /* ⊖ */
0, /* ⍉ */
0, /* ⍎ */
0, /* ⍕ */
@@ -1328,6 +1328,57 @@ fnReshape(Array *left, Array *right)
}
Array *
+fnRotateLast(Array *left, Array *right)
+{
+ return rundfn(L"⍉(⍉⍺)⊖⍉⍵", nil, nil, left, right);
+}
+
+Array *
+fnRotateFirst(Array *left, Array *right)
+{
+ if(left->type != AtypeInt)
+ throwerror(nil, EType);
+
+ if(right->rank == 0 || right->size < 2)
+ return fnSame(right);
+
+ int i, j;
+ if(left->size == 1 && right->rank != 0){
+ vlong v = left->intdata[0];
+ left = allocarray(AtypeInt, right->rank-1, right->size / right->shape[0]);
+ for(i = 0; i < left->rank; i++)
+ left->shape[i] = right->shape[i+1];
+ for(i = 0; i < left->size; i++)
+ left->intdata[i] = v;
+ }else
+ left = fnSame(left);
+
+ if(left->rank != right->rank-1)
+ throwerror(nil, ERank);
+ for(i = 0; i < left->rank; i++)
+ if(left->shape[i] != right->shape[i+1])
+ throwerror(nil, EShape);
+
+ int n = right->shape[0];
+ for(i = 0; i < left->size; i++)
+ while(left->intdata[i] < 0)
+ left->intdata[i] += n;
+
+ Array *result = duparray(right);
+ for(i = 0; i < n; i++){
+ for(j = 0; j < left->size; j++){
+ vlong rot = left->intdata[j];
+ vlong from = j + ((i+rot)%n)*left->size;
+ vlong to = j + i*left->size;
+ memcpy(result->rawdata + to*datasizes[right->type],
+ right->rawdata + from*datasizes[right->type],
+ datasizes[right->type]);
+ }
+ }
+ return result;
+}
+
+Array *
fnSelfReference2(Array *left, Array *right)
{
DfnFrame *dfn = getcurrentdfn();