pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:162:
case BIT_FLOAT: { FLOAT_TYPE sum; sum=0.0; for(e=-args; e<0; e++) sum+=sp[e].u.float_number; sp-=args-1; sp[-1].u.float_number=sum; break; }
+
case BIT_FLOAT | BIT_INT:
+
{
+
FLOAT_TYPE sum;
+
sum=0.0;
+
for(e=-args; e<0; e++)
+
{
+
if(sp[e].type==T_FLOAT)
+
{
+
sum+=sp[e].u.float_number;
+
}else{
+
sum+=(FLOAT_TYPE)sp[e].u.integer;
+
}
+
}
+
sp-=args-1;
+
sp[-1].u.float_number=sum;
+
break;
+
}
+
case BIT_ARRAY: { struct array *a; a=add_arrays(sp-args,args); pop_n_elems(args); push_array(a); break; } case BIT_MAPPING:
pike.git/src/operators.c:224:
if(count_args(CDR(n))==2) { first_arg=my_get_arg(&CDR(n), 0); second_arg=my_get_arg(&CDR(n), 1); #ifdef DEBUG if(!first_arg || !second_arg) fatal("Couldn't find argument!\n"); #endif
-
if((*second_arg)->type == (*first_arg)->type)
+
if((*second_arg)->type == (*first_arg)->type
&&
+
compile_type_to_runtime_type((*second_arg
)
->type) != T_MIXED)
{ if((*first_arg)->token == F_APPLY && CAR(*first_arg)->token == F_CONSTANT && is_eq(& CAR(*first_arg)->u.sval, & CAR(n)->u.sval)) { ret=mknode(F_APPLY, CAR(n), mknode(F_ARG_LIST, CDR(*first_arg), *second_arg));
pike.git/src/operators.c:288:
ins_f_byte(F_GT); else if(CAR(n)->u.sval.u.efun->function == f_ge) ins_f_byte(F_GE); else fatal("Couldn't generate comparison!\n"); return 1; } return 0; }
+
static int float_promote()
+
{
+
if(sp[-2].type==T_INT)
+
{
+
sp[-2].u.float_number=(FLOAT_TYPE)sp[-2].u.integer;
+
sp[-2].type=T_FLOAT;
+
}
-
+
if(sp[-1].type==T_INT)
+
{
+
sp[-1].u.float_number=(FLOAT_TYPE)sp[-1].u.integer;
+
sp[-1].type=T_FLOAT;
+
}
+
+
return sp[-2].type == sp[-1].type;
+
}
+
void o_subtract() {
-
if (sp[-2].type != sp[-1].type )
+
if (sp[-2].type != sp[-1].type
&& !float_promote(
)
)
error("Subtract on different types.\n"); switch(sp[-1].type) { case T_ARRAY: { struct array *a; check_array_for_destruct(sp[-2].u.array); check_array_for_destruct(sp[-1].u.array);
pike.git/src/operators.c:652:
{ if(count_args(CDR(n))==2) { do_docode(CDR(n),DO_NOT_COPY); ins_f_byte(F_RSH); return 1; } return 0; }
+
+
#define TWO_TYPES(X,Y) (((X)<<8)|(Y))
void o_multiply() {
-
switch(sp[-2].type)
+
switch(
TWO_TYPES(
sp[-2].type
,sp[-1].type
)
)
{
-
case T_ARRAY
:
-
if(sp[-1].type!=
T_STRING)
+
case
TWO_TYPES(
T_ARRAY
,
T_STRING)
:
{
-
error("Bad argument 2 to multiply.\n");
-
}else{
+
struct lpc_string *ret; sp--; ret=implode(sp[-1].u.array,sp[0].u.string); free_string(sp[0].u.string); free_array(sp[-1].u.array); sp[-1].type=T_STRING; sp[-1].u.string=ret; return; }
-
case T_FLOAT
:
-
if(sp[-1].type!=
T_FLOAT)
error("Bad argument 2 to multiply.\n");
+
case
TWO_TYPES(
T_FLOAT
,
T_FLOAT)
:
sp--; sp[-1].u.float_number *= sp[0].u.float_number; return;
-
case
T
_
INT:
-
if
(
sp[-1].type!=
T_INT)
error("Bad argument 2 to multiply.\n");
+
case
TWO
_
TYPES
(T_
FLOAT,T_
INT)
:
sp--;
-
+
sp[-1].u.float_number *= (FLOAT_TYPE)sp[0].u.integer;
+
return;
+
+
case TWO_TYPES(T_INT,T_FLOAT):
+
sp--;
+
sp[-1].u.float_number=
+
(FLOAT_TYPE) sp[-1].u.integer * (FLOAT_TYPE)sp[0].u.float_number;
+
sp[-1].type=T_FLOAT;
+
return;
+
+
case TWO_TYPES(T_INT,T_INT):
+
sp--;
sp[-1].u.integer *= sp[0].u.integer; return; default:
-
error("Bad
argument
1
to multiply.\n");
+
error("Bad
arguments
to multiply.\n");
} } void f_multiply(INT32 args) { switch(args) { case 0: error("Too few arguments to `*\n"); case 1: return; case 2: o_multiply(); return;
pike.git/src/operators.c:719:
ins_f_byte(F_MULTIPLY); return 1; default: return 0; } } void o_divide() {
-
if(sp[-2].type!=sp[-1].type)
+
if(sp[-2].type!=sp[-1].type
&& !float_promote(
)
)
error("Division on different types.\n"); switch(sp[-2].type) { case T_STRING: { struct array *ret; sp--; ret=explode(sp[-1].u.string,sp[0].u.string); free_string(sp[-1].u.string);
pike.git/src/operators.c:775:
{ do_docode(CDR(n),DO_NOT_COPY); ins_f_byte(F_DIVIDE); return 1; } return 0; } void o_mod() {
-
if(sp[-2].type != sp[-1].type)
+
if(sp[-2].type != sp[-1].type
&& !float_promote(
)
)
error("Modulo on different types.\n"); switch(sp[-1].type) { case T_FLOAT: { FLOAT_TYPE foo; if(sp[-1].u.float_number == 0.0) error("Modulo by zero.\n"); sp--;
pike.git/src/operators.c:949:
default: error("[ .. ] can only be done on strings and arrays.\n"); } } void init_operators() { add_efun2("`==",f_eq,"function(mixed,mixed:int)",0,0,generate_comparison); add_efun2("`!=",f_ne,"function(mixed,mixed:int)",0,0,generate_comparison);
-
add_efun2("`<", f_lt,"function(int,int
:int)
|
function(
float
,float
:int)|function(string,string:int)",0,0,generate_comparison);
-
add_efun2("`<=",f_le,"function(int,int
:int)
|
function(
float
,float
:int)|function(string,string:int)",0,0,generate_comparison);
-
add_efun2("`>", f_gt,"function(int,int
:int)
|
function(
float
,float
:int)|function(string,string:int)",0,0,generate_comparison);
-
add_efun2("`>=",f_ge,"function(int,int
:int)
|
function(
float
,float
:int)|function(string,string:int)",0,0,generate_comparison);
+
add_efun2("`<", f_lt,"function(int
|float
,int|float:int)|function(string,string:int)",0,0,generate_comparison);
+
add_efun2("`<=",f_le,"function(int
|float
,int|float:int)|function(string,string:int)",0,0,generate_comparison);
+
add_efun2("`>", f_gt,"function(int
|float
,int|float:int)|function(string,string:int)",0,0,generate_comparison);
+
add_efun2("`>=",f_ge,"function(int
|float
,int|float:int)|function(string,string:int)",0,0,generate_comparison);
-
add_efun2("`+",f_add,"function(int
...:int)|function(
float
...:
float
)
|
function(
string,string|
int|float
...:
string
)|function(
string,string|
int|float
...:
string
)
|
function(
int|float,
string
,string
|int|float:string)|function(array
...:array)|function(mapping
...:mapping)|function(list...:list)",0,optimize_binary,generate_sum);
+
add_efun2("`+",f_add,"function(int...:int)|
!
function(
int
...:
mixed
)
&
function(int|float...:
float
)|
!
function(int|float...:
mixed
)
&
function(string|int|float
...
:string)|function(array...:array)|function(mapping...:mapping)|function(list...:list)",0,optimize_binary,generate_sum);
-
add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float,float:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus);
+
add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float
|int
,float:float)|function(
float,
int
:float)|function(int
,int:int)|function(string,string:string)",0,0,generate_minus);
add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_and); add_efun2("`|",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_or); add_efun2("`^",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_xor); add_efun2("`<<",f_lsh,"function(int,int:int)",0,0,generate_lsh); add_efun2("`>>",f_rsh,"function(int,int:int)",0,0,generate_rsh);
-
add_efun2("`*",f_multiply,"function(int...:int)|function(float...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply);
+
add_efun2("`*",f_multiply,"function(int...:int)|
!
function(
int...:mixed)&function(
float
|int
...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply);
-
add_efun2("`/",f_divide,"function(int,int:int)|function(float,float:float)|function(string,string:string*)",0,0,generate_divide);
+
add_efun2("`/",f_divide,"function(int,int:int)|function(float
|int
,float:float)|function(
float,int:float)|function(
string,string:string*)",0,0,generate_divide);
add_efun2("`%",f_mod,"function(int,int:int)|function(float,float:float)",0,0,generate_mod); add_efun2("`!",f_not,"function(mixed:int)",0,0,generate_not); add_efun2("`~",f_compl,"function(int:int)",0,0,generate_compl);
-
+
}