#include "global.h" #include "array.h" #include "interpret.h" #include "list.h" #include "object.h" #include "stralloc.h" #include "mapping.h" void free_list(struct vector *v) { free_vector(v); } struct vector *allocate_list(struct vector *v) { struct vector *m; m = allocate_array_no_init(1,0); m->item[0].u.vec = v; m->item[0].type = T_ALIST_PART; return m; } struct vector *mklist(struct vector *v) { v=allocate_list(slice_array(v,0,v->size)); order_alist(v); return v; } void mutilate_mapping(struct vector *a,int ap,struct vector *b,int bp) { assign_svalue_raw(&(a->item[0].u.vec->item[ap]),&(b->item[0].u.vec->item[bp])); assign_svalue_raw(&(a->item[1].u.vec->item[ap]),&(b->item[1].u.vec->item[bp])); } void list_assign(struct vector *a,int ap,struct vector *b,int bp) { assign_svalue_raw(&(a->item[0].u.vec->item[ap]),&(b->item[0].u.vec->item[bp])); } void array_assign(struct vector *a,int ap,struct vector *b,int bp) { assign_svalue_raw(&(a->item[ap]),&(b->item[0].u.vec->item[bp])); } /* * This function handles or, xor, and, sub on lists, mapping and arrays * /Profezzorn */ struct vector *do_array_surgery( struct vector *a, struct vector *b, int op, int type ) { register int ap,bp,d,num; int asize,bsize; struct vector *ret; struct svalue *ap2,*bp2; struct svalue *ap3,*bp3; void (*assignfunc)(struct vector *,int,struct vector *,int); asize=bsize=0; ap2=bp2=0; assignfunc=0; /* make gcc happy */ switch(type) { case T_POINTER: /* All surgery on arrays return alists */ { struct vector *tt; tt=allocate_array_no_init(1,0); tt->item[0].type=T_POINTER; tt->item[0].u.vec=slice_array(a,0,a->size-1); order_alist(a=tt); tt=allocate_array_no_init(1,0); tt->item[0].type=T_POINTER; tt->item[0].u.vec=slice_array(b,0,b->size-1); order_alist(b=tt); asize=a->item[0].u.vec->size; bsize=b->item[0].u.vec->size; ap2=& a->item[0].u.vec->item[0]; bp2=& b->item[0].u.vec->item[0]; assignfunc=&array_assign; } break; case T_LIST: asize=a->item[0].u.vec->size; bsize=b->item[0].u.vec->size; ap2=& a->item[0].u.vec->item[0]; bp2=& b->item[0].u.vec->item[0]; assignfunc=&list_assign; break; case T_MAPPING: asize=a->item[0].u.vec->size; bsize=b->item[0].u.vec->size; ap2=& a->item[0].u.vec->item[0]; bp2=& b->item[0].u.vec->item[0]; assignfunc=&mutilate_mapping; break; } num=ap=bp=0; ap3=ap2; bp3=bp2; while(ap<asize && bp<bsize) { d=alist_cmp(ap2,bp2); if(!d) d=op & 7; else if(d<0) d=op>>4 & 7; else d=op>>8 & 7; switch(d) { case GETA: num++; case NOTA: ap++; ap2++; break; case GETB: num++; case NOTB: bp++; bp2++; break; case BOTH: num++; case EITHER: num++; case NONE: ap++; ap2++; bp++; bp2++; } } if(OPER_A_TAKE==(op & 0x0f0) ) num += asize-ap; if(OPER_B_TAKE==(op & 0xf00) ) num += bsize-bp; if(type==T_MAPPING) ret=allocate_mapping(allocate_array_no_init(num,0),allocate_array_no_init(num,0)); else if(type==T_LIST) ret=allocate_list(allocate_array_no_init(num,0)); else ret=allocate_array_no_init(num,0); num=ap=bp=0; ap2=ap3; bp2=bp3; while(ap<asize && bp<bsize) { d=alist_cmp(ap2,bp2); if(!d) d=op & 7; else if(d<0) d=op>>4 & 7; else d=op>>8 & 7; switch(d) { case GETA: assignfunc(ret,num++,a,ap); case NOTA: ap++; ap2++; break; case GETB: assignfunc(ret,num++,b,bp); case NOTB: bp++; bp2++; break; case BOTH: assignfunc(ret,num++,a,ap); case EITHER: assignfunc(ret,num++,b,bp); case NONE: bp++; ap++; bp2++; ap2++; } } if(OPER_A_TAKE==(op & 0x0f0)) while(ap<asize) assignfunc(ret,num++,a,ap++); if(OPER_B_TAKE==(op & 0xf00)) while(bp<bsize) assignfunc(ret,num++,b,bp++); if(type==T_POINTER) { free_vector(a); free_vector(b); } return ret; } /* Ha ha Now I can clean the shit out in a quick manner ! */ struct vector *cleanup_map(struct vector *map) { int size,e,newsize; struct svalue *i,*v,*ii,*vv,*def; struct vector *indices,*values,*ret; check_alist_for_destruct(map); size=map->item[0].u.vec->size; def=& map->item[2]; newsize=0; v=& map->item[1].u.vec->item[0]; for(e=0;e<size;e++,v++) if(alist_cmp(def,v)) newsize++; indices=allocate_array_no_init(newsize,0); values=allocate_array_no_init(newsize,0); i=& map->item[0].u.vec->item[0]; v=& map->item[1].u.vec->item[0]; ii=& indices->item[0]; vv=& values ->item[0]; for(e=0;e<size;e++) { if(alist_cmp(def,v)) { assign_svalue_raw(ii++,i); assign_svalue_raw(vv++,v); } i++; v++; } ret=allocate_mapping(indices,values); assign_svalue(map->item+2,ret->item+2); return ret; }