pike.git/
src/
operators.c
Branch:
Tag:
Non-build tags
All tags
No tags
1998-02-20
1998-02-20 01:00:42 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>
1b6166c88143da3e39d08243fbd44fc15968f2ee (
258
lines) (+
254
/-
4
)
[
Show
|
Annotate
]
Branch:
7.9
new operators {array,string}*int and array,string/{int,float}
Rev: src/operators.c:1.24
5:
\*/ #include <math.h> #include "global.h"
-
RCSID("$Id: operators.c,v 1.
23
1998/
01
/
26
19
:
59
:
57
hubbe Exp $");
+
RCSID("$Id: operators.c,v 1.
24
1998/
02
/
20
01
:
00
:
42
hubbe Exp $");
#include "interpret.h" #include "svalue.h" #include "multiset.h"
936:
{ switch(TWO_TYPES(sp[-2].type,sp[-1].type)) {
+
case TWO_TYPES(T_ARRAY, T_INT):
+
{
+
struct array *ret;
+
struct svalue *pos;
+
INT32 e;
+
if(sp[-1].u.integer < 0)
+
error("Cannot multiply array by negative number.\n");
+
ret=allocate_array(sp[-2].u.array->size * sp[-1].u.integer);
+
pos=ret->item;
+
for(e=0;e<sp[-1].u.integer;e++,pos+=sp[-2].u.array->size)
+
assign_svalues_no_free(pos,
+
sp[-2].u.array->item,
+
sp[-2].u.array->size,
+
sp[-2].u.array->type_field);
+
ret->type_field=sp[-2].u.array->type_field;
+
pop_n_elems(2);
+
push_array(ret);
+
return;
+
}
+
case TWO_TYPES(T_STRING, T_INT):
+
{
+
struct pike_string *ret;
+
char *pos;
+
INT32 e;
+
if(sp[-1].u.integer < 0)
+
error("Cannot multiply string by negative number.\n");
+
ret=begin_shared_string(sp[-2].u.string->len * sp[-1].u.integer);
+
pos=ret->str;
+
for(e=0;e<sp[-1].u.integer;e++,pos+=sp[-2].u.string->len)
+
MEMCPY(pos,sp[-2].u.string->str,sp[-2].u.string->len);
+
pop_n_elems(2);
+
push_string(end_shared_string(ret));
+
return;
+
}
+
case TWO_TYPES(T_ARRAY,T_STRING): { struct pike_string *ret;
954:
ret=implode_array(sp[-2].u.array, sp[-1].u.array); pop_n_elems(2); push_array(ret);
-
break
;
+
return
;
} case TWO_TYPES(T_FLOAT,T_FLOAT):
1028:
{ if(call_lfun(LFUN_DIVIDE, LFUN_RDIVIDE)) return;
+
+
switch(TWO_TYPES(sp[-2].type,sp[-1].type))
+
{
+
case TWO_TYPES(T_STRING,T_INT):
+
{
+
struct array *a;
+
char *pos=sp[-2].u.string->str;
+
INT32 size,e,len;
+
+
len=sp[-1].u.integer;
+
if(!len)
+
error("Division by zero.\n");
+
+
size=sp[-2].u.string->len / len;
+
if(len<0)
+
{
+
len=-len;
+
pos+=size % len;
+
}
+
a=allocate_array(size);
+
for(e=0;e<size;e++)
+
{
+
a->item[e].u.string=make_shared_binary_string(pos,len);
+
a->item[e].type=T_STRING;
+
pos+=len;
+
}
+
a->type_field=BIT_STRING;
+
pop_n_elems(2);
+
push_array(a);
+
return;
+
}
+
+
case TWO_TYPES(T_STRING,T_FLOAT):
+
{
+
struct array *a;
+
INT32 last,pos,e,size;
+
double len;
+
+
len=sp[-1].u.float_number;
+
if(len==0.0)
+
error("Division by zero.\n");
+
+
if(len<0)
+
{
+
len=-len;
+
size=(INT32)ceil( ((double)sp[-2].u.string->len) / len);
+
a=allocate_array(size);
+
+
for(last=sp[-2].u.string->len,e=0;e<size;e++)
+
{
+
pos=sp[-2].u.string->len - (INT32)((e+1)*len);
+
a->item[e].u.string=make_shared_binary_string(
+
sp[-2].u.string->str + pos,
+
last-pos);
+
last=pos;
+
}
+
pos=0;
+
a->item[e].u.string=make_shared_binary_string(
+
sp[-2].u.string->str + pos,
+
last-pos);
+
}else{
+
size=(INT32)ceil( ((double)sp[-2].u.string->len) / len);
+
a=allocate_array(size);
+
+
for(last=0,e=0;e<size;e++)
+
{
+
pos=(INT32)((e+1)*len);
+
a->item[e].u.string=make_shared_binary_string(
+
sp[-2].u.string->str + last,
+
pos-last);
+
last=pos;
+
}
+
pos=sp[2].u.string->len;
+
a->item[e].u.string=make_shared_binary_string(
+
sp[-2].u.string->str + last,
+
pos-last);
+
}
+
a->type_field=BIT_STRING;
+
pop_n_elems(2);
+
push_array(a);
+
break;
+
}
+
+
+
case TWO_TYPES(T_ARRAY, T_INT):
+
{
+
struct array *a;
+
INT32 size,e,len,pos=0;
+
+
len=sp[-1].u.integer;
+
if(!len)
+
error("Division by zero.\n");
+
+
size=sp[-2].u.array->size / len;
+
if(len<0)
+
{
+
len=-len;
+
pos+=size % len;
+
}
+
a=allocate_array(size);
+
for(e=0;e<size;e++)
+
{
+
a->item[e].u.array=friendly_slice_array(sp[-2].u.array,
+
pos,
+
pos+len);
+
a->item[e].type=T_ARRAY;
+
pos+=len;
+
}
+
a->type_field=BIT_ARRAY;
+
pop_n_elems(2);
+
push_array(a);
+
return;
+
}
+
+
case TWO_TYPES(T_ARRAY,T_FLOAT):
+
{
+
struct array *a;
+
INT32 last,pos,e,size;
+
double len;
+
+
len=sp[-1].u.float_number;
+
if(len==0.0)
+
error("Division by zero.\n");
+
+
if(len<0)
+
{
+
len=-len;
+
size=(INT32)ceil( ((double)sp[-2].u.array->size) / len);
+
a=allocate_array(size);
+
+
for(last=sp[-2].u.array->size,e=0;e<size;e++)
+
{
+
pos=sp[-2].u.array->size - (INT32)((e+1)*len);
+
a->item[e].u.array=friendly_slice_array(sp[-2].u.array,
+
pos,
+
last);
+
last=pos;
+
}
+
a->item[e].u.array=slice_array(sp[-2].u.array,
+
0,
+
last);
+
}else{
+
size=(INT32)ceil( ((double)sp[-2].u.array->size) / len);
+
a=allocate_array(size);
+
+
for(last=0,e=0;e<size;e++)
+
{
+
pos=(INT32)((e+1)*len);
+
a->item[e].u.array=friendly_slice_array(sp[-2].u.array,
+
last,
+
pos);
+
last=pos;
+
}
+
a->item[e].u.array=slice_array(sp[-2].u.array,
+
last,
+
sp[2].u.array->size);
+
}
+
a->type_field=BIT_ARRAY;
+
pop_n_elems(2);
+
push_array(a);
+
break;
+
}
+
}
+
error("Division on different types.\n"); }
1111:
if(call_lfun(LFUN_MOD, LFUN_RMOD)) return;
+
switch(TWO_TYPES(sp[-2].type,sp[-1].type))
+
{
+
case TWO_TYPES(T_STRING,T_INT):
+
{
+
struct pike_string *s=sp[-2].u.string;
+
INT32 tmp,base;
+
if(!sp[-1].u.integer)
+
error("Modulo by zero.\n");
+
+
tmp=s->len % sp[-1].u.integer;
+
base=s->len<0 ? 0 : s->len - tmp;
+
s=make_shared_binary_string(s->str + base, tmp);
+
pop_n_elems(2);
+
push_string(s);
+
return;
+
}
+
+
+
case TWO_TYPES(T_ARRAY,T_INT):
+
{
+
struct array *a=sp[-2].u.array;
+
INT32 tmp,base;
+
if(!sp[-1].u.integer)
+
error("Modulo by zero.\n");
+
+
tmp=a->size % sp[-1].u.integer;
+
base=a->size<0 ? 0 : a->size - tmp;
+
a=slice_array(a,base,base+tmp);
+
pop_n_elems(2);
+
push_array(a);
+
return;
+
}
+
}
+
error("Modulo on different types.\n"); }
1464:
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)&function(mixed...:mixed)|function(array(array),array:array)|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(!object...:mixed)&function(mixed...:mixed)|
"
+
"
function(array(array),array:array)|
"
+
"
function(int...:int)|
"
+
"
!function(int...:mixed)&function(float|int...:float)|
"
+
"
function(string*,string:string)
|
"
+
"function(array
,
int:array)|"
+
"function(string,int:string)",
+
OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply);
-
add_efun2("`/",f_divide,"function(mixed,object:mixed)|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_divide,
+
"function(mixed,object:mixed)|
"
+
"
function(array,array
|int|float
:array(array))|
"
+
"
function(object,mixed:mixed)|
"
+
"
function(int,int:int)|
"
+
"
function(float|int,float:float)|
"
+
"
function(float,int:float)|
"
+
"
function(string,string
|int|float
:string*)",
+
OPT_TRY_OPTIMIZE,0,generate_divide);
add_efun2("`%",f_mod,"function(mixed,object:mixed)|function(object,mixed:mixed)|function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",OPT_TRY_OPTIMIZE,0,generate_mod);