summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <peter@pmikkelsen.com>2022-02-09 17:06:41 +0000
committerPeter Mikkelsen <peter@pmikkelsen.com>2022-02-09 17:06:41 +0000
commit36e45dfccb5e5321682c0ec24dead22cf40fcb16 (patch)
tree5b51a2f46d50c4ae2ae93e94bf337ca9af2f4348
parente195d66a333102924bae452ba09dc20cba4e96e6 (diff)
Make the array type a tiny bit smaller, by packing control information into a bit array
-rw-r--r--apl9.h26
-rw-r--r--array.c124
-rw-r--r--eval.c22
-rw-r--r--functions.c522
-rw-r--r--hybrids.c89
-rw-r--r--memory.c23
-rw-r--r--operators.c50
-rw-r--r--print.c30
-rw-r--r--quadnames.c38
9 files changed, 466 insertions, 458 deletions
diff --git a/apl9.h b/apl9.h
index 3f592d9..8135f39 100644
--- a/apl9.h
+++ b/apl9.h
@@ -83,14 +83,18 @@ struct Mixed
};
};
+#define GetSize(a) ((u32int)(a->info & 0x00000000FFFFFFFF))
+#define GetRank(a) ((u8int)((a->info & 0x0000000F00000000) >> 32))
+#define GetType(a) ((u8int)((a->info & 0x000000F000000000) >> 36))
+#define GetStrand(a) ((u8int)((a->info & 0x0000010000000000) >> 40))
+#define SetSize(a,v) (a->info ^= ((u64int)GetSize(a)^v))
+#define SetRank(a,v) (a->info ^= ((u64int)(GetRank(a)^v) << 32))
+#define SetType(a,v) (a->info ^= ((u64int)(GetType(a)^v) << 36))
+#define SetStrand(a,v) (a->info ^= ((u64int)(GetStrand(a)^v) << 40))
+
struct Array
{
- arrayDataType type;
- int rank;
- int *shape;
- int size;
- int stranded; /* 1 if build directly by stranding */
- int refs; /* reference counting */
+ u32int *shape;
union {
char *rawdata;
vlong *intdata;
@@ -99,6 +103,16 @@ struct Array
Mixed *mixeddata;
Array **arraydata;
};
+ u64int info;
+ /* info is a bitmap of information, divided as follows:
+ * 0-31: 32 bits for size (max size = 4294967296)
+ * 32-35: 4 bits for the rank (max rank 15)
+ * 36-39: 4 bits for the type (16 options)
+ * 40: 1 bit for stranding
+ * 41-63: unused
+ * NOTE: should only be modified through the macros defined above
+ */
+ ulong refs;
};
struct Statement
diff --git a/array.c b/array.c
index a712ad3..f97ac5c 100644
--- a/array.c
+++ b/array.c
@@ -43,8 +43,8 @@ Array *
mkrunearray(Rune *str)
{
Array *a = allocarray(AtypeRune, 1, runestrlen(str));
- a->shape[0] = a->size;
- for(int i = 0; i < a->size; i++)
+ a->shape[0] = GetSize(a);
+ for(int i = 0; i < GetSize(a); i++)
a->runedata[i] = str[i];
return a;
}
@@ -52,10 +52,10 @@ mkrunearray(Rune *str)
Array *
duparray(Array *a)
{
- Array *b = duparrayshape(a, a->type);
- memcpy(b->rawdata, a->rawdata, datasizes[a->type]*a->size);
- if(b->type == AtypeArray)
- for(int i = 0; i < b->size; i++)
+ Array *b = duparrayshape(a, GetType(a));
+ memcpy(b->rawdata, a->rawdata, datasizes[GetType(a)]*GetSize(a));
+ if(GetType(b) == AtypeArray)
+ for(int i = 0; i < GetSize(b); i++)
incarrayref(b->arraydata[i]);
return b;
}
@@ -63,22 +63,22 @@ duparray(Array *a)
Array *
duparrayshape(Array *a, int type)
{
- Array *b = allocarray(type, a->rank, a->size);
- memcpy(b->shape, a->shape, sizeof(int) * a->rank);
- b->stranded = a->stranded;
+ Array *b = allocarray(type, GetRank(a), GetSize(a));
+ memcpy(b->shape, a->shape, sizeof(*a->shape) * GetRank(a));
+ SetStrand(b, GetStrand(a));
return b;
}
int
simplearray(Array *a)
{
- return a->type != AtypeArray;
+ return GetType(a) != AtypeArray;
}
int
simplescalar(Array *a)
{
- return a->rank == 0 && a->type != AtypeArray;
+ return GetRank(a) == 0 && GetType(a) != AtypeArray;
}
Array *
@@ -101,35 +101,35 @@ scalarextend(Array *a, Array *b, Array **aa, Array **bb)
aa and bb are unchanged.
*/
- if(a->rank == 0 && b->rank != 0){
+ if(GetRank(a) == 0 && GetRank(b) != 0){
*aa = extend(a, b);
*bb = fnSame(b);
- }else if(a->rank != 0 && b->rank == 0){
+ }else if(GetRank(a) != 0 && GetRank(b) == 0){
*aa = fnSame(a);
*bb = extend(b, a);
- }else if(a->size == b->size && a->rank == b->rank){
+ }else if(GetSize(a) == GetSize(b) && GetRank(a) == GetRank(b)){
/* Check that each dimension matches */
- for(int i = 0; i < a->rank; i++){
+ for(int i = 0; i < GetRank(a); i++){
if(a->shape[i] != b->shape[i])
return 0;
}
*aa = fnSame(a);
*bb = fnSame(b);
- }else if(a->size == 1 && b->size == 1){
+ }else if(GetSize(a) == 1 && GetSize(b) == 1){
Array *shape;
- if(a->rank > b->rank)
+ if(GetRank(a) > GetRank(b))
shape = fnShape(a);
else
shape = fnShape(b);
*aa = fnReshape(shape, a);
*bb = fnReshape(shape, b);
freearray(shape);
- }else if(a->size == 1 && b->size != 1){
+ }else if(GetSize(a) == 1 && GetSize(b) != 1){
Array *shape = fnShape(b);
*aa = fnReshape(shape, a);
*bb = fnSame(b);
freearray(shape);
- }else if(a->size != 1 && b->size == 1){
+ }else if(GetSize(a) != 1 && GetSize(b) == 1){
Array *shape = fnShape(a);
*aa = fnSame(a);
*bb = fnReshape(shape, b);
@@ -142,10 +142,8 @@ scalarextend(Array *a, Array *b, Array **aa, Array **bb)
Array *
inttofloatarray(Array *a)
{
- Array *b = allocarray(AtypeFloat, a->rank, a->size);
- for(int i = 0; i < a->rank; i++)
- b->shape[i] = a->shape[i];
- for(int i = 0; i < a->size; i++)
+ Array *b = duparrayshape(a, AtypeFloat);
+ for(int i = 0; i < GetSize(a); i++)
b->floatdata[i] = a->intdata[i];
return b;
}
@@ -157,15 +155,15 @@ commontype(Array *a, Array *b, Array **aa, Array **bb, int forcefloat)
to arrays that have compatible types, with the same data.
*/
if(forcefloat){
- *aa = a->type == AtypeFloat ? fnSame(a) : inttofloatarray(a);
- *bb = b->type == AtypeFloat ? fnSame(b) : inttofloatarray(b);
- }else if(a->type == b->type){
+ *aa = GetType(a) == AtypeFloat ? fnSame(a) : inttofloatarray(a);
+ *bb = GetType(b) == AtypeFloat ? fnSame(b) : inttofloatarray(b);
+ }else if(GetType(a) == GetType(b)){
*aa = fnSame(a);
*bb = fnSame(b);
- }else if(a->type == AtypeFloat && b->type == AtypeInt){
+ }else if(GetType(a) == AtypeFloat && GetType(b) == AtypeInt){
*aa = fnSame(a);
*bb = inttofloatarray(b);
- }else if(a->type == AtypeInt && b->type == AtypeFloat){
+ }else if(GetType(a) == AtypeInt && GetType(b) == AtypeFloat){
*aa = inttofloatarray(a);
*bb = fnSame(b);
}else
@@ -177,7 +175,7 @@ Array *
arrayitem(Array *a, int index)
{
Array *res = nil;
- switch(a->type){
+ switch(GetType(a)){
case AtypeInt:
res = mkscalarint(a->intdata[index]);
break;
@@ -210,33 +208,33 @@ Array *
simplifyarray(Array *a)
{
/* simplify an array if possible. */
- if((a->type != AtypeArray && a->type != AtypeMixed) || a->size == 0)
+ if((GetType(a) != AtypeArray && GetType(a) != AtypeMixed) || GetSize(a) == 0)
return fnSame(a);
- int nested = a->type == AtypeArray;
- int type = nested ? a->arraydata[0]->type : a->mixeddata[0].type;
+ int nested = GetType(a) == AtypeArray;
+ int type = nested ? GetType(a->arraydata[0]) : a->mixeddata[0].type;
int canfloat = type == AtypeFloat || type == AtypeInt;
int sametype = 1;
int canmix = 1;
int i;
- for(i = 0; i < a->size; i++){
- int t = nested ? a->arraydata[i]->type : a->mixeddata[i].type;
+ for(i = 0; i < GetSize(a); i++){
+ int t = nested ? GetType(a->arraydata[i]) : a->mixeddata[i].type;
canfloat = canfloat && (t == AtypeFloat || t == AtypeInt);
sametype = sametype && (t == type);
canmix = canmix && (t != AtypeArray);
- if(nested && a->arraydata[i]->rank != 0)
+ if(nested && GetRank(a->arraydata[i]) != 0)
return fnSame(a); /* cannot be simplified */
}
if(sametype && type != AtypeArray){
Array *b = duparrayshape(a, type);
- for(i = 0; i < a->size; i++){
+ for(i = 0; i < GetSize(a); i++){
if(nested){
memcpy(b->rawdata + i * datasizes[type], a->arraydata[i]->rawdata, datasizes[type]);
- if(b->type == AtypeArray)
+ if(GetType(b) == AtypeArray)
incarrayref(b->arraydata[i]);
}else{
- switch(b->type){
+ switch(GetType(b)){
case AtypeInt: b->intdata[i] = a->mixeddata[i].i; break;
case AtypeFloat: b->floatdata[i] = a->mixeddata[i].f; break;
case AtypeRune: b->runedata[i] = a->mixeddata[i].r; break;
@@ -245,7 +243,7 @@ simplifyarray(Array *a)
}
}
}
- if(b->type == AtypeArray){
+ if(GetType(b) == AtypeArray){
Array *tmp = b;
b = simplifyarray(b);
freearray(tmp);
@@ -253,9 +251,9 @@ simplifyarray(Array *a)
return b;
}else if(canfloat){
Array *b = duparrayshape(a, AtypeFloat);
- for(i = 0; i < a->size; i++){
+ for(i = 0; i < GetSize(a); i++){
if(nested){
- if(a->arraydata[i]->type == AtypeFloat)
+ if(GetType(a->arraydata[i]) == AtypeFloat)
b->floatdata[i] = a->arraydata[i]->floatdata[0];
else
b->floatdata[i] = a->arraydata[i]->intdata[0];
@@ -269,8 +267,8 @@ simplifyarray(Array *a)
return b;
}else if(canmix && nested){
Array *b = duparrayshape(a, AtypeMixed);
- for(i = 0; i < a->size; i++){
- b->mixeddata[i].type = a->arraydata[i]->type;
+ for(i = 0; i < GetSize(a); i++){
+ b->mixeddata[i].type = GetType(a->arraydata[i]);
switch(b->mixeddata[i].type){
case AtypeInt: b->mixeddata[i].i = a->arraydata[i]->intdata[0]; break;
case AtypeFloat: b->mixeddata[i].f = a->arraydata[i]->floatdata[0]; break;
@@ -290,17 +288,17 @@ comparearray(Array *a, Array *b, int checkshapes)
/* returns -1 if a < b, 0 if a == b and 1 if a > b. */
int i;
- if(a->type < b->type)
+ if(GetType(a) < GetType(b))
return -1;
- else if(a->type > b->type)
+ else if(GetType(a) > GetType(b))
return 1;
if(checkshapes){
- if(a->rank < b->rank)
+ if(GetRank(a) < GetRank(b))
return -1;
- else if(a->rank > b->rank)
+ else if(GetRank(a) > GetRank(b))
return 1;
- for(i = 0; i < a->rank; i++){
+ for(i = 0; i < GetRank(a); i++){
if(a->shape[i] < b->shape[i])
return -1;
else if(a->shape[i] > b->shape[i])
@@ -308,9 +306,9 @@ comparearray(Array *a, Array *b, int checkshapes)
}
}
- for(i = 0; i < a->size && i < b->size; i++){
+ for(i = 0; i < GetSize(a) && i < GetSize(b); i++){
int sub = 0;
- switch(a->type){
+ switch(GetType(a)){
case AtypeInt:
sub = a->intdata[i] > b->intdata[i] ? 1 : a->intdata[i] == b->intdata[i] ? 0 : -1;
break;
@@ -324,16 +322,16 @@ comparearray(Array *a, Array *b, int checkshapes)
sub = comparearray(a->arraydata[i], b->arraydata[i], checkshapes);
break;
default:
- print("Missing comparison code for type %d\n", a->type);
+ print("Missing comparison code for type %d\n", GetType(a));
threadexitsall(nil);
}
if(sub != 0)
return sub;
}
- if(i < a->size)
+ if(i < GetSize(a))
return 1;
- else if(i < b->size)
+ else if(i < GetSize(b))
return -1;
else
return 0;
@@ -342,7 +340,7 @@ comparearray(Array *a, Array *b, int checkshapes)
Array *
fillelement(Array *a)
{
- switch(a->type){
+ switch(GetType(a)){
case AtypeInt: return mkscalarint(0);
case AtypeFloat: return mkscalarfloat(0);
case AtypeRune: return mkscalarrune(' ');
@@ -353,8 +351,8 @@ fillelement(Array *a)
return fill;
}
case AtypeArray:{
- Array *b = duparrayshape(a, a->type);
- for(int i = 0; i < b->size; i++){
+ Array *b = duparrayshape(a, GetType(a));
+ for(int i = 0; i < GetSize(b); i++){
Array *fill = fillelement(a->arraydata[i]);
Array *shape = fnShape(a->arraydata[i]);
b->arraydata[i] = fnReshape(shape, fill);
@@ -364,7 +362,7 @@ fillelement(Array *a)
return b;
}
default:
- print("Can't make fill element of array type %d\n", a->type);
+ print("Can't make fill element of array type %d\n", GetType(a));
threadexitsall(nil);
return 0;
}
@@ -375,10 +373,10 @@ arrayspaceused(Array *a)
{
uvlong size = 0;
size += sizeof(*a);
- size += sizeof(int) * a->rank;
- size += datasizes[a->type] * a->size;
+ size += sizeof(*a->shape) * GetRank(a);
+ size += datasizes[GetType(a)] * GetSize(a);
- for(int i = 0; i < a->size && a->type == AtypeArray; i++)
+ for(int i = 0; i < GetSize(a) && GetType(a) == AtypeArray; i++)
size += arrayspaceused(a->arraydata[i]);
return size;
}
@@ -386,11 +384,11 @@ arrayspaceused(Array *a)
int
arraydepth(Array *a, int *uniform)
{
- if(a->type == AtypeArray){
+ if(GetType(a) == AtypeArray){
int max = -1;
int subuniform;
*uniform = 1;
- for(int i = 0; i < a->size; i++){
+ for(int i = 0; i < GetSize(a); i++){
int subdepth = arraydepth(a->arraydata[i], &subuniform);
if((subdepth != max && max != -1) || subuniform == 0)
*uniform = 0;
@@ -400,7 +398,7 @@ arraydepth(Array *a, int *uniform)
return max+1;
}else{
*uniform = 1;
- if(a->rank == 0)
+ if(GetRank(a) == 0)
return 0;
else
return 1;
diff --git a/eval.c b/eval.c
index ea7e84f..aa74698 100644
--- a/eval.c
+++ b/eval.c
@@ -113,9 +113,9 @@ retry:
int guardOK = 1;
if(stmt->toks[0]->tag != ArrayTag)
guardOK = 0;
- else if(stmt->toks[0]->array->size != 1)
+ else if(GetSize(stmt->toks[0]->array) != 1)
guardOK = 0;
- else if(stmt->toks[0]->array->type != AtypeInt)
+ else if(GetType(stmt->toks[0]->array) != AtypeInt)
guardOK = 0;
else if(stmt->toks[0]->array->intdata[0] != 0 && stmt->toks[0]->array->intdata[0] != 1)
guardOK = 0;
@@ -161,13 +161,13 @@ lookup(Datum *var)
Datum *
strand(Datum *left, Datum *right)
{
- traceprint("Stranding (%d %d)\n", left->array->stranded, right->array->stranded);
+ traceprint("Stranding (%d %d)\n", GetStrand(left->array), GetStrand(right->array));
Datum *result = allocdatum(ArrayTag, 0);
- Array *leftarr = left->array->stranded ? fnSame(left->array) : fnEnclose(left->array);
- Array *rightarr = right->array->stranded ? fnSame(right->array) : fnEnclose(right->array);
+ Array *leftarr = GetStrand(left->array) ? fnSame(left->array) : fnEnclose(left->array);
+ Array *rightarr = GetStrand(right->array) ? fnSame(right->array) : fnEnclose(right->array);
Array *tmp = fnCatenateFirst(leftarr, rightarr);
result->array = simplifyarray(tmp);
- result->array->stranded = 1;
+ SetStrand(result->array, 1);
freearray(tmp);
freearray(leftarr);
freearray(rightarr);
@@ -207,7 +207,7 @@ parens(Datum *left, Datum *right)
Datum *result = eval(&left->stmt, 1);
incdatumref(result);
if(result->tag == ArrayTag)
- result->array->stranded = 0;
+ SetStrand(result->array, 0);
result->shy = 0;
return result; /* TODO handle error if ntoks != 1 */
}
@@ -263,12 +263,12 @@ assign(Datum *left, Datum *right)
symbol->value = right;
incdatumref(right);
if(symbol->value->tag == ArrayTag)
- symbol->value->array->stranded = 0;
+ SetStrand(symbol->value->array, 0);
}
}else{
if(right->tag != ArrayTag)
throwerror(nil, ESyntax);
- if(right->array->rank != 1 && right->array->rank != 0)
+ if(GetRank(right->array) != 1 && GetRank(right->array) != 0)
throwerror(nil, ERank);
int nlocs = 0;
@@ -297,12 +297,12 @@ assign(Datum *left, Datum *right)
}
}
- if(right->array->rank == 1 && right->array->size != nlocs)
+ if(GetRank(right->array) == 1 && GetSize(right->array) != nlocs)
throwerror(nil, ELength);
for(int i = 0; i < nlocs; i++){
Datum *item;
- if(right->array->rank == 0)
+ if(GetRank(right->array) == 0)
item = right;
else{
item = allocdatum(ArrayTag, 0);
diff --git a/functions.c b/functions.c
index 7c49554..9eb444e 100644
--- a/functions.c
+++ b/functions.c
@@ -322,14 +322,14 @@ fnNaturalLog(Array *right)
Array *
fnMatrixInverse(Array *right)
{
- if(right->type != AtypeInt && right->type != AtypeFloat)
+ if(GetType(right) != AtypeInt && GetType(right) != AtypeFloat)
throwerror(nil, EType);
- if(right->rank > 2)
+ if(GetRank(right) > 2)
throwerror(nil, ERank);
- if(right->rank == 0)
+ if(GetRank(right) == 0)
return rundfn(L"⌹1 1⍴⍵", nil, nil, nil, right);
- if(right->rank == 1)
+ if(GetRank(right) == 1)
return rundfn(L"⌹(1⍪⍨⍴⍵)⍴⍵", nil, nil, nil, right);
throwerror(L"Matrix inverse", ENotImplemented);
@@ -349,13 +349,13 @@ Array *
fnFactorial(Array *right)
{
Array *result = nil;
- if(right->type == AtypeArray){
+ if(GetType(right) == AtypeArray){
result = duparrayshape(right, AtypeArray);
- for(int i = 0; i < right->size; i++)
+ for(int i = 0; i < GetSize(right); i++)
result->arraydata[i] = fnFactorial(right->arraydata[i]);
- }else if(right->type == AtypeInt){
+ }else if(GetType(right) == AtypeInt){
result = duparrayshape(right, AtypeFloat);
- for(int i = 0; i < result->size; i++){
+ for(int i = 0; i < GetSize(result); i++){
double x = 1;
vlong n = right->intdata[i];
if(n < 0)
@@ -364,7 +364,7 @@ fnFactorial(Array *right)
x *= j;
result->floatdata[i] = x;
}
- }else if(right->type == AtypeFloat)
+ }else if(GetType(right) == AtypeFloat)
throwerror(L"Factorial of floating values", ENotImplemented);
else
throwerror(nil, EType);
@@ -375,23 +375,23 @@ Array *
fnRoll(Array *right)
{
Array *result = nil;
- if(right->type == AtypeArray){
+ if(GetType(right) == AtypeArray){
result = duparrayshape(right, AtypeArray);
- for(int i = 0; i < right->size; i++)
+ for(int i = 0; i < GetSize(right); i++)
result->arraydata[i] = fnRoll(right->arraydata[i]);
- }else if(right->type == AtypeInt){
- if(right->size == 0)
+ }else if(GetType(right) == AtypeInt){
+ if(GetSize(right) == 0)
return duparrayshape(right, AtypeInt);
int io = globalIO();
vlong lowest = right->intdata[0];
- for(int i = 1; i < right->size; i++)
+ for(int i = 1; i < GetSize(right); i++)
if(right->intdata[i] < lowest)
lowest = right->intdata[i];
if(lowest < 0)
throwerror(nil, EDomain);
else if(lowest == 0){
result = duparrayshape(right, AtypeFloat);
- for(int i = 0; i < right->size; i++){
+ for(int i = 0; i < GetSize(right); i++){
vlong max = right->intdata[i];
if(max == 0)
do{
@@ -402,7 +402,7 @@ fnRoll(Array *right)
}
}else{
result = duparrayshape(right, AtypeInt);
- for(int i = 0; i < right->size; i++)
+ for(int i = 0; i < GetSize(right); i++)
result->intdata[i] = io + lrand() % right->intdata[i];
}
}else
@@ -426,18 +426,18 @@ Array *
fnFloor(Array *right)
{
Array *res = nil;
- switch(right->type){
+ switch(GetType(right)){
case AtypeInt:
res = fnSame(right);
break;
case AtypeFloat:
res = duparrayshape(right, AtypeInt);
- for(int i = 0; i < right->size; i++)
+ for(int i = 0; i < GetSize(right); i++)
res->intdata[i] = floor(right->floatdata[i]);
break;
case AtypeArray:
res = duparrayshape(right, AtypeArray);
- for(int i = 0; i < right->size; i++)
+ for(int i = 0; i < GetSize(right); i++)
res->arraydata[i] = fnFloor(right->arraydata[i]);
break;
default:
@@ -456,13 +456,13 @@ fnSame(Array *right)
Array *
fnUniqueMask(Array *right)
{
- if(right->rank == 0){
+ if(GetRank(right) == 0){
Array *res = allocarray(AtypeInt, 1, 1);
res->shape[0] = 1;
res->intdata[0] = 1;
return res;
}
- if(right->size == 0){
+ if(GetSize(right) == 0){
Array *res = allocarray(AtypeInt, 1, 0);
res->shape[0] = 0;
return res;
@@ -484,47 +484,47 @@ fnDepth(Array *right)
Array *
fnTally(Array *right)
{
- return mkscalarint(right->rank==0 ? 1 : right->shape[0]);
+ return mkscalarint(GetRank(right)==0 ? 1 : right->shape[0]);
}
Array *
fnMix(Array *right)
{
- if(right->type != AtypeArray || right->size == 0)
+ if(GetType(right) != AtypeArray || GetSize(right) == 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;
+ for(i = 0; i < GetSize(right); i++)
+ if(GetRank(right->arraydata[i]) > commonrank)
+ commonrank = GetRank(right->arraydata[i]);
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++){
+ for(i = 0; i < GetSize(right); 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];
+ for(j = 0; j < GetRank(a); j++){
+ if(a->shape[GetRank(a)-1-j] > commonshape->intdata[commonrank-1-j])
+ commonshape->intdata[commonrank-1-j] = a->shape[GetRank(a)-1-j];
}
}
int size = 1;
int commonsize = 1;
- for(i = 0; i < right->rank; i++)
+ for(i = 0; i < GetRank(right); i++)
size *= right->shape[i];
- for(i = 0; i < commonshape->size; i++){
+ for(i = 0; i < GetSize(commonshape); i++){
size *= commonshape->intdata[i];
commonsize *= commonshape->intdata[i];
}
- Array *result = allocarray(AtypeArray, right->rank + commonrank, size);
- for(i = 0; i < right->rank; i++)
+ Array *result = allocarray(AtypeArray, GetRank(right) + commonrank, size);
+ for(i = 0; i < GetRank(right); i++)
result->shape[i] = right->shape[i];
- for(j = 0; j < commonshape->size; j++)
+ for(j = 0; j < GetSize(commonshape); j++)
result->shape[i+j] = commonshape->intdata[j];
int *index = emalloc(sizeof(int) * commonrank);
@@ -532,8 +532,8 @@ fnMix(Array *right)
for(i = 0; i < size/commonsize; i++){
Array *a = right->arraydata[i];
Array *fill = fillelement(a);
- if(a->rank == 0){
- if(a->type == AtypeArray)
+ if(GetRank(a) == 0){
+ if(GetType(a) == AtypeArray)
result->arraydata[i*commonsize] = a->arraydata[0];
else
result->arraydata[i*commonsize] = a;
@@ -546,8 +546,8 @@ fnMix(Array *right)
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];
+ for(int k = 0; index[commonrank-1-k] == a->shape[GetRank(a)-1-k]; k++){
+ int nfill = commonshape->intdata[commonrank-1-k] - a->shape[GetRank(a)-1-k];
while(nfill--){
result->arraydata[i*commonsize+offset] = fill;
incarrayref(fill);
@@ -556,7 +556,7 @@ fnMix(Array *right)
index[commonrank-1-k] = 0;
index[commonrank-2-k]++;
}
- if(j < a->size){
+ if(j < GetSize(a)){
result->arraydata[i*commonsize+offset] = arrayitem(a, j);
offset++;
index[commonrank-1]++;
@@ -597,7 +597,7 @@ fnEnclose(Array *right)
Array *
fnDisclose(Array *right)
{
- if(right->size == 0)
+ if(GetSize(right) == 0)
return fillelement(right);
else
return arrayitem(right, 0);
@@ -615,7 +615,7 @@ fnNest(Array *right)
Array *
fnGradeUp(Array *right)
{
- if(right->rank == 0)
+ if(GetRank(right) == 0)
throwerror(nil, ERank);
int i,j;
@@ -664,7 +664,7 @@ Array *
fnIndexGenerator(Array *right)
{
Array *result = nil;
- if(right->rank == 0){
+ if(GetRank(right) == 0){
vlong n = right->intdata[0];
if(n < 0)
throwerror(nil, EDomain);
@@ -673,8 +673,8 @@ fnIndexGenerator(Array *right)
vlong io = globalIO();
for(vlong i = 0; i < n; i++)
result->intdata[i] = i + io;
- }else if(right->rank == 1){
- if(right->size == 0)
+ }else if(GetRank(right) == 1){
+ if(GetSize(right) == 0)
return rundfn(L"⊂⍬", nil, nil, nil, nil);
else
result = rundfn(L"⊃⍣(0<≢⍵),⌾⌿⍳¨⍵", nil, nil, nil, right);
@@ -692,13 +692,13 @@ fnWhere(Array *right)
Array *
fnEnlist(Array *right)
{
- if(right->size == 0)
+ if(GetSize(right) == 0)
return fnSame(right);
- if(right->type != AtypeArray)
+ if(GetType(right) != AtypeArray)
return fnRavel(right);
else{
Array *res = fnEnlist(right->arraydata[0]);
- for(int i = 1; i < right->size; i++){
+ for(int i = 1; i < GetSize(right); i++){
Array *old = res;
Array *tmp = fnEnlist(right->arraydata[i]);
res = fnCatenateFirst(res, tmp);
@@ -712,7 +712,7 @@ fnEnlist(Array *right)
Array *
fnUnique(Array *right)
{
- if(right->rank == 0)
+ if(GetRank(right) == 0)
return fnRavel(right);
return rundfn(L"(≠⍵)⌿⍵", nil, nil, nil, right);
@@ -721,10 +721,10 @@ fnUnique(Array *right)
Array *
fnNot(Array *right)
{
- if(right->type != AtypeInt)
+ if(GetType(right) != AtypeInt)
throwerror(nil, EType);
Array *res = duparray(right);
- for(int i = 0; i < res->size; i++){
+ for(int i = 0; i < GetSize(res); i++){
if(res->intdata[i] == 0)
res->intdata[i] = 1;
else if(res->intdata[i] == 1)
@@ -741,9 +741,9 @@ Array *
fnRavel(Array *right)
{
Array *res = duparray(right);
- res->rank = 1;
- res->shape = erealloc(res->shape, sizeof(int) * 1);
- res->shape[0] = res->size;
+ SetRank(res, 1);
+ res->shape = erealloc(res->shape, sizeof(*res->shape) * 1);
+ res->shape[0] = GetSize(res);
return res;
}
@@ -751,19 +751,19 @@ Array *
fnTable(Array *right)
{
Array *res = duparray(right);
- res->rank = 2;
- res->shape = erealloc(res->shape, sizeof(int) * 2);
- res->shape[0] = right->rank ? res->shape[0] : 1;
- res->shape[1] = right->size / res->shape[0];
+ SetRank(res, 2);
+ res->shape = erealloc(res->shape, sizeof(*res->shape) * 2);
+ res->shape[0] = GetRank(right) ? res->shape[0] : 1;
+ res->shape[1] = GetSize(right) / res->shape[0];
return res;
}
Array *
fnShape(Array *right)
{
- Array *res = allocarray(AtypeInt, 1, right->rank);
- res->shape[0] = right->rank;
- for(int i = 0; i < right->rank; i++)
+ Array *res = allocarray(AtypeInt, 1, GetRank(right));
+ res->shape[0] = GetRank(right);
+ for(int i = 0; i < GetRank(right); i++)
res->intdata[i] = right->shape[i];
return res;
}
@@ -771,22 +771,22 @@ fnShape(Array *right)
Array *
fnReverseLast(Array *right)
{
- if(right->rank < 1)
+ if(GetRank(right) < 1)
return fnSame(right);
Array *res = duparray(right);
int nrows = 1;
- int rowsize = res->shape[res->rank-1];
- for(int i = 0; i < res->rank - 1; i++)
+ int rowsize = res->shape[GetRank(res)-1];
+ for(int i = 0; i < GetRank(res) - 1; i++)
nrows *= res->shape[i];
for(int row = 0; row < nrows; row++){
for(int i = 0; i < rowsize; i++)
memcpy(
- res->rawdata + (row * rowsize + i) * datasizes[res->type],
- right->rawdata + ((1+row) * rowsize - 1 - i) * datasizes[res->type],
- datasizes[res->type]);
+ res->rawdata + (row * rowsize + i) * datasizes[GetType(res)],
+ right->rawdata + ((1+row) * rowsize - 1 - i) * datasizes[GetType(res)],
+ datasizes[GetType(res)]);
}
return res;
}
@@ -794,17 +794,17 @@ fnReverseLast(Array *right)
Array *
fnReverseFirst(Array *right)
{
- if(right->rank < 1 || right->shape[0] == 0)
+ if(GetRank(right) < 1 || right->shape[0] == 0)
return fnSame(right);
Array *res = duparray(right);
int cells = res->shape[0];
- int elems = res->size / cells;
+ int elems = GetSize(res) / cells;
for(int i = 0; i < cells; i++)
memcpy(
- res->rawdata + i * elems * datasizes[res->type],
- right->rawdata + (cells - 1 - i) * elems * datasizes[res->type],
- datasizes[res->type] * elems);
+ res->rawdata + i * elems * datasizes[GetType(res)],
+ right->rawdata + (cells - 1 - i) * elems * datasizes[GetType(res)],
+ datasizes[GetType(res)] * elems);
return res;
}
@@ -812,31 +812,31 @@ Array *
fnTranspose(Array *right)
{
Array *res = duparray(right);
- for(int i = 0; i < res->rank; i++)
- res->shape[i] = right->shape[res->rank - 1 - i];
+ for(int i = 0; i < GetRank(res); i++)
+ res->shape[i] = right->shape[GetRank(res) - 1 - i];
int from, to;
- int *sizesFrom = emalloc(sizeof(int) * right->rank);
- int *sizesTo = emalloc(sizeof(int) * right->rank);
+ int *sizesFrom = emalloc(sizeof(int) * GetRank(right));
+ int *sizesTo = emalloc(sizeof(int) * GetRank(right));
int accFrom = 1, accTo = 1;
- for(int i = 0; i < right->rank; i++){
+ for(int i = 0; i < GetRank(right); i++){
sizesFrom[i] = accFrom;
sizesTo[i] = accTo;
accFrom *= res->shape[i];
accTo *= right->shape[i];
}
- for(from = 0; from < right->size; from++){
+ for(from = 0; from < GetSize(right); from++){
to = 0;
int tmp = from;
- for(int i = right->rank-1; i >= 0; i--){
- to += sizesTo[right->rank-1-i] * (tmp / sizesFrom[i]);
+ for(int i = GetRank(right)-1; i >= 0; i--){
+ to += sizesTo[GetRank(right)-1-i] * (tmp / sizesFrom[i]);
tmp = tmp % sizesFrom[i];
}
memcpy(
- res->rawdata + to * datasizes[res->type],
- right->rawdata + from * datasizes[res->type],
- datasizes[res->type]);
+ res->rawdata + to * datasizes[GetType(res)],
+ right->rawdata + from * datasizes[GetType(res)],
+ datasizes[GetType(res)]);
}
free(sizesFrom);
free(sizesTo);
@@ -846,7 +846,7 @@ fnTranspose(Array *right)
Array *
fnExecute(Array *right)
{
- if(right->type != AtypeRune)
+ if(GetType(right) != AtypeRune)
throwerror(nil, EType);
Rune *code = pparray(right);
Datum *result = evalline(code, nil, 1);
@@ -863,11 +863,11 @@ fnExecute(Array *right)
Array *
fnFormat(Array *right)
{
- if(right->type == AtypeArray)
+ if(GetType(right) == AtypeArray)
throwerror(L"Format for nested arrays", ENotImplemented);
/* TODO add support for formatting nested arrays */
- right = right->rank == 0 ? fnRavel(right) : fnSame(right);
+ right = GetRank(right) == 0 ? fnRavel(right) : fnSame(right);
Rune *str = pparray(right);
int maxwidth = 0;
@@ -882,14 +882,14 @@ fnFormat(Array *right)
}
}
vlong size;
- if(right->shape[right->rank-1] == 0)
+ if(right->shape[GetRank(right)-1] == 0)
size = 0;
else
- size = maxwidth * right->size / right->shape[right->rank-1];
+ size = maxwidth * GetSize(right) / right->shape[GetRank(right)-1];
- Array *result = allocarray(AtypeRune, right->rank, size);
- result->shape[result->rank-1] = maxwidth;
- for(int i = 0; i < result->rank-1; i++)
+ Array *result = allocarray(AtypeRune, GetRank(right), size);
+ result->shape[GetRank(result)-1] = maxwidth;
+ for(int i = 0; i < GetRank(result)-1; i++)
result->shape[i] = right->shape[i];
int offset = 0;
for(int i = 0; str[i] != 0; i++)
@@ -918,7 +918,7 @@ fnSelfReference1(Array *right)
#define SCALAR_FUNCTION_2(name, forcefloat, restype, cases) \
Array *name(Array *left, Array *right){\
Array *leftarr, *rightarr;\
- int nested = left->type == AtypeArray || right->type == AtypeArray;\
+ int nested = GetType(left) == AtypeArray || GetType(right) == AtypeArray;\
if(nested){\
leftarr = fnSame(left);\
rightarr = fnSame(right);\
@@ -930,7 +930,7 @@ Array *name(Array *left, Array *right){\
Array *res;\
if(nested){\
res = duparrayshape(left, AtypeArray);\
- for(int i = 0; i < left->size; i++){\
+ for(int i = 0; i < GetSize(left); i++){\
Array *l = arrayitem(left, i);\
Array *r = arrayitem(right, i);\
res->arraydata[i] = name(l,r);\
@@ -939,8 +939,8 @@ Array *name(Array *left, Array *right){\
}\
}else{\
res = duparray(left);\
- for(int i = 0; i < left->size; i++)\
- switch(left->type){\
+ for(int i = 0; i < GetSize(left); i++)\
+ switch(GetType(left)){\
default: throwerror(nil, EType); break;\
cases\
}\
@@ -948,7 +948,7 @@ Array *name(Array *left, Array *right){\
freearray(leftarr); freearray(rightarr); freearray(left); freearray(right);\
return res;}
-SCALAR_FUNCTION_2(fnPlus, 0, left->type,
+SCALAR_FUNCTION_2(fnPlus, 0, GetType(left),
case AtypeFloat:
res->floatdata[i] += right->floatdata[i];
break;
@@ -957,7 +957,7 @@ SCALAR_FUNCTION_2(fnPlus, 0, left->type,
break;
)
-SCALAR_FUNCTION_2(fnMinus, 0, left->type,
+SCALAR_FUNCTION_2(fnMinus, 0, GetType(left),
case AtypeFloat:
res->floatdata[i] -= right->floatdata[i];
break;
@@ -966,7 +966,7 @@ SCALAR_FUNCTION_2(fnMinus, 0, left->type,
break;
)
-SCALAR_FUNCTION_2(fnTimes, 0, left->type,
+SCALAR_FUNCTION_2(fnTimes, 0, GetType(left),
case AtypeFloat:
res->floatdata[i] *= right->floatdata[i];
break;
@@ -975,7 +975,7 @@ SCALAR_FUNCTION_2(fnTimes, 0, left->type,
break;
)
-SCALAR_FUNCTION_2(fnDivide, 1, left->type,
+SCALAR_FUNCTION_2(fnDivide, 1, GetType(left),
case AtypeFloat:
if(right->floatdata[i] == 0){
if(globalDIV())
@@ -988,7 +988,7 @@ SCALAR_FUNCTION_2(fnDivide, 1, left->type,
break;
)
-SCALAR_FUNCTION_2(fnPower, 0, left->type,
+SCALAR_FUNCTION_2(fnPower, 0, GetType(left),
case AtypeFloat:
res->floatdata[i] = pow(res->floatdata[i], right->floatdata[i]);
break;
@@ -997,7 +997,7 @@ SCALAR_FUNCTION_2(fnPower, 0, left->type,
break;
)
-SCALAR_FUNCTION_2(fnLogarithm, 1, left->type,
+SCALAR_FUNCTION_2(fnLogarithm, 1, GetType(left),
case AtypeFloat:
res->floatdata[i] = log(right->floatdata[i])/log(res->floatdata[i]);
break;
@@ -1075,9 +1075,9 @@ SCALAR_FUNCTION_2(fnBinomial, 0, AtypeFloat,
Array *
fnDeal(Array *left, Array *right)
{
- if(left->type != AtypeInt || right->type != AtypeInt)
+ if(GetType(left) != AtypeInt || GetType(right) != AtypeInt)
throwerror(nil, EType);
- if(left->size != 1 || right->size != 1)
+ if(GetSize(left) != 1 || GetSize(right) != 1)
throwerror(nil, EShape);
vlong x = left->intdata[0];
vlong y = right->intdata[0];
@@ -1098,7 +1098,7 @@ fnDeal(Array *left, Array *right)
return result;
}
-SCALAR_FUNCTION_2(fnResidue, 1, left->type,
+SCALAR_FUNCTION_2(fnResidue, 1, GetType(left),
case AtypeFloat:
if(res->floatdata[i] == 0)
res->floatdata[i] = right->floatdata[i];
@@ -1106,7 +1106,7 @@ SCALAR_FUNCTION_2(fnResidue, 1, left->type,
res->floatdata[i] = right->floatdata[i] - res->floatdata[i] * floor(right->floatdata[i]/res->floatdata[i]);
)
-SCALAR_FUNCTION_2(fnMaximum, 0, left->type,
+SCALAR_FUNCTION_2(fnMaximum, 0, GetType(left),
case AtypeFloat:
if(res->floatdata[i] < right->floatdata[i])
res->floatdata[i] = right->floatdata[i];
@@ -1115,7 +1115,7 @@ SCALAR_FUNCTION_2(fnMaximum, 0, left->type,
res->intdata[i] = right->intdata[i];
)
-SCALAR_FUNCTION_2(fnMinimum, 0, left->type,
+SCALAR_FUNCTION_2(fnMinimum, 0, GetType(left),
case AtypeFloat:
if(res->floatdata[i] > right->floatdata[i])
res->floatdata[i] = right->floatdata[i];
@@ -1127,9 +1127,9 @@ SCALAR_FUNCTION_2(fnMinimum, 0, left->type,
Array *
fnDecode(Array *left, Array *right)
{
- if(left->type != AtypeInt && left->type != AtypeFloat)
+ if(GetType(left) != AtypeInt && GetType(left) != AtypeFloat)
throwerror(nil, EType);
- if(right->type != AtypeInt && right->type != AtypeFloat)
+ if(GetType(right) != AtypeInt && GetType(right) != AtypeFloat)
throwerror(nil, EType);
return rundfn(L"(⌽×\\1,⌽⍵∘{1↓(≢⍺)⍴⍵}⍤1⊢⍺)+.×⍵", nil, nil, left, right);
}
@@ -1137,12 +1137,12 @@ fnDecode(Array *left, Array *right)
Array *
fnEncode(Array *left, Array *right)
{
- if(left->type != AtypeInt && left->type != AtypeFloat)
+ if(GetType(left) != AtypeInt && GetType(left) != AtypeFloat)
throwerror(nil, EType);
- if(right->type != AtypeInt && right->type != AtypeFloat)
+ if(GetType(right) != AtypeInt && GetType(right) != AtypeFloat)
throwerror(nil, EType);
- if(left->rank > 1)
+ if(GetRank(left) > 1)
return rundfn(L"⍉(⍉⍺) (⊤⍤1) ⍵", nil, nil, left, right);
else
return rundfn(L"⎕div←1 ⋄ ((⍴⍺),⍴⍵)⍴(⌽⍺){0=≢⍺:⍬ ⋄ n←⊃⍺ ⋄ x←n|⍵ ⋄ ((1↓⍺)∇n÷⍨⍵-x)⍪x}⍵", nil, nil, left, right);
@@ -1231,7 +1231,7 @@ fnMatch(Array *left, Array *right)
return mkscalarint(cmp == 0);
}
-SCALAR_FUNCTION_2(fnOr, 0, left->type,
+SCALAR_FUNCTION_2(fnOr, 0, GetType(left),
case AtypeInt:
if((left->intdata[i] == 0 || left->intdata[i] == 1) && (right->intdata[i] == 0 || right->intdata[i] == 1))
res->intdata[i] = left->intdata[i] || right->intdata[i];
@@ -1243,7 +1243,7 @@ SCALAR_FUNCTION_2(fnOr, 0, left->type,
break;
)
-SCALAR_FUNCTION_2(fnAnd, 0, left->type,
+SCALAR_FUNCTION_2(fnAnd, 0, GetType(left),
case AtypeInt:
if((left->intdata[i] == 0 || left->intdata[i] == 1) && (right->intdata[i] == 0 || right->intdata[i] == 1))
res->intdata[i] = left->intdata[i] && right->intdata[i];
@@ -1283,81 +1283,81 @@ Array *
fnTake(Array *left, Array *right)
{
int i;
- if(left->type != AtypeInt)
+ if(GetType(left) != AtypeInt)
throwerror(nil, EType);
- if(left->rank > 1)
+ if(GetRank(left) > 1)
throwerror(nil, ERank);
- if(right->rank == 0){
+ if(GetRank(right) == 0){
right = duparray(right);
- right->rank = left->size;
- right->shape = erealloc(right->shape, sizeof(int) * right->rank);
- for(i = 0; i < right->rank; i++)
+ SetRank(right, GetSize(left));
+ right->shape = erealloc(right->shape, sizeof(*right->shape) * GetRank(right));
+ for(i = 0; i < GetRank(right); i++)
right->shape[i] = 1;
}else
right = fnSame(right);
- if(left->size > right->rank)
+ if(GetSize(left) > GetRank(right))
throwerror(nil, ELength);
- else if(left->size == right->rank)
+ else if(GetSize(left) == GetRank(right))
left = fnSame(left);
else{
Array *old = left;
left = fnShape(right);
- for(i = 0; i < old->size; i++)
+ for(i = 0; i < GetSize(old); i++)
left->intdata[i] = old->intdata[i];
}
- int *shape = emalloc(sizeof(int) * left->size);
+ int *shape = emalloc(sizeof(int) * GetSize(left));
int size = 1;
- for(i = 0; i < left->size; i++){
+ for(i = 0; i < GetSize(left); i++){
int s = left->intdata[i];
shape[i] = s < 0 ? -s : s;
size *= shape[i];
}
Array *fill = fillelement(right);
- Array *result = allocarray(right->type, right->rank, size);
- for(i = 0; i < right->rank; i++)
+ Array *result = allocarray(GetType(right), GetRank(right), size);
+ for(i = 0; i < GetRank(right); i++)
result->shape[i] = shape[i];
- int *index = emallocz(sizeof(int) * left->size, 1);
+ int *index = emallocz(sizeof(int) * GetSize(left), 1);
int fromindex;
for(i = 0; i < size; i++){
- for(int j = left->size-1; index[j] == shape[j]; j--){
+ for(int j = GetSize(left)-1; index[j] == shape[j]; j--){
index[j] = 0;
index[j-1]++;
}
int inside = 1;
fromindex = 0;
- for(int j = 0; j < left->size && inside; j++){
+ for(int j = 0; j < GetSize(left) && inside; j++){
vlong n = left->intdata[j];
vlong m = index[j];
if(n > 0 && m >= right->shape[j])
inside = 0;
- else if(n < 0 && m < ((-n)-right->shape[j]))
+ else if(n < 0 && m < (vlong)((-n)-right->shape[j]))
inside = 0;
int add;
if(n < 0)
add = n + index[j] + right->shape[j];
else
add = index[j];
- for(int k = j+1; k < right->rank; k++)
+ for(int k = j+1; k < GetRank(right); k++)
add *= right->shape[k];
fromindex += add;
}
if(inside)
- memcpy(result->rawdata + i*datasizes[result->type],
- right->rawdata + fromindex*datasizes[result->type],
- datasizes[result->type]);
+ memcpy(result->rawdata + i*datasizes[GetType(result)],
+ right->rawdata + fromindex*datasizes[GetType(result)],
+ datasizes[GetType(result)]);
else
- memcpy(result->rawdata + i*datasizes[result->type],
- fill->rawdata, datasizes[result->type]);
- if(result->type == AtypeArray)
+ memcpy(result->rawdata + i*datasizes[GetType(result)],
+ fill->rawdata, datasizes[GetType(result)]);
+ if(GetType(result) == AtypeArray)
incarrayref(result->arraydata[i]);
- index[left->size-1]++;
+ index[GetSize(left)-1]++;
}
free(shape);
@@ -1372,34 +1372,34 @@ Array *
fnDrop(Array *left, Array *right)
{
int i;
- if(left->type != AtypeInt)
+ if(GetType(left) != AtypeInt)
throwerror(nil, EType);
- if(left->rank > 1)
+ if(GetRank(left) > 1)
throwerror(nil, ERank);
- if(right->rank == 0){
+ if(GetRank(right) == 0){
right = duparray(right);
- right->rank = left->size;
- right->shape = erealloc(right->shape, sizeof(int) * right->rank);
- for(i = 0; i < right->rank; i++)
+ SetRank(right, GetSize(left));
+ right->shape = erealloc(right->shape, sizeof(*right->shape) * GetRank(right));
+ for(i = 0; i < GetRank(right); i++)
right->shape[i] = 1;
}else
right = fnSame(right);
- if(left->size > right->rank)
+ if(GetSize(left) > GetRank(right))
throwerror(nil, ELength);
- else if(left->size == right->rank)
+ else if(GetSize(left) == GetRank(right))
left = fnSame(left);
else{
Array *old = left;
- left = allocarray(AtypeInt, 1, right->rank);
- left->shape[0] = left->size;
- for(i = 0; i < old->size; i++)
+ left = allocarray(AtypeInt, 1, GetRank(right));
+ left->shape[0] = GetSize(left);
+ for(i = 0; i < GetSize(old); i++)
left->intdata[i] = old->intdata[i];
- for(; i < left->size; i++)
+ for(; i < GetSize(left); i++)
left->intdata[i] = 0;
}
- for(int i = 0; i < left->size; i++){
+ for(int i = 0; i < GetSize(left); i++){
vlong n = left->intdata[i];
vlong m = right->shape[i];
if(n > m || (-n) > m)
@@ -1418,27 +1418,27 @@ fnDrop(Array *left, Array *right)
Array *
fnPick(Array *left, Array *right)
{
- if(left->rank > 1)
+ if(GetRank(left) > 1)
throwerror(nil, ERank);
- if(left->size == 0)
+ if(GetSize(left) == 0)
return fnSame(right);
int io = globalIO();
Array *result = fnSame(right);
- for(int i = 0; i < left->size; i++){
+ for(int i = 0; i < GetSize(left); i++){
Array *ix = arrayitem(left, i);
- if(ix->rank > 1)
+ if(GetRank(ix) > 1)
throwerror(nil, ERank);
- if(ix->size != result->rank)
+ if(GetSize(ix) != GetRank(result))
throwerror(nil, ERank);
int index = 0;
- for(int j = 0; j < ix->size; j++){
+ for(int j = 0; j < GetSize(ix); j++){
int add = ix->intdata[j] - io;
- for(int k = j+1; k < ix->size; k++)
+ for(int k = j+1; k < GetSize(ix); k++)
add *= result->shape[k];
index += add;
}
- if(index >= result->size)
+ if(index >= GetSize(result))
throwerror(nil, EIndex);
Array *tmp = result;
result = arrayitem(result, index);
@@ -1450,13 +1450,13 @@ fnPick(Array *left, Array *right)
Array *
fnPartition(Array *left, Array *right)
{
- if(right->rank == 0)
+ if(GetRank(right) == 0)
throwerror(nil, ERank);
- if(left->rank > 2)
+ if(GetRank(left) > 2)
throwerror(nil, ERank);
- if(left->type != AtypeInt)
+ if(GetType(left) != AtypeInt)
throwerror(nil, EType);
- if(left->size != right->shape[0])
+ if(GetSize(left) != right->shape[0])
throwerror(nil, ELength);
if(right->shape[0] == 0)
return fnSame(right); /* TODO figure out if this is correct */
@@ -1469,8 +1469,8 @@ fnPartition(Array *left, Array *right)
int start = -1;
int io = globalIO();
int active = 0;
- for(i = 0; i <= left->size; i++){
- vlong n = i == left->size ? 0 : left->intdata[i];
+ for(i = 0; i <= GetSize(left); i++){
+ vlong n = i == GetSize(left) ? 0 : left->intdata[i];
if(n < 0)
throwerror(nil, EDomain);
if(active && (n == 0 || n > prev)){
@@ -1505,31 +1505,31 @@ fnIndex(Array *left, Array *right)
int io = globalIO();
int i;
- if(left->rank > 1)
+ if(GetRank(left) > 1)
throwerror(nil, ERank);
- if(left->type != AtypeArray && left->type != AtypeInt)
+ if(GetType(left) != AtypeArray && GetType(left) != AtypeInt)
throwerror(nil, EType);
- if(left->size > right->rank)
+ if(GetSize(left) > GetRank(right))
throwerror(nil, ELength);
/* extend left index vector to full format */
Array *oldleft = left;
- left = allocarray(AtypeArray, 1, right->rank);
- left->shape[0] = right->rank;
- for(i = 0; i < left->size; i++){
- if(i >= oldleft->size){
+ left = allocarray(AtypeArray, 1, GetRank(right));
+ left->shape[0] = GetRank(right);
+ for(i = 0; i < GetSize(left); i++){
+ if(i >= GetSize(oldleft)){
Array *n = mkscalarint(right->shape[i]);
left->arraydata[i] = fnIndexGenerator(n);
freearray(n);
- }else if(oldleft->type == AtypeInt){
+ }else if(GetType(oldleft) == AtypeInt){
if(oldleft->intdata[i] < io || oldleft->intdata[i] >= io + right->shape[i])
throwerror(nil, EIndex);
left->arraydata[i] = mkscalarint(oldleft->intdata[i]);
- }else if(oldleft->type == AtypeArray){
+ }else if(GetType(oldleft) == AtypeArray){
Array *sub = oldleft->arraydata[i];
- if(sub->type != AtypeInt)
+ if(GetType(sub) != AtypeInt)
throwerror(nil, EType);
- for(int j = 0; j < sub->size; j++){
+ for(int j = 0; j < GetSize(sub); j++){
if(sub->intdata[j] < io || sub->intdata[j] >= io + right->shape[i])
throwerror(nil, EIndex);
}
@@ -1543,8 +1543,8 @@ fnIndex(Array *left, Array *right)
int rank = 0;
int size = 1;
- for(i = 0; i < left->size; i++){
- if(left->type == AtypeArray){
+ for(i = 0; i < GetSize(left); i++){
+ if(GetType(left) == AtypeArray){
Array *tmp = shape;
Array *newShape = fnShape(left->arraydata[i]);
shape = fnCatenateFirst(tmp, newShape);
@@ -1553,34 +1553,34 @@ fnIndex(Array *left, Array *right)
}
}
- for(i = 0; i < shape->size; i++){
+ for(i = 0; i < GetSize(shape); i++){
size *= shape->intdata[i];
rank++;
}
- Array *result = allocarray(right->type, rank, size);
+ Array *result = allocarray(GetType(right), rank, size);
for(i = 0; i < rank; i++)
result->shape[i] = shape->intdata[i];
freearray(shape);
- int *leftindex = emallocz(sizeof(int) * right->rank, 1);
- for(i = 0; i < result->size; i++){
- for(int j = left->size-1; leftindex[j] == left->arraydata[j]->size; j--){
+ int *leftindex = emallocz(sizeof(int) * GetRank(right), 1);
+ for(i = 0; i < GetSize(result); i++){
+ for(int j = GetSize(left)-1; leftindex[j] == GetSize(left->arraydata[j]); j--){
leftindex[j] = 0;
leftindex[j-1]++;
}
int from = 0;
- int cellsize = right->size;
- for(int j = 0; j < left->size; j++){
+ int cellsize = GetSize(right);
+ for(int j = 0; j < GetSize(left); j++){
cellsize = cellsize / right->shape[j];
from += cellsize * (left->arraydata[j]->intdata[leftindex[j]] - io);
}
memcpy(
- result->rawdata + i * datasizes[result->type],
- right->rawdata + from * datasizes[result->type],
- datasizes[result->type]);
- if(result->type == AtypeArray)
+ result->rawdata + i * datasizes[GetType(result)],
+ right->rawdata + from * datasizes[GetType(result)],
+ datasizes[GetType(result)]);
+ if(GetType(result) == AtypeArray)
incarrayref(result->arraydata[i]);
- leftindex[left->size-1]++;
+ leftindex[GetSize(left)-1]++;
}
free(leftindex);
freearray(left);
@@ -1602,10 +1602,10 @@ fnIntervalIndex(Array *left, Array *right)
Array *
fnMembership(Array *left, Array *right)
{
- if(right->size == 0)
+ if(GetSize(right) == 0)
return rundfn(L"(⍴⍵)⍴0", nil, nil, nil, left);
- if(right->rank == 0)
+ if(GetRank(right) == 0)
return rundfn(L"⍺∊,⍵", nil, nil, left, right);
/* TODO avoid outer product */
@@ -1616,20 +1616,20 @@ Array *
fnFind(Array *left, Array *right)
{
int i,j;
- if(left->rank > right->rank){
+ if(GetRank(left) > GetRank(right)){
print("Left rank larger\n");
return rundfn(L"(⍴⍵)⍴0", nil, nil, nil, right);
}
- if(left->rank < right->rank){
- Array *newleft = allocarray(left->type, right->rank, left->size);
- for(i = 0; i < right->rank - left->rank; i++)
+ if(GetRank(left) < GetRank(right)){
+ Array *newleft = allocarray(GetType(left), GetRank(right), GetSize(left));
+ for(i = 0; i < GetRank(right) - GetRank(left); i++)
newleft->shape[i] = 1;
- for(j = 0; j < left->rank; j++)
+ for(j = 0; j < GetRank(left); j++)
newleft->shape[i+j] = left->shape[j];
- memcpy(newleft->rawdata, left->rawdata, datasizes[left->type] * left->size);
- if(left->type == AtypeArray)
- for(i = 0; i < left->size; i++)
+ memcpy(newleft->rawdata, left->rawdata, datasizes[GetType(left)] * GetSize(left));
+ if(GetType(left) == AtypeArray)
+ for(i = 0; i < GetSize(left); i++)
incarrayref(newleft->arraydata[i]);
left = newleft;
}else
@@ -1642,7 +1642,7 @@ fnFind(Array *left, Array *right)
Array *
fnUnion(Array *left, Array *right)
{
- if(left->rank > 1 || right->rank > 1)
+ if(GetRank(left) > 1 || GetRank(right) > 1)
throwerror(nil, ERank);
return rundfn(L"⍺⍪⍵~⍺", nil, nil, left, right);
}
@@ -1650,7 +1650,7 @@ fnUnion(Array *left, Array *right)
Array *
fnIntersection(Array *left, Array *right)
{
- if(left->rank > 1 || right->rank > 1)
+ if(GetRank(left) > 1 || GetRank(right) > 1)
throwerror(nil, ERank);
return rundfn(L"(⍺∊⍵)⌿⍺", nil, nil, left, right);
}
@@ -1673,64 +1673,64 @@ fnCatenateFirst(Array *left, Array *right)
Array *leftarr = nil;
Array *rightarr = nil;
- if(left->rank == 0 && right->rank != 0){
- /* extend left to right->rank with first axis=1 */
+ if(GetRank(left) == 0 && GetRank(right) != 0){
+ /* extend left to GetRank(right) with first axis=1 */
rightarr = fnSame(right);
Array *shape = fnShape(right);
shape->intdata[0] = 1;
leftarr = fnReshape(shape, left);
freearray(shape);
- }else if(left->rank != 0 && right->rank == 0){
- /* extend right to left->rank with first axis=1 */
+ }else if(GetRank(left) != 0 && GetRank(right) == 0){
+ /* extend right to GetRank(left) with first axis=1 */
leftarr = fnSame(left);
Array *shape = fnShape(left);
shape->intdata[0] = 1;
rightarr = fnReshape(shape, right);
freearray(shape);
- }else if(left->rank == 0 && right->rank == 0){
+ }else if(GetRank(left) == 0 && GetRank(right) == 0){
/* turn both scalars into vectors */
leftarr = fnRavel(left);
rightarr = fnRavel(right);
}else{
/* Check that the shapes match */
- if(left->rank == right->rank-1){
+ if(GetRank(left) == GetRank(right)-1){
/* extend left with unit dimension */
- Array *shape = allocarray(AtypeInt, 1, left->rank+1);
+ Array *shape = allocarray(AtypeInt, 1, GetRank(left)+1);
shape->intdata[0] = 1;
- for(int i = 1; i < left->rank+1; i++)
+ for(int i = 1; i < GetRank(left)+1; i++)
shape->intdata[i] = left->shape[i-1];
leftarr = fnReshape(shape, left);
rightarr = fnSame(right);
freearray(shape);
- }else if(right->rank == left->rank-1){
+ }else if(GetRank(right) == GetRank(left)-1){
/* extend right with unit dimension */
- Array *shape = allocarray(AtypeInt, 1, right->rank+1);
+ Array *shape = allocarray(AtypeInt, 1, GetRank(right)+1);
shape->intdata[0] = 1;
- for(int i = 1; i < right->rank+1; i++)
+ for(int i = 1; i < GetRank(right)+1; i++)
shape->intdata[i] = right->shape[i-1];
rightarr = fnReshape(shape, right);
leftarr = fnSame(left);
freearray(shape);
- }else if(right->rank == left->rank){
+ }else if(GetRank(right) == GetRank(left)){
leftarr = fnSame(left);
rightarr = fnSame(right);
}else
throwerror(nil, ERank);
- for(int i = 1; i < leftarr->rank; i++)
+ for(int i = 1; i < GetRank(leftarr); i++)
if(leftarr->shape[i] != rightarr->shape[i])
throwerror(nil, EShape);
}
int type, rank, leftsize, rightsize;
- if(leftarr->type == AtypeArray || rightarr->type == AtypeArray || leftarr->type != rightarr->type)
+ if(GetType(leftarr) == AtypeArray || GetType(rightarr) == AtypeArray || GetType(leftarr) != GetType(rightarr))
type = AtypeArray;
else
- type = leftarr->type;
- if(leftarr->rank > rightarr->rank)
- rank = leftarr->rank;
+ type = GetType(leftarr);
+ if(GetRank(leftarr) > GetRank(rightarr))
+ rank = GetRank(leftarr);
else
- rank = rightarr->rank;
+ rank = GetRank(rightarr);
leftsize = leftarr->shape[0];
rightsize = rightarr->shape[0];
@@ -1742,16 +1742,16 @@ fnCatenateFirst(Array *left, Array *right)
Array *result = allocarray(type, rank, leftsize + rightsize);
int i, j;
result->shape[0] = leftarr->shape[0] + rightarr->shape[0];
- for(i = 1; i < result->rank; i++)
+ for(i = 1; i < GetRank(result); i++)
result->shape[i] = leftarr->shape[i];
/* TODO reduce duplicated code between copies from left and right */
/* Copy data from the left array */
- for(i = 0, j = 0; i < leftarr->size; i++, j++){
- if(type == AtypeArray && leftarr->type == AtypeArray){
+ for(i = 0, j = 0; i < GetSize(leftarr); i++, j++){
+ if(type == AtypeArray && GetType(leftarr) == AtypeArray){
result->arraydata[j] = leftarr->arraydata[i];
incarrayref(result->arraydata[j]);
- }else if(type == AtypeArray && leftarr->type != AtypeArray){
+ }else if(type == AtypeArray && GetType(leftarr) != AtypeArray){
result->arraydata[j] = arrayitem(leftarr, i);
}else{
memcpy(
@@ -1762,11 +1762,11 @@ fnCatenateFirst(Array *left, Array *right)
}
/* Copy data from the right array */
- for(i = 0; i < rightarr->size; i++, j++){
- if(type == AtypeArray && rightarr->type == AtypeArray){
+ for(i = 0; i < GetSize(rightarr); i++, j++){
+ if(type == AtypeArray && GetType(rightarr) == AtypeArray){
result->arraydata[j] = rightarr->arraydata[i];
incarrayref(result->arraydata[j]);
- }else if(type == AtypeArray && rightarr->type != AtypeArray){
+ }else if(type == AtypeArray && GetType(rightarr) != AtypeArray){
result->arraydata[j] = arrayitem(rightarr, i);
}else{
memcpy(
@@ -1787,18 +1787,18 @@ fnReshape(Array *left, Array *right)
vlong size = 1;
int i;
char *p;
- for(i = 0; i < left->size; i++)
+ for(i = 0; i < GetSize(left); i++)
size *= left->intdata[i];
- if(left->size == 0)
+ if(GetSize(left) == 0)
return arrayitem(right, 0);
- Array *res = allocarray(right->type, left->size, size);
- for(i = 0; i < left->size; i++)
+ Array *res = allocarray(GetType(right), GetSize(left), size);
+ for(i = 0; i < GetSize(left); i++)
res->shape[i] = left->intdata[i];
- for(i = 0, p = res->rawdata; i < size; i++, p += datasizes[res->type])
- memcpy(p, right->rawdata + (datasizes[res->type] * (i % right->size)), datasizes[res->type]);
- if(res->type == AtypeArray)
- for(i = 0; i < res->size; i++)
+ for(i = 0, p = res->rawdata; i < size; i++, p += datasizes[GetType(res)])
+ memcpy(p, right->rawdata + (datasizes[GetType(res)] * (i % GetSize(right))), datasizes[GetType(res)]);
+ if(GetType(res) == AtypeArray)
+ for(i = 0; i < GetSize(res); i++)
incarrayref(res->arraydata[i]);
return res;
}
@@ -1812,43 +1812,43 @@ fnRotateLast(Array *left, Array *right)
Array *
fnRotateFirst(Array *left, Array *right)
{
- if(left->type != AtypeInt)
+ if(GetType(left) != AtypeInt)
throwerror(nil, EType);
- if(right->rank == 0 || right->size < 2)
+ if(GetRank(right) == 0 || GetSize(right) < 2)
return fnSame(right);
int i, j;
- if(left->size == 1 && right->rank != 0){
+ if(GetSize(left) == 1 && GetRank(right) != 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 = allocarray(AtypeInt, GetRank(right)-1, GetSize(right) / right->shape[0]);
+ for(i = 0; i < GetRank(left); i++)
left->shape[i] = right->shape[i+1];
- for(i = 0; i < left->size; i++)
+ for(i = 0; i < GetSize(left); i++)
left->intdata[i] = v;
}else
left = fnSame(left);
- if(left->rank != right->rank-1)
+ if(GetRank(left) != GetRank(right)-1)
throwerror(nil, ERank);
- for(i = 0; i < left->rank; i++)
+ for(i = 0; i < GetRank(left); i++)
if(left->shape[i] != right->shape[i+1])
throwerror(nil, EShape);
int n = right->shape[0];
- for(i = 0; i < left->size; i++)
+ for(i = 0; i < GetSize(left); 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++){
+ for(j = 0; j < GetSize(left); 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]);
+ vlong from = j + ((i+rot)%n)*GetSize(left);
+ vlong to = j + i*GetSize(left);
+ memcpy(result->rawdata + to*datasizes[GetType(right)],
+ right->rawdata + from*datasizes[GetType(right)],
+ datasizes[GetType(right)]);
}
}
return result;
@@ -1869,9 +1869,9 @@ fnSelfReference2(Array *left, Array *right)
Array *
fnSend(Array *left, Array *right)
{
- if(right->size != 1)
+ if(GetSize(right) != 1)
throwerror(nil, ELength);
- if(right->type != AtypeInt)
+ if(GetType(right) != AtypeInt)
throwerror(nil, EType);
messagesend(left, right->intdata[0]);
return fnSame(left);
@@ -1899,17 +1899,17 @@ gcd_float(double a, double b)
Array *
indexOfHelper(Array *left, Array *right, int interval)
{
- if(left->rank < 1)
+ if(GetRank(left) < 1)
throwerror(nil, ERank);
- if(right->rank < left->rank-1)
+ if(GetRank(right) < GetRank(left)-1)
throwerror(nil, ERank);
int i, j;
- for(i = 0; i < left->rank-1; i++)
- if(left->shape[left->rank-1-i] != right->shape[right->rank-1-i])
+ for(i = 0; i < GetRank(left)-1; i++)
+ if(left->shape[GetRank(left)-1-i] != right->shape[GetRank(right)-1-i])
throwerror(nil, EShape);
- int rank = right->rank + 1 - left->rank;
+ int rank = GetRank(right) + 1 - GetRank(left);
int size = 1;
int io = globalIO();
int n = left->shape[0];
@@ -1920,11 +1920,11 @@ indexOfHelper(Array *left, Array *right, int interval)
for(i = 0; i < rank; i++)
result->shape[i] = right->shape[i];
/* Reshape Y to allow easy picking of sub-arrays */
- Array *rightshape = allocarray(AtypeInt, 1, right->rank - rank + 1);
- rightshape->shape[0] = rightshape->size;
+ Array *rightshape = allocarray(AtypeInt, 1, GetRank(right) - rank + 1);
+ rightshape->shape[0] = GetSize(rightshape);
rightshape->intdata[0] = size;
- for(i = 0; i < rightshape->size - 1; i++)
- rightshape->intdata[rightshape->size-1-i] = right->shape[right->rank-1-i];
+ for(i = 0; i < GetSize(rightshape) - 1; i++)
+ rightshape->intdata[GetSize(rightshape)-1-i] = right->shape[GetRank(right)-1-i];
right = fnReshape(rightshape, right);
Array **lefts = emalloc(sizeof(Array *) * n);
diff --git a/hybrids.c b/hybrids.c
index 18bab50..2a6b9b5 100644
--- a/hybrids.c
+++ b/hybrids.c
@@ -36,44 +36,44 @@ fnExpandLast(Array *left, Array *right)
Array *
fnReplicateFirst(Array *left, Array *right)
{
- if(left->type != AtypeInt)
+ if(GetType(left) != AtypeInt)
throwerror(nil, EType);
- if(left->rank > 1)
+ if(GetRank(left) > 1)
throwerror(nil, ERank);
/* Reshape right if scalar */
- if(right->size == 1){
- Array *shape = right->rank == 0 ? mkscalarint(1) : fnShape(right);
- shape->intdata[0] = left->size;
+ if(GetSize(right) == 1){
+ Array *shape = GetRank(right) == 0 ? mkscalarint(1) : fnShape(right);
+ shape->intdata[0] = GetSize(left);
right = fnReshape(shape, right);
freearray(shape);
}else
right = fnSame(right);
int nsize = right->shape[0];
- int cellsize = nsize == 0 ? 1 : right->size / nsize;
+ int cellsize = nsize == 0 ? 1 : GetSize(right) / nsize;
int i;
- if(left->size == 1){
+ if(GetSize(left) == 1){
Array *shape = mkscalarint(nsize);
left = fnReshape(shape, left);
}else
left = fnSame(left);
- if(left->size != nsize){
+ if(GetSize(left) != nsize){
freearray(left);
freearray(right);
throwerror(nil, ELength);
}
nsize = 0;
- for(i = 0; i < left->size; i++){
+ for(i = 0; i < GetSize(left); i++){
vlong n = left->intdata[i];
nsize += n > 0 ? n : -n;
}
- Array *result = allocarray(right->type, right->rank, nsize * cellsize);
+ Array *result = allocarray(GetType(right), GetRank(right), nsize * cellsize);
result->shape[0] = nsize;
- for(i = 1; i < result->rank; i++)
+ for(i = 1; i < GetRank(result); i++)
result->shape[i] = right->shape[i];
Array *fill = fillelement(right);
@@ -85,15 +85,15 @@ fnReplicateFirst(Array *left, Array *right)
if(neg){
npos = -npos;
for(int j = 0; j < npos*cellsize; j++)
- memcpy(result->rawdata + (to*cellsize+j)*datasizes[result->type],
- fill->rawdata, datasizes[result->type]);
+ memcpy(result->rawdata + (to*cellsize+j)*datasizes[GetType(result)],
+ fill->rawdata, datasizes[GetType(result)]);
}else{
for(int j = 0; j < npos; j++)
- memcpy(result->rawdata + (to+j)*cellsize*datasizes[result->type],
- right->rawdata + from*cellsize*datasizes[result->type],
- cellsize*datasizes[result->type]);
+ memcpy(result->rawdata + (to+j)*cellsize*datasizes[GetType(result)],
+ right->rawdata + from*cellsize*datasizes[GetType(result)],
+ cellsize*datasizes[GetType(result)]);
}
- if(result->type == AtypeArray)
+ if(GetType(result) == AtypeArray)
for(int j = 0; j < npos*cellsize; j++)
incarrayref(result->arraydata[to*cellsize+j]);
}
@@ -106,17 +106,17 @@ fnReplicateFirst(Array *left, Array *right)
Array *
fnExpandFirst(Array *left, Array *right)
{
- if(left->type != AtypeInt)
+ if(GetType(left) != AtypeInt)
throwerror(nil, EType);
- if(left->rank > 1)
+ if(GetRank(left) > 1)
throwerror(nil, ERank);
- right = right->rank == 0 ? fnRavel(right) : fnSame(right);
+ right = GetRank(right) == 0 ? fnRavel(right) : fnSame(right);
int npos = 0;
int nsize = 0;
int i;
- for(i = 0; i < left->size; i++){
+ for(i = 0; i < GetSize(left); i++){
if(left->intdata[i] > 0)
npos++;
else if(left->intdata[i] == 0)
@@ -129,10 +129,10 @@ fnExpandFirst(Array *left, Array *right)
if(right->shape[0] != 1 && right->shape[0] != npos)
throwerror(nil, ELength);
- vlong cellsize = right->shape[0] == 0 ? 1 : right->size / right->shape[0];
- Array *result = allocarray(right->type, right->rank, nsize * cellsize);
+ vlong cellsize = right->shape[0] == 0 ? 1 : GetSize(right) / right->shape[0];
+ Array *result = allocarray(GetType(right), GetRank(right), nsize * cellsize);
result->shape[0] = nsize;
- for(i = 1; i < result->rank; i++)
+ for(i = 1; i < GetRank(result); i++)
result->shape[i] = right->shape[i];
Array *fill = fillelement(right);
@@ -143,15 +143,15 @@ fnExpandFirst(Array *left, Array *right)
if(neg){
npos = -npos;
for(int j = 0; j < npos*cellsize; j++)
- memcpy(result->rawdata + (to*cellsize+j)*datasizes[result->type],
- fill->rawdata, datasizes[result->type]);
+ memcpy(result->rawdata + (to*cellsize+j)*datasizes[GetType(result)],
+ fill->rawdata, datasizes[GetType(result)]);
}else{
for(int j = 0; j < npos; j++)
- memcpy(result->rawdata + (to+j)*cellsize*datasizes[result->type],
- right->rawdata + from*cellsize*datasizes[result->type],
- cellsize*datasizes[result->type]);
+ memcpy(result->rawdata + (to+j)*cellsize*datasizes[GetType(result)],
+ right->rawdata + from*cellsize*datasizes[GetType(result)],
+ cellsize*datasizes[GetType(result)]);
}
- if(result->type == AtypeArray)
+ if(GetType(result) == AtypeArray)
for(int j = 0; j < npos*cellsize; j++)
incarrayref(result->arraydata[to*cellsize+j]);
if(right->shape[0] != 1 && !neg)
@@ -192,9 +192,9 @@ Array *
opReduceFirst(Datum *lefto, Array *left, Array *right)
{
if(left){
- if(left->type != AtypeInt)
+ if(GetType(left) != AtypeInt)
throwerror(nil, EType);
- if(left->size != 1)
+ if(GetSize(left) != 1)
throwerror(nil, ELength);
vlong winsize = left->intdata[0];
if(winsize > right->shape[0])
@@ -207,7 +207,7 @@ opReduceFirst(Datum *lefto, Array *left, Array *right)
return rundfn(code, lefto, nil, left, right);
}
- if(right->rank == 0)
+ if(GetRank(right) == 0)
return fnSame(right);
int n = right->shape[0];
@@ -215,20 +215,20 @@ opReduceFirst(Datum *lefto, Array *left, Array *right)
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++)
+ Array *result = allocarray(AtypeArray, GetRank(right) - 1, GetSize(right) / n);
+ for(int i = 0; i < GetRank(right)-1; i++)
result->shape[i] = right->shape[i+1];
- Array *index = allocarray(AtypeArray, 1, right->rank);
- index->shape[0] = right->rank;
+ Array *index = allocarray(AtypeArray, 1, GetRank(right));
+ index->shape[0] = GetRank(right);
Array *tmp = mkscalarint(n);
index->arraydata[0] = fnIndexGenerator(tmp);
freearray(tmp);
- for(int i = 1; i < index->size; i++)
+ for(int i = 1; i < GetSize(index); 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--){
+ for(int i = 0; i < GetSize(result); i++){
+ for(int j = GetSize(index) - 1; index->arraydata[j]->intdata[0] == io + right->shape[j]; j--){
index->arraydata[j]->intdata[0] = io;
index->arraydata[j-1]->intdata[0]++;
}
@@ -242,7 +242,7 @@ opReduceFirst(Datum *lefto, Array *left, Array *right)
freearray(argR);
}
freearray(vector);
- index->arraydata[index->size-1]->intdata[0]++;
+ index->arraydata[GetSize(index)-1]->intdata[0]++;
}
freearray(index);
@@ -255,12 +255,9 @@ opScanFirst(Datum *lefto, Array *left, Array *right)
if(left)
throwerror(L"f⍀ doesn't take a left argument", ESyntax);
- Array *result = allocarray(AtypeArray, right->rank, right->size);
- for(int i = 0; i < right->rank; i++)
- result->shape[i] = right->shape[i];
-
+ Array *result = duparrayshape(right, AtypeArray);
int n = result->shape[0];
- int m = result->size / n;
+ int m = GetSize(result) / n;
for(int i = 0; i < n; i++){
Array *len = mkscalarint(i + 1);
Array *index = fnIndexGenerator(len);
diff --git a/memory.c b/memory.c
index 33c30d7..8bca068 100644
--- a/memory.c
+++ b/memory.c
@@ -57,34 +57,33 @@ freearray(Array *a)
{
if(a == nil)
return;
+ if(a->refs == 0){
+ print("NEGATIVE REF COUNT (array)! %p\n", a);
+ threadexitsall(nil);
+ }
a->refs--;
if(a->refs == 0){
- if(a->type == AtypeArray)
- for(int i = 0; i < a->size; i++)
+ if(GetType(a) == AtypeArray)
+ for(int i = 0; i < GetSize(a); i++)
freearray(a->arraydata[i]);
free(a->shape);
free(a->rawdata);
free(a);
arrayalloccounts--;
- }else if(a->refs < 0){
- print("NEGATIVE REF COUNT (array)! %p\n", a);
- threadexitsall(nil);
}
-
}
Array *
allocarray(arrayDataType t, int rank, int size)
{
Array *a = emalloc(sizeof(Array));
- a->rank = rank;
- a->type = t;
- a->size = size;
- a->stranded = 0;
- a->shape = emalloc(sizeof(int) * rank);
+ SetRank(a, rank);
+ SetType(a, t);
+ SetSize(a, size);
+ SetStrand(a, 0);
+ a->shape = emalloc(sizeof(*a->shape) * rank);
a->rawdata = emalloc(datasizes[t] * size);
- a->type = t;
a->refs = 1;
arrayalloccounts++;
return a;
diff --git a/operators.c b/operators.c
index 336588a..73d5ec2 100644
--- a/operators.c
+++ b/operators.c
@@ -50,10 +50,10 @@ opEach(Datum *lefto, Array *left, Array *right)
rightarr = fnSame(right);
}
- Array *result = allocarray(AtypeArray, rightarr->rank, rightarr->size);
- for(i = 0; i < rightarr->rank; i++)
+ Array *result = allocarray(AtypeArray, GetRank(rightarr), GetSize(rightarr));
+ for(i = 0; i < GetRank(rightarr); i++)
result->shape[i] = rightarr->shape[i];
- for(i = 0; i < rightarr->size; i++){
+ for(i = 0; i < GetSize(rightarr); i++){
Array *elem1 = leftarr ? arrayitem(leftarr, i) : nil;
Array *elem2 = arrayitem(rightarr, i);
result->arraydata[i] = runfunc(lefto->func, elem1, elem2);
@@ -109,24 +109,24 @@ opOuterProduct(Datum *lefto, Array *left, Array *right)
throwerror(nil, EType);
int i;
- int rank = left->rank + right->rank;
+ int rank = GetRank(left) + GetRank(right);
int size = 1;
int *shape = emalloc(sizeof(int) * rank);
- for(i = 0; i < left->rank; i++){
+ for(i = 0; i < GetRank(left); i++){
shape[i] = left->shape[i];
size *= left->shape[i];
}
- for(i = 0; i < right->rank; i++){
- shape[i+left->rank] = right->shape[i];
+ for(i = 0; i < GetRank(right); i++){
+ shape[i+GetRank(left)] = right->shape[i];
size *= right->shape[i];
}
Array *result = allocarray(AtypeArray, rank, size);
for(i = 0; i < rank; i++)
result->shape[i] = shape[i];
- for(int leftindex = 0; leftindex < left->size; leftindex++){
- for(int rightindex = 0; rightindex < right->size; rightindex++){
- i = leftindex * right->size + rightindex;
+ for(int leftindex = 0; leftindex < GetSize(left); leftindex++){
+ for(int rightindex = 0; rightindex < GetSize(right); rightindex++){
+ i = leftindex * GetSize(right) + rightindex;
Array *leftitem = arrayitem(left, leftindex);
Array *rightitem = arrayitem(right, rightindex);
result->arraydata[i] = runfunc(lefto->func, leftitem, rightitem);
@@ -155,9 +155,9 @@ opReceive(Datum *lefto, Array *left, Array *right)
{
if(lefto->tag != FunctionTag)
throwerror(nil, EType);
- if(right->type != AtypeInt)
+ if(GetType(right) != AtypeInt)
throwerror(nil, EType);
- if(right->size != 1)
+ if(GetSize(right) != 1)
throwerror(nil, ELength);
USED(left);
return messagerecv(lefto->func, right->intdata[0]);
@@ -176,7 +176,7 @@ opPower(Datum *lefto, Datum *righto, Array *left, Array *right)
else
code = L"next←⍶⍵ ⋄ next⍹⍵:⍵ ⋄ ∇next";
}else if(righto->tag == ArrayTag){
- if(righto->array->type != AtypeInt || righto->array->rank != 0 || righto->array->size != 1)
+ if(GetType(righto->array) != AtypeInt || GetRank(righto->array) != 0 || GetSize(righto->array) != 1)
throwerror(L"right operand to ⍣", EDomain);
vlong times = righto->array->intdata[0];
if(times < 0){
@@ -206,7 +206,7 @@ opInnerProduct(Datum *lefto, Datum *righto, Array *left, Array *right)
if(lefto->tag != FunctionTag || righto->tag != FunctionTag)
throwerror(nil, EType);
- if(left->rank > 0 && right->rank > 0 && left->shape[left->rank-1] != right->shape[0])
+ if(GetRank(left) > 0 && GetRank(right) > 0 && left->shape[GetRank(left)-1] != right->shape[0])
throwerror(nil, ELength);
return rundfn(L"↑(↓⍺)(⍶/⍹¨)⌾⍉↓⍉⍵", lefto, righto, left, right);
@@ -246,14 +246,14 @@ opAtop(Datum *lefto, Datum *righto, Array *left, Array *right)
return result;
}else if(lefto->tag == FunctionTag && righto->tag == ArrayTag){
Array *ranks = righto->array;
- if(ranks->rank > 1)
+ if(GetRank(ranks) > 1)
throwerror(nil, ERank);
- if(ranks->type != AtypeInt)
+ if(GetType(ranks) != AtypeInt)
throwerror(nil, EType);
- if(ranks->size < 1 || ranks->size > 3)
+ if(GetSize(ranks) < 1 || GetSize(ranks) > 3)
throwerror(nil, ELength);
int p,q,r;
- switch(ranks->size){
+ switch(GetSize(ranks)){
case 1: p = q = r = ranks->intdata[0]; break;
case 2:
q = ranks->intdata[0];
@@ -270,16 +270,16 @@ opAtop(Datum *lefto, Datum *righto, Array *left, Array *right)
/* "Normalize" the ranks (remove negatives, and ranks above the array's ranks */
if(left){
- q = q < 0 ? left->rank + q : q;
+ q = q < 0 ? GetRank(left) + q : q;
q = q < 0 ? 0 : q;
- q = q > left->rank ? left->rank : q;
+ q = q > GetRank(left) ? GetRank(left) : q;
}
- p = p < 0 ? right->rank + p : p;
+ p = p < 0 ? GetRank(right) + p : p;
p = p < 0 ? 0 : p;
- p = p > right->rank ? right->rank : p;
- r = r < 0 ? right->rank + r : r;
+ p = p > GetRank(right) ? GetRank(right) : p;
+ r = r < 0 ? GetRank(right) + r : r;
r = r < 0 ? 0 : r;
- r = r > right->rank ? right->rank : r;
+ r = r > GetRank(right) ? GetRank(right) : r;
Array *result;
if(left){
@@ -293,7 +293,7 @@ opAtop(Datum *lefto, Datum *righto, Array *left, Array *right)
freearray(lefts);
freearray(rights);
}else{
- if(right->rank == p)
+ if(GetRank(right) == p)
result = runfunc(lefto->func, nil, right);
else{
Array *cellrank = mkscalarint(p);
diff --git a/print.c b/print.c
index 232fc54..075d372 100644
--- a/print.c
+++ b/print.c
@@ -48,28 +48,28 @@ ppdatums(Datum **ds, int n)
Rune *
pparray(Array *a)
{
- Rune **elemstrs = emalloc(sizeof(Rune *) * a->size);
+ Rune **elemstrs = emalloc(sizeof(Rune *) * GetSize(a));
int rowcount = 1;
- if(a->rank > 0){
- for(int i = 0; i < a->rank-1; i++)
+ if(GetRank(a) > 0){
+ for(int i = 0; i < GetRank(a)-1; i++)
rowcount *= a->shape[i];
}
Rune **rowstrs = emallocz(sizeof(Rune *) * rowcount, 1);
int boxing = !simplearray(a);
- char *align = a->type == AtypeArray ? "-" : "";
- for(int i = 0; i < a->size; i++){
- if(a->type == AtypeArray){
+ char *align = GetType(a) == AtypeArray ? "-" : "";
+ for(int i = 0; i < GetSize(a); i++){
+ if(GetType(a) == AtypeArray){
Rune *arrstr = pparray(a->arraydata[i]);
elemstrs[i] = runesmprint("%S", arrstr);
free(arrstr);
}else{
Array *e = arrayitem(a, i); /* a scalar */
- if(e->type == AtypeInt)
+ if(GetType(e) == AtypeInt)
elemstrs[i] = runesmprint("%lld", e->intdata[0]);
- else if(e->type == AtypeRune)
+ else if(GetType(e) == AtypeRune)
elemstrs[i] = runesmprint("%C", e->runedata[0]);
- else if(e->type == AtypeFloat){
+ else if(GetType(e) == AtypeFloat){
char *fmt = smprint("%%.%df", printprecision);
elemstrs[i] = runesmprint(fmt, e->floatdata[0]);
free(fmt);
@@ -82,17 +82,17 @@ pparray(Array *a)
}
}
- if(elemstrs[i][0] == '-' && (e->type == AtypeInt || e->type == AtypeFloat))
+ if(elemstrs[i][0] == '-' && (GetType(e) == AtypeInt || GetType(e) == AtypeFloat))
elemstrs[i][0] = L'¯';
freearray(e);
}
}
- int lastdim = a->rank ? a->shape[a->rank-1] : 1;
+ int lastdim = GetRank(a) ? a->shape[GetRank(a)-1] : 1;
int *widths = emallocz(sizeof(int) * lastdim, 1);
int *heights = emallocz(sizeof(int) * rowcount, 1);
- for(int i = 0; i < a->size; i++){
+ for(int i = 0; i < GetSize(a); i++){
int w,h;
strdims(elemstrs[i], &w, &h);
if(w > widths[i%lastdim])
@@ -119,7 +119,7 @@ pparray(Array *a)
Rune *spacing;
if(boxing)
spacing = L"│";
- else if(x == lastdim - 1 || a->type == AtypeRune)
+ else if(x == lastdim - 1 || GetType(a) == AtypeRune)
spacing = L"";
else
spacing = L" ";
@@ -148,8 +148,8 @@ pparray(Array *a)
res = printborder(res, widths, lastdim, 0);
int j = 1;
int blanks = 0;
- for(int dim = 0; dim < a->rank - 1 && i+1 != a->size; dim++){
- j *= a->shape[a->rank-dim-2];
+ for(int dim = 0; dim < GetRank(a) - 1 && i+1 != GetSize(a); dim++){
+ j *= a->shape[GetRank(a)-dim-2];
if(i%j == 0)
blanks++;
}
diff --git a/quadnames.c b/quadnames.c
index 209c339..d711ebb 100644
--- a/quadnames.c
+++ b/quadnames.c
@@ -175,7 +175,7 @@ getio(void)
void
setio(Datum *new)
{
- if(new->tag != ArrayTag || new->array->rank != 0 || new->array->type != AtypeInt || (new->array->intdata[0] != 0 && new->array->intdata[0] != 1))
+ if(new->tag != ArrayTag || GetRank(new->array) != 0 || GetType(new->array) != AtypeInt || (new->array->intdata[0] != 0 && new->array->intdata[0] != 1))
throwerror(nil, EDomain);
else
globalIOset(new->array->intdata[0]);
@@ -193,7 +193,7 @@ getpp(void)
void
setpp(Datum *new)
{
- if(new->tag != ArrayTag || new->array->rank != 0 || new->array->type != AtypeInt || new->array->intdata[0] < 0)
+ if(new->tag != ArrayTag || GetRank(new->array) != 0 || GetType(new->array) != AtypeInt || new->array->intdata[0] < 0)
throwerror(nil, EDomain);
else
printprecision = new->array->intdata[0];
@@ -211,7 +211,7 @@ getdiv(void)
void
setdiv(Datum *new)
{
- if(new->tag != ArrayTag || new->array->rank != 0 || new->array->type != AtypeInt || (new->array->intdata[0] != 0 && new->array->intdata[0] != 1))
+ if(new->tag != ArrayTag || GetRank(new->array) != 0 || GetType(new->array) != AtypeInt || (new->array->intdata[0] != 0 && new->array->intdata[0] != 1))
throwerror(nil, EDomain);
else
globalDIVset(new->array->intdata[0]);
@@ -249,7 +249,7 @@ getself(void)
Array *
runfile(Array *a)
{
- if(a->type != AtypeRune || a->rank > 1){
+ if(GetType(a) != AtypeRune || GetRank(a) > 1){
return mkscalarint(0);
}
@@ -274,9 +274,9 @@ runfile(Array *a)
Array *
quadthrow1(Array *code)
{
- if(code->type != AtypeInt)
+ if(GetType(code) != AtypeInt)
throwerror(nil, EType);
- if(code->size != 1)
+ if(GetSize(code) != 1)
throwerror(nil, ELength);
throwerror(nil, code->intdata[0]);
return nil;
@@ -285,11 +285,11 @@ quadthrow1(Array *code)
Array *
quadthrow2(Array *msg, Array *code)
{
- if(code->type != AtypeInt || msg->type != AtypeRune)
+ if(GetType(code) != AtypeInt || GetType(msg) != AtypeRune)
throwerror(nil, EType);
- if(code->size != 1)
+ if(GetSize(code) != 1)
throwerror(nil, ELength);
- if(msg->rank > 1)
+ if(GetRank(msg) > 1)
throwerror(nil, ERank);
throwerror(pparray(msg), code->intdata[0]);
return nil;
@@ -299,7 +299,7 @@ quadthrow2(Array *msg, Array *code)
Array *
quadinfo(Array *a)
{
- if(a->type != AtypeRune)
+ if(GetType(a) != AtypeRune)
throwerror(nil, EType);
Rune *code = pparray(a);
Datum *res = evalline(code, nil, 0);
@@ -307,7 +307,7 @@ quadinfo(Array *a)
switch(res->tag){
case ArrayTag:{
char *typestring = "?";
- switch(res->array->type){
+ switch(GetType(res->array)){
case AtypeInt: typestring = "int"; break;
case AtypeFloat: typestring = "float"; break;
case AtypeRune: typestring = "rune"; break;
@@ -340,13 +340,13 @@ Array *
quaducs(Array *a)
{
Array *res = nil;
- if(a->type == AtypeInt){
+ if(GetType(a) == AtypeInt){
res = duparrayshape(a, AtypeRune);
- for(int i = 0; i < res->size; i++)
+ for(int i = 0; i < GetSize(res); i++)
res->runedata[i] = a->intdata[i];
- }else if(a->type == AtypeRune){
+ }else if(GetType(a) == AtypeRune){
res = duparrayshape(a, AtypeInt);
- for(int i = 0; i < res->size; i++)
+ for(int i = 0; i < GetSize(res); i++)
res->intdata[i] = a->runedata[i];
}else
throwerror(nil, EType);
@@ -358,14 +358,14 @@ Array *
quaddl(Array *a)
{
/* TODO: return amount of seconds slept */
- if(a->size != 1)
+ if(GetSize(a) != 1)
throwerror(nil, ELength);
- if(a->type != AtypeInt && a->type != AtypeFloat)
+ if(GetType(a) != AtypeInt && GetType(a) != AtypeFloat)
throwerror(nil, EType);
- if(a->type == AtypeInt && a->intdata[0] >= 0)
+ if(GetType(a) == AtypeInt && a->intdata[0] >= 0)
sleep(a->intdata[0] * 1000);
- else if(a->type == AtypeFloat && a->floatdata[0] >= 0)
+ else if(GetType(a) == AtypeFloat && a->floatdata[0] >= 0)
sleep(a->floatdata[0] * 1000);
else
throwerror(nil, EDomain);