#include #include #include #include "apl9.h" Rune primhybridnames[] = L"/\\⌿⍀"; fndyad hybridfunctiondefs[] = { 0, /* / */ 0, /* \ */ 0, /* ⌿ */ 0, /* ⍀ */ }; opmonad hybridoperatordefs[] = { opReduceLast, /* / */ 0, /* \ */ opReduceFirst, /* ⌿ */ 0, /* ⍀ */ }; /* function definitions */ /* operator definitions */ Array * opReduceLast(Datum *lefto, Array *left, Array *right) { if(left) throwerror(L"left argument to f/", ENotImplemented); right = fnTranspose(right); Array *tmp = opReduceFirst(lefto, left, right); Array *res = fnTranspose(tmp); freearray(right); freearray(tmp); return res; } Array * opReduceFirst(Datum *lefto, Array *left, Array *right) { if(left) throwerror(L"left argument to f⌿", ENotImplemented); if(right->rank == 0) return fnSame(right); int n = right->shape[0]; int io = currentsymtab->io; if(n == 0) throwerror(L"Can't figure out identity element", ENotImplemented); Array *result = allocarray(AtypeArray, right->rank - 1, right->size / n); for(int i = 0; i < right->rank-1; i++) result->shape[i] = right->shape[i+1]; Array *index = allocarray(AtypeArray, 1, right->rank); index->shape[0] = right->rank; Array *tmp = mkscalarint(n); index->arraydata[0] = fnIndexGenerator(tmp); freearray(tmp); for(int i = 1; i < index->size; i++) index->arraydata[i] = mkscalarint(io); for(int i = 0; i < result->size; i++){ for(int j = index->size - 1; index->arraydata[j]->intdata[0] == io + right->shape[j]; j--){ index->arraydata[j]->intdata[0] = io; index->arraydata[j-1]->intdata[0]++; } Array *vector = fnIndex(index, right); result->arraydata[i] = arrayitem(vector, n-1); for(int j = n-2; j >= 0; j--){ Array *argL = arrayitem(vector, j); Array *argR = result->arraydata[i]; result->arraydata[i] = runfunc(lefto->func, argL, argR); freearray(argL); freearray(argR); } index->arraydata[index->size-1]->intdata[0]++; } freearray(index); return result; }