pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:1:
/*\ ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License) ||| See the files COPYING and DISCLAIMER for more information. \*/ #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" #include "mapping.h" #include "array.h" #include "stralloc.h" #include "opcodes.h" #include "operators.h" #include "language.h" #include "pike_memory.h"
pike.git/src/operators.c:929:
} return 0; } #define TWO_TYPES(X,Y) (((X)<<8)|(Y)) void o_multiply(void) { 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; ret=implode(sp[-2].u.array,sp[-1].u.string); free_string(sp[-1].u.string); free_array(sp[-2].u.array); sp[-2].type=T_STRING; sp[-2].u.string=ret; sp--; 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
;
+
return
;
} case TWO_TYPES(T_FLOAT,T_FLOAT): sp--; sp[-1].u.float_number *= sp[0].u.float_number; return; case TWO_TYPES(T_FLOAT,T_INT): sp--; sp[-1].u.float_number *= (FLOAT_TYPE)sp[0].u.integer;
pike.git/src/operators.c:1021:
return 0; } } void o_divide(void) { if(sp[-2].type!=sp[-1].type && !float_promote()) { 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"); } switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_DIVIDE,2); break; case T_STRING:
pike.git/src/operators.c:1104:
return 0; } void o_mod(void) { if(sp[-2].type != sp[-1].type && !float_promote()) { 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"); } switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_MOD,2); break; case T_FLOAT:
pike.git/src/operators.c:1457:
add_efun2("`|",f_or,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_or); add_efun2("`^",f_xor,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_xor); #define SHIFT_TYPE "function(object,mixed:mixed)|function(mixed,object:mixed)|function(int,int:int)" 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); add_efun2("`~",f_compl,"function(object:mixed)|function(int:int)|function(float:float)|function(string:string)",OPT_TRY_OPTIMIZE,0,generate_compl); add_efun2("sizeof", f_sizeof, "function(string|multiset|array|mapping|object:int)",0,0,generate_sizeof); add_efun2("`()",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function); /* This one should be removed */ add_efun2("call_function",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function); }