diff --git a/src/array.c b/src/array.c index d36e1ba56ef69a5caf929d28d15b1c9ec1c2fd15..3f299e7ff08d999557166b9e2e142fd54f32446e 100644 --- a/src/array.c +++ b/src/array.c @@ -1548,3 +1548,83 @@ void count_memory_in_arrays(INT32 *num_, INT32 *size_) *num_=num; *size_=size; } + +struct array *explode_array(struct array *a, struct array *b) +{ + INT32 e,d,q,start; + struct array *tmp; + + q=start=0; + push_array(a); /* Save us from destructive slice_arrays */ + a->refs++; + if(b->size) + { + for(e=0;e<a->size - b->size;e++) + { + for(d=0;d<b->size;d++) + { + if(!is_eq(ITEM(a)+(e+d),ITEM(b)+d)) + break; + } + if(d==b->size) + { + check_stack(1); + push_array(slice_array(a, start, e)); + q++; + e+=b->size-1; + start=e+1; + } + } + check_stack(1); + push_array(slice_array(a, start, a->size)); + q++; + }else{ + check_stack(a->size); + for(e=0;e<a->size;e++) push_array(slice_array(a, e, e+1)); + q=a->size; + } + tmp=aggregate_array(q); + if(tmp->size) tmp->type_field=BIT_ARRAY; + pop_stack(); + return tmp; +} + +struct array *implode_array(struct array *a, struct array *b) +{ + INT32 e,size; + struct array *ret; + size=0; + for(e=0;e<a->size;e++) + { + if(ITEM(a)[e].type!=T_ARRAY) + error("Implode array contains non-arrays.\n"); + size+=ITEM(a)[e].u.array->size; + } + + ret=allocate_array((a->size -1) * b->size + size); + size=0; + ret->type_field=0; + for(e=0;e<a->size;e++) + { + if(e) + { + ret->type_field|=b->type_field; + assign_svalues_no_free(ITEM(ret)+size, + ITEM(b), + b->size, + b->type_field); + size+=b->size; + } + ret->type_field|=ITEM(a)[e].u.array->type_field; + assign_svalues_no_free(ITEM(ret)+size, + ITEM(ITEM(a)[e].u.array), + ITEM(a)[e].u.array->size, + ITEM(a)[e].u.array->type_field); + size+=ITEM(a)[e].u.array->size; + } +#ifdef DEBUG + if(size != ret->size) + fatal("Implode_array failed miserably\n"); +#endif + return ret; +} diff --git a/src/array.h b/src/array.h index 9300beb2564666f43b207a2496701b3e0ccb96b9..70ca9c3a910476670d95bc6a792f33ce64d17c8f 100644 --- a/src/array.h +++ b/src/array.h @@ -132,6 +132,8 @@ void debug_dump_type_field(TYPE_FIELD t); void debug_dump_array(struct array *a); void zap_all_arrays(); void count_memory_in_arrays(INT32 *num_, INT32 *size_); +struct array *explode_array(struct array *a, struct array *b); +struct array *implode_array(struct array *a, struct array *b); /* Prototypes end here */ diff --git a/src/operators.c b/src/operators.c index 23a7985c6ad2b9ff057823572c3db22b2631d888..42f525efeb78189bcfeb8d2aa5919fc6f0c3bde1 100644 --- a/src/operators.c +++ b/src/operators.c @@ -5,7 +5,7 @@ \*/ #include <math.h> #include "global.h" -RCSID("$Id: operators.c,v 1.8 1997/02/13 02:38:58 nisse Exp $"); +RCSID("$Id: operators.c,v 1.9 1997/02/19 05:04:19 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "multiset.h" @@ -834,6 +834,15 @@ void o_multiply() return; } + case TWO_TYPES(T_ARRAY,T_ARRAY): + { + struct array *ret; + ret=implode_array(sp[-2].u.array, sp[-1].u.array); + pop_n_elems(2); + push_array(ret); + break; + } + case TWO_TYPES(T_FLOAT,T_FLOAT): sp--; sp[-1].u.float_number *= sp[0].u.float_number; @@ -927,6 +936,14 @@ void o_divide() return; } + case T_ARRAY: + { + struct array *ret=explode_array(sp[-2].u.array, sp[-1].u.array); + pop_n_elems(2); + push_array(ret); + return; + } + case T_FLOAT: if(sp[-1].u.float_number == 0.0) error("Division by zero.\n"); @@ -1252,9 +1269,9 @@ void init_operators() add_efun2("`<<",f_lsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_lsh); add_efun2("`>>",f_rsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_rsh); - add_efun2("`*",f_multiply,"function(object,mixed...:mixed)|function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply); + add_efun2("`*",f_multiply,"function(array(array),array:array)|function(object,mixed...:mixed)|function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply); - add_efun2("`/",f_divide,"function(object,mixed:mixed)|function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",OPT_TRY_OPTIMIZE,0,generate_divide); + add_efun2("`/",f_divide,"function(array,array:array(array))|function(object,mixed:mixed)|function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",OPT_TRY_OPTIMIZE,0,generate_divide); add_efun2("`%",f_mod,"function(object,mixed:mixed)|function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",OPT_TRY_OPTIMIZE,0,generate_mod);