pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:1:
/*\ ||| This file is part of Pike. For copyright information see COPYRIGHT. ||| Pike is distributed under GPL, LGPL and MPL. See the file COPYING ||| for more information. \*/ /**/ #include "global.h" #include <math.h>
-
RCSID("$Id: operators.c,v 1.
156
2002/
06
/
25
14
:
26
:
41
grubba
Exp $");
+
RCSID("$Id: operators.c,v 1.
157
2002/
08
/
02
03
:
07
:
18
jhs
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:1916:
emit0(F_XOR); return 1; default: return 0; } } PMOD_EXPORT void o_lsh(void) {
-
if(sp[-2].type == T_STRING) /* s[n..] */
-
{
-
struct pike_string *s;
-
ptrdiff_t from, len;
-
int args = 2;
-
-
if(sp[-1].type != T_INT)
-
SIMPLE_BAD_ARG_ERROR("`<<", 2, "int");
-
-
from = sp[-1].u.integer;
-
if(from <= 0) /* NOP */
-
{
-
sp--;
-
return;
-
}
-
if(from > sp[-2].u.string->len)
-
from = sp[-2].u.string->len;
-
len = sp[-2].u.string->len - from;
-
-
s = string_slice(sp[-2].u.string, from, len);
-
free_string(sp[-2].u.string);
-
-
sp--;
-
sp[-1].u.string = s;
-
return;
-
}
+
#ifdef AUTO_BIGNUM if ((sp[-1].type == T_INT) && (sp[-2].type == T_INT) && INT_TYPE_LSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) convert_stack_top_to_bignum(); #endif /* AUTO_BIGNUM */ if(sp[-1].type != T_INT || sp[-2].type != T_INT) { int args = 2; if(call_lfun(LFUN_LSH, LFUN_RLSH)) return; if(sp[-2].type != T_INT)
-
SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|
string|
object");
+
SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|object");
SIMPLE_BAD_ARG_ERROR("`<<", 2, "int|object"); } #ifndef AUTO_BIGNUM if (sp[-1].u.integer > 31) { sp--; sp[-1].u.integer = 0; return; } #endif /* !AUTO_BIGNUM */ sp--; sp[-1].u.integer = sp[-1].u.integer << sp->u.integer; } /*! @decl int `<<(int arg1, int arg2) *! @decl mixed `<<(object arg1, int|object arg2) *! @decl mixed `<<(int arg1, object arg2)
-
*! @decl string `<<(string arg1, int arg2)
+
*! *! Left shift operator. *! *! 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 string, it will be truncated @[arg2] characters
-
*! from the left ("Hi!" << 2 == "Hi!"[2..] == "!").
-
*!
+
*! 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:2012:
{ do_docode(CDR(n),DO_NOT_COPY_TOPLEVEL); emit0(F_LSH); return 1; } return 0; } PMOD_EXPORT void o_rsh(void) {
-
if(sp[-2].type == T_STRING) /* s[..sizeof(s)-n-1] */
-
{
-
struct pike_string *s;
-
ptrdiff_t len;
-
int args = 2;
-
-
if(sp[-1].type != T_INT)
-
SIMPLE_BAD_ARG_ERROR("`>>", 2, "int");
-
-
len = sp[-1].u.integer;
-
if(len <= 0) /* NOP */
-
{
-
sp--;
-
return;
-
}
-
if(len > sp[-2].u.string->len)
-
len = sp[-2].u.string->len;
-
len = sp[-2].u.string->len - len;
-
-
s = string_slice(sp[-2].u.string, 0, len);
-
free_string(sp[-2].u.string);
-
sp--;
-
sp[-1].u.string = s;
-
return;
-
}
-
+
if(sp[-2].type != T_INT || sp[-1].type != T_INT) { int args = 2; if(call_lfun(LFUN_RSH, LFUN_RRSH)) return; if(sp[-2].type != T_INT)
-
SIMPLE_BAD_ARG_ERROR("`>>", 1, "int|
string|
object");
+
SIMPLE_BAD_ARG_ERROR("`>>", 1, "int|object");
SIMPLE_BAD_ARG_ERROR("`>>", 2, "int|object"); } #ifdef AUTO_BIGNUM if(INT_TYPE_RSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) { sp--; sp[-1].u.integer = 0; return; }
pike.git/src/operators.c:2074:
} #endif /* AUTO_BIGNUM */ sp--; sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer; } /*! @decl int `>>(int arg1, int arg2) *! @decl mixed `>>(object arg1, int|object arg2) *! @decl mixed `>>(int arg1, object arg2)
-
*! @decl string `>>(string arg1, int arg2)
+
*! *! Right shift operator. *! *! 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 string, it
will be
truncated
@[arg2]
characters
-
*! from the right ("Hi!" >> 2 == "Hi!"[
.
.sizeof("Hi!")-3] == "H").
+
*!
Otherwise
@[arg1] will be
shifted
@[arg2]
bits
left
.
*!
-
*! 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); } o_rsh();
pike.git/src/operators.c:3748:
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
(tOr(tFuncV(tMix tObj,tMix,tMix), \
+
tOr
(tOr(tFuncV(tMix tObj,tMix,tMix), \
tFuncV(tObj tMix,tMix,tMix)), \
-
tFuncV(tInt,tInt,tInt)
, \
-
tFuncV(tStr,tInt,tStr
)
)
+
tFuncV(tInt,tInt,tInt))
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)|" "!function(int...:mixed)&function(float|int...:float)|"