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.
19
1997/10/
10
20
:
19
:
58
hubbe Exp $");
+
RCSID("$Id: operators.c,v 1.
20
1997/10/
11
06
:
48
:
24
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:61:
{ INT32 e,size; TYPE_FIELD types; types=0; for(e=-args;e<0;e++) types|=1<<sp[e].type; switch(types) { default:
-
if(args)
+
if(
!
args)
{
-
switch
(
sp[-args].type
)
+
error
(
"Too few arguments to `+(
)
\n");
+
}else{
+
if(types & BIT_OBJECT)
{
-
case
T_OBJECT
:
-
CALL
_
OPERATOR
(LFUN_ADD,args);
+
if(sp[-args].type ==
T_OBJECT
&&
+
sp[-args].u.object->prog &&
+
sp[-args].u.object->prog->lfuns[LFUN
_
ADD] != -1)
+
{
+
apply_lfun
(
sp[-args].u.object,
LFUN_ADD,
args
-1
);
+
free_svalue(sp-2);
+
sp[-2]=sp[-1];
+
sp--;
return;
-
+
}
+
for(e=1;e<args;e++)
+
{
+
if(sp[e-args].type == T_OBJECT &&
+
sp[e-args].u.object->prog &&
+
sp[e-args].u.object->prog->lfuns[LFUN_RADD] != -1)
+
{
+
struct svalue *tmp=sp+e-args;
+
check_stack(e);
+
assign_svalues_no_free(sp, sp-args, e, -1);
+
sp+=e;
+
apply_lfun(tmp->u.object, LFUN_RADD, e);
+
if(args - e > 2)
+
{
+
assign_svalue(tmp, sp-1);
+
pop_stack();
+
f_add(args - e);
+
assign_svalue(sp-e-1,sp-1);
+
pop_n_elems(e);
+
}else{
+
assign_svalue(sp-args-1,sp-1);
+
pop_n_elems(args);
+
}
+
return;
+
}
+
}
+
}
+
}
-
+
switch(sp[-args].type)
+
{
case T_PROGRAM: case T_FUNCTION: error("Bad argument 1 to summation\n"); }
-
}
+
error("Incompatible types to sum() or +\n"); return; /* compiler hint */ case BIT_STRING: { struct pike_string *r; char *buf; INT32 tmp; switch(args)
pike.git/src/operators.c:328:
emit2(F_GE); else fatal("Couldn't generate comparison!\n"); return 1; } return 0; } static int float_promote(void) {
-
if(sp[-2].type==T_INT)
+
if(sp[-2].type==T_INT
&& sp[-1].type==T_FLOAT
)
{ sp[-2].u.float_number=(FLOAT_TYPE)sp[-2].u.integer; sp[-2].type=T_FLOAT;
-
+
return 1;
}
-
-
if(sp[-1].type==T_INT)
+
else
if(sp[-1].type==T_INT
&& sp[-2].type==T_FLOAT
)
{ sp[-1].u.float_number=(FLOAT_TYPE)sp[-1].u.integer; sp[-1].type=T_FLOAT;
-
+
return 1;
}
-
+
return 0;
+
}
-
return
sp[-2].type == sp[-1].
type
;
+
static
int
call_lfun(int
left, int right)
+
{
+
if(
sp[-2].type ==
T_OBJECT &&
+
sp[-
2].u.object->prog &&
+
sp[-2].u.object->prog->lfuns[left] != -
1
)
+
{
+
apply_lfun(sp[-2
].
u.object, left, 1)
;
+
free_svalue(sp-2);
+
sp[-2]=sp[-1];
+
sp--;
+
return 1;
}
-
+
if(sp[-1].type == T_OBJECT &&
+
sp[-1].u.object->prog &&
+
sp[-1].u.object->prog->lfuns[right] != -1)
+
{
+
push_svalue(sp-2);
+
apply_lfun(sp[-2].u.object, right, 1);
+
free_svalue(sp-3);
+
sp[-3]=sp[-1];
+
sp--;
+
pop_stack();
+
return 1;
+
}
+
+
return 0;
+
}
+
void o_subtract(void) {
-
if (sp[-2].type != sp[-1].type &&
-
!float_promote()
&&
-
sp[-2].type
!= T
_
OBJECT
)
+
if (sp[-2].type != sp[-1].type &&
!float_promote())
+
{
+
if(call
_
lfun
(
LFUN_SUBTRACT, LFUN_RSUBTRACT
)
)
+
return;
error("Subtract on different types.\n");
-
+
}
switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_SUBTRACT,2); break; case T_ARRAY: { struct array *a;
pike.git/src/operators.c:444:
case 2: do_docode(CDR(n),DO_NOT_COPY); emit2(F_SUBTRACT); return 1; } return 0; } void o_and(void) {
-
if(sp[-1].type != sp[-2].type
&&
-
sp[-2].type
!=
T
_
OBJECT
)
+
if(sp[-1].type != sp[-2].type
)
+
{
+
if(call_lfun(LFUN_AND,
LFUN
_
RAND
)
)
+
return;
+
error("Bitwise and on different types.\n");
-
+
}
switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_AND,2); break; case T_INT: sp--; sp[-1].u.integer &= sp[0].u.integer;
pike.git/src/operators.c:580:
emit2(F_AND); return 1; default: return 0; } } void o_or(void) {
-
if(sp[-1].type != sp[-2].type
&&
-
sp[-2].type
!=
T
_
OBJECT
)
+
if(sp[-1].type != sp[-2].type
)
+
{
+
if(call_lfun(LFUN_OR,
LFUN
_
ROR
)
)
+
return;
+
error("Bitwise or on different types.\n");
-
+
}
switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_OR,2); break; case T_INT: sp--; sp[-1].u.integer |= sp[0].u.integer;
pike.git/src/operators.c:681:
return 1; default: return 0; } } void o_xor(void) {
-
if(sp[-1].type != sp[-2].type
&&
-
sp[-2].type
!=
T
_
OBJECT
)
+
if(sp[-1].type != sp[-2].type
)
+
{
+
if(call_lfun(LFUN_XOR,
LFUN
_
RXOR
)
)
+
return;
error("Bitwise xor on different types.\n");
-
+
}
switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_XOR,2); break; case T_INT: sp--; sp[-1].u.integer ^= sp[0].u.integer;
pike.git/src/operators.c:781:
emit2(F_XOR); return 1; default: return 0; } } void o_lsh(void) {
-
if(sp[-2].type != T_INT)
+
if(sp[-
1].type != T_INT || sp[-
2].type != T_INT)
{
-
if(
sp[-2].type == T
_
OBJECT)
-
{
-
CALL_OPERATOR
(LFUN_LSH,
2
)
;
+
if(
call
_
lfun
(LFUN_LSH,
LFUN_RLSH
)
)
return;
-
}
+
-
+
if(sp[-2].type != T_INT)
error("Bad argument 1 to <<\n");
-
+
error("Bad argument 2 to <<\n");
}
-
if(sp[-1].type != T_INT) error("Bad argument 2 to <<\n");
+
sp--; sp[-1].u.integer = sp[-1].u.integer << sp->u.integer; } void f_lsh(INT32 args) { if(args != 2) error("Bad number of args to `<<\n"); o_lsh(); }
pike.git/src/operators.c:816:
{ do_docode(CDR(n),DO_NOT_COPY); emit2(F_LSH); return 1; } return 0; } void o_rsh(void) {
-
if(sp[-2].type != T_INT)
+
if(sp[-2].type != T_INT
|| sp[-1].type != T_INT
)
{
-
if(
sp[-2].type == T
_
OBJECT)
-
{
-
CALL_OPERATOR
(LFUN_RSH,
2
)
;
+
if(
call
_
lfun
(LFUN_RSH,
LFUN_RRSH
)
)
return;
-
}
+
if(sp[-2].type != T_INT)
error("Bad argument 1 to >>\n");
-
+
error("Bad argument 2 to >>\n");
}
-
if(sp[-1].type != T_INT) error("Bad argument 2 to >>\n");
+
sp--; sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer; } void f_rsh(INT32 args) { if(args != 2) error("Bad number of args to `>>\n"); o_rsh(); }
pike.git/src/operators.c:898:
(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:
-
if(
sp[-2].type == T
_
OBJECT)
-
{
-
CALL_OPERATOR
(LFUN_MULTIPLY,
2
)
;
+
if(
call
_
lfun
(LFUN_MULTIPLY,
LFUN_RMULTIPLY
)
)
return;
-
}
+
error("Bad arguments to multiply.\n"); } } void f_multiply(INT32 args) { switch(args) { case 0: error("Too few arguments to `*\n");
pike.git/src/operators.c:945:
emit2(F_MULTIPLY); return 1; default: return 0; } } void o_divide(void) {
-
if(sp[-2].type!=sp[-1].type &&
-
!float_promote()
&&
-
sp[-2].type
!=
T
_
OBJECT
)
+
if(sp[-2].type!=sp[-1].type && !float_promote()
)
+
{
+
if(call_lfun(LFUN_DIVIDE,
LFUN
_
RDIVIDE
)
)
+
return;
error("Division on different types.\n");
-
+
}
switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_DIVIDE,2); break; case T_STRING: { struct array *ret;
pike.git/src/operators.c:1023:
{ do_docode(CDR(n),DO_NOT_COPY); emit2(F_DIVIDE); return 1; } return 0; } void o_mod(void) {
-
if(sp[-2].type != sp[-1].type &&
-
!float_promote()
&&
-
sp[-2].type
!=
T
_
OBJECT
)
+
if(sp[-2].type != sp[-1].type && !float_promote()
)
+
{
+
if(call_lfun(LFUN_MOD,
LFUN
_
RMOD
)
)
+
return;
+
error("Modulo on different types.\n");
-
+
}
switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_MOD,2); break; case T_FLOAT: { FLOAT_TYPE foo;
pike.git/src/operators.c:1350:
add_efun2("`==",f_eq,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison); add_efun2("`!=",f_ne,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison); add_efun2("`!",f_not,"function(mixed:int)",OPT_TRY_OPTIMIZE,0,generate_not); #define CMP_TYPE "function(object,mixed:int)|function(mixed,object:int)|function(int|float,int|float:int)|function(string,string:int)" add_efun2("`<", f_lt,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison); add_efun2("`<=",f_le,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison); add_efun2("`>", f_gt,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison); add_efun2("`>=",f_ge,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);
-
add_efun2("`+",f_add,"function(object
,
mixed...:mixed)|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(multiset...:multiset)",OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
+
add_efun2("`+",f_add,"
!
function(
!
object
...:
mixed
)&function(mixed
...:mixed)|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(multiset...:multiset)",OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
-
add_efun2("`-",f_minus,"function(object
,
mixed...:mixed)|function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(multiset,multiset:multiset)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",OPT_TRY_OPTIMIZE,0,generate_minus);
+
add_efun2("`-",f_minus,"
!
function(
!
object
...:
mixed
)&function(mixed
...:mixed)|function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(multiset,multiset:multiset)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",OPT_TRY_OPTIMIZE,0,generate_minus);
-
#define LOG_TYPE "function(object,mixed...:mixed)|function(int...:int)|function(mapping...:mapping)|function(multiset...:multiset)|function(array...:array)|function(string...:string)"
+
#define LOG_TYPE "function(
mixed,
object
...:mixed)|function(object
,mixed...:mixed)|function(int...:int)|function(mapping...:mapping)|function(multiset...:multiset)|function(array...:array)|function(string...:string)"
add_efun2("`&",f_and,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_and); 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(int,int:int)"
+
#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(
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_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_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_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_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);
+
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); }