diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-26 09:40:50 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-26 09:40:50 +0000 |
commit | bcaf7f25f42b21067a26895e097ada73765ba7d5 (patch) | |
tree | ccfb887cf08619c17b3afa3b517bfc3dcdfa18ad /array.c | |
parent | 57a86f761605b6261d1045558c9cb7c83d723b60 (diff) |
Implement a new "mixed" type which can be either of the three scalar types: int, float, rune. This allows scalar arrays with mixed scalar types
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 92 |
1 files changed, 71 insertions, 21 deletions
@@ -10,6 +10,7 @@ int datasizes[] = { [AtypeInt] = sizeof(vlong), [AtypeFloat] = sizeof(double), [AtypeRune] = sizeof(Rune), + [AtypeMixed] = sizeof(Mixed), [AtypeArray] = sizeof(Array *) }; @@ -63,6 +64,7 @@ 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; return b; } @@ -174,13 +176,21 @@ arrayitem(Array *a, int index) case AtypeRune: res = mkscalarrune(a->runedata[index]); break; + case AtypeMixed: + switch(a->mixeddata[index].type){ + case AtypeInt: res = mkscalarint(a->mixeddata[index].i); break; + case AtypeFloat: res = mkscalarfloat(a->mixeddata[index].f); break; + case AtypeRune: res = mkscalarrune(a->mixeddata[index].r); break; + default: + throwerror(L"Unhandled case in arrayitem", ENotImplemented); + } + break; case AtypeArray: res = a->arraydata[index]; incref(res); break; default: - print("Unhandled case in arrayitem()\n"); - exits(nil); + throwerror(L"Unhandled case in arrayitem", ENotImplemented); } return res; } @@ -189,30 +199,40 @@ Array * simplifyarray(Array *a) { /* simplify an array if possible. */ - if(a->type != AtypeArray || a->size == 0) + if((a->type != AtypeArray && a->type != AtypeMixed) || a->size == 0) return fnSame(a); - int type = a->arraydata[0]->type; + int nested = a->type == AtypeArray; + int type = nested ? a->arraydata[0]->type : 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 = a->arraydata[i]->type; + int t = nested ? a->arraydata[i]->type : a->mixeddata[i].type; canfloat = canfloat && (t == AtypeFloat || t == AtypeInt); sametype = sametype && (t == type); - if(a->arraydata[i]->rank != 0) + canmix = canmix && (t != AtypeArray); + if(nested && a->arraydata[i]->rank != 0) return fnSame(a); /* cannot be simplified */ } if(sametype){ - Array *b = allocarray(type, a->rank, a->size); - b->stranded = a->stranded; - for(i = 0; i < a->rank; i++) - b->shape[i] = a->shape[i]; + Array *b = duparrayshape(a, type); for(i = 0; i < a->size; i++){ - memcpy(b->rawdata + i * datasizes[type], a->arraydata[i]->rawdata, datasizes[type]); - if(b->type == AtypeArray) - incref(b->arraydata[i]); + if(nested){ + memcpy(b->rawdata + i * datasizes[type], a->arraydata[i]->rawdata, datasizes[type]); + if(b->type == AtypeArray) + incref(b->arraydata[i]); + }else{ + switch(b->type){ + 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; + default: + throwerror(L"Missing case in simplifyarray", ENotImplemented); + } + } } if(b->type == AtypeArray){ Array *tmp = b; @@ -221,15 +241,32 @@ simplifyarray(Array *a) } return b; }else if(canfloat){ - Array *b = allocarray(AtypeFloat, a->rank, a->size); - b->stranded = a->stranded; - for(i = 0; i < a->rank; i++) - b->shape[i] = a->shape[i]; + Array *b = duparrayshape(a, AtypeFloat); for(i = 0; i < a->size; i++){ - if(a->arraydata[i]->type == AtypeFloat) - b->floatdata[i] = a->arraydata[i]->floatdata[0]; - else - b->floatdata[i] = a->arraydata[i]->intdata[0]; + if(nested){ + if(a->arraydata[i]->type == AtypeFloat) + b->floatdata[i] = a->arraydata[i]->floatdata[0]; + else + b->floatdata[i] = a->arraydata[i]->intdata[0]; + }else{ + if(a->mixeddata[i].type == AtypeFloat) + b->floatdata[i] = a->mixeddata[i].f; + else + b->floatdata[i] = a->mixeddata[i].i; + } + } + 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; + 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; + case AtypeRune: b->mixeddata[i].r = a->arraydata[i]->runedata[0]; break; + default: + throwerror(L"Missing case in simplifyarray", ENotImplemented); + } } return b; }else @@ -304,4 +341,17 @@ fillelement(Array *a) exits(nil); return 0; } +} + +uvlong +arrayspaceused(Array *a) +{ + uvlong size = 0; + size += sizeof(*a); + size += sizeof(int) * a->rank; + size += datasizes[a->type] * a->size; + + for(int i = 0; i < a->size && a->type == AtypeArray; i++) + size += arrayspaceused(a->arraydata[i]); + return size; }
\ No newline at end of file |