pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:3377:
modify_stack_depth(-1); return 1; default: return 0; } } PMOD_EXPORT void o_lsh(void) {
-
if (sp[-1].u.integer < 0) {
+
int args = 2;
-
+
if ((TYPEOF(sp[-2]) == T_OBJECT) ||
+
(TYPEOF(sp[-1]) == T_OBJECT))
+
goto call_lfun;
+
+
if ((TYPEOF(sp[-1]) != T_INT) || (sp[-1].u.integer < 0)) {
SIMPLE_BAD_ARG_ERROR("`<<", 2, "int(0..)|object"); }
-
if
(
(
TYPEOF(sp[-
1
])
== T_INT
)
&&
(TYPEOF(sp[-2])
==
T_INT
) &&
-
INT_TYPE_LSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
+
+
switch
(TYPEOF(sp[-
2
]))
{
+
case
T_INT
:
+
if
(!
INT_TYPE_LSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
+
break;
convert_stack_top_to_bignum();
-
if(TYPEOF(sp[-1])
!=
T
_
INT
||
TYPEOF(sp[-2])
!=
T_
INT)
-
{
-
int args = 2;
+
/* FALL
_
THROUGH
*/
+
+
case
T_
OBJECT:
+
call_lfun:
if(call_lfun(LFUN_LSH, LFUN_RLSH)) return; if(TYPEOF(sp[-2]) != T_INT)
-
SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|object");
+
SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|
float|
object");
SIMPLE_BAD_ARG_ERROR("`<<", 2, "int(0..)|object");
-
+
break;
+
+
case T_FLOAT:
+
sp--;
+
sp[-1].u.float_number = ldexp(sp[-1].u.float_number, sp->u.integer);
+
return;
+
+
default:
+
SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|float|object");
+
break;
} sp--; SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, sp[-1].u.integer << sp->u.integer); }
-
/*! @decl int `<<(int arg1, int arg2)
-
*! @decl mixed `<<(object arg1, int|object arg2)
+
/*! @decl int `<<(int arg1, int
(0..)
arg2)
+
*! @decl mixed `<<(object arg1, int
(0..)
|object arg2)
*! @decl mixed `<<(int arg1, object arg2)
-
+
*! @decl mixed `<<(float arg1, int(0..) arg2)
*! *! Left shift. *! *! Every expression with the @expr{<<@} operator becomes a call to *! this function, i.e. @expr{a<<b@} is the same as *! @expr{predef::`<<(a,b)@}. *! *! If @[arg1] is an object that implements @[lfun::`<<()], that *! function will be called with @[arg2] as the single argument. *! *! If @[arg2] is an object that implements @[lfun::``<<()], that *! function will be called with @[arg1] as the single argument. *!
-
+
*! If @[arg1] is a float and @[arg2] is a non-negative integer,
+
*! @[arg1] will be multiplied by @expr{1<<@[arg2]@}.
+
*!
*! Otherwise @[arg1] will be shifted @[arg2] bits left. *! *! @seealso *! @[`>>()] */ PMOD_EXPORT void f_lsh(INT32 args) { if(args != 2) { /* FIXME: Not appropriate if too many args. */ SIMPLE_TOO_FEW_ARGS_ERROR("`<<", 2);
pike.git/src/operators.c:3446:
do_docode(CDR(n),DO_NOT_COPY_TOPLEVEL); emit0(F_LSH); modify_stack_depth(-1); return 1; } return 0; } PMOD_EXPORT void o_rsh(void) {
-
if(TYPEOF(sp[-2]) != T_INT || TYPEOF(sp[-1]) != T_INT)
-
{
+
int args = 2;
-
+
if ((TYPEOF(sp[-2]) == T_OBJECT) || (TYPEOF(sp[-1]) == T_OBJECT))
+
{
if(call_lfun(LFUN_RSH, LFUN_RRSH)) return; if(TYPEOF(sp[-2]) != T_INT) SIMPLE_BAD_ARG_ERROR("`>>", 1, "int|object"); SIMPLE_BAD_ARG_ERROR("`>>", 2, "int(0..)|object"); }
-
if (sp[-1].u.integer < 0) {
-
int args = 2;
+
if (
(TYPEOF(
sp[-1]
) != T_INT) || (sp[-1]
.u.integer < 0)
)
{
SIMPLE_BAD_ARG_ERROR("`>>", 2, "int(0..)|object"); }
-
if( INT_TYPE_RSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer) )
-
{
+
sp--;
-
+
switch(TYPEOF(sp[-1])) {
+
case T_INT:
+
if( INT_TYPE_RSH_OVERFLOW(sp[-1].u.integer, sp->u.integer) )
+
{
if (sp[-1].u.integer < 0) { SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, -1); } else { SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, 0); } return; }
-
+
break;
+
case T_FLOAT:
+
sp[-1].u.float_number = ldexp(sp[-1].u.float_number, -sp->u.integer);
+
return;
+
default:
+
SIMPLE_BAD_ARG_ERROR("`>>", 1, "int|float|object");
+
break;
+
}
-
sp--;
+
SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, sp[-1].u.integer >> sp->u.integer); }
-
/*! @decl int `>>(int arg1, int arg2)
-
*! @decl mixed `>>(object arg1, int|object arg2)
+
/*! @decl int `>>(int arg1, int
(0..)
arg2)
+
*! @decl mixed `>>(object arg1, int
(0..)
|object arg2)
*! @decl mixed `>>(int arg1, object arg2)
-
+
*! @decl float `>>(float arg1, int(0..) arg2)
*! *! Right shift. *! *! Every expression with the @expr{>>@} operator becomes a call to *! this function, i.e. @expr{a>>b@} is the same as *! @expr{predef::`>>(a,b)@}. *! *! If @[arg1] is an object that implements @[lfun::`>>()], that *! function will be called with @[arg2] as the single argument. *! *! If @[arg2] is an object that implements @[lfun::``>>()], that *! function will be called with @[arg1] as the single argument. *!
-
+
*! If @[arg1] is a float and @[arg2] is a non-negative integer,
+
*! @[arg1] will be divided by @expr{1<<@[arg2]@}.
+
*!
*! Otherwise @[arg1] will be shifted @[arg2] bits right. *! *! @seealso *! @[`<<()] */ PMOD_EXPORT void f_rsh(INT32 args) { if(args != 2) { /* FIXME: Not appropriate if too many args. */ SIMPLE_TOO_FEW_ARGS_ERROR("`>>", 2);
pike.git/src/operators.c:5817:
tFuncV(tSetvar(3,tMultiset),tSetvar(4,tMultiset),tOr(tVar(3),tVar(4))), \ tFuncV(tSetvar(5,tArray),tSetvar(6,tArray),tOr(tVar(5),tVar(6))), \ tFuncV(tString,tString,tString), \ tFuncV(tOr(tType(tMix),tPrg(tObj)),tOr(tType(tMix),tPrg(tObj)),tType(tMix))) 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 \
-
tOr3
(tIfnot(tFuncV(tNone, tNot(tObj), tMix), \
+
tOr4
(tIfnot(tFuncV(tNone, tNot(tObj), tMix), \
tOr(tFunc(tMix tObj,tMix), \ tFunc(tObj tMix,tMix))), \ tIfnot(tFuncV(tNone, tNot(tInt), tMix), \ tFunc(tInt tInt, tInt)), \
-
+
tFunc(tFloat tIntPos, tFloat), \
tFunc(tIntPos tIntPos, tIntPos)) ADD_EFUN2("`<<", f_lsh, SHIFT_TYPE, OPT_TRY_OPTIMIZE, may_have_side_effects, generate_lsh); ADD_EFUN2("`>>", f_rsh, SHIFT_TYPE, OPT_TRY_OPTIMIZE, may_have_side_effects, generate_rsh); /* !function(!object...:mixed)&function(mixed...:mixed)|" "function(array(array(1=mixed)),array(1=mixed):array(1))|" "function(int...:int)|"