diff options
-rw-r--r-- | apl9.h | 26 | ||||
-rw-r--r-- | array.c | 124 | ||||
-rw-r--r-- | eval.c | 22 | ||||
-rw-r--r-- | functions.c | 522 | ||||
-rw-r--r-- | hybrids.c | 89 | ||||
-rw-r--r-- | memory.c | 23 | ||||
-rw-r--r-- | operators.c | 50 | ||||
-rw-r--r-- | print.c | 30 | ||||
-rw-r--r-- | quadnames.c | 38 |
9 files changed, 466 insertions, 458 deletions
@@ -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 @@ -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; @@ -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); @@ -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); @@ -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); @@ -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); |