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 as GPL (General Public License) ||| See the files COPYING and DISCLAIMER for more information. \*/ /**/ #include "global.h" #include <math.h>
-
RCSID("$Id: operators.c,v 1.
145
2002/
01
/
16
02
:
54
:
16
nilsson
Exp $");
+
RCSID("$Id: operators.c,v 1.
146
2002/
04
/
20
14
:
56
:
14
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:1914:
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(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|object");
+
SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|
string|
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:1979:
{ 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|object");
+
SIMPLE_BAD_ARG_ERROR("`>>", 1, "int|
string|
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:2015:
} #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. *! *! @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:3706:
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 \
-
tOr
(tOr(tFuncV(tMix tObj,tMix,tMix),
\
-
tFuncV(tObj tMix,tMix,tMix)),
\
-
tFuncV(tInt,tInt,tInt))
+
tOr3
(tOr(tFuncV(tMix tObj,tMix,tMix), \
+
tFuncV(tObj tMix,tMix,tMix)), \
+
tFuncV(tInt,tInt,tInt)
, \
+
tFuncV(tStr,tInt,tStr
)
)
ADD_EFUN2("`<<",f_lsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_lsh); ADD_EFUN2("`>>",f_rsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,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)|" "function(string*,string:string)|" "function(array(0=mixed),int:array(0))|"