summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'array.c')
-rw-r--r--array.c92
1 files changed, 71 insertions, 21 deletions
diff --git a/array.c b/array.c
index b6bc87b..1ae2125 100644
--- a/array.c
+++ b/array.c
@@ -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