pike.git/src/operators.c:110:
else
Pike_error ("Expected integer as string index, got %s.\n",
get_name_of_type (TYPEOF(*ind)));
}
case T_FUNCTION:
case T_PROGRAM:
if (program_index_no_free(to, what, ind)) break;
goto index_error;
- #ifdef AUTO_BIGNUM
+
case T_INT:
if (TYPEOF(*ind) == T_STRING && !IS_UNDEFINED (what)) {
INT_TYPE val = what->u.integer;
convert_svalue_to_bignum(what);
index_no_free(to, what, ind);
if(IS_UNDEFINED(to)) {
if (val) {
Pike_error("Indexing the integer %"PRINTPIKEINT"d "
"with unknown method \"%S\".\n",
val, ind->u.string);
} else {
Pike_error("Indexing the NULL value with \"%S\".\n",
ind->u.string);
}
}
break;
}
/* FALL_THROUGH */
- #endif /* AUTO_BIGNUM */
+
default:
index_error:
if (TYPEOF(*ind) == T_INT)
Pike_error ("Cannot index %s with %"PRINTPIKEINT"d.\n",
(TYPEOF(*what) == T_INT && !what->u.integer)?
"the NULL value":get_name_of_type(TYPEOF(*what)),
ind->u.integer);
else if (TYPEOF(*ind) == T_FLOAT)
Pike_error ("Cannot index %s with %"PRINTPIKEFLOAT"e.\n",
pike.git/src/operators.c:272: Inside #if defined(HAVE_ISINF)
#ifdef HAVE_ISINF
isinf(sp[-1].u.float_number) ||
#endif
#ifdef HAVE_ISNAN
isnan(sp[-1].u.float_number) ||
#endif
0) {
Pike_error("Can't cast infinites or NaN to int.\n");
} else {
int i=DO_NOT_WARN((int)(sp[-1].u.float_number));
- #ifdef AUTO_BIGNUM
+
if((i < 0 ? -i : i) < floor(fabs(sp[-1].u.float_number)))
{
/* Note: This includes the case when i = 0x80000000, i.e.
the absolute value is not computable. */
convert_stack_top_to_bignum();
return; /* FIXME: OK to return? Cast tests below indicates
we have to do this, at least for now... /Noring */
/* Yes, it is ok to return, it is actually an optimization :)
* /Hubbe
*/
}
else
- #endif /* AUTO_BIGNUM */
+
{
SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, i);
}
}
break;
case T_STRING:
- /* This can be here independently of AUTO_BIGNUM. Besides,
- we really want to reduce the number of number parsers
- around here. :) /Noring */
- #ifdef AUTO_BIGNUM
+
/* The generic function is rather slow, so I added this
* code for benchmark purposes. :-) /per
*/
if( (sp[-1].u.string->len >= 10) || sp[-1].u.string->size_shift )
convert_stack_top_string_to_inumber(10);
else
- #endif /* AUTO_BIGNUM */
+
{
INT_TYPE i = STRTOL(sp[-1].u.string->str, 0, 10);
free_string(sp[-1].u.string);
SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, i);
}
break;
case PIKE_T_INT:
break;
pike.git/src/operators.c:957:
return !s->u.integer;
case PIKE_T_FUNCTION:
if (SUBTYPEOF(*s) == FUNCTION_BUILTIN) return 0;
/* FALL_THROUGH */
case PIKE_T_OBJECT:
return !s->u.object->prog;
}
return 0;
case T_ASSIGN:
case PIKE_T_NAME:
+ case PIKE_T_ATTRIBUTE:
type = type->cdr;
goto loop;
case T_AND:
if (!low_check_soft_cast(s, type->car)) return 0;
type = type->cdr;
goto loop;
case T_OR:
if (low_check_soft_cast(s, type->car)) return 1;
type = type->cdr;
goto loop;
case T_NOT:
return !low_check_soft_cast(s, type->car);
}
if ((TYPEOF(*s) == PIKE_T_INT) && !s->u.integer) return 1;
if (TYPEOF(*s) == type->type) {
- if (type->type == PIKE_T_INT) {
+ switch(type->type) {
+ case PIKE_T_INT:
if (((((INT32)CAR_TO_INT(type)) != MIN_INT32) &&
(s->u.integer < (INT32)CAR_TO_INT(type))) ||
((((INT32)CDR_TO_INT(type)) != MAX_INT32) &&
(s->u.integer > (INT32)CDR_TO_INT(type)))) {
return 0;
}
return 1;
- }
- if (type->type == PIKE_T_FLOAT) return 1;
- if (type->type == PIKE_T_STRING) {
+ case PIKE_T_FLOAT:
+ return 1;
+ case PIKE_T_STRING:
if ((8<<s->u.string->size_shift) > CAR_TO_INT(type)) {
return 0;
}
return 1;
- }
- switch(type->type) {
+
case PIKE_T_OBJECT:
{
struct program *p;
/* Common cases. */
if (!type->cdr) return 1;
if (s->u.object->prog->id == CDR_TO_INT(type)) return 1;
p = id_to_program(CDR_TO_INT(type));
if (!p) return 1;
return implements(s->u.object->prog, p);
}
pike.git/src/operators.c:1073:
void o_check_soft_cast(struct svalue *s, struct pike_type *type)
{
if (!low_check_soft_cast(s, type)) {
/* Note: get_type_from_svalue() doesn't return a fully specified type
* for array, mapping and multiset, so we perform a more lenient
* check for them.
*/
struct pike_type *sval_type = get_type_of_svalue(s);
struct pike_string *t1;
- struct pike_string *t2;
+ struct string_builder s;
char *fname = "__soft-cast";
-
+ ONERROR tmp0;
ONERROR tmp1;
- ONERROR tmp2;
+
-
+ init_string_builder(&s, 0);
+
+ SET_ONERROR(tmp0, free_string_builder, &s);
+
+ string_builder_explain_nonmatching_types(&s, type, sval_type);
+
if (Pike_fp->current_program) {
/* Look up the function-name */
struct pike_string *name =
ID_FROM_INT(Pike_fp->current_program, Pike_fp->fun)->name;
if ((!name->size_shift) && (name->len < 100))
fname = name->str;
}
t1 = describe_type(type);
SET_ONERROR(tmp1, do_free_string, t1);
- t2 = describe_type(sval_type);
- SET_ONERROR(tmp2, do_free_string, t2);
-
+
free_type(sval_type);
bad_arg_error(NULL, Pike_sp-1, 1, 1, t1->str, Pike_sp-1,
- "%s(): Soft cast failed. Expected %s, got %s\n",
- fname, t1->str, t2->str);
+ "%s(): Soft cast failed.\n%S",
+ fname, s.s);
/* NOT_REACHED */
- UNSET_ONERROR(tmp2);
- UNSET_ONERROR(tmp1);
- free_string(t2);
- free_string(t1);
+ CALL_AND_UNSET_ONERROR(tmp1);
+ CALL_AND_UNSET_ONERROR(tmp0);
}
}
#define COMPARISON(ID,NAME,FUN) \
PMOD_EXPORT void ID(INT32 args) \
{ \
int i; \
switch(args) \
{ \
case 0: case 1: \
pike.git/src/operators.c:1547:
"string|object|int|float|array|mapping|multiset", sp-args,
"Incompatible types\n");
return; /* compiler hint */
case BIT_STRING:
{
struct pike_string *r;
PCHARP buf;
ptrdiff_t tmp;
int max_shift=0;
-
+
if(args==1) return;
size=0;
for(e=-args;e<0;e++)
{
size+=sp[e].u.string->len;
if(sp[e].u.string->size_shift > max_shift)
max_shift=sp[e].u.string->size_shift;
}
if(size == sp[-args].u.string->len)
{
pop_n_elems(args-1);
return;
}
-
+ else if(args == 2 && (size == sp[-1].u.string->len))
+ {
+ stack_swap();
+ pop_stack();
+ return;
+ }
tmp=sp[-args].u.string->len;
r=new_realloc_shared_string(sp[-args].u.string,size,max_shift);
mark_free_svalue (sp - args);
buf=MKPCHARP_STR_OFF(r,tmp);
for(e=-args+1;e<0;e++)
{
-
+ if( sp[e].u.string->len )
+ {
+ update_flags_for_add( r, sp[e].u.string );
pike_string_cpy(buf,sp[e].u.string);
INC_PCHARP(buf,sp[e].u.string->len);
}
-
+ }
SET_SVAL(sp[-args], T_STRING, 0, string, low_end_shared_string(r));
- for(e=-args+1;e<0;e++) free_string(sp[e].u.string);
+
+ for(e=-args+1;e<0;e++)
+ free_string(sp[e].u.string);
+
sp-=args-1;
break;
}
case BIT_STRING | BIT_INT:
case BIT_STRING | BIT_FLOAT:
case BIT_STRING | BIT_FLOAT | BIT_INT:
{
struct pike_string *r;
pike.git/src/operators.c:1710:
}
}
r = realloc_unlinked_string(r, SUBTRACT_PCHARP(buf, MKPCHARP_STR(r)));
r = low_end_shared_string(r);
pop_n_elems(args);
push_string(r);
break;
}
case BIT_INT:
- #ifdef AUTO_BIGNUM
+ {
+ int of = 0;
size = 0;
for(e = -args; e < 0; e++)
{
- if(INT_TYPE_ADD_OVERFLOW(sp[e].u.integer, size))
+ size = DO_INT_TYPE_ADD_OVERFLOW(size, sp[e].u.integer, &of);
+ }
+ if(of)
{
convert_svalue_to_bignum(sp-args);
f_add(args);
return;
}
- else
- {
- size += sp[e].u.integer;
- }
- }
+
sp-=args;
push_int(size);
- #else
- size=0;
- for(e=-args; e<0; e++) size+=sp[e].u.integer;
- sp-=args-1;
- SET_SVAL(sp[-1], PIKE_T_INT, NUMBER_NUMBER, integer, size);
- #endif /* AUTO_BIGNUM */
+
break;
-
+ }
case BIT_FLOAT:
if (args > 2) {
/* Attempt to minimize the accumulated summation error
* by adding the smallest (absolute) values first.
*
* Large accumulated errors can occur eg when the number
* of values to add is of the same order as the largest
* number representable by the mantissa alone. ie when
* the sum differs by an order of magnitude from a
* typical term.
pike.git/src/operators.c:2233:
{
SET_SVAL(sp[-2], T_FLOAT, 0, float_number, (FLOAT_TYPE)sp[-2].u.integer);
return 1;
}
else if(TYPEOF(sp[-1]) == T_INT && TYPEOF(sp[-2]) == T_FLOAT)
{
SET_SVAL(sp[-1], T_FLOAT, 0, float_number, (FLOAT_TYPE)sp[-1].u.integer);
return 1;
}
- #ifdef AUTO_BIGNUM
+
if(is_bignum_object_in_svalue(sp-2) && TYPEOF(sp[-1]) == T_FLOAT)
{
stack_swap();
ref_push_type_value(float_type_string);
stack_swap();
f_cast();
stack_swap();
return 1;
}
else if(is_bignum_object_in_svalue(sp-1) && TYPEOF(sp[-2]) == T_FLOAT)
{
ref_push_type_value(float_type_string);
stack_swap();
f_cast();
return 1;
}
- #endif
+
return 0;
}
static int call_lfun(int left, int right)
{
struct object *o;
struct program *p;
int i;
if(TYPEOF(sp[-2]) == T_OBJECT &&
pike.git/src/operators.c:2389:
push_multiset(l);
return;
}
case T_FLOAT:
sp--;
sp[-1].u.float_number -= sp[0].u.float_number;
return;
case T_INT:
- #ifdef AUTO_BIGNUM
+
if(INT_TYPE_SUB_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
{
convert_stack_top_to_bignum();
f_minus(2);
return;
}
- #endif /* AUTO_BIGNUM */
+
sp--;
SET_SVAL(sp[-1], PIKE_T_INT, NUMBER_NUMBER, integer,
sp[-1].u.integer - sp[0].u.integer);
return;
case T_STRING:
{
struct pike_string *s,*ret;
s=make_shared_string("");
ret=string_replace(sp[-2].u.string,sp[-1].u.string,s);
pike.git/src/operators.c:3410:
modify_stack_depth(-1);
return 1;
default:
return 0;
}
}
PMOD_EXPORT void o_lsh(void)
{
- #ifdef AUTO_BIGNUM
+
if ((TYPEOF(sp[-1]) == T_INT) && (TYPEOF(sp[-2]) == T_INT) &&
INT_TYPE_LSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
convert_stack_top_to_bignum();
- #endif /* AUTO_BIGNUM */
+
if(TYPEOF(sp[-1]) != T_INT || TYPEOF(sp[-2]) != T_INT)
{
int args = 2;
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("`<<", 2, "int(0..)|object");
}
- #ifndef AUTO_BIGNUM
- if (sp[-1].u.integer > 31) {
- sp--;
- SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, 0);
- return;
- }
- #endif /* !AUTO_BIGNUM */
+
if (sp[-1].u.integer < 0) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`<<", 2, "int(0..)|object");
}
sp--;
SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer,
sp[-1].u.integer << sp->u.integer);
}
/*! @decl int `<<(int arg1, int arg2)
pike.git/src/operators.c:3502:
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;
SIMPLE_BAD_ARG_ERROR("`>>", 2, "int(0..)|object");
}
- if(
- #ifdef AUTO_BIGNUM
- (INT_TYPE_RSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
- #else /* !AUTO_BIGNUM */
- (sp[-1].u.integer > 31)
- #endif /* AUTO_BIGNUM */
- )
+ if( INT_TYPE_RSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer) )
{
sp--;
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;
}
pike.git/src/operators.c:3732:
return;
case TWO_TYPES(T_INT,T_FLOAT):
sp--;
sp[-1].u.float_number=
(FLOAT_TYPE) sp[-1].u.integer * sp[0].u.float_number;
SET_SVAL_TYPE(sp[-1], T_FLOAT);
return;
case TWO_TYPES(T_INT,T_INT):
- #ifdef AUTO_BIGNUM
- if(INT_TYPE_MUL_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
+
{
-
+ INT_TYPE res;
+ int of = 0;
+
+ res = DO_INT_TYPE_MUL_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer, &of);
+
+ if(of)
+ {
convert_stack_top_to_bignum();
goto do_lfun_multiply;
}
- #endif /* AUTO_BIGNUM */
+
sp--;
- SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer,
- sp[-1].u.integer * sp[0].u.integer);
+ SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, res);
return;
-
+ }
default:
do_lfun_multiply:
if(call_lfun(LFUN_MULTIPLY, LFUN_RMULTIPLY))
return;
PIKE_ERROR("`*", "Bad arguments.\n", sp, 2);
}
}
/*! @decl mixed `*(mixed arg1)
pike.git/src/operators.c:4080:
case T_INT:
{
INT_TYPE tmp;
if (sp[-1].u.integer == 0)
OP_DIVISION_BY_ZERO_ERROR("`/");
if(INT_TYPE_DIV_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
{
- #ifdef AUTO_BIGNUM
+
stack_swap();
convert_stack_top_to_bignum();
stack_swap();
goto do_lfun_division;
- #else
- /* It's not possible to do MININT/-1 (it gives FPU exception on
- some CPU:s), thus we return what MININT*-1 returns: MININT. */
- tmp = sp[-2].u.integer;
- #endif /* AUTO_BIGNUM */
+
}
else
tmp = sp[-2].u.integer/sp[-1].u.integer;
sp--;
/* What is this trying to solve? /Noring */
/* It fixes rounding towards negative infinity. /mast */
if((sp[-1].u.integer<0) != (sp[0].u.integer<0))
if(tmp*sp[0].u.integer!=sp[-1].u.integer)
tmp--;
pike.git/src/operators.c:4217:
modify_stack_depth(-1);
return 1;
}
return 0;
}
PMOD_EXPORT void o_mod(void)
{
if(TYPEOF(sp[-2]) != TYPEOF(sp[-1]) && !float_promote())
{
+ do_lfun_modulo:
if(call_lfun(LFUN_MOD, LFUN_RMOD))
return;
switch(TWO_TYPES(TYPEOF(sp[-2]), TYPEOF(sp[-1])))
{
case TWO_TYPES(T_STRING,T_INT):
{
struct pike_string *s=sp[-2].u.string;
ptrdiff_t tmp,base;
pike.git/src/operators.c:4291:
OP_MODULO_BY_ZERO_ERROR("`%");
sp--;
foo = DO_NOT_WARN((FLOAT_TYPE)(sp[-1].u.float_number /
sp[0].u.float_number));
foo = DO_NOT_WARN((FLOAT_TYPE)(sp[-1].u.float_number -
sp[0].u.float_number * floor(foo)));
sp[-1].u.float_number=foo;
return;
}
case T_INT:
- if (sp[-1].u.integer == 0)
+ {
+ int of = 0;
+ INT_TYPE a = sp[-2].u.integer,
+ b = sp[-1].u.integer;
+ INT_TYPE res;
+ if (b == 0)
OP_MODULO_BY_ZERO_ERROR("`%");
- sp--;
- if(sp[-1].u.integer>=0)
+ if(a>=0)
{
- if(sp[0].u.integer>=0)
+ if(b>=0)
{
- sp[-1].u.integer %= sp[0].u.integer;
+ res = a % b;
}else{
- sp[-1].u.integer=((sp[-1].u.integer+~sp[0].u.integer)%-sp[0].u.integer)-~sp[0].u.integer;
+ /* res = ((a+~b)%-b)-~b */
+ res = DO_INT_TYPE_ADD_OVERFLOW(a, ~b, &of);
+ res = DO_INT_TYPE_MOD_OVERFLOW(res, b, &of);
+ res = DO_INT_TYPE_SUB_OVERFLOW(res, ~b, &of);
}
}else{
- if(sp[0].u.integer>=0)
+ if(b>=0)
{
- sp[-1].u.integer=sp[0].u.integer+~((~sp[-1].u.integer) % sp[0].u.integer);
+ /* res = b+~((~a) % b) */
+ res = DO_INT_TYPE_MOD_OVERFLOW(~a, b, &of);
+ res = DO_INT_TYPE_ADD_OVERFLOW(b, ~res, &of);
}else{
- sp[-1].u.integer=-(-sp[-1].u.integer % -sp[0].u.integer);
+ /* a % b and a % -b are equivalent, if overflow does not
+ * happen
+ * res = -(-a % -b) = a % b; */
+ res = DO_INT_TYPE_MOD_OVERFLOW(a, b, &of);
}
}
- SET_SVAL_SUBTYPE(sp[-1], NUMBER_NUMBER);
+ if (of) {
+ stack_swap();
+ convert_stack_top_to_bignum();
+ stack_swap();
+ goto do_lfun_modulo;
+ }
+ sp--;
+ SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, res);
return;
-
+ }
default:
PIKE_ERROR("`%", "Bad argument 1.\n", sp, 2);
}
}
/*! @decl mixed `%(object arg1, mixed arg2)
*! @decl mixed `%(mixed arg1, object arg2)
*! @decl string `%(string arg1, int arg2)
*! @decl array `%(array arg1, int arg2)
*! @decl float `%(float arg1, float|int arg2)
pike.git/src/operators.c:4607:
case T_OBJECT:
do_lfun_negate:
CALL_OPERATOR(LFUN_SUBTRACT,1);
break;
case T_FLOAT:
sp[-1].u.float_number=-sp[-1].u.float_number;
return;
case T_INT:
- #ifdef AUTO_BIGNUM
+
if(INT_TYPE_NEG_OVERFLOW(sp[-1].u.integer))
{
convert_stack_top_to_bignum();
goto do_lfun_negate;
}
- #endif /* AUTO_BIGNUM */
+
SET_SVAL(sp[-1], T_INT, NUMBER_NUMBER, integer, -sp[-1].u.integer);
return;
default:
PIKE_ERROR("`-", "Bad argument to unary minus.\n", sp, 1);
}
}
static void string_or_array_range (int bound_types,
struct svalue *ind,
pike.git/src/operators.c:5650:
sp[-1].u.string=modify_shared_string(sp[-1].u.string,i,j);
assign_lvalue(THIS->lval, sp-1);
pop_stack();
}
pop_n_elems(args);
push_int(j);
}
- static void init_string_assignment_storage(struct object *o)
+ static void init_string_assignment_storage(struct object *UNUSED(o))
{
SET_SVAL(THIS->lval[0], T_INT, PIKE_T_FREE, integer, 0);
SET_SVAL(THIS->lval[1], T_INT, PIKE_T_FREE, integer, 0);
THIS->s = NULL;
}
- static void exit_string_assignment_storage(struct object *o)
+ static void exit_string_assignment_storage(struct object *UNUSED(o))
{
free_svalues(THIS->lval, 2, BIT_MIXED);
if(THIS->s)
free_string(THIS->s);
}
/*! @endclass
*/
void init_operators(void)
pike.git/src/operators.c:5709:
OPT_SIDE_EFFECT|OPT_TRY_OPTIMIZE);
ADD_EFUN("`->=", f_arrow_assign,
tOr3(tFunc(tArr(tOr4(tArray,tObj,tMultiset,tMapping)) tStr tSetvar(0,tMix), tVar(0)),
tFunc(tOr(tObj, tMultiset) tStr tSetvar(1,tMix), tVar(1)),
tFunc(tMap(tMix, tSetvar(2,tMix)) tStr tVar(2), tVar(2))),
OPT_SIDE_EFFECT|OPT_TRY_OPTIMIZE);
/* function(mixed...:int) */
ADD_EFUN2("`==",f_eq,
- tOr5(tFuncV(tOr(tInt,tFloat) tOr(tInt,tFloat),
+ tOr6(tFuncV(tOr(tInt,tFloat) tOr(tInt,tFloat),
tOr(tInt,tFloat),tInt01),
tFuncV(tSetvar(0,tOr4(tString,tMapping,tMultiset,tArray))
tVar(0), tVar(0),tInt01),
tFuncV(tOr3(tObj,tPrg(tObj),tFunction) tMix,tMix,tInt01),
tFuncV(tMix tOr3(tObj,tPrg(tObj),tFunction),tMix,tInt01),
tFuncV(tType(tMix) tType(tMix),
- tOr3(tPrg(tObj),tFunction,tType(tMix)),tInt01)),
+ tOr3(tPrg(tObj),tFunction,tType(tMix)),tInt01),
+ tFuncV(tSetvar(0,tOr4(tString,tMapping,tMultiset,tArray)),
+ tNot(tVar(0)),tInt0)),
OPT_WEAK_TYPE|OPT_TRY_OPTIMIZE,optimize_eq,generate_comparison);
/* function(mixed...:int) */
ADD_EFUN2("`!=",f_ne,
- tOr5(tFuncV(tOr(tInt,tFloat) tOr(tInt,tFloat),
+ tOr6(tFuncV(tOr(tInt,tFloat) tOr(tInt,tFloat),
tOr(tInt,tFloat),tInt01),
tFuncV(tSetvar(0,tOr4(tString,tMapping,tMultiset,tArray))
tVar(0), tVar(0),tInt01),
tFuncV(tOr3(tObj,tPrg(tObj),tFunction) tMix,tMix,tInt01),
tFuncV(tMix tOr3(tObj,tPrg(tObj),tFunction),tMix,tInt01),
tFuncV(tType(tMix) tType(tMix),
- tOr3(tPrg(tObj),tFunction,tType(tMix)),tInt01)),
+ tOr3(tPrg(tObj),tFunction,tType(tMix)),tInt01),
+ tFuncV(tSetvar(0,tOr4(tString,tMapping,tMultiset,tArray)),
+ tNot(tVar(0)),tInt1)),
OPT_WEAK_TYPE|OPT_TRY_OPTIMIZE,0,generate_comparison);
/* function(mixed:int) */
ADD_EFUN2("`!",f_not,tFuncV(tMix,tVoid,tInt01),
OPT_TRY_OPTIMIZE,optimize_not,generate_not);
#define CMP_TYPE "!function(!(object|mixed)...:mixed)&function(mixed...:int(0..1))|function(int|float...:int(0..1))|function(string...:int(0..1))|function(type|program,type|program,type|program...:int(0..1))"
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,
tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),
tFuncV(tNone,tMix,tMix)),
tFuncV(tInt,tInt,tInt),
tIfnot(tFuncV(tNone, tNot(tFlt), tMix),
tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)),
tIfnot(tFuncV(tNone, tNot(tStr), tMix),
- tFuncV(tOr3(tStr,tInt,tFlt),
- tOr3(tStr,tInt,tFlt),tStr)),
+ tFuncV(tOr3(tSetvar(0, tStr),tInt,tFlt),
+ tOr3(tSetvar(1, tStr),tInt,tFlt),tOr(tVar(0),tVar(1)))),
tFuncV(tSetvar(0,tArray),tSetvar(1,tArray),
tOr(tVar(0),tVar(1))),
tFuncV(tSetvar(0,tMapping),tSetvar(1,tMapping),
tOr(tVar(0),tVar(1))),
tFuncV(tSetvar(0,tMultiset),tSetvar(1,tMultiset),
tOr(tVar(0),tVar(1)))),
OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
ADD_EFUN2("`-",f_minus,
tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),
tFuncV(tNone,tMix,tMix)),
tFuncV(tInt,tInt,tInt),
tIfnot(tFuncV(tNone,tNot(tFlt),tMix),
tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)),
tFuncV(tArr(tSetvar(0,tMix)),tArray,tArr(tVar(0))),
tFuncV(tMap(tSetvar(1,tMix),tSetvar(2,tMix)),
tOr3(tMapping,tArray,tMultiset),
tMap(tVar(1),tVar(2))),
tFunc(tSet(tSetvar(3,tMix)) tMultiset,tSet(tVar(3))),
- tFuncV(tStr,tStr,tStr)),
+ tFuncV(tSetvar(0,tStr),tStr,tVar(0))),
OPT_TRY_OPTIMIZE,0,generate_minus);
/*
object & mixed -> mixed
mixed & object -> mixed
int & int -> int
array & array -> array
multiset & multiset -> multiset
pike.git/src/operators.c:5911:
/* function(object:mixed)|function(int:int)|function(float:float)|function(string:string) */
ADD_EFUN2("`~",f_compl,
tOr6(tFunc(tObj,tMix),
tFunc(tInt,tInt),
tFunc(tFlt,tFlt),
tFunc(tStr,tStr),
tFunc(tType(tSetvar(0, tMix)), tType(tNot(tVar(0)))),
tFunc(tPrg(tObj), tType(tMix))),
OPT_TRY_OPTIMIZE,0,generate_compl);
- /* function(string|multiset|array|mapping|object:int) */
+ /* function(string|multiset|array|mapping|object:int(0..)) */
ADD_EFUN2("sizeof", f_sizeof,
- tFunc(tOr5(tStr,tMultiset,tArray,tMapping,tObj),tInt),
+ tFunc(tOr5(tStr,tMultiset,tArray,tMapping,tObj),tIntPos),
OPT_TRY_OPTIMIZE, optimize_sizeof, generate_sizeof);
-
+ ADD_EFUN2("strlen", f_sizeof,
+ tFunc(tStr,tIntPos), OPT_TRY_OPTIMIZE, optimize_sizeof,
+ generate_sizeof);
+
/* function(mixed,mixed ...:mixed) */
ADD_EFUN2("`()",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);
/* This one should be removed */
/* function(mixed,mixed ...:mixed) */
ADD_EFUN2("call_function",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);
/* From the 201x C standard */
ADD_EFUN2("_Static_assert", NULL,
tFunc(tInt tStr, tVoid), OPT_TRY_OPTIMIZE,