e576bb | 2002-10-11 | Martin Nilsson | |
|
aedfb1 | 2002-10-09 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "global.h"
#include "interpret.h"
#include "svalue.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "multiset.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "mapping.h"
#include "array.h"
#include "stralloc.h"
|
afc93f | 2010-05-28 | Martin Stjernholm | | #include "pike_float.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "opcodes.h"
#include "operators.h"
|
9aa6fa | 1997-05-19 | Fredrik Hübinette (Hubbe) | | #include "pike_memory.h"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | #include "pike_error.h"
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | #include "docode.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "constants.h"
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | #include "peep.h"
#include "lex.h"
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | #include "program.h"
#include "object.h"
|
9c6f7d | 1997-04-15 | Fredrik Hübinette (Hubbe) | | #include "pike_types.h"
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | #include "module_support.h"
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
fda0de | 1999-10-08 | Fredrik Noring | | #include "bignum.h"
|
89c445 | 2000-04-12 | Henrik Grubbström (Grubba) | | #include "builtin_functions.h"
|
6898c0 | 2003-11-14 | Martin Stjernholm | | #include "cyclic.h"
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | #include "pike_compiler.h"
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | #define OP_DIVISION_BY_ZERO_ERROR(FUNC) \
|
3efc85 | 2018-02-19 | Martin Nilsson | | math_error(FUNC, 2, 0, "Division by zero.\n")
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | #define OP_MODULO_BY_ZERO_ERROR(FUNC) \
|
3efc85 | 2018-02-19 | Martin Nilsson | | math_error(FUNC, 2, 0, "Modulo by zero.\n")
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | |
|
afc93f | 2010-05-28 | Martin Stjernholm | |
#define MAX_INT_SPRINTF_LEN (2 + (SIZEOF_INT_TYPE * 5 + 1) / 2)
|
d6b238 | 2009-07-12 | Henrik Grubbström (Grubba) | |
|
afc93f | 2010-05-28 | Martin Stjernholm | | |
3aff75 | 2008-08-26 | Stephen R. van den Berg | | */
|
afc93f | 2010-05-28 | Martin Stjernholm | | #define MAX_NUM_BUF (MAXIMUM(MAX_INT_SPRINTF_LEN,MAX_FLOAT_SPRINTF_LEN))
|
3aff75 | 2008-08-26 | Stephen R. van den Berg | |
|
8580bb | 2017-01-02 | Martin Nilsson | | static int has_lfun(enum LFUN lfun, int arg);
|
c17a08 | 2017-01-02 | Martin Nilsson | | static int call_lfun(enum LFUN left, enum LFUN right);
|
8580bb | 2017-01-02 | Martin Nilsson | | static int call_lhs_lfun(enum LFUN lfun, int arg);
|
b83b37 | 2016-12-31 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(*what))
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
case T_ARRAY:
simple_array_index_no_free(to,what->u.array,ind);
break;
case T_MAPPING:
mapping_index_no_free(to,what->u.mapping,ind);
break;
case T_OBJECT:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | object_index_no_free(to, what->u.object, SUBTYPEOF(*what), ind);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | break;
case T_MULTISET: {
int i=multiset_member(what->u.multiset, ind);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(*to, T_INT, i ? NUMBER_NUMBER : NUMBER_UNDEFINED, integer, i);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | break;
}
case T_STRING:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(*ind) == T_INT)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
ptrdiff_t len = what->u.string->len;
INT_TYPE p = ind->u.integer;
INT_TYPE i = p < 0 ? p + len : p;
if(i<0 || i>=len)
{
if(len == 0)
Pike_error("Attempt to index the empty string with %"PRINTPIKEINT"d.\n", i);
else
Pike_error("Index %"PRINTPIKEINT"d is out of string range "
"%"PRINTPTRDIFFT"d..%"PRINTPTRDIFFT"d.\n",
i, -len, len - 1);
} else
i=index_shared_string(what->u.string,i);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(*to, T_INT, NUMBER_NUMBER, integer, i);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | break;
}else{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(*ind) == T_STRING)
|
9606eb | 2004-11-12 | Henrik Grubbström (Grubba) | | Pike_error ("Expected integer as string index, got \"%S\".\n",
ind->u.string);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | else
Pike_error ("Expected integer as string index, got %s.\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | get_name_of_type (TYPEOF(*ind)));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
case T_FUNCTION:
|
354bbe | 2007-09-24 | Henrik Grubbström (Grubba) | | case T_PROGRAM:
if (program_index_no_free(to, what, ind)) break;
goto index_error;
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
case T_INT:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(*ind) == T_STRING && !IS_UNDEFINED (what)) {
|
6898c0 | 2003-11-14 | Martin Stjernholm | | INT_TYPE val = what->u.integer;
convert_svalue_to_bignum(what);
index_no_free(to, what, ind);
if(IS_UNDEFINED(to)) {
if (val) {
|
9606eb | 2004-11-12 | Henrik Grubbström (Grubba) | | Pike_error("Indexing the integer %"PRINTPIKEINT"d "
"with unknown method \"%S\".\n",
val, ind->u.string);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | } else {
|
9606eb | 2004-11-12 | Henrik Grubbström (Grubba) | | Pike_error("Indexing the NULL value with \"%S\".\n",
ind->u.string);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
}
break;
}
|
5f5084 | 2018-02-12 | Marcus Comstedt | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
default:
|
354bbe | 2007-09-24 | Henrik Grubbström (Grubba) | | index_error:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(*ind) == T_INT)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | Pike_error ("Cannot index %s with %"PRINTPIKEINT"d.\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | (TYPEOF(*what) == T_INT && !what->u.integer)?
"the NULL value":get_name_of_type(TYPEOF(*what)),
|
6898c0 | 2003-11-14 | Martin Stjernholm | | ind->u.integer);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | else if (TYPEOF(*ind) == T_FLOAT)
|
484419 | 2009-06-30 | Martin Stjernholm | | Pike_error ("Cannot index %s with %"PRINTPIKEFLOAT"e.\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | (TYPEOF(*what) == T_INT && !what->u.integer)?
"the NULL value":get_name_of_type(TYPEOF(*what)),
|
6898c0 | 2003-11-14 | Martin Stjernholm | | ind->u.float_number);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | else if (TYPEOF(*ind) == T_STRING)
|
9606eb | 2004-11-12 | Henrik Grubbström (Grubba) | | Pike_error ("Cannot index %s with \"%S\".\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | (TYPEOF(*what) == T_INT && !what->u.integer)?
"the NULL value":get_name_of_type(TYPEOF(*what)),
|
9606eb | 2004-11-12 | Henrik Grubbström (Grubba) | | ind->u.string);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | else
Pike_error ("Cannot index %s with %s.\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | (TYPEOF(*what) == T_INT && !what->u.integer)?
"the NULL value":get_name_of_type(TYPEOF(*what)),
get_name_of_type (TYPEOF(*ind)));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
}
|
9d7108 | 2012-09-11 | Stefan Wallström | | PMOD_EXPORT void o_index(void)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
struct svalue s;
|
19961b | 2017-04-08 | Martin Nilsson | | index_no_free(&s,Pike_sp-2,Pike_sp-1);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | pop_n_elems(2);
|
19961b | 2017-04-08 | Martin Nilsson | | *Pike_sp=s;
dmalloc_touch_svalue(Pike_sp);
Pike_sp++;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | dmalloc_touch_svalue(Pike_sp-1);
}
|
e7a29a | 2007-12-28 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void o_cast_to_int(void)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
case T_OBJECT:
|
19961b | 2017-04-08 | Martin Nilsson | | if(!Pike_sp[-1].u.object->prog) {
|
ef8a14 | 2004-09-20 | Martin Stjernholm | |
pop_stack();
push_int (0);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
b83b37 | 2016-12-31 | Martin Nilsson | | else
{
|
19961b | 2017-04-08 | Martin Nilsson | | if( Pike_sp[-1].u.object->prog == bignum_program )
|
b83b37 | 2016-12-31 | Martin Nilsson | | return;
|
ef8a14 | 2004-09-20 | Martin Stjernholm | |
|
b83b37 | 2016-12-31 | Martin Nilsson | | ref_push_string(literal_int_string);
if(!call_lhs_lfun(LFUN_CAST,2))
Pike_error("No cast method in object <2>.\n");
stack_pop_keep_top();
|
ef8a14 | 2004-09-20 | Martin Stjernholm | |
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) != PIKE_T_INT)
|
ef8a14 | 2004-09-20 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) == T_OBJECT)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct object *o = Pike_sp[-1].u.object;
|
b83b37 | 2016-12-31 | Martin Nilsson | | if( o->prog == bignum_program )
return;
else if( o->prog )
{
ref_push_string(literal_int_string);
if( call_lhs_lfun(LFUN__IS_TYPE,2) )
|
19961b | 2017-04-08 | Martin Nilsson | | if( !UNSAFE_IS_ZERO(Pike_sp-1) )
|
b83b37 | 2016-12-31 | Martin Nilsson | | {
pop_stack();
return;
}
pop_stack();
}
|
efd379 | 2016-12-31 | Martin Nilsson | | }
|
b83b37 | 2016-12-31 | Martin Nilsson | | Pike_error("Cast failed, wanted int, got %s\n",
|
19961b | 2017-04-08 | Martin Nilsson | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
19961b | 2017-04-08 | Martin Nilsson | | else if(SUBTYPEOF(Pike_sp[-1]) == NUMBER_UNDEFINED)
|
c43e8c | 2014-08-16 | Martin Nilsson | | Pike_error("Cannot cast this object to int.\n");
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
break;
|
4998a9 | 2015-07-12 | Arne Goedeke | | case T_FLOAT: {
|
19961b | 2017-04-08 | Martin Nilsson | | FLOAT_TYPE f = Pike_sp[-1].u.float_number;
|
4998a9 | 2015-07-12 | Arne Goedeke | |
|
10b43e | 2016-01-10 | Martin Nilsson | | if ( PIKE_ISINF(f) || PIKE_ISNAN(f) )
|
4998a9 | 2015-07-12 | Arne Goedeke | | Pike_error("Can't cast infinites or NaN to int.\n");
|
18678b | 2016-12-30 | Martin Nilsson | |
|
4998a9 | 2015-07-12 | Arne Goedeke | |
if (UNLIKELY(f > MAX_INT_TYPE || f < MIN_INT_TYPE)) {
convert_stack_top_to_bignum();
} else {
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, f);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
4998a9 | 2015-07-12 | Arne Goedeke | | break;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
13670c | 2015-05-25 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_STRING:
|
19961b | 2017-04-08 | Martin Nilsson | | if( (Pike_sp[-1].u.string->len >= 10) || Pike_sp[-1].u.string->size_shift )
|
6898c0 | 2003-11-14 | Martin Stjernholm | | convert_stack_top_string_to_inumber(10);
|
2f260d | 2009-11-05 | Henrik Grubbström (Grubba) | | else
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | INT_TYPE i = strtol(Pike_sp[-1].u.string->str, 0, 10);
free_string(Pike_sp[-1].u.string);
SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, i);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
break;
case PIKE_T_INT:
break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | default:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_error("Cannot cast %s to int.\n", get_name_of_type(TYPEOF(Pike_sp[-1])));
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
}
|
e68c78 | 2006-07-05 | Martin Stjernholm | | PMOD_EXPORT void o_cast_to_string(void)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | | struct pike_string *s;
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
case T_OBJECT:
|
19961b | 2017-04-08 | Martin Nilsson | | if(!Pike_sp[-1].u.object->prog) {
|
ef8a14 | 2004-09-20 | Martin Stjernholm | |
pop_stack();
|
af40e4 | 2004-09-20 | Henrik Grubbström (Grubba) | | push_constant_text("0");
|
b83b37 | 2016-12-31 | Martin Nilsson | | } else
{
ref_push_string(literal_string_string);
if(!call_lhs_lfun(LFUN_CAST,2))
Pike_error("No cast method in object.\n");
stack_pop_keep_top();
|
ef8a14 | 2004-09-20 | Martin Stjernholm | |
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) != PIKE_T_STRING)
|
ef8a14 | 2004-09-20 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1])==PIKE_T_INT && SUBTYPEOF(Pike_sp[-1])==NUMBER_UNDEFINED)
|
c43e8c | 2014-08-16 | Martin Nilsson | | Pike_error("Cannot cast this object to string.\n");
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) == T_OBJECT && Pike_sp[-1].u.object->prog)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
b83b37 | 2016-12-31 | Martin Nilsson | | ref_push_string(literal_string_string);
if( call_lhs_lfun( LFUN__IS_TYPE,2 ) )
|
19961b | 2017-04-08 | Martin Nilsson | | if( !UNSAFE_IS_ZERO(Pike_sp-1) )
|
b83b37 | 2016-12-31 | Martin Nilsson | | {
pop_stack();
return;
}
pop_stack();
}
|
ef8a14 | 2004-09-20 | Martin Stjernholm | | Pike_error("Cast failed, wanted string, got %s\n",
|
19961b | 2017-04-08 | Martin Nilsson | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
}
|
08261e | 2008-08-24 | Stephen R. van den Berg | | return;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_ARRAY:
{
|
10c663 | 2009-02-06 | Stephen R. van den Berg | | int i, alen;
|
19961b | 2017-04-08 | Martin Nilsson | | struct array *a = Pike_sp[-1].u.array;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | int shift = 0;
|
10c663 | 2009-02-06 | Stephen R. van den Berg | | alen = a->size;
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
|
10c663 | 2009-02-06 | Stephen R. van den Berg | | for(i = 0; i<alen; i++) {
|
e956bb | 2008-07-11 | Martin Stjernholm | | INT_TYPE val;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(a->item[i]) != T_INT) {
|
10c663 | 2009-02-06 | Stephen R. van den Berg | | Pike_error(
"Can only cast array(int) to string, item %d is not an integer: %O\n",
i, a->item + i);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
e956bb | 2008-07-11 | Martin Stjernholm | | val = a->item[i].u.integer;
switch (shift) {
case 0:
if ((unsigned INT32) val <= 0xff)
break;
shift = 1;
|
ff2bc9 | 2018-02-15 | Martin Nilsson | |
|
e956bb | 2008-07-11 | Martin Stjernholm | |
case 1:
if ((unsigned INT32) val <= 0xffff)
break;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | shift = 2;
|
ff2bc9 | 2018-02-15 | Martin Nilsson | |
|
e956bb | 2008-07-11 | Martin Stjernholm | |
case 2:
#if SIZEOF_INT_TYPE > 4
if (val < MIN_INT32 || val > MAX_INT32)
|
368623 | 2014-08-18 | Martin Nilsson | | Pike_error ("Item %d is too large: %"PRINTPIKEINT"x.\n",
|
e956bb | 2008-07-11 | Martin Stjernholm | | i, val);
#endif
|
6898c0 | 2003-11-14 | Martin Stjernholm | | break;
}
}
|
e956bb | 2008-07-11 | Martin Stjernholm | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | s = begin_wide_shared_string(a->size, shift);
switch(shift) {
case 0:
for(i = a->size; i--; ) {
|
e956bb | 2008-07-11 | Martin Stjernholm | | s->str[i] = (p_wchar0) a->item[i].u.integer;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
break;
case 1:
{
p_wchar1 *str1 = STR1(s);
for(i = a->size; i--; ) {
|
e956bb | 2008-07-11 | Martin Stjernholm | | str1[i] = (p_wchar1) a->item[i].u.integer;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
}
break;
case 2:
{
p_wchar2 *str2 = STR2(s);
for(i = a->size; i--; ) {
|
e956bb | 2008-07-11 | Martin Stjernholm | | str2[i] = (p_wchar2) a->item[i].u.integer;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
}
break;
}
pop_stack();
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | | push_string(end_shared_string(s));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
08261e | 2008-08-24 | Stephen R. van den Berg | | return;
|
ef8a14 | 2004-09-20 | Martin Stjernholm | |
|
3aff75 | 2008-08-26 | Stephen R. van den Berg | | default:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_error("Cannot cast %s to string.\n", get_name_of_type(TYPEOF(Pike_sp[-1])));
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
3aff75 | 2008-08-26 | Stephen R. van den Berg | |
case PIKE_T_STRING:
return;
|
08261e | 2008-08-24 | Stephen R. van den Berg | | case T_FLOAT:
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | | {
char buf[MAX_FLOAT_SPRINTF_LEN+1];
|
19961b | 2017-04-08 | Martin Nilsson | | format_pike_float (buf, Pike_sp[-1].u.float_number);
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | | s = make_shared_string(buf);
break;
}
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
|
3aff75 | 2008-08-26 | Stephen R. van den Berg | | case T_INT:
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | | {
INT_TYPE org;
char buf[MAX_INT_SPRINTF_LEN];
|
636bc5 | 2014-11-01 | Martin Nilsson | | char *b = buf+sizeof buf-1;
unsigned INT_TYPE i;
|
19961b | 2017-04-08 | Martin Nilsson | | org = Pike_sp[-1].u.integer;
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | | *b-- = '\0';
i = org;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | | if( org < 0 )
i = -i;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | | goto jin;
do
{
i /= 10;
jin: *b-- = '0'+(i%10);
}
while( i >= 10 );
|
13670c | 2015-05-25 | Martin Nilsson | |
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | | if( org < 0 )
*b = '-';
else
b++;
s = make_shared_string(b);
}
|
3aff75 | 2008-08-26 | Stephen R. van den Berg | | break;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
1d3721 | 2010-02-23 | Stephen R. van den Berg | |
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], PIKE_T_STRING, 0, string, s);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
e7a29a | 2007-12-28 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void o_cast(struct pike_type *type, INT32 run_time_type)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(run_time_type != TYPEOF(Pike_sp[-1]))
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
if(run_time_type == T_MIXED)
return;
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-1]) == T_OBJECT && !Pike_sp[-1].u.object->prog) {
|
ef8a14 | 2004-09-20 | Martin Stjernholm | |
pop_stack();
push_int (0);
}
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) == T_OBJECT)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct object *o = Pike_sp[-1].u.object;
int f = FIND_LFUN(o->prog->inherits[SUBTYPEOF(Pike_sp[-1])].prog, LFUN_CAST);
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | | if(f == -1) {
|
3f3075 | 2016-01-11 | Martin Nilsson | | if (run_time_type == T_MAPPING) {
stack_dup();
f_indices(1);
stack_swap();
f_values(1);
f_mkmapping(2);
goto emulated_type_ok;
}
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | | if (run_time_type != T_PROGRAM) {
Pike_error("No cast method in object.\n");
}
f_object_program(1);
return;
}
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(get_name_of_type(type->type));
|
af40e4 | 2004-09-20 | Henrik Grubbström (Grubba) | | apply_low(o, f, 1);
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | |
if (run_time_type == T_PROGRAM) {
if (IS_UNDEFINED(Pike_sp-1)) {
pop_stack();
f_object_program(1);
return;
}
}
|
ef8a14 | 2004-09-20 | Martin Stjernholm | | stack_pop_keep_top();
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | |
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) == T_INT &&
SUBTYPEOF(Pike_sp[-1]) == NUMBER_UNDEFINED)
|
71e54e | 2014-08-18 | Martin Nilsson | | Pike_error("Cannot cast this object to %s.\n",
get_name_of_type(type->type));
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | | } else
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
|
6b336f | 2015-05-01 | Martin Nilsson | | switch(run_time_type)
{
|
6898c0 | 2003-11-14 | Martin Stjernholm | | default:
Pike_error("Cannot perform cast to that type.\n");
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
case T_MULTISET:
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
6b336f | 2015-05-01 | Martin Nilsson | | case T_ARRAY:
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
f_mkmultiset(1);
break;
}
|
6b336f | 2015-05-01 | Martin Nilsson | | default:
Pike_error("Cannot cast %s to multiset.\n",
|
19961b | 2017-04-08 | Martin Nilsson | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
break;
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_MAPPING:
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
6b336f | 2015-05-01 | Martin Nilsson | | case T_ARRAY:
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct array *a=Pike_sp[-1].u.array;
|
6b336f | 2015-05-01 | Martin Nilsson | | struct array *b;
struct mapping *m;
INT32 i;
m=allocate_mapping(a->size);
push_mapping(m);
for (i=0; i<a->size; i++)
{
if (TYPEOF(ITEM(a)[i]) != T_ARRAY)
Pike_error("Cast array to mapping: "
"element %d is not an array\n", i);
b=ITEM(a)[i].u.array;
if (b->size!=2)
Pike_error("Cast array to mapping: "
"element %d is not an array of size 2\n", i);
mapping_insert(m,ITEM(b)+0,ITEM(b)+1);
}
stack_swap();
pop_n_elems(1);
break;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
6b336f | 2015-05-01 | Martin Nilsson | | default:
Pike_error("Cannot cast %s to mapping.\n",
|
19961b | 2017-04-08 | Martin Nilsson | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
break;
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_ARRAY:
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
6b336f | 2015-05-01 | Martin Nilsson | | case T_MAPPING:
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct array *a=mapping_to_array(Pike_sp[-1].u.mapping);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | pop_stack();
push_array(a);
break;
}
|
6b336f | 2015-05-01 | Martin Nilsson | | case T_STRING:
f_values(1);
break;
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
|
6b336f | 2015-05-01 | Martin Nilsson | | case T_MULTISET:
f_indices(1);
break;
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
|
6b336f | 2015-05-01 | Martin Nilsson | | default:
Pike_error("Cannot cast %s to array.\n",
|
19961b | 2017-04-08 | Martin Nilsson | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
break;
|
6b336f | 2015-05-01 | Martin Nilsson | |
case T_INT:
o_cast_to_int();
return;
case T_STRING:
o_cast_to_string();
return;
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
case T_FLOAT:
|
6b336f | 2015-05-01 | Martin Nilsson | | {
FLOAT_TYPE f = 0.0;
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
6b336f | 2015-05-01 | Martin Nilsson | | {
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | f=(FLOAT_TYPE)(Pike_sp[-1].u.integer);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | break;
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_STRING:
|
9e10fe | 2020-06-06 | Marcus Comstedt | | #if SIZEOF_FLOAT_TYPE > SIZEOF_DOUBLE
f =
(FLOAT_TYPE)STRTOLD_PCHARP(MKPCHARP(Pike_sp[-1].u.string->str,
Pike_sp[-1].u.string->size_shift),
0);
#else
|
6898c0 | 2003-11-14 | Martin Stjernholm | | f =
|
19961b | 2017-04-08 | Martin Nilsson | | (FLOAT_TYPE)STRTOD_PCHARP(MKPCHARP(Pike_sp[-1].u.string->str,
Pike_sp[-1].u.string->size_shift),
|
6898c0 | 2003-11-14 | Martin Stjernholm | | 0);
|
9e10fe | 2020-06-06 | Marcus Comstedt | | #endif
|
19961b | 2017-04-08 | Martin Nilsson | | free_string(Pike_sp[-1].u.string);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | break;
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | default:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | Pike_error("Cannot cast %s to float.\n",
|
19961b | 2017-04-08 | Martin Nilsson | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
6b336f | 2015-05-01 | Martin Nilsson | | }
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_FLOAT, 0, float_number, f);
|
6b336f | 2015-05-01 | Martin Nilsson | | break;
}
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_OBJECT:
|
2a74cb | 2018-03-25 | Henrik Grubbström (Grubba) | | {
struct program *p = program_from_type(type);
if (p) {
struct svalue s;
SET_SVAL(s, T_PROGRAM, 0, program, p);
apply_svalue(&s, 1);
return;
}
}
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
6b336f | 2015-05-01 | Martin Nilsson | | case T_STRING: {
struct pike_string *file;
INT_TYPE lineno;
if(Pike_fp->pc &&
|
f14ace | 2019-02-02 | Henrik Grubbström (Grubba) | | (file = low_get_line(Pike_fp->pc, Pike_fp->context->prog,
&lineno, NULL))) {
|
6b336f | 2015-05-01 | Martin Nilsson | | push_string(file);
}else{
push_int(0);
}
APPLY_MASTER("cast_to_object",2);
return;
}
case T_FUNCTION:
if (SUBTYPEOF(Pike_sp[-1]) == FUNCTION_BUILTIN) {
Pike_error("Cannot cast builtin functions to object.\n");
} else if (Pike_sp[-1].u.object->prog == pike_trampoline_program) {
ref_push_object(((struct pike_trampoline *)
(Pike_sp[-1].u.object->storage))->
frame->current_object);
stack_pop_keep_top();
} else {
SET_SVAL_TYPE(Pike_sp[-1], T_OBJECT);
SET_SVAL_SUBTYPE(Pike_sp[-1], 0);
}
break;
default:
Pike_error("Cannot cast %s to object.\n",
|
19961b | 2017-04-08 | Martin Nilsson | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
break;
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_PROGRAM:
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
6b336f | 2015-05-01 | Martin Nilsson | | {
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_STRING: {
struct pike_string *file;
|
ef24a8 | 2012-01-12 | Henrik Grubbström (Grubba) | | INT_TYPE lineno;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | if(Pike_fp->pc &&
|
f14ace | 2019-02-02 | Henrik Grubbström (Grubba) | | (file = low_get_line(Pike_fp->pc, Pike_fp->context->prog,
&lineno, NULL))) {
|
6898c0 | 2003-11-14 | Martin Stjernholm | | push_string(file);
}else{
push_int(0);
}
APPLY_MASTER("cast_to_program",2);
return;
}
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | case T_FUNCTION:
|
6b336f | 2015-05-01 | Martin Nilsson | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct program *p=program_from_function(Pike_sp-1);
|
6b336f | 2015-05-01 | Martin Nilsson | | if(p)
{
add_ref(p);
pop_stack();
push_program(p);
}else{
pop_stack();
push_int(0);
}
}
return;
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
|
fe46a5 | 2014-02-26 | Henrik Grubbström (Grubba) | | case PIKE_T_TYPE:
|
6b336f | 2015-05-01 | Martin Nilsson | | {
struct pike_type *t = Pike_sp[-1].u.type;
struct program *p = program_from_type(t);
pop_stack();
if (p) {
ref_push_program(p);
} else {
push_int(0);
}
return;
}
|
fe46a5 | 2014-02-26 | Henrik Grubbström (Grubba) | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | default:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | Pike_error("Cannot cast %s to a program.\n",
|
19961b | 2017-04-08 | Martin Nilsson | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
6b336f | 2015-05-01 | Martin Nilsson | | }
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
}
|
19961b | 2017-04-08 | Martin Nilsson | | if(run_time_type != TYPEOF(Pike_sp[-1]))
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1])) {
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | | case T_OBJECT:
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.object->prog)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct object *o = Pike_sp[-1].u.object;
int f = FIND_LFUN(o->prog->inherits[SUBTYPEOF(Pike_sp[-1])].prog,
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | | LFUN__IS_TYPE);
if( f != -1)
{
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(get_name_of_type(run_time_type));
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | | apply_low(o, f, 1);
|
19961b | 2017-04-08 | Martin Nilsson | | f=!UNSAFE_IS_ZERO(Pike_sp-1);
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | | pop_stack();
if(f) goto emulated_type_ok;
}
}
break;
case T_FUNCTION:
if ((run_time_type == T_PROGRAM) &&
|
19961b | 2017-04-08 | Martin Nilsson | | program_from_function(Pike_sp-1)) {
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | | return;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
6e5a75 | 2012-10-27 | Henrik Grubbström (Grubba) | | break;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
Pike_error("Cast failed, wanted %s, got %s\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | get_name_of_type(run_time_type),
|
19961b | 2017-04-08 | Martin Nilsson | | get_name_of_type(TYPEOF(Pike_sp[-1])));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
6b336f | 2015-05-01 | Martin Nilsson | | emulated_type_ok:
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
if (!type) return;
switch(run_time_type)
{
|
6b336f | 2015-05-01 | Martin Nilsson | | case T_ARRAY:
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
struct pike_type *itype;
INT32 run_time_itype;
push_type_value(itype = index_type(type, int_type_string, 0));
run_time_itype = compile_type_to_runtime_type(itype);
if(run_time_itype != T_MIXED)
{
struct array *a;
|
19961b | 2017-04-08 | Martin Nilsson | | struct array *tmp=Pike_sp[-2].u.array;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | DECLARE_CYCLIC();
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | if((a=(struct array *)BEGIN_CYCLIC(tmp,0)))
{
ref_push_array(a);
}else{
INT32 e;
TYPE_FIELD types = 0;
#ifdef PIKE_DEBUG
|
19961b | 2017-04-08 | Martin Nilsson | | struct svalue *save_sp=Pike_sp+1;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | #endif
push_array(a=allocate_array(tmp->size));
SET_CYCLIC_RET(a);
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | for(e=0;e<a->size;e++)
{
push_svalue(tmp->item+e);
o_cast(itype, run_time_itype);
stack_pop_to_no_free (ITEM(a) + e);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | types |= 1 << TYPEOF(ITEM(a)[e]);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
a->type_field = types;
#ifdef PIKE_DEBUG
|
19961b | 2017-04-08 | Martin Nilsson | | if(save_sp!=Pike_sp)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | Pike_fatal("o_cast left stack droppings.\n");
#endif
}
END_CYCLIC();
|
19961b | 2017-04-08 | Martin Nilsson | | assign_svalue(Pike_sp-3,Pike_sp-1);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | pop_stack();
}
pop_stack();
}
break;
|
6b336f | 2015-05-01 | Martin Nilsson | | case T_MULTISET:
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
struct pike_type *itype;
INT32 run_time_itype;
push_type_value(itype = key_type(type, 0));
run_time_itype = compile_type_to_runtime_type(itype);
if(run_time_itype != T_MIXED)
{
struct multiset *m;
|
19961b | 2017-04-08 | Martin Nilsson | | struct multiset *tmp=Pike_sp[-2].u.multiset;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | DECLARE_CYCLIC();
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | if((m=(struct multiset *)BEGIN_CYCLIC(tmp,0)))
{
ref_push_multiset(m);
}else{
#ifdef PIKE_DEBUG
|
19961b | 2017-04-08 | Martin Nilsson | | struct svalue *save_sp=Pike_sp+1;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | #endif
ptrdiff_t nodepos;
push_multiset (m = allocate_multiset (multiset_sizeof (tmp),
multiset_get_flags (tmp),
multiset_get_cmp_less (tmp)));
SET_CYCLIC_RET(m);
if ((nodepos = multiset_first (tmp)) >= 0) {
ONERROR uwp;
SET_ONERROR (uwp, do_sub_msnode_ref, tmp);
do {
push_multiset_index (tmp, nodepos);
o_cast(itype, run_time_itype);
|
19961b | 2017-04-08 | Martin Nilsson | | multiset_insert (m, Pike_sp - 1);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | pop_stack();
} while ((nodepos = multiset_next (tmp, nodepos)) >= 0);
UNSET_ONERROR (uwp);
sub_msnode_ref (tmp);
}
#ifdef PIKE_DEBUG
|
19961b | 2017-04-08 | Martin Nilsson | | if(save_sp!=Pike_sp)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | Pike_fatal("o_cast left stack droppings.\n");
#endif
}
END_CYCLIC();
|
19961b | 2017-04-08 | Martin Nilsson | | assign_svalue(Pike_sp-3,Pike_sp-1);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | pop_stack();
}
pop_stack();
}
break;
|
6b336f | 2015-05-01 | Martin Nilsson | | case T_MAPPING:
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
struct pike_type *itype, *vtype;
INT32 run_time_itype;
INT32 run_time_vtype;
push_type_value(itype = key_type(type, 0));
run_time_itype = compile_type_to_runtime_type(itype);
push_type_value(vtype = index_type(type, mixed_type_string, 0));
run_time_vtype = compile_type_to_runtime_type(vtype);
if(run_time_itype != T_MIXED ||
run_time_vtype != T_MIXED)
{
struct mapping *m;
|
19961b | 2017-04-08 | Martin Nilsson | | struct mapping *tmp=Pike_sp[-3].u.mapping;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | DECLARE_CYCLIC();
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | if((m=(struct mapping *)BEGIN_CYCLIC(tmp,0)))
{
ref_push_mapping(m);
}else{
INT32 e;
struct keypair *k;
|
fa666b | 2004-04-15 | Martin Nilsson | | struct mapping_data *md;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
19961b | 2017-04-08 | Martin Nilsson | | struct svalue *save_sp=Pike_sp+1;
|
6898c0 | 2003-11-14 | Martin Stjernholm | | #endif
push_mapping(m=allocate_mapping(m_sizeof(tmp)));
|
6b336f | 2015-05-01 | Martin Nilsson | |
|
6898c0 | 2003-11-14 | Martin Stjernholm | | SET_CYCLIC_RET(m);
|
fa666b | 2004-04-15 | Martin Nilsson | |
md = tmp->data;
NEW_MAPPING_LOOP(md)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | {
push_svalue(& k->ind);
o_cast(itype, run_time_itype);
push_svalue(& k->val);
o_cast(vtype, run_time_vtype);
|
19961b | 2017-04-08 | Martin Nilsson | | mapping_insert(m,Pike_sp-2,Pike_sp-1);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | pop_n_elems(2);
}
#ifdef PIKE_DEBUG
|
19961b | 2017-04-08 | Martin Nilsson | | if(save_sp!=Pike_sp)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | Pike_fatal("o_cast left stack droppings.\n");
#endif
}
END_CYCLIC();
|
19961b | 2017-04-08 | Martin Nilsson | | assign_svalue(Pike_sp-4,Pike_sp-1);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | pop_stack();
}
pop_n_elems(2);
}
}
}
PMOD_EXPORT void f_cast(void)
{
#ifdef PIKE_DEBUG
|
19961b | 2017-04-08 | Martin Nilsson | | struct svalue *save_sp=Pike_sp;
if(TYPEOF(Pike_sp[-2]) != T_TYPE)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | Pike_fatal("Cast expression destroyed stack or left droppings! (Type:%d)\n",
|
19961b | 2017-04-08 | Martin Nilsson | | TYPEOF(Pike_sp[-2]));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | #endif
|
19961b | 2017-04-08 | Martin Nilsson | | o_cast(Pike_sp[-2].u.type,
compile_type_to_runtime_type(Pike_sp[-2].u.type));
|
6898c0 | 2003-11-14 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
19961b | 2017-04-08 | Martin Nilsson | | if(save_sp != Pike_sp)
|
6898c0 | 2003-11-14 | Martin Stjernholm | | Pike_fatal("Internal error: o_cast() left droppings on stack.\n");
#endif
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp-2);
Pike_sp[-2]=Pike_sp[-1];
Pike_sp--;
dmalloc_touch_svalue(Pike_sp);
|
6898c0 | 2003-11-14 | Martin Stjernholm | | }
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | |
int low_check_soft_cast(struct svalue *s, struct pike_type *type)
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | | {
loop:
switch(type->type) {
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | case T_MIXED: return 1;
case T_ZERO:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch(TYPEOF(*s)) {
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | case PIKE_T_INT:
return !s->u.integer;
case PIKE_T_FUNCTION:
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (SUBTYPEOF(*s) == FUNCTION_BUILTIN) return 0;
|
5f5084 | 2018-02-12 | Marcus Comstedt | |
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | case PIKE_T_OBJECT:
return !s->u.object->prog;
}
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | | return 0;
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | case T_ASSIGN:
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | | case PIKE_T_NAME:
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | type = type->cdr;
goto loop;
|
c497ac | 2018-05-31 | Henrik Grubbström (Grubba) | | case PIKE_T_ATTRIBUTE:
{
int ret;
if (!low_check_soft_cast(s, type->cdr)) return 0;
push_svalue(s);
ref_push_string((struct pike_string *)type->car);
SAFE_MAYBE_APPLY_MASTER("handle_attribute", 2);
ret = !SAFE_IS_ZERO(Pike_sp-1) || IS_UNDEFINED(Pike_sp-1);
pop_stack();
return ret;
}
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | | case T_AND:
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | if (!low_check_soft_cast(s, type->car)) return 0;
type = type->cdr;
goto loop;
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | | case T_OR:
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | 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);
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(*s) == PIKE_T_INT) && !s->u.integer) return 1;
if (TYPEOF(*s) == type->type) {
|
47e181 | 2013-02-19 | Henrik Grubbström (Grubba) | | switch(type->type) {
case PIKE_T_INT:
|
cba109 | 2007-04-26 | Henrik Grubbström (Grubba) | | 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;
|
47e181 | 2013-02-19 | Henrik Grubbström (Grubba) | | case PIKE_T_FLOAT:
return 1;
case PIKE_T_STRING:
|
cba109 | 2007-04-26 | Henrik Grubbström (Grubba) | | if ((8<<s->u.string->size_shift) > CAR_TO_INT(type)) {
return 0;
}
return 1;
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | case PIKE_T_OBJECT:
{
struct program *p;
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);
}
case PIKE_T_PROGRAM:
{
struct program *p;
if (!type->car->cdr) return 1;
if (s->u.program->id == CDR_TO_INT(type->car)) return 1;
p = id_to_program(CDR_TO_INT(type->car));
if (!p) return 1;
return implements(s->u.program, p);
}
case PIKE_T_ARRAY:
{
struct array *a = s->u.array;
int i;
for (i = a->size; i--;) {
if (!low_check_soft_cast(a->item + i, type->car)) return 0;
}
}
break;
case PIKE_T_MULTISET:
break;
case PIKE_T_MAPPING:
break;
case PIKE_T_FUNCTION:
break;
case PIKE_T_TYPE:
break;
}
return 1;
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(*s) == PIKE_T_OBJECT) {
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | int lfun;
if (!s->u.object->prog) return 0;
if (type->type == PIKE_T_FUNCTION) {
if ((lfun = FIND_LFUN(s->u.object->prog, LFUN_CALL)) != -1) {
return 1;
}
}
if ((lfun = FIND_LFUN(s->u.object->prog, LFUN__IS_TYPE)) != -1) {
int ret;
|
5e9fc0 | 2015-08-18 | Per Hedbor | | push_static_text(get_name_of_type(type->type));
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | apply_low(s->u.object, lfun, 1);
ret = !UNSAFE_IS_ZERO(Pike_sp-1);
pop_stack();
return ret;
}
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | | return 0;
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(*s) == PIKE_T_FUNCTION) && (type->type == PIKE_T_PROGRAM)) {
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | |
return 1;
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((TYPEOF(*s) == PIKE_T_FUNCTION) && (type->type == T_MANY)) {
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | |
return 1;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | return 0;
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | | }
void o_check_soft_cast(struct svalue *s, struct pike_type *type)
{
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | if (!low_check_soft_cast(s, type)) {
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | | * for array, mapping and multiset, so we perform a more lenient
* check for them.
*/
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | struct pike_type *sval_type = get_type_of_svalue(s);
struct pike_string *t1;
|
4d404a | 2013-02-19 | Henrik Grubbström (Grubba) | | struct string_builder s;
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | char *fname = "__soft-cast";
|
4d404a | 2013-02-19 | Henrik Grubbström (Grubba) | | ONERROR tmp0;
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | ONERROR tmp1;
|
4d404a | 2013-02-19 | Henrik Grubbström (Grubba) | |
init_string_builder(&s, 0);
SET_ONERROR(tmp0, free_string_builder, &s);
string_builder_explain_nonmatching_types(&s, type, sval_type);
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | |
|
fa93a5 | 2008-02-28 | Henrik Grubbström (Grubba) | | if (Pike_fp->current_program) {
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | |
struct pike_string *name =
|
fa93a5 | 2008-02-28 | Henrik Grubbström (Grubba) | | ID_FROM_INT(Pike_fp->current_program, Pike_fp->fun)->name;
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | if ((!name->size_shift) && (name->len < 100))
fname = name->str;
}
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | |
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | t1 = describe_type(type);
SET_ONERROR(tmp1, do_free_string, t1);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
b5955a | 2006-08-21 | Henrik Grubbström (Grubba) | | free_type(sval_type);
|
212c39 | 2018-02-25 | Martin Nilsson | | bad_arg_error(NULL, -1, 1, t1->str, Pike_sp-1,
|
4d404a | 2013-02-19 | Henrik Grubbström (Grubba) | | "%s(): Soft cast failed.\n%S",
fname, s.s);
|
9282fd | 2015-09-27 | Martin Nilsson | |
UNREACHABLE(CALL_AND_UNSET_ONERROR(tmp1));
UNREACHABLE(CALL_AND_UNSET_ONERROR(tmp0));
|
257fcd | 2006-08-15 | Henrik Grubbström (Grubba) | | }
}
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | #define COMPARISON(ID,NAME,FUN) \
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void ID(INT32 args) \
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | { \
int i; \
switch(args) \
{ \
case 0: case 1: \
|
06bd61 | 2016-01-26 | Martin Nilsson | | SIMPLE_WRONG_NUM_ARGS_ERROR(NAME, 2); \
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | case 2: \
|
19961b | 2017-04-08 | Martin Nilsson | | i=FUN (Pike_sp-2,Pike_sp-1); \
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2); \
push_int(i); \
break; \
default: \
for(i=1;i<args;i++) \
|
19961b | 2017-04-08 | Martin Nilsson | | if(! ( FUN (Pike_sp-args+i-1, Pike_sp-args+i))) \
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | break; \
pop_n_elems(args); \
push_int(i==args); \
} \
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | |
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Inequality test.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! 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)@}.
*!
*! This is the inverse of @[`==()]; see that function for further
*! details.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @returns
*! Returns @expr{1@} if the test is successful, @expr{0@}
*! otherwise.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`==()]
*/
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_ne(INT32 args)
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | {
f_eq(args);
|
18678b | 2016-12-30 | Martin Nilsson | |
Pike_sp[-1].u.integer = !Pike_sp[-1].u.integer;
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | }
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | |
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Equality test.
*!
*! 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 more than two arguments are given, each argument is compared
*! with the following one as described below, and the test is
*! successful iff all comparisons are successful.
*!
*! If the first argument is an object with an @[lfun::`==()], that
|
75dc29 | 2005-01-14 | Martin Nilsson | | *! function is called with the second as argument, unless the
*! second argument is the same as the first argument. The test is
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! successful iff its result is nonzero (according to @[`!]).
*!
*! Otherwise, if the second argument is an object with an
*! @[lfun::`==()], that function is called with the first as
*! argument, and the test is successful iff its result is nonzero
*! (according to @[`!]).
*!
*! Otherwise, if the arguments are of different types, the test is
*! unsuccessful. Function pointers to programs are automatically
*! converted to program pointers if necessary, though.
*!
*! Otherwise the test depends on the type of the arguments:
*! @mixed
*! @type int
*! Successful iff the two integers are numerically equal.
*! @type float
|
10789d | 2014-05-23 | Chris Angelico | | *! Successful iff the two floats are numerically equal and
*! not NaN.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type string
*! Successful iff the two strings are identical, character for
*! character. (Since all strings are kept unique, this is
*! actually a test whether the arguments point to the same
*! string, and it therefore run in constant time.)
*! @type array|mapping|multiset|object|function|program|type
*! Successful iff the two arguments point to the same instance.
*! @endmixed
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @returns
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Returns @expr{1@} if the test is successful, @expr{0@}
*! otherwise.
*!
*! @note
*! Floats and integers are not automatically converted to test
*! against each other, so e.g. @expr{0==0.0@} is false.
*!
*! @note
*! Programs are not automatically converted to types to be compared
*! type-wise.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @seealso
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @[`!()], @[`!=()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | COMPARISON(f_eq,"`==", is_eq)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | |
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Less than test.
*!
*! 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)@}.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @returns
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Returns @expr{1@} if the test is successful, @expr{0@}
*! otherwise.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`<=()], @[`>()], @[`>=()]
*/
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | COMPARISON(f_lt,"`<" , is_lt)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | |
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Less than or equal test.
*!
*! 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)@}.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @returns
|
f5971b | 2004-11-27 | Martin Stjernholm | | *! Returns @expr{1@} if the test is successful, @expr{0@}
*! otherwise.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
f5971b | 2004-11-27 | Martin Stjernholm | | *! @note
*! For total orders, e.g. integers, this is the inverse of @[`>()].
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`<()], @[`>()], @[`>=()]
*/
|
f5971b | 2004-11-27 | Martin Stjernholm | | COMPARISON(f_le,"`<=",is_le)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | |
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Greater than test.
*!
*! 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)@}.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @returns
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if the arguments are strictly decreasing, and
*! @expr{0@} (zero) otherwise.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`<()], @[`<=()], @[`>=()]
*/
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | COMPARISON(f_gt,"`>" , is_gt)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | |
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Greater than or equal test.
*!
*! 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)@}.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @returns
|
f5971b | 2004-11-27 | Martin Stjernholm | | *! Returns @expr{1@} if the test is successful, @expr{0@}
*! otherwise.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
f5971b | 2004-11-27 | Martin Stjernholm | | *! @note
*! For total orders, e.g. integers, this is the inverse of @[`<()].
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`<=()], @[`>()], @[`<()]
*/
|
f5971b | 2004-11-27 | Martin Stjernholm | | COMPARISON(f_ge,"`>=",is_ge)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
56a261 | 2005-09-15 | Henrik Grubbström (Grubba) | |
PMOD_EXPORT INT32 low_rop(struct object *o, int i, INT32 e, INT32 args)
{
if (e == args-1) {
ONERROR err;
Pike_sp--;
SET_ONERROR(err, do_free_object, o);
apply_low(o, i, e);
CALL_AND_UNSET_ONERROR(err);
return args - e;
} else {
struct svalue *tmp;
if (e*2 < args) {
tmp = xalloc(e*sizeof(struct svalue));
memcpy(tmp, Pike_sp-args, e*sizeof(struct svalue));
memmove(Pike_sp-args, (Pike_sp-args)+e,
(args-e)*sizeof(struct svalue));
memcpy(Pike_sp-e, tmp, e*sizeof(struct svalue));
} else {
tmp = xalloc((args-e)*sizeof(struct svalue));
memcpy(tmp, (Pike_sp-args)+e, (args-e)*sizeof(struct svalue));
memmove(Pike_sp-e, Pike_sp-args, e*sizeof(struct svalue));
memcpy(Pike_sp-args, tmp, (args-e)*sizeof(struct svalue));
}
free(tmp);
#ifdef PIKE_DEBUG
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(Pike_sp[-args]) != T_OBJECT ||
|
56a261 | 2005-09-15 | Henrik Grubbström (Grubba) | | Pike_sp[-args].u.object != o ||
!o->prog) {
Pike_fatal("low_rop() Lost track of object.\n");
}
#endif /* PIKE_DEBUG */
apply_low(o, i, e);
args -= e;
assign_svalue(Pike_sp-(args+1), Pike_sp-1);
pop_stack();
return args;
}
}
|
4799eb | 2017-01-03 | Martin Nilsson | | static void add_strings(INT32 args)
{
struct pike_string *r;
PCHARP buf;
ptrdiff_t tmp;
int max_shift=0;
ptrdiff_t size=0,e;
int num=0;
for(e=-args;e<0;e++)
{
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[e].u.string->len != 0) num++;
size += Pike_sp[e].u.string->len;
if(Pike_sp[e].u.string->size_shift > max_shift)
max_shift=Pike_sp[e].u.string->size_shift;
|
4799eb | 2017-01-03 | Martin Nilsson | | }
if(num == 0)
{
pop_n_elems(args-1);
return;
}
if(num == 1)
{
for(e=-args;e<0;e++)
{
|
19961b | 2017-04-08 | Martin Nilsson | | if( Pike_sp[e].u.string->len )
|
4799eb | 2017-01-03 | Martin Nilsson | | {
if( e != -args )
{
|
19961b | 2017-04-08 | Martin Nilsson | | r = Pike_sp[e].u.string;
Pike_sp[e].u.string = Pike_sp[-args].u.string;
Pike_sp[-args].u.string = r;
|
4799eb | 2017-01-03 | Martin Nilsson | | }
}
}
pop_n_elems(args-1);
return;
}
|
19961b | 2017-04-08 | Martin Nilsson | | tmp=Pike_sp[-args].u.string->len;
r=new_realloc_shared_string(Pike_sp[-args].u.string,size,max_shift);
mark_free_svalue (Pike_sp - args);
|
4799eb | 2017-01-03 | Martin Nilsson | | buf=MKPCHARP_STR_OFF(r,tmp);
for(e=-args+1;e<0;e++)
{
|
19961b | 2017-04-08 | Martin Nilsson | | if( Pike_sp[e].u.string->len )
|
4799eb | 2017-01-03 | Martin Nilsson | | {
|
19961b | 2017-04-08 | Martin Nilsson | | update_flags_for_add( r, Pike_sp[e].u.string );
pike_string_cpy(buf,Pike_sp[e].u.string);
INC_PCHARP(buf,Pike_sp[e].u.string->len);
|
4799eb | 2017-01-03 | Martin Nilsson | | }
|
979dc5 | 2017-06-20 | Henrik Grubbström (Grubba) | | free_string(Pike_sp[e].u.string);
|
4799eb | 2017-01-03 | Martin Nilsson | | }
Pike_sp -= args-1;
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_STRING, 0, string, low_end_shared_string(r));
|
4799eb | 2017-01-03 | Martin Nilsson | | }
|
c17a08 | 2017-01-02 | Martin Nilsson | | static int pair_add()
{
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) == PIKE_T_OBJECT ||
TYPEOF(Pike_sp[-2]) == PIKE_T_OBJECT)
|
c17a08 | 2017-01-02 | Martin Nilsson | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-2]) == PIKE_T_OBJECT &&
|
c17a08 | 2017-01-02 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp[-2].u.object->refs == 2 &&
|
c17a08 | 2017-01-02 | Martin Nilsson | | call_lhs_lfun(LFUN_ADD_EQ,2))
return 1;
if(call_lfun(LFUN_ADD, LFUN_RADD))
|
19961b | 2017-04-08 | Martin Nilsson | | return !IS_UNDEFINED(Pike_sp-1);
|
c17a08 | 2017-01-02 | Martin Nilsson | | }
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-2]) != TYPEOF(Pike_sp[-1]))
|
c17a08 | 2017-01-02 | Martin Nilsson | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(IS_UNDEFINED(Pike_sp-2))
|
c17a08 | 2017-01-02 | Martin Nilsson | | {
stack_swap();
pop_stack();
return 1;
}
|
19961b | 2017-04-08 | Martin Nilsson | | if(IS_UNDEFINED(Pike_sp-1))
|
c17a08 | 2017-01-02 | Martin Nilsson | | {
pop_stack();
return 1;
}
if( TYPEOF(Pike_sp[-2]) == PIKE_T_STRING )
o_cast_to_string();
else if( TYPEOF(Pike_sp[-1]) == PIKE_T_STRING )
{
stack_swap();
o_cast_to_string();
stack_swap();
}
else if( TYPEOF(Pike_sp[-2]) == PIKE_T_FLOAT )
{
if( TYPEOF(Pike_sp[-1]) == PIKE_T_INT )
{
Pike_sp[-1].u.float_number = Pike_sp[-1].u.integer;
TYPEOF(Pike_sp[-1]) = PIKE_T_FLOAT;
}
}
else if( TYPEOF(Pike_sp[-1]) == PIKE_T_FLOAT )
{
if( TYPEOF(Pike_sp[-2]) == PIKE_T_INT )
{
Pike_sp[-2].u.float_number = Pike_sp[-2].u.integer;
TYPEOF(Pike_sp[-2]) = PIKE_T_FLOAT;
}
}
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-2]) != TYPEOF(Pike_sp[-1]))
|
c17a08 | 2017-01-02 | Martin Nilsson | | return 0;
}
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
c17a08 | 2017-01-02 | Martin Nilsson | | {
case PIKE_T_INT:
{
INT_TYPE res;
|
19961b | 2017-04-08 | Martin Nilsson | | if (DO_INT_TYPE_ADD_OVERFLOW(Pike_sp[-2].u.integer, Pike_sp[-1].u.integer, &res))
|
c17a08 | 2017-01-02 | Martin Nilsson | | {
|
19961b | 2017-04-08 | Martin Nilsson | | convert_svalue_to_bignum(Pike_sp-2);
|
b0f528 | 2019-08-09 | Henrik Grubbström (Grubba) | | if (LIKELY(call_lfun(LFUN_ADD,LFUN_RADD))) {
return 1;
}
Pike_fatal("Failed to call `+() in bignum.\n");
|
c17a08 | 2017-01-02 | Martin Nilsson | | }
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp[-2].u.integer = res;
Pike_sp--;
|
c17a08 | 2017-01-02 | Martin Nilsson | | }
return 1;
case PIKE_T_FLOAT:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp[-2].u.float_number += Pike_sp[-1].u.float_number;
Pike_sp--;
|
c17a08 | 2017-01-02 | Martin Nilsson | | return 1;
case PIKE_T_STRING:
Pike_sp[-2].u.string = add_and_free_shared_strings(Pike_sp[-2].u.string,
Pike_sp[-1].u.string);
Pike_sp--;
return 1;
case PIKE_T_ARRAY:
|
19961b | 2017-04-08 | Martin Nilsson | | push_array( add_arrays(Pike_sp-2,2) );
|
c17a08 | 2017-01-02 | Martin Nilsson | | stack_swap(); pop_stack();
stack_swap(); pop_stack();
return 1;
case PIKE_T_MAPPING:
|
19961b | 2017-04-08 | Martin Nilsson | | push_mapping( add_mappings(Pike_sp-2,2) );
|
c17a08 | 2017-01-02 | Martin Nilsson | | stack_swap(); pop_stack();
stack_swap(); pop_stack();
return 1;
case PIKE_T_MULTISET:
|
19961b | 2017-04-08 | Martin Nilsson | | push_multiset( add_multisets(Pike_sp-2,2) );
|
c17a08 | 2017-01-02 | Martin Nilsson | | stack_swap(); pop_stack();
stack_swap(); pop_stack();
return 1;
case PIKE_T_OBJECT:
return call_lfun(LFUN_ADD,LFUN_RADD);
}
return 0;
}
|
09cae2 | 2003-11-12 | Martin Stjernholm | | |
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Addition/concatenation.
*!
*! 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)@}. Longer @expr{+@} expressions are
*! normally optimized to one call, so e.g. @expr{a+b+c@} becomes
*! @expr{predef::`+(a,b,c)@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there's a single argument, that argument is returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
09cae2 | 2003-11-12 | Martin Stjernholm | | *! If @[arg] is an object with only one reference and an
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @[lfun::`+=()], that function is called with the rest of the
*! arguments, and its result is returned.
|
5d9136 | 2003-04-18 | Martin Stjernholm | | *!
|
09cae2 | 2003-11-12 | Martin Stjernholm | | *! Otherwise, if @[arg] is an object with an @[lfun::`+()], that
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! function is called with the rest of the arguments, and its
|
5d9136 | 2003-04-18 | Martin Stjernholm | | *! result is returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise, if any of the other arguments is an object that has
*! an @[lfun::``+()], the first such function is called with the
*! arguments leading up to it, and @[`+()] is then called
|
5d9136 | 2003-04-18 | Martin Stjernholm | | *! recursively with the result and the rest of the arguments.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
09cae2 | 2003-11-12 | Martin Stjernholm | | *! Otherwise, if @[arg] is @[UNDEFINED] and the other arguments are
*! either arrays, mappings or multisets, the first argument is
*! ignored and the remaining are added together as described below.
*! This is useful primarily when appending to mapping values since
*! @expr{m[x] += ({foo})@} will work even if @expr{m[x]@} doesn't
*! exist yet.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *!
*! Otherwise the result depends on the argument types:
|
09cae2 | 2003-11-12 | Martin Stjernholm | | *! @mixed
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type int|float
|
09cae2 | 2003-11-12 | Martin Stjernholm | | *! The result is the sum of all the arguments. It's a float if
*! any argument is a float.
*! @type string|int|float
*! If any argument is a string, all will be converted to
*! strings and concatenated in order to form the result.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type array
|
09cae2 | 2003-11-12 | Martin Stjernholm | | *! The array arguments are concatened in order to form the
*! result.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type mapping
|
09cae2 | 2003-11-12 | Martin Stjernholm | | *! The result is like @[arg] but extended with the entries from
*! the other arguments. If the same index (according to
*! @[hash_value] and @[`==]) occur in several arguments, the
*! value from the last one is used.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type multiset
|
09cae2 | 2003-11-12 | Martin Stjernholm | | *! The result is like @[arg] but extended with the entries from
*! the other arguments. Subsequences with orderwise equal
*! indices (i.e. where @[`<] returns false) are concatenated
*! into the result in argument order.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @endmixed
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! The function is not destructive on the arguments - the result is
*! always a new instance.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @note
*! In Pike 7.0 and earlier the addition order was unspecified.
*!
|
09cae2 | 2003-11-12 | Martin Stjernholm | | *! The treatment of @[UNDEFINED] was new
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *! in Pike 7.0.
*!
*! @seealso
*! @[`-()], @[lfun::`+()], @[lfun::``+()]
*/
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_add(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
3bcf05 | 2017-01-03 | Martin Nilsson | | INT_TYPE e;
|
4799eb | 2017-01-03 | Martin Nilsson | | TYPE_FIELD types=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
c17a08 | 2017-01-02 | Martin Nilsson | | if(!args)
SIMPLE_WRONG_NUM_ARGS_ERROR("`+", 1);
|
08b3ec | 2011-04-08 | Henrik Grubbström (Grubba) | | if (args == 1) return;
|
19961b | 2017-04-08 | Martin Nilsson | | for(e=-args;e<0;e++) types |= 1<<TYPEOF(Pike_sp[e]);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | switch(types)
{
default:
|
4799eb | 2017-01-03 | Martin Nilsson | | pairwise_add:
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct svalue *s=Pike_sp-args;
|
4799eb | 2017-01-03 | Martin Nilsson | | push_svalue(s);
for(e=1;e<args;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
4799eb | 2017-01-03 | Martin Nilsson | | push_svalue(s+e);
if(!pair_add())
{
Pike_error("Addition on unsupported types: %s + %s\nm",
|
444843 | 2017-01-04 | Martin Nilsson | | get_name_of_type(TYPEOF(*(s+e))),
|
4799eb | 2017-01-03 | Martin Nilsson | | get_name_of_type(TYPEOF(*s)));
}
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
19961b | 2017-04-08 | Martin Nilsson | | assign_svalue(s,Pike_sp-1);
pop_n_elems(Pike_sp-s-1);
|
66769e | 1999-11-04 | Fredrik Hübinette (Hubbe) | | return;
}
|
992551 | 2013-05-31 | Per Hedbor | |
|
4799eb | 2017-01-03 | Martin Nilsson | | case BIT_STRING:
add_strings(args);
return;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
case BIT_STRING | BIT_INT:
case BIT_STRING | BIT_FLOAT:
case BIT_STRING | BIT_FLOAT | BIT_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | if ((TYPEOF(Pike_sp[-args]) != T_STRING) && (TYPEOF(Pike_sp[1-args]) != T_STRING))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
4799eb | 2017-01-03 | Martin Nilsson | |
goto pairwise_add;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
for(e=-args;e<0;e++)
{
|
19961b | 2017-04-08 | Martin Nilsson | | if( TYPEOF(Pike_sp[e]) != PIKE_T_STRING )
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | *Pike_sp = Pike_sp[e];
|
4799eb | 2017-01-03 | Martin Nilsson | | Pike_sp++;
|
19961b | 2017-04-08 | Martin Nilsson | | o_cast_to_string();
Pike_sp[e-1] = Pike_sp[-1];
|
4799eb | 2017-01-03 | Martin Nilsson | | Pike_sp--;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
4799eb | 2017-01-03 | Martin Nilsson | | add_strings(args);
return;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
case BIT_INT:
|
f30663 | 2012-12-31 | Arne Goedeke | | {
|
19961b | 2017-04-08 | Martin Nilsson | | INT_TYPE size = Pike_sp[-args].u.integer;
|
3bcf05 | 2017-01-03 | Martin Nilsson | | for(e = -args+1; e < 0; e++)
|
fda0de | 1999-10-08 | Fredrik Noring | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if (DO_INT_TYPE_ADD_OVERFLOW(size, Pike_sp[e].u.integer, &size))
|
fe6269 | 2014-01-11 | Arne Goedeke | | {
|
19961b | 2017-04-08 | Martin Nilsson | | convert_svalue_to_bignum(Pike_sp-args);
|
fe6269 | 2014-01-11 | Arne Goedeke | | f_add(args);
return;
}
|
fda0de | 1999-10-08 | Fredrik Noring | | }
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp-=args;
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | push_int(size);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
|
f30663 | 2012-12-31 | Arne Goedeke | | }
|
3bcf05 | 2017-01-03 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case BIT_FLOAT:
|
f75069 | 2017-01-01 | Martin Nilsson | | {
|
9e10fe | 2020-06-06 | Marcus Comstedt | | FLOAT_ARG_TYPE res = Pike_sp[-args].u.float_number;
|
f75069 | 2017-01-01 | Martin Nilsson | | for(e=args-1; e>0; e-- )
|
19961b | 2017-04-08 | Martin Nilsson | | res += Pike_sp[-e].u.float_number;
|
f75069 | 2017-01-01 | Martin Nilsson | | Pike_sp -= args-1;
Pike_sp[-1].u.float_number = res;
|
08b3ec | 2011-04-08 | Henrik Grubbström (Grubba) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
|
482fb5 | 1999-03-12 | Per Hedbor | | case BIT_FLOAT|BIT_INT:
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
|
9e10fe | 2020-06-06 | Marcus Comstedt | | FLOAT_ARG_TYPE res = 0.0;
|
56c540 | 2017-04-14 | Henrik Grubbström (Grubba) | | int i;
for(i=0; i<args; i++)
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[i-args]) == T_FLOAT)
|
f75069 | 2017-01-01 | Martin Nilsson | | res += Pike_sp[i-args].u.float_number;
else
|
9e10fe | 2020-06-06 | Marcus Comstedt | | res += (FLOAT_ARG_TYPE)Pike_sp[i-args].u.integer;
|
f75069 | 2017-01-01 | Martin Nilsson | | Pike_sp-=args;
push_float(res);
return;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | }
|
09cae2 | 2003-11-12 | Martin Stjernholm | | #define ADD(TYPE, ADD_FUNC, PUSH_FUNC) do { \
|
19961b | 2017-04-08 | Martin Nilsson | | struct TYPE *x = ADD_FUNC (Pike_sp - args, args); \
|
09cae2 | 2003-11-12 | Martin Stjernholm | | pop_n_elems (args); \
PUSH_FUNC (x); \
return; \
} while (0)
|
3bcf05 | 2017-01-03 | Martin Nilsson | | #define REMOVE_UNDEFINED(TYPE) \
do { \
int to = -args, i=-args; \
for(; i<0; i++) \
{ \
if(TYPEOF(Pike_sp[i]) == PIKE_T_INT) \
{ \
if(!IS_UNDEFINED(Pike_sp+i)) \
SIMPLE_ARG_TYPE_ERROR("`+", args+i, #TYPE); \
} \
else if(to!=i) \
Pike_sp[to++] = Pike_sp[i]; \
else to++; \
} \
|
56c540 | 2017-04-14 | Henrik Grubbström (Grubba) | | for(i=to; i<0; i++) \
|
3bcf05 | 2017-01-03 | Martin Nilsson | | TYPEOF(Pike_sp[i])=PIKE_T_INT; \
Pike_sp += to; \
args += to; \
} while(0);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
3bcf05 | 2017-01-03 | Martin Nilsson | | case BIT_ARRAY|BIT_INT:
REMOVE_UNDEFINED (array);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case BIT_ARRAY:
|
09cae2 | 2003-11-12 | Martin Stjernholm | | ADD (array, add_arrays, push_array);
|
7c15fa | 2015-04-22 | Henrik Grubbström (Grubba) | | break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
482fb5 | 1999-03-12 | Per Hedbor | | case BIT_MAPPING|BIT_INT:
|
3bcf05 | 2017-01-03 | Martin Nilsson | | REMOVE_UNDEFINED (mapping);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case BIT_MAPPING:
|
09cae2 | 2003-11-12 | Martin Stjernholm | | ADD (mapping, add_mappings, push_mapping);
|
7c15fa | 2015-04-22 | Henrik Grubbström (Grubba) | | break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
09cae2 | 2003-11-12 | Martin Stjernholm | | case BIT_MULTISET|BIT_INT:
|
3bcf05 | 2017-01-03 | Martin Nilsson | | REMOVE_UNDEFINED (multiset);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | case BIT_MULTISET:
|
09cae2 | 2003-11-12 | Martin Stjernholm | | ADD (multiset, add_multisets, push_multiset);
|
7c15fa | 2015-04-22 | Henrik Grubbström (Grubba) | | break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
3bcf05 | 2017-01-03 | Martin Nilsson | | #undef REMOVE_UNDEFINED
|
09cae2 | 2003-11-12 | Martin Stjernholm | | #undef ADD
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | static int generate_sum(node *n)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | node **first_arg, **second_arg, **third_arg;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | switch(count_args(CDR(n)))
{
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | case 0: return 0;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | case 1:
do_docode(CDR(n),0);
return 1;
case 2:
|
a2b70a | 2000-04-30 | Fredrik Hübinette (Hubbe) | | first_arg=my_get_arg(&_CDR(n), 0);
second_arg=my_get_arg(&_CDR(n), 1);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5e4442 | 2001-02-25 | Fredrik Hübinette (Hubbe) | | do_docode(CDR(n),DO_NOT_COPY_TOPLEVEL);
|
a2b70a | 2000-04-30 | Fredrik Hübinette (Hubbe) | | if(first_arg[0]->type == float_type_string &&
second_arg[0]->type == float_type_string)
{
emit0(F_ADD_FLOATS);
}
|
70a0f0 | 2004-08-25 | Henrik Grubbström (Grubba) | | else if(first_arg[0]->type && second_arg[0]->type &&
pike_types_le(first_arg[0]->type, int_type_string) &&
|
29e7e4 | 2004-08-24 | Henrik Grubbström (Grubba) | | pike_types_le(second_arg[0]->type, int_type_string))
|
a2b70a | 2000-04-30 | Fredrik Hübinette (Hubbe) | | {
emit0(F_ADD_INTS);
}
else
{
emit0(F_ADD);
}
|
f4f864 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | case 3:
first_arg = my_get_arg(&_CDR(n), 0);
second_arg = my_get_arg(&_CDR(n), 1);
third_arg = my_get_arg(&_CDR(n), 2);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | if(first_arg[0]->type == float_type_string &&
second_arg[0]->type == float_type_string)
{
do_docode(*first_arg, 0);
do_docode(*second_arg, 0);
emit0(F_ADD_FLOATS);
|
f4f864 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | if (third_arg[0]->type == float_type_string) {
do_docode(*third_arg, 0);
emit0(F_ADD_FLOATS);
|
f4f864 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | return 1;
}
}
|
70a0f0 | 2004-08-25 | Henrik Grubbström (Grubba) | | else if(first_arg[0]->type && second_arg[0]->type &&
pike_types_le(first_arg[0]->type, int_type_string) &&
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | pike_types_le(second_arg[0]->type, int_type_string))
{
do_docode(*first_arg, 0);
do_docode(*second_arg, 0);
emit0(F_ADD_INTS);
|
f4f864 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
70a0f0 | 2004-08-25 | Henrik Grubbström (Grubba) | | if (third_arg[0]->type &&
pike_types_le(third_arg[0]->type, int_type_string)) {
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | do_docode(*third_arg, 0);
emit0(F_ADD_INTS);
|
f4f864 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | return 1;
}
}
else
{
return 0;
}
do_docode(*third_arg, 0);
emit0(F_ADD);
|
f4f864 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | | return 1;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | default:
return 0;
}
}
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | static node *optimize_eq(node *n)
{
node **first_arg, **second_arg, *ret;
if(count_args(CDR(n))==2)
{
|
f807f0 | 1999-11-11 | Henrik Grubbström (Grubba) | | first_arg=my_get_arg(&_CDR(n), 0);
|
177c56 | 1999-11-11 | Henrik Grubbström (Grubba) | | second_arg=my_get_arg(&_CDR(n), 1);
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | |
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | if(!first_arg || !second_arg)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Couldn't find argument!\n");
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | #endif
|
01eb48 | 2011-03-05 | Martin Stjernholm | |
|
ffa452 | 2001-05-11 | Henrik Grubbström (Grubba) | | if (((*second_arg)->token == F_CONSTANT) &&
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | (TYPEOF((*second_arg)->u.sval) == T_STRING) &&
|
408a1e | 2004-10-30 | Martin Stjernholm | | ((*first_arg)->token == F_RANGE)) {
node *low = CADR (*first_arg), *high = CDDR (*first_arg);
INT_TYPE c;
if ((low->token == F_RANGE_OPEN ||
(low->token == F_RANGE_FROM_BEG &&
(CAR (low)->token == F_CONSTANT) &&
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | (TYPEOF(CAR (low)->u.sval) == T_INT) &&
|
408a1e | 2004-10-30 | Martin Stjernholm | | (!(CAR (low)->u.sval.u.integer)))) &&
(high->token == F_RANGE_OPEN ||
(high->token == F_RANGE_FROM_BEG &&
(CAR (high)->token == F_CONSTANT) &&
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | (TYPEOF(CAR (high)->u.sval) == T_INT) &&
|
408a1e | 2004-10-30 | Martin Stjernholm | | (c = CAR (high)->u.sval.u.integer, 1)))) {
if (high->token == F_RANGE_OPEN ||
(*second_arg)->u.sval.u.string->len <= c) {
ADD_NODE_REF2(CAR(*first_arg),
ADD_NODE_REF2(*second_arg,
ret = mkopernode("`==", CAR(*first_arg), *second_arg);
));
return ret;
} else if ((*second_arg)->u.sval.u.string->len == c+1) {
ADD_NODE_REF2(CAR(*first_arg),
ADD_NODE_REF2(*second_arg,
ret = mkopernode("has_prefix", CAR(*first_arg), *second_arg);
));
return ret;
} else {
ADD_NODE_REF2(CAR(*first_arg),
ret = mknode(F_COMMA_EXPR, CAR(*first_arg), mkintnode(0));
);
return ret;
}
|
ffa452 | 2001-05-11 | Henrik Grubbström (Grubba) | | }
}
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | }
return 0;
}
static node *optimize_not(node *n)
{
node **first_arg, **more_args;
if(count_args(CDR(n))==1)
{
|
f807f0 | 1999-11-11 | Henrik Grubbström (Grubba) | | first_arg=my_get_arg(&_CDR(n), 0);
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | if(!first_arg)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Couldn't find argument!\n");
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | #endif
if(node_is_true(*first_arg)) return mkintnode(0);
if(node_is_false(*first_arg)) return mkintnode(1);
|
f807f0 | 1999-11-11 | Henrik Grubbström (Grubba) | | #define TMP_OPT(X,Y) do { \
if((more_args=is_call_to(*first_arg, X))) \
{ \
node *tmp=*more_args; \
|
ea71c2 | 2000-11-11 | Fredrik Hübinette (Hubbe) | | if(count_args(*more_args) > 2) return 0; \
|
01b2c2 | 1999-11-22 | Henrik Grubbström (Grubba) | | ADD_NODE_REF(*more_args); \
|
f807f0 | 1999-11-11 | Henrik Grubbström (Grubba) | | return mkopernode(Y,tmp,0); \
} } while(0)
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | |
TMP_OPT(f_eq, "`!=");
TMP_OPT(f_ne, "`==");
|
f5971b | 2004-11-27 | Martin Stjernholm | | #if 0
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | TMP_OPT(f_lt, "`>=");
TMP_OPT(f_gt, "`<=");
TMP_OPT(f_le, "`>");
TMP_OPT(f_ge, "`<");
|
f5971b | 2004-11-27 | Martin Stjernholm | | #endif
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | #undef TMP_OPT
|
89c445 | 2000-04-12 | Henrik Grubbström (Grubba) | | if((more_args = is_call_to(*first_arg, f_search)) &&
(count_args(*more_args) == 2)) {
node *search_args = *more_args;
if ((search_args->token == F_ARG_LIST) &&
CAR(search_args) &&
|
a0c96c | 2007-03-20 | Henrik Grubbström (Grubba) | | pike_types_le(CAR(search_args)->type, string_type_string) &&
|
89c445 | 2000-04-12 | Henrik Grubbström (Grubba) | | CDR(search_args) &&
|
a0c96c | 2007-03-20 | Henrik Grubbström (Grubba) | | pike_types_le(CDR(search_args)->type, string_type_string)) {
|
89c445 | 2000-04-12 | Henrik Grubbström (Grubba) | |
ADD_NODE_REF(*more_args);
return mkefuncallnode("has_prefix", search_args);
}
}
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | }
return 0;
}
|
9d4cae | 2002-06-17 | Henrik Grubbström (Grubba) | | static node *may_have_side_effects(node *n)
{
node **arg;
int argno;
for (argno = 0; (arg = my_get_arg(&_CDR(n), argno)); argno++) {
|
940342 | 2010-11-18 | Henrik Grubbström (Grubba) | | if (((*arg)->type != zero_type_string) &&
match_types(object_type_string, (*arg)->type)) {
|
9d4cae | 2002-06-17 | Henrik Grubbström (Grubba) | | n->node_info |= OPT_SIDE_EFFECT;
n->tree_info |= OPT_SIDE_EFFECT;
return NULL;
}
}
return NULL;
}
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | |
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | static node *optimize_binary(node *n)
{
node **first_arg, **second_arg, *ret;
|
a0c96c | 2007-03-20 | Henrik Grubbström (Grubba) | | int args;
if((args = count_args(CDR(n)))==2)
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
|
f807f0 | 1999-11-11 | Henrik Grubbström (Grubba) | | first_arg=my_get_arg(&_CDR(n), 0);
second_arg=my_get_arg(&_CDR(n), 1);
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | if(!first_arg || !second_arg)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Couldn't find argument!\n");
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | #endif
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | if((*second_arg)->type == (*first_arg)->type &&
compile_type_to_runtime_type((*second_arg)->type) != T_MIXED)
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
if((*first_arg)->token == F_APPLY &&
CAR(*first_arg)->token == F_CONSTANT &&
is_eq(& CAR(*first_arg)->u.sval, & CAR(n)->u.sval))
{
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | |
|
8f2fa4 | 2000-10-03 | Henrik Grubbström (Grubba) | | ADD_NODE_REF2(CAR(n),
ADD_NODE_REF2(CDR(*first_arg),
ADD_NODE_REF2(*second_arg,
ret = mknode(F_APPLY,
CAR(n),
mknode(F_ARG_LIST,
CDR(*first_arg),
*second_arg))
)));
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | return ret;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | if((*second_arg)->token == F_APPLY &&
CAR(*second_arg)->token == F_CONSTANT &&
is_eq(& CAR(*second_arg)->u.sval, & CAR(n)->u.sval))
{
|
204a5a | 2004-08-24 | Henrik Grubbström (Grubba) | |
|
8f2fa4 | 2000-10-03 | Henrik Grubbström (Grubba) | | ADD_NODE_REF2(CAR(n),
ADD_NODE_REF2(*first_arg,
ADD_NODE_REF2(CDR(*second_arg),
ret = mknode(F_APPLY,
CAR(n),
mknode(F_ARG_LIST,
*first_arg,
CDR(*second_arg)))
)));
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | return ret;
}
}
}
|
a0c96c | 2007-03-20 | Henrik Grubbström (Grubba) | | #if 0 /* Does not work for multiplication. */
if (n->type && (n->type->type == T_STRING) &&
CAR_TO_INT(n->type) == 32 && (args > 0)) {
int str_width = 6;
while (args--) {
struct pike_type *t;
node **arg = my_get_arg(&_CDR(n), args);
if (!arg || !(t = (*arg)->type)) continue;
if (t->type == T_STRING) {
int w = CAR_TO_INT(t);
if (w > str_width) str_width = w;
}
}
if (str_width != 32) {
type_stack_mark();
|
7a1c05 | 2007-05-03 | Henrik Grubbström (Grubba) | | push_int_type(0, (1<<str_width)-1);
|
664cad | 2020-01-23 | Henrik Grubbström (Grubba) | | push_unlimited_array_type(T_STRING);
|
a0c96c | 2007-03-20 | Henrik Grubbström (Grubba) | | free_type(n->type);
n->type = pop_unfinished_type();
}
}
#endif /* 0 */
|
693018 | 1996-02-25 | Fredrik Hübinette (Hubbe) | | return 0;
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | static int generate_comparison(node *n)
{
if(count_args(CDR(n))==2)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
4c573c | 1996-08-03 | Fredrik Hübinette (Hubbe) | | if(do_docode(CDR(n),DO_NOT_COPY) != 2)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Count args was wrong in generate_comparison.\n");
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
if(CAR(n)->u.sval.u.efun->function == f_eq)
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_EQ);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_ne)
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_NE);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_lt)
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_LT);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_le)
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_LE);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_gt)
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_GT);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_ge)
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_GE);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else
|
80ee91 | 2006-03-25 | Henrik Grubbström (Grubba) | | Pike_fatal("Couldn't generate comparison!\n"
"efun->function: %p\n"
"f_eq: %p\n"
"f_ne: %p\n"
"f_lt: %p\n"
"f_le: %p\n"
"f_gt: %p\n"
"f_ge: %p\n",
CAR(n)->u.sval.u.efun->function,
f_eq, f_ne, f_lt, f_le, f_gt, f_ge);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | static int float_promote(void)
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-2]) == T_INT && TYPEOF(Pike_sp[-1]) == T_FLOAT)
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-2], T_FLOAT, 0, float_number, (FLOAT_TYPE)Pike_sp[-2].u.integer);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return 1;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | }
|
19961b | 2017-04-08 | Martin Nilsson | | else if(TYPEOF(Pike_sp[-1]) == T_INT && TYPEOF(Pike_sp[-2]) == T_FLOAT)
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_FLOAT, 0, float_number, (FLOAT_TYPE)Pike_sp[-1].u.integer);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return 1;
}
|
e92449 | 1999-12-14 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | if(is_bignum_object_in_svalue(Pike_sp-2) && TYPEOF(Pike_sp[-1]) == T_FLOAT)
|
e92449 | 1999-12-14 | Fredrik Hübinette (Hubbe) | | {
stack_swap();
|
b103b3 | 2001-02-20 | Henrik Grubbström (Grubba) | | ref_push_type_value(float_type_string);
|
e92449 | 1999-12-14 | Fredrik Hübinette (Hubbe) | | stack_swap();
f_cast();
stack_swap();
return 1;
}
|
19961b | 2017-04-08 | Martin Nilsson | | else if(is_bignum_object_in_svalue(Pike_sp-1) && TYPEOF(Pike_sp[-2]) == T_FLOAT)
|
e92449 | 1999-12-14 | Fredrik Hübinette (Hubbe) | | {
|
b103b3 | 2001-02-20 | Henrik Grubbström (Grubba) | | ref_push_type_value(float_type_string);
|
e92449 | 1999-12-14 | Fredrik Hübinette (Hubbe) | | stack_swap();
f_cast();
return 1;
}
|
031171 | 2013-06-17 | Martin Nilsson | |
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return 0;
}
|
b83b37 | 2016-12-31 | Martin Nilsson | | static int has_lfun(enum LFUN lfun, int arg)
{
struct program *p;
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-arg]) == T_OBJECT && (p = Pike_sp[-arg].u.object->prog))
return FIND_LFUN(p->inherits[SUBTYPEOF(Pike_sp[-arg])].prog, lfun);
|
b83b37 | 2016-12-31 | Martin Nilsson | | return -1;
}
static int call_lhs_lfun( enum LFUN lfun, int arg )
{
|
efd379 | 2016-12-31 | Martin Nilsson | | int i = has_lfun(lfun,arg);
|
b83b37 | 2016-12-31 | Martin Nilsson | |
|
efd379 | 2016-12-31 | Martin Nilsson | | if(i != -1)
{
apply_low(Pike_sp[-arg].u.object, i, arg-1);
return 1;
}
|
b83b37 | 2016-12-31 | Martin Nilsson | | return 0;
}
|
18678b | 2016-12-30 | Martin Nilsson | | static int call_lfun(enum LFUN left, enum LFUN right)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
|
9793b7 | 2004-12-18 | Henrik Grubbström (Grubba) | | struct object *o;
struct program *p;
|
33c958 | 2003-11-10 | Martin Stjernholm | | int i;
|
9793b7 | 2004-12-18 | Henrik Grubbström (Grubba) | |
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-2]) == T_OBJECT &&
(p = (o = Pike_sp[-2].u.object)->prog) &&
(i = FIND_LFUN(p->inherits[SUBTYPEOF(Pike_sp[-2])].prog, left)) != -1)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
|
9793b7 | 2004-12-18 | Henrik Grubbström (Grubba) | | apply_low(o, i, 1);
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp-2);
Pike_sp[-2]=Pike_sp[-1];
Pike_sp--;
dmalloc_touch_svalue(Pike_sp);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return 1;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | }
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) == T_OBJECT &&
(p = (o = Pike_sp[-1].u.object)->prog) &&
(i = FIND_LFUN(p->inherits[SUBTYPEOF(Pike_sp[-1])].prog, right)) != -1)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | push_svalue(Pike_sp-2);
|
9793b7 | 2004-12-18 | Henrik Grubbström (Grubba) | | apply_low(o, i, 1);
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp-3);
Pike_sp[-3]=Pike_sp[-1];
Pike_sp--;
dmalloc_touch_svalue(Pike_sp);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | pop_stack();
return 1;
}
return 0;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
13670c | 2015-05-25 | Martin Nilsson | | struct mapping *merge_mapping_array_ordered(struct mapping *a,
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | struct array *b, INT32 op);
|
13670c | 2015-05-25 | Martin Nilsson | | struct mapping *merge_mapping_array_unordered(struct mapping *a,
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | struct array *b, INT32 op);
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_subtract(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-2]) != TYPEOF(Pike_sp[-1]) && !float_promote())
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
if(call_lfun(LFUN_SUBTRACT, LFUN_RSUBTRACT))
return;
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | |
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-2]) == T_MAPPING)
switch (TYPEOF(Pike_sp[-1]))
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | {
case T_ARRAY:
{
struct mapping *m;
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mapping_array_unordered(Pike_sp[-2].u.mapping,
Pike_sp[-1].u.array,
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | PIKE_ARRAY_OP_SUB);
pop_n_elems(2);
push_mapping(m);
return;
}
case T_MULTISET:
{
struct mapping *m;
|
19961b | 2017-04-08 | Martin Nilsson | | int got_cmp_less = !!multiset_get_cmp_less (Pike_sp[-1].u.multiset);
struct array *ind = multiset_indices (Pike_sp[-1].u.multiset);
|
5b15bb | 2001-12-10 | Martin Stjernholm | | pop_stack();
push_array (ind);
if (got_cmp_less)
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mapping_array_unordered(Pike_sp[-2].u.mapping,
Pike_sp[-1].u.array,
|
5b15bb | 2001-12-10 | Martin Stjernholm | | PIKE_ARRAY_OP_SUB);
else
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mapping_array_ordered(Pike_sp[-2].u.mapping,
Pike_sp[-1].u.array,
|
5b15bb | 2001-12-10 | Martin Stjernholm | | PIKE_ARRAY_OP_SUB);
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | pop_n_elems(2);
push_mapping(m);
return;
}
}
|
212c39 | 2018-02-25 | Martin Nilsson | | bad_arg_error("`-", 2, 2, get_name_of_type(TYPEOF(Pike_sp[-2])),
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp-1, "Subtract on different types.\n");
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-2]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
2a8925 | 2016-12-30 | Martin Nilsson | | if(!call_lfun(LFUN_SUBTRACT, LFUN_RSUBTRACT))
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`-", "Subtract on objects without `- operator.\n", Pike_sp, 2);
|
2a8925 | 2016-12-30 | Martin Nilsson | | return;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
{
struct array *a;
|
19961b | 2017-04-08 | Martin Nilsson | | check_array_for_destruct(Pike_sp[-2].u.array);
check_array_for_destruct(Pike_sp[-1].u.array);
a = subtract_arrays(Pike_sp[-2].u.array, Pike_sp[-1].u.array);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_array(a);
return;
}
case T_MAPPING:
{
struct mapping *m;
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mappings(Pike_sp[-2].u.mapping, Pike_sp[-1].u.mapping,PIKE_ARRAY_OP_SUB);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_mapping(m);
return;
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | case T_MULTISET:
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct multiset *l;
|
19961b | 2017-04-08 | Martin Nilsson | | l=merge_multisets(Pike_sp[-2].u.multiset, Pike_sp[-1].u.multiset,
|
d05ad7 | 2016-12-30 | Martin Nilsson | | PIKE_ARRAY_OP_SUB);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | push_multiset(l);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
case T_FLOAT:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
Pike_sp[-1].u.float_number -= Pike_sp[0].u.float_number;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | if(INT_TYPE_SUB_OVERFLOW(Pike_sp[-2].u.integer, Pike_sp[-1].u.integer))
|
ff0d46 | 1999-10-15 | Fredrik Noring | | {
convert_stack_top_to_bignum();
|
b0f528 | 2019-08-09 | Henrik Grubbström (Grubba) | | if (LIKELY(call_lfun(LFUN_SUBTRACT, LFUN_RSUBTRACT))) {
return;
}
Pike_fatal("Failed to call `-() in bignum.\n");
|
ff0d46 | 1999-10-15 | Fredrik Noring | | }
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
SET_SVAL(Pike_sp[-1], PIKE_T_INT, NUMBER_NUMBER, integer,
Pike_sp[-1].u.integer - Pike_sp[0].u.integer);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
case T_STRING:
{
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s,*ret;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | s=make_shared_string("");
|
19961b | 2017-04-08 | Martin Nilsson | | ret=string_replace(Pike_sp[-2].u.string,Pike_sp[-1].u.string,s);
free_string(Pike_sp[-2].u.string);
free_string(Pike_sp[-1].u.string);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | free_string(s);
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp[-2].u.string=ret;
Pike_sp--;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
33c958 | 2003-11-10 | Martin Stjernholm | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`-", 1,
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | "int|float|string|mapping|multiset|array|object");
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | |
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl mixed `-(mixed arg1, mixed arg2, mixed ... extras)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *! @decl mixed `-(object arg1, mixed arg2)
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl mixed `-(mixed arg1, object arg2)
*! @decl int `-(int arg1, int arg2)
*! @decl float `-(float arg1, int|float arg2)
*! @decl float `-(int|float arg1, float arg2)
*! @decl string `-(string arg1, string arg2)
*! @decl array `-(array arg1, array arg2)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *! @decl mapping `-(mapping arg1, array arg2)
*! @decl mapping `-(mapping arg1, mapping arg2)
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl mapping `-(mapping arg1, multiset arg2)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *! @decl multiset `-(multiset arg1, multiset arg2)
*!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Negation/subtraction/set difference.
*!
*! Every expression with the @expr{-@} operator becomes a call to
*! this function, i.e. @expr{-a@} is the same as
*! @expr{predef::`-(a)@} and @expr{a-b@} is the same as
*! @expr{predef::`-(a,b)@}. Longer @expr{-@} expressions are
*! normally optimized to one call, so e.g. @expr{a-b-c@} becomes
*! @expr{predef::`-(a,b,c)@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there's a single argument, that argument is returned negated.
*! If @[arg1] is an object with an @[lfun::`-()], that function is
*! called without arguments, and its result is returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there are more than two arguments the result is:
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! @expr{`-(`-(@[arg1], @[arg2]), @@@[extras])@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise, if @[arg1] is an object with an @[lfun::`-()], that
*! function is called with @[arg2] as argument, and its result is
*! returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise, if @[arg2] is an object with an @[lfun::``-()], that
*! function is called with @[arg1] as argument, and its result is
*! returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise the result depends on the argument types:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg1
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type int|float
*! The result is @expr{@[arg1] - @[arg2]@}, and is a float if
*! either @[arg1] or @[arg2] is a float.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type string
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! The result is @[arg1] with all nonoverlapping occurrences of
*! the substring @[arg2] removed. In cases with two overlapping
*! occurrences, the leftmost is removed.
*! @type array|mapping|multiset
*! The result is like @[arg1] but without the elements/indices
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! that match any in @[arg2] (according to @[`>], @[`<], @[`==]
*! and, in the case of mappings, @[hash_value]).
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @endmixed
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! The function is not destructive on the arguments - the result is
*! always a new instance.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @note
*! In Pike 7.0 and earlier the subtraction order was unspecified.
*!
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! @note
*! If this operator is used with arrays or multisets containing objects
*! which implement @[lfun::`==()] but @b{not@} @[lfun::`>()] and
*! @[lfun::`<()], the result will be undefined.
*!
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *! @seealso
*! @[`+()]
*/
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_minus(INT32 args)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
switch(args)
{
|
06bd61 | 2016-01-26 | Martin Nilsson | | case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`-", 1);
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | case 1: o_negate(); break;
case 2: o_subtract(); break;
default:
{
INT32 e;
|
8496b2 | 2011-04-09 | Henrik Grubbström (Grubba) | | TYPE_FIELD types = 0;
|
19961b | 2017-04-08 | Martin Nilsson | | struct svalue *s=Pike_sp-args;
|
8496b2 | 2011-04-09 | Henrik Grubbström (Grubba) | |
|
19961b | 2017-04-08 | Martin Nilsson | | for(e=-args;e<0;e++) types |= 1<<TYPEOF(Pike_sp[e]);
|
8496b2 | 2011-04-09 | Henrik Grubbström (Grubba) | |
if ((types | BIT_INT | BIT_FLOAT) == (BIT_INT | BIT_FLOAT)) {
|
5c22db | 2011-04-09 | Henrik Grubbström (Grubba) | | INT32 carry = 0;
if (types == BIT_INT) {
f_add(args-1);
o_subtract();
break;
}
|
8496b2 | 2011-04-09 | Henrik Grubbström (Grubba) | |
|
5c22db | 2011-04-09 | Henrik Grubbström (Grubba) | | for(e = 1; e < args; e++) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(s[e]) == PIKE_T_INT) {
|
5c22db | 2011-04-09 | Henrik Grubbström (Grubba) | | INT_TYPE val = s[e].u.integer;
if (val >= -0x7fffffff) {
s[e].u.integer = -val;
} else {
s[e].u.integer = ~val;
carry++;
}
} else {
s[e].u.float_number = -s[e].u.float_number;
}
}
if (carry) {
push_int(carry);
args++;
}
f_add(args);
|
8496b2 | 2011-04-09 | Henrik Grubbström (Grubba) | | break;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | push_svalue(s);
for(e=1;e<args;e++)
{
push_svalue(s+e);
o_subtract();
}
|
19961b | 2017-04-08 | Martin Nilsson | | assign_svalue(s,Pike_sp-1);
pop_n_elems(Pike_sp-s-1);
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
}
static int generate_minus(node *n)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | switch(count_args(CDR(n)))
{
case 1:
do_docode(CDR(n),DO_NOT_COPY);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_NEGATE);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
case 2:
|
5e4442 | 2001-02-25 | Fredrik Hübinette (Hubbe) | | do_docode(CDR(n),DO_NOT_COPY_TOPLEVEL);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_SUBTRACT);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_and(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(UNLIKELY(TYPEOF(Pike_sp[-1]) != TYPEOF(Pike_sp[-2])))
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
|
13670c | 2015-05-25 | Martin Nilsson | | if(call_lfun(LFUN_AND, LFUN_RAND))
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | return;
|
19961b | 2017-04-08 | Martin Nilsson | | else if (((TYPEOF(Pike_sp[-1]) == T_TYPE) || (TYPEOF(Pike_sp[-1]) == T_PROGRAM) ||
(TYPEOF(Pike_sp[-1]) == T_FUNCTION)) &&
((TYPEOF(Pike_sp[-2]) == T_TYPE) || (TYPEOF(Pike_sp[-2]) == T_PROGRAM) ||
(TYPEOF(Pike_sp[-2]) == T_FUNCTION)))
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-2]) != T_TYPE)
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct program *p = program_from_svalue(Pike_sp - 2);
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`&", 1, "type");
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp - 2);
SET_SVAL(Pike_sp[-2], T_TYPE, 0, type, pop_unfinished_type());
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-1]) != T_TYPE)
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | struct program *p = program_from_svalue(Pike_sp - 1);
|
13670c | 2015-05-25 | Martin Nilsson | | if (!p)
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`&", 2, "type");
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp - 1);
SET_SVAL(Pike_sp[-1], T_TYPE, 0, type, pop_unfinished_type());
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
|
13670c | 2015-05-25 | Martin Nilsson | | }
|
19961b | 2017-04-08 | Martin Nilsson | | else if (TYPEOF(Pike_sp[-2]) == T_MAPPING)
switch (TYPEOF(Pike_sp[-1]))
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | {
case T_ARRAY:
{
struct mapping *m;
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mapping_array_unordered(Pike_sp[-2].u.mapping,
Pike_sp[-1].u.array,
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | PIKE_ARRAY_OP_AND);
pop_n_elems(2);
push_mapping(m);
return;
}
case T_MULTISET:
{
struct mapping *m;
|
19961b | 2017-04-08 | Martin Nilsson | | int got_cmp_less = !!multiset_get_cmp_less (Pike_sp[-1].u.multiset);
struct array *ind = multiset_indices (Pike_sp[-1].u.multiset);
|
5b15bb | 2001-12-10 | Martin Stjernholm | | pop_stack();
push_array (ind);
if (got_cmp_less)
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mapping_array_unordered(Pike_sp[-2].u.mapping,
Pike_sp[-1].u.array,
|
5b15bb | 2001-12-10 | Martin Stjernholm | | PIKE_ARRAY_OP_AND);
else
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mapping_array_ordered(Pike_sp[-2].u.mapping,
Pike_sp[-1].u.array,
|
5b15bb | 2001-12-10 | Martin Stjernholm | | PIKE_ARRAY_OP_AND);
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | pop_n_elems(2);
push_mapping(m);
return;
}
|
eed2da | 2001-06-11 | Henrik Grubbström (Grubba) | | default:
{
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`&", 2, "mapping");
|
eed2da | 2001-06-11 | Henrik Grubbström (Grubba) | | }
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | }
|
13670c | 2015-05-25 | Martin Nilsson | | else
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | {
int args = 2;
|
19961b | 2017-04-08 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`&", 2, get_name_of_type(TYPEOF(Pike_sp[-2])));
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | }
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-2]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
4d4265 | 2016-12-31 | Martin Nilsson | | if(!call_lfun(LFUN_AND,LFUN_RAND))
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`&", "Bitwise and on objects without `& operator.\n", Pike_sp, 2);
|
4d4265 | 2016-12-31 | Martin Nilsson | | return;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
SET_SVAL(Pike_sp[-1], PIKE_T_INT, NUMBER_NUMBER, integer,
Pike_sp[-1].u.integer & Pike_sp[0].u.integer);
|
4d4265 | 2016-12-31 | Martin Nilsson | | return;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
case T_MAPPING:
{
struct mapping *m;
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mappings(Pike_sp[-2].u.mapping, Pike_sp[-1].u.mapping, PIKE_ARRAY_OP_AND);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_mapping(m);
return;
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | case T_MULTISET:
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct multiset *l;
|
19961b | 2017-04-08 | Martin Nilsson | | l=merge_multisets(Pike_sp[-2].u.multiset, Pike_sp[-1].u.multiset,
|
d05ad7 | 2016-12-30 | Martin Nilsson | | PIKE_ARRAY_OP_AND);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | push_multiset(l);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
{
struct array *a;
|
19961b | 2017-04-08 | Martin Nilsson | | a=and_arrays(Pike_sp[-2].u.array, Pike_sp[-1].u.array);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_array(a);
return;
}
|
fc0bb5 | 1997-02-13 | Niels Möller | |
|
3db0d2 | 1999-12-13 | Henrik Grubbström (Grubba) | | case T_TYPE:
{
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | struct pike_type *t;
|
19961b | 2017-04-08 | Martin Nilsson | | t = and_pike_types(Pike_sp[-2].u.type, Pike_sp[-1].u.type);
|
3db0d2 | 1999-12-13 | Henrik Grubbström (Grubba) | | pop_n_elems(2);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(t);
|
3db0d2 | 1999-12-13 | Henrik Grubbström (Grubba) | | return;
}
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_PROGRAM:
{
struct program *p;
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | struct pike_type *a;
struct pike_type *b;
struct pike_type *t;
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | |
|
19961b | 2017-04-08 | Martin Nilsson | | p = program_from_svalue(Pike_sp - 2);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`&", 1, "type");
|
13670c | 2015-05-25 | Martin Nilsson | | }
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | a = pop_unfinished_type();
|
19961b | 2017-04-08 | Martin Nilsson | | p = program_from_svalue(Pike_sp - 1);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`&", 2, "type");
|
13670c | 2015-05-25 | Martin Nilsson | | }
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | b = pop_unfinished_type();
t = and_pike_types(a, b);
pop_n_elems(2);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(t);
free_type(a);
free_type(b);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | return;
}
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | #define STRING_BITOP(OP,STROP) \
case T_STRING: \
{ \
|
a2a581 | 2013-08-25 | Arne Goedeke | | struct pike_string *s; \
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | ptrdiff_t len, i; \
|
a2a581 | 2013-08-25 | Arne Goedeke | | \
|
19961b | 2017-04-08 | Martin Nilsson | | len = Pike_sp[-2].u.string->len; \
if (len != Pike_sp[-1].u.string->len) \
PIKE_ERROR("`" #OP, "Bitwise "STROP \
" on strings of different lengths.\n", Pike_sp, 2); \
if(!Pike_sp[-2].u.string->size_shift && !Pike_sp[-1].u.string->size_shift) \
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | { \
s = begin_shared_string(len); \
for (i=0; i<len; i++) \
|
19961b | 2017-04-08 | Martin Nilsson | | s->str[i] = Pike_sp[-2].u.string->str[i] OP Pike_sp[-1].u.string->str[i]; \
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }else{ \
s = begin_wide_shared_string(len, \
|
19961b | 2017-04-08 | Martin Nilsson | | MAXIMUM(Pike_sp[-2].u.string->size_shift, \
Pike_sp[-1].u.string->size_shift)); \
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | for (i=0; i<len; i++) \
|
19961b | 2017-04-08 | Martin Nilsson | | low_set_index(s,i,index_shared_string(Pike_sp[-2].u.string,i) OP \
index_shared_string(Pike_sp[-1].u.string,i)); \
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | } \
pop_n_elems(2); \
|
a2a581 | 2013-08-25 | Arne Goedeke | | push_string(end_shared_string(s)); \
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | return; \
}
STRING_BITOP(&,"AND")
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`&", "Bitwise AND on illegal type.\n", Pike_sp, 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
3c04e8 | 1997-03-13 | Fredrik Hübinette (Hubbe) | |
|
adbb78 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | static void r_speedup(INT32 args, void (*func)(void))
{
struct svalue tmp;
ONERROR err;
switch(args)
{
|
3595ea | 2018-02-12 | Marcus Comstedt | | case 3: func();
case 2: func();
|
adbb78 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | case 1: return;
default:
r_speedup((args+1)>>1,func);
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(Pike_sp-1);
|
19961b | 2017-04-08 | Martin Nilsson | | tmp=*--Pike_sp;
|
adbb78 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | SET_ONERROR(err,do_free_svalue,&tmp);
r_speedup(args>>1,func);
UNSET_ONERROR(err);
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp++[0]=tmp;
|
adbb78 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | func();
}
}
|
3c04e8 | 1997-03-13 | Fredrik Hübinette (Hubbe) | | static void speedup(INT32 args, void (*func)(void))
{
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-args]))
|
3c04e8 | 1997-03-13 | Fredrik Hübinette (Hubbe) | | {
|
c2769b | 1999-10-01 | Fredrik Hübinette (Hubbe) | |
case T_ARRAY:
|
adbb78 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | case T_MAPPING:
r_speedup(args,func);
return;
|
3c04e8 | 1997-03-13 | Fredrik Hübinette (Hubbe) | |
|
adbb78 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | default:
while(--args > 0) func();
|
3c04e8 | 1997-03-13 | Fredrik Hübinette (Hubbe) | | }
}
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | |
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl mixed `&(mixed arg1, mixed arg2, mixed ... extras)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *! @decl mixed `&(object arg1, mixed arg2)
*! @decl mixed `&(mixed arg1, object arg2)
*! @decl int `&(int arg1, int arg2)
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl string `&(string arg1, string arg2)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *! @decl array `&(array arg1, array arg2)
*! @decl mapping `&(mapping arg1, mapping arg2)
*! @decl mapping `&(mapping arg1, array arg2)
*! @decl mapping `&(mapping arg1, multiset arg2)
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl multiset `&(multiset arg1, multiset arg2)
*! @decl type `&(type|program arg1, type|program arg2)
*!
*! Bitwise and/intersection.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! 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)@}.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @returns
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there's a single argument, that argument is returned.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there are more than two arguments the result is:
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! @expr{`&(`&(@[arg1], @[arg2]), @@@[extras])@}.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise, if @[arg1] is an object with an @[lfun::`&()], that
*! function is called with @[arg2] as argument, and its result is
*! returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise, if @[arg2] is an object with an @[lfun::``&()], that
*! function is called with @[arg1] as argument, and its result is
*! returned.
*!
*! Otherwise the result depends on the argument types:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg1
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type int
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Bitwise and of @[arg1] and @[arg2].
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type string
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! The result is a string where each character is the bitwise
*! and of the characters in the same position in @[arg1] and
*! @[arg2]. The arguments must be strings of the same length.
*! @type array|mapping|multiset
*! The result is like @[arg1] but only with the
*! elements/indices that match any in @[arg2] (according to
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! @[`>], @[`<], @[`==] and, in the case of mappings,
*! @[hash_value]).
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type type|program
*! Type intersection of @[arg1] and @[arg2].
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @endmixed
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! The function is not destructive on the arguments - the result is
*! always a new instance.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! @note
*! If this operator is used with arrays or multisets containing objects
*! which implement @[lfun::`==()] but @b{not@} @[lfun::`>()] and
*! @[lfun::`<()], the result will be undefined.
*!
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *! @seealso
*! @[`|()], @[lfun::`&()], @[lfun::``&()]
*/
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_and(INT32 args)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
switch(args)
{
|
06bd61 | 2016-01-26 | Martin Nilsson | | case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`&", 1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | case 1: return;
case 2: o_and(); return;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | default:
|
c62935 | 2016-12-30 | Martin Nilsson | | speedup(args, o_and);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
}
static int generate_and(node *n)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | switch(count_args(CDR(n)))
{
case 1:
do_docode(CDR(n),0);
return 1;
case 2:
do_docode(CDR(n),0);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_AND);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
default:
return 0;
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_or(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) != TYPEOF(Pike_sp[-2]))
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if(call_lfun(LFUN_OR, LFUN_ROR)) {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return;
|
19961b | 2017-04-08 | Martin Nilsson | | } else if (((TYPEOF(Pike_sp[-1]) == T_TYPE) ||
(TYPEOF(Pike_sp[-1]) == T_PROGRAM) ||
(TYPEOF(Pike_sp[-1]) == T_FUNCTION)) &&
((TYPEOF(Pike_sp[-2]) == T_TYPE) ||
(TYPEOF(Pike_sp[-2]) == T_PROGRAM) ||
(TYPEOF(Pike_sp[-2]) == T_FUNCTION))) {
if (TYPEOF(Pike_sp[-2]) != T_TYPE) {
struct program *p = program_from_svalue(Pike_sp - 2);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`|", 1, "type");
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp - 2);
SET_SVAL(Pike_sp[-2], T_TYPE, 0, type, pop_unfinished_type());
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-1]) != T_TYPE) {
struct program *p = program_from_svalue(Pike_sp - 1);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`|", 2, "type");
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp - 1);
SET_SVAL(Pike_sp[-1], T_TYPE, 0, type, pop_unfinished_type());
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
} else {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | int args = 2;
|
087772 | 2020-03-19 | Henrik Grubbström (Grubba) | |
if ((TYPEOF(Pike_sp[-1]) == PIKE_T_INT) &&
(SUBTYPEOF(Pike_sp[-1]) == NUMBER_UNDEFINED)) {
if (TYPEOF(Pike_sp[-2]) == PIKE_T_MULTISET) {
struct multiset *l = copy_multiset(Pike_sp[-2].u.multiset);
pop_stack();
pop_stack();
push_multiset(l);
return;
}
} else if ((TYPEOF(Pike_sp[-2]) == PIKE_T_INT) &&
(SUBTYPEOF(Pike_sp[-2]) == NUMBER_UNDEFINED)) {
if (TYPEOF(Pike_sp[-1]) == PIKE_T_MULTISET) {
struct multiset *l = copy_multiset(Pike_sp[-1].u.multiset);
pop_stack();
pop_stack();
push_multiset(l);
return;
}
}
|
19961b | 2017-04-08 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`|", 2, get_name_of_type(TYPEOF(Pike_sp[-2])));
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | }
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-2]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
4d4265 | 2016-12-31 | Martin Nilsson | | if(!call_lfun(LFUN_OR,LFUN_ROR))
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`|", "Bitwise or on objects without `| operator.\n", Pike_sp, 2);
|
4d4265 | 2016-12-31 | Martin Nilsson | | return;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer,
Pike_sp[-1].u.integer | Pike_sp[0].u.integer);
|
4d4265 | 2016-12-31 | Martin Nilsson | | return;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
case T_MAPPING:
{
struct mapping *m;
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mappings(Pike_sp[-2].u.mapping, Pike_sp[-1].u.mapping, PIKE_ARRAY_OP_OR);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_mapping(m);
return;
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | case T_MULTISET:
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct multiset *l;
|
19961b | 2017-04-08 | Martin Nilsson | | l=merge_multisets(Pike_sp[-2].u.multiset, Pike_sp[-1].u.multiset,
|
d05ad7 | 2016-12-30 | Martin Nilsson | | PIKE_ARRAY_OP_OR_LEFT);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | push_multiset(l);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
{
|
19961b | 2017-04-08 | Martin Nilsson | | if (Pike_sp[-1].u.array->size == 1) {
|
5768c2 | 2009-09-07 | Henrik Grubbström (Grubba) | |
|
19961b | 2017-04-08 | Martin Nilsson | | int i = array_search(Pike_sp[-2].u.array, Pike_sp[-1].u.array->item, 0);
|
5768c2 | 2009-09-07 | Henrik Grubbström (Grubba) | | if (i == -1) {
f_add(2);
} else {
pop_stack();
}
|
19961b | 2017-04-08 | Martin Nilsson | | } else if ((Pike_sp[-2].u.array == Pike_sp[-1].u.array) &&
(Pike_sp[-1].u.array->refs == 2)) {
|
5768c2 | 2009-09-07 | Henrik Grubbström (Grubba) | |
pop_stack();
} else {
struct array *a;
|
19961b | 2017-04-08 | Martin Nilsson | | a=merge_array_with_order(Pike_sp[-2].u.array, Pike_sp[-1].u.array,
|
5768c2 | 2009-09-07 | Henrik Grubbström (Grubba) | | PIKE_ARRAY_OP_OR_LEFT);
pop_n_elems(2);
push_array(a);
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
3db0d2 | 1999-12-13 | Henrik Grubbström (Grubba) | | case T_TYPE:
{
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | struct pike_type *t;
|
19961b | 2017-04-08 | Martin Nilsson | | t = or_pike_types(Pike_sp[-2].u.type, Pike_sp[-1].u.type, 0);
|
3db0d2 | 1999-12-13 | Henrik Grubbström (Grubba) | | pop_n_elems(2);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(t);
|
3db0d2 | 1999-12-13 | Henrik Grubbström (Grubba) | | return;
}
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_PROGRAM:
{
struct program *p;
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | struct pike_type *a;
struct pike_type *b;
struct pike_type *t;
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | |
|
19961b | 2017-04-08 | Martin Nilsson | | p = program_from_svalue(Pike_sp - 2);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`|", 1, "type");
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | a = pop_unfinished_type();
|
19961b | 2017-04-08 | Martin Nilsson | | p = program_from_svalue(Pike_sp - 1);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`|", 2, "type");
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | b = pop_unfinished_type();
t = or_pike_types(a, b, 0);
pop_n_elems(2);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(t);
free_type(a);
free_type(b);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | return;
}
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | STRING_BITOP(|,"OR")
|
fc0bb5 | 1997-02-13 | Niels Möller | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`|", "Bitwise OR on illegal type.\n", Pike_sp, 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl mixed `|(mixed arg1, mixed arg2, mixed ... extras)
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @decl mixed `|(object arg1, mixed arg2)
*! @decl mixed `|(mixed arg1, object arg2)
*! @decl int `|(int arg1, int arg2)
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl string `|(string arg1, string arg2)
*! @decl array `|(array arg1, array arg2)
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @decl mapping `|(mapping arg1, mapping arg2)
*! @decl multiset `|(multiset arg1, multiset arg2)
*! @decl type `|(program|type arg1, program|type arg2)
*!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Bitwise or/union.
*!
*! 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)@}.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @returns
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there's a single argument, that argument is returned.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there are more than two arguments, the result is:
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! @expr{`|(`|(@[arg1], @[arg2]), @@@[extras])@}.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise, if @[arg1] is an object with an @[lfun::`|()], that
*! function is called with @[arg2] as argument, and its result is
*! returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise, if @[arg2] is an object with an @[lfun::``|()], that
*! function is called with @[arg1] as argument, and its result is
*! returned.
*!
*! Otherwise the result depends on the argument types:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg1
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type int
*! Bitwise or of @[arg1] and @[arg2].
|
087772 | 2020-03-19 | Henrik Grubbström (Grubba) | | *! @type zero
*! @[UNDEFINED] may be or:ed with multisets, behaving as if
*! it was an empty multiset.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type string
*! The result is a string where each character is the bitwise
*! or of the characters in the same position in @[arg1] and
*! @[arg2]. The arguments must be strings of the same length.
*! @type array
*! The result is an array with the elements in @[arg1]
*! concatenated with those in @[arg2] that doesn't occur in
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! @[arg1] (according to @[`>], @[`<], @[`==]). The order
*! between the elements that come from the same argument is kept.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *!
*! Every element in @[arg1] is only matched once against an
*! element in @[arg2], so if @[arg2] contains several elements
*! that are equal to each other and are more than their
*! counterparts in @[arg1], the rightmost remaining elements in
*! @[arg2] are kept.
*! @type mapping
*! The result is like @[arg1] but extended with the entries
*! from @[arg2]. If the same index (according to @[hash_value]
*! and @[`==]) occur in both, the value from @[arg2] is used.
*! @type multiset
*! The result is like @[arg1] but extended with the entries in
|
087772 | 2020-03-19 | Henrik Grubbström (Grubba) | | *! @[arg2] that don't already occur in @[arg1] (according to
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! @[`>], @[`<] and @[`==]). Subsequences with orderwise equal
*! entries (i.e. where @[`<] returns false) are handled just
*! like the array case above.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type type|program
*! Type union of @[arg1] and @[arg2].
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @endmixed
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! The function is not destructive on the arguments - the result is
*! always a new instance.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! @note
*! If this operator is used with arrays or multisets containing objects
*! which implement @[lfun::`==()] but @b{not@} @[lfun::`>()] and
*! @[lfun::`<()], the result will be undefined.
*!
|
087772 | 2020-03-19 | Henrik Grubbström (Grubba) | | *! The treatment of @[UNDEFINED] with multisets was new in Pike 8.1.
*!
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @seealso
*! @[`&()], @[lfun::`|()], @[lfun::``|()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_or(INT32 args)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
switch(args)
{
|
06bd61 | 2016-01-26 | Martin Nilsson | | case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`|", 1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | case 1: return;
case 2: o_or(); return;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | default:
|
c62935 | 2016-12-30 | Martin Nilsson | | speedup(args, o_or);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
}
static int generate_or(node *n)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | switch(count_args(CDR(n)))
{
case 1:
do_docode(CDR(n),0);
return 1;
case 2:
do_docode(CDR(n),0);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_OR);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
default:
return 0;
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_xor(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-1]) != TYPEOF(Pike_sp[-2]))
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if(call_lfun(LFUN_XOR, LFUN_RXOR)) {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return;
|
19961b | 2017-04-08 | Martin Nilsson | | } else if (((TYPEOF(Pike_sp[-1]) == T_TYPE) ||
(TYPEOF(Pike_sp[-1]) == T_PROGRAM) ||
(TYPEOF(Pike_sp[-1]) == T_FUNCTION)) &&
((TYPEOF(Pike_sp[-2]) == T_TYPE) ||
(TYPEOF(Pike_sp[-2]) == T_PROGRAM) ||
(TYPEOF(Pike_sp[-2]) == T_FUNCTION))) {
if (TYPEOF(Pike_sp[-2]) != T_TYPE) {
struct program *p = program_from_svalue(Pike_sp - 2);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`^", 1, "type");
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp - 2);
SET_SVAL(Pike_sp[-2], T_TYPE, 0, type, pop_unfinished_type());
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
|
19961b | 2017-04-08 | Martin Nilsson | | if (TYPEOF(Pike_sp[-1]) != T_TYPE) {
struct program *p = program_from_svalue(Pike_sp - 1);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`^", 2, "type");
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp - 1);
SET_SVAL(Pike_sp[-1], T_TYPE, 0, type, pop_unfinished_type());
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
} else {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | int args = 2;
|
19961b | 2017-04-08 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`^", 2, get_name_of_type(TYPEOF(Pike_sp[-2])));
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | }
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-2]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
2a8925 | 2016-12-30 | Martin Nilsson | | if(!call_lfun(LFUN_XOR,LFUN_RXOR))
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`^", "Bitwise xor on objects without `^ operator.\n", Pike_sp, 2);
|
4d4265 | 2016-12-31 | Martin Nilsson | | return;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer,
Pike_sp[-1].u.integer ^ Pike_sp[0].u.integer);
|
4d4265 | 2016-12-31 | Martin Nilsson | | return;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
case T_MAPPING:
{
struct mapping *m;
|
19961b | 2017-04-08 | Martin Nilsson | | m=merge_mappings(Pike_sp[-2].u.mapping, Pike_sp[-1].u.mapping, PIKE_ARRAY_OP_XOR);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_mapping(m);
return;
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | case T_MULTISET:
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct multiset *l;
|
19961b | 2017-04-08 | Martin Nilsson | | l=merge_multisets(Pike_sp[-2].u.multiset, Pike_sp[-1].u.multiset,
|
d05ad7 | 2016-12-30 | Martin Nilsson | | PIKE_ARRAY_OP_XOR);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | push_multiset(l);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
{
struct array *a;
|
19961b | 2017-04-08 | Martin Nilsson | | a=merge_array_with_order(Pike_sp[-2].u.array, Pike_sp[-1].u.array, PIKE_ARRAY_OP_XOR);
|
c1d3f2 | 1999-08-16 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | push_array(a);
return;
}
|
fc0bb5 | 1997-02-13 | Niels Möller | |
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_PROGRAM:
{
struct program *p;
|
19961b | 2017-04-08 | Martin Nilsson | | p = program_from_svalue(Pike_sp - 1);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`^", 2, "type");
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | pop_stack();
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(pop_unfinished_type());
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | |
stack_swap();
|
19961b | 2017-04-08 | Martin Nilsson | | p = program_from_svalue(Pike_sp - 1);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
int args = 2;
stack_swap();
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`^", 1, "type");
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | pop_stack();
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(pop_unfinished_type());
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
|
5f5084 | 2018-02-12 | Marcus Comstedt | |
|
3db0d2 | 1999-12-13 | Henrik Grubbström (Grubba) | | case T_TYPE:
{
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | |
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | struct pike_type *a;
struct pike_type *b;
|
19961b | 2017-04-08 | Martin Nilsson | | copy_pike_type(a, Pike_sp[-2].u.type);
copy_pike_type(b, Pike_sp[-1].u.type);
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | o_compl();
o_and();
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(a);
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | o_compl();
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(b);
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | o_and();
o_or();
|
3db0d2 | 1999-12-13 | Henrik Grubbström (Grubba) | | return;
}
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | STRING_BITOP(^,"XOR")
|
fc0bb5 | 1997-02-13 | Niels Möller | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`^", "Bitwise XOR on illegal type.\n", Pike_sp, 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl mixed `^(mixed arg1, mixed arg2, mixed ... extras)
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @decl mixed `^(object arg1, mixed arg2)
*! @decl mixed `^(mixed arg1, object arg2)
*! @decl int `^(int arg1, int arg2)
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @decl string `^(string arg1, string arg2)
*! @decl array `^(array arg1, array arg2)
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @decl mapping `^(mapping arg1, mapping arg2)
*! @decl multiset `^(multiset arg1, multiset arg2)
*! @decl type `^(program|type arg1, program|type arg2)
*!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Exclusive or.
*!
*! 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)@}.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @returns
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there's a single argument, that argument is returned.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there are more than two arguments, the result is:
|
f79bd8 | 2003-04-01 | Martin Nilsson | | *! @expr{`^(`^(@[arg1], @[arg2]), @@@[extras])@}.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise, if @[arg1] is an object with an @[lfun::`^()], that
*! function is called with @[arg2] as argument, and its result is
*! returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Otherwise, if @[arg2] is an object with an @[lfun::``^()], that
*! function is called with @[arg1] as argument, and its result is
*! returned.
*!
*! Otherwise the result depends on the argument types:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg1
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @type int
*! Bitwise exclusive or of @[arg1] and @[arg2].
*! @type string
*! The result is a string where each character is the bitwise
*! exclusive or of the characters in the same position in
*! @[arg1] and @[arg2]. The arguments must be strings of the
*! same length.
*! @type array
*! The result is an array with the elements in @[arg1] that
*! doesn't occur in @[arg2] concatenated with those in @[arg2]
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! that doesn't occur in @[arg1] (according to @[`>], @[`<] and
*! @[`==]). The order between the elements that come from the
*! same argument is kept.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *!
*! Every element is only matched once against an element in the
*! other array, so if one contains several elements that are
*! equal to each other and are more than their counterparts in
*! the other array, the rightmost remaining elements are kept.
*! @type mapping
*! The result is like @[arg1] but with the entries from @[arg1]
*! and @[arg2] whose indices are different between them
*! (according to @[hash_value] and @[`==]).
*! @type multiset
*! The result is like @[arg1] but with the entries from @[arg1]
*! and @[arg2] that are different between them (according to
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! @[`>], @[`<] and @[`==]). Subsequences with orderwise equal
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! entries (i.e. where @[`<] returns false) are handled just
*! like the array case above.
*! @type type|program
*! The result is a type computed like this:
|
9fcd24 | 2002-05-31 | Martin Nilsson | | *! @expr{(@[arg1]&~@[arg2])|(~@[arg1]&@[arg2])@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @endmixed
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! The function is not destructive on the arguments - the result is
*! always a new instance.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
b912e9 | 2018-05-19 | Arne Goedeke | | *! @note
*! If this operator is used with arrays or multisets containing objects
*! which implement @[lfun::`==()] but @b{not@} @[lfun::`>()] and
*! @[lfun::`<()], the result will be undefined.
*!
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @seealso
*! @[`&()], @[`|()], @[lfun::`^()], @[lfun::``^()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_xor(INT32 args)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
switch(args)
{
|
06bd61 | 2016-01-26 | Martin Nilsson | | case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`^", 1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | case 1: return;
case 2: o_xor(); return;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | default:
|
c62935 | 2016-12-30 | Martin Nilsson | | speedup(args, o_xor);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
}
static int generate_xor(node *n)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | switch(count_args(CDR(n)))
{
case 1:
do_docode(CDR(n),0);
return 1;
case 2:
do_docode(CDR(n),0);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_XOR);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
default:
return 0;
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_lsh(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | int args = 2;
|
19961b | 2017-04-08 | Martin Nilsson | | if ((TYPEOF(Pike_sp[-2]) == T_OBJECT) ||
(TYPEOF(Pike_sp[-1]) == T_OBJECT))
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | goto call_lfun;
|
19961b | 2017-04-08 | Martin Nilsson | | if ((TYPEOF(Pike_sp[-1]) != T_INT) || (Pike_sp[-1].u.integer < 0)) {
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`<<", 2, "int(0..)|object");
|
37f1a8 | 2014-08-31 | Per Hedbor | | }
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | |
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-2])) {
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | if (!INT_TYPE_LSH_OVERFLOW(Pike_sp[-2].u.integer, Pike_sp[-1].u.integer))
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | break;
|
ff0d46 | 1999-10-15 | Fredrik Noring | | convert_stack_top_to_bignum();
|
031171 | 2013-06-17 | Martin Nilsson | |
|
5f5084 | 2018-02-12 | Marcus Comstedt | |
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | |
case T_OBJECT:
call_lfun:
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(call_lfun(LFUN_LSH, LFUN_RLSH))
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | return;
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-2]) != T_INT)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`<<", 1, "int|float|object");
SIMPLE_ARG_TYPE_ERROR("`<<", 2, "int(0..)|object");
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | break;
case T_FLOAT:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
Pike_sp[-1].u.float_number = ldexp(Pike_sp[-1].u.float_number,
Pike_sp->u.integer);
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | return;
default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`<<", 1, "int|float|object");
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | break;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
031171 | 2013-06-17 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer,
Pike_sp[-1].u.integer << Pike_sp->u.integer);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | |
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @decl mixed `<<(int arg1, object arg2)
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | *! @decl mixed `<<(float arg1, int(0..) arg2)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! 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)@}.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! If @[arg1] is an object that implements @[lfun::`<<()], that
*! function will be called with @[arg2] as the single argument.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! If @[arg2] is an object that implements @[lfun::``<<()], that
*! function will be called with @[arg1] as the single argument.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | *! If @[arg1] is a float and @[arg2] is a non-negative integer,
*! @[arg1] will be multiplied by @expr{1<<@[arg2]@}.
*!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! Otherwise @[arg1] will be shifted @[arg2] bits left.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`>>()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_lsh(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 2)
SIMPLE_WRONG_NUM_ARGS_ERROR("`<<", 2);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | o_lsh();
}
static int generate_lsh(node *n)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | if(count_args(CDR(n))==2)
{
|
5e4442 | 2001-02-25 | Fredrik Hübinette (Hubbe) | | do_docode(CDR(n),DO_NOT_COPY_TOPLEVEL);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_LSH);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_rsh(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | int args = 2;
|
19961b | 2017-04-08 | Martin Nilsson | | if ((TYPEOF(Pike_sp[-2]) == T_OBJECT) || (TYPEOF(Pike_sp[-1]) == T_OBJECT))
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(call_lfun(LFUN_RSH, LFUN_RRSH))
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | return;
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-2]) != T_INT)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`>>", 1, "int|object");
SIMPLE_ARG_TYPE_ERROR("`>>", 2, "int(0..)|object");
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
13670c | 2015-05-25 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | if ((TYPEOF(Pike_sp[-1]) != T_INT) || (Pike_sp[-1].u.integer < 0)) {
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`>>", 2, "int(0..)|object");
|
ba1830 | 2002-04-20 | Johan Sundström | | }
|
b01963 | 2002-10-15 | Henrik Grubbström (Grubba) | |
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
switch(TYPEOF(Pike_sp[-1])) {
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | if( INT_TYPE_RSH_OVERFLOW(Pike_sp[-1].u.integer, Pike_sp->u.integer) )
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if (Pike_sp[-1].u.integer < 0) {
SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, -1);
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | } else {
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, 0);
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | }
return;
|
ba1830 | 2002-04-20 | Johan Sundström | | }
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | break;
case T_FLOAT:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp[-1].u.float_number = ldexp(Pike_sp[-1].u.float_number,
-Pike_sp->u.integer);
|
ba1830 | 2002-04-20 | Johan Sundström | | return;
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | default:
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`>>", 1, "int|float|object");
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | break;
|
ba1830 | 2002-04-20 | Johan Sundström | | }
|
13670c | 2015-05-25 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer,
Pike_sp[-1].u.integer >> Pike_sp->u.integer);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | |
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @decl mixed `>>(int arg1, object arg2)
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | *! @decl float `>>(float arg1, int(0..) arg2)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! 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)@}.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! If @[arg1] is an object that implements @[lfun::`>>()], that
*! function will be called with @[arg2] as the single argument.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! If @[arg2] is an object that implements @[lfun::``>>()], that
*! function will be called with @[arg1] as the single argument.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
a320e5 | 2015-09-16 | Henrik Grubbström (Grubba) | | *! If @[arg1] is a float and @[arg2] is a non-negative integer,
*! @[arg1] will be divided by @expr{1<<@[arg2]@}.
*!
|
9a147d | 2002-08-02 | Johan Sundström | | *! Otherwise @[arg1] will be shifted @[arg2] bits right.
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`<<()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_rsh(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 2)
SIMPLE_WRONG_NUM_ARGS_ERROR("`>>", 2);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | o_rsh();
}
static int generate_rsh(node *n)
{
if(count_args(CDR(n))==2)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | do_docode(CDR(n),DO_NOT_COPY);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_RSH);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | |
#define TWO_TYPES(X,Y) (((X)<<8)|(Y))
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_multiply(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | int args = 2;
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TWO_TYPES(TYPEOF(Pike_sp[-2]), TYPEOF(Pike_sp[-1])))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | case TWO_TYPES(T_ARRAY, T_INT):
{
struct array *ret;
struct svalue *pos;
INT32 e;
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.integer < 0)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`*", 2, "int(0..)");
|
19961b | 2017-04-08 | Martin Nilsson | | ret=allocate_array(Pike_sp[-2].u.array->size * Pike_sp[-1].u.integer);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | pos=ret->item;
|
19961b | 2017-04-08 | Martin Nilsson | | for(e=0;e<Pike_sp[-1].u.integer;e++,pos+=Pike_sp[-2].u.array->size)
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | assign_svalues_no_free(pos,
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp[-2].u.array->item,
Pike_sp[-2].u.array->size,
Pike_sp[-2].u.array->type_field);
ret->type_field=Pike_sp[-2].u.array->type_field;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_array(ret);
return;
}
|
3a3bc3 | 2000-09-26 | Henrik Wallin | |
case TWO_TYPES(T_ARRAY, T_FLOAT):
{
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | struct array *src;
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | struct array *ret;
struct svalue *pos;
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | ptrdiff_t asize, delta;
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.float_number < 0)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`*", 2, "float(0..)");
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | |
|
19961b | 2017-04-08 | Martin Nilsson | | src = Pike_sp[-2].u.array;
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | delta = src->size;
|
19961b | 2017-04-08 | Martin Nilsson | | asize = (ptrdiff_t)floor(delta * Pike_sp[-1].u.float_number + 0.5);
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | ret = allocate_array(asize);
pos = ret->item;
|
fa95e6 | 2000-10-15 | Henrik Grubbström (Grubba) | | if (asize > delta) {
|
3ee2ea | 2000-10-15 | Henrik Grubbström (Grubba) | | ret->type_field = src->type_field;
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | assign_svalues_no_free(pos,
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | src->item,
delta,
src->type_field);
pos += delta;
asize -= delta;
|
fa95e6 | 2000-10-15 | Henrik Grubbström (Grubba) | | while (asize > delta) {
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | assign_svalues_no_free(pos, ret->item, delta, ret->type_field);
pos += delta;
asize -= delta;
delta <<= 1;
}
if (asize) {
assign_svalues_no_free(pos, ret->item, asize, ret->type_field);
}
} else if (asize) {
|
2523ce | 2003-04-28 | Martin Stjernholm | | ret->type_field =
assign_svalues_no_free(pos,
src->item,
asize,
src->type_field);
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | }
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | pop_n_elems(2);
push_array(ret);
return;
}
case TWO_TYPES(T_STRING, T_FLOAT):
{
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | struct pike_string *src;
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | struct pike_string *ret;
char *pos;
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | ptrdiff_t len, delta;
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.float_number < 0)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`*", 2, "float(0..)");
|
19961b | 2017-04-08 | Martin Nilsson | | src = Pike_sp[-2].u.string;
len = (ptrdiff_t)floor(src->len * Pike_sp[-1].u.float_number + 0.5);
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | ret = begin_wide_shared_string(len, src->size_shift);
len <<= src->size_shift;
delta = src->len << src->size_shift;
pos = ret->str;
|
fa95e6 | 2000-10-15 | Henrik Grubbström (Grubba) | | if (len > delta) {
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(pos, src->str, delta);
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | pos += delta;
len -= delta;
|
fa95e6 | 2000-10-15 | Henrik Grubbström (Grubba) | | while (len > delta) {
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(pos, ret->str, delta);
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | pos += delta;
len -= delta;
delta <<= 1;
}
if (len) {
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(pos, ret->str, len);
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | }
} else if (len) {
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(pos, src->str, len);
|
fc3a64 | 2000-09-26 | Henrik Wallin | | }
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | pop_n_elems(2);
push_string(low_end_shared_string(ret));
return;
}
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | case TWO_TYPES(T_STRING, T_INT):
{
struct pike_string *ret;
char *pos;
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | INT_TYPE e;
ptrdiff_t len;
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.integer < 0)
|
f98274 | 2016-01-26 | Martin Nilsson | | SIMPLE_ARG_TYPE_ERROR("`*", 2, "int(0..)");
|
19961b | 2017-04-08 | Martin Nilsson | | ret=begin_wide_shared_string(Pike_sp[-2].u.string->len * Pike_sp[-1].u.integer,
Pike_sp[-2].u.string->size_shift);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | pos=ret->str;
|
19961b | 2017-04-08 | Martin Nilsson | | len=Pike_sp[-2].u.string->len << Pike_sp[-2].u.string->size_shift;
for(e=0;e<Pike_sp[-1].u.integer;e++,pos+=len)
memcpy(pos,Pike_sp[-2].u.string->str,len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | push_string(low_end_shared_string(ret));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | return;
}
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | case TWO_TYPES(T_ARRAY,T_STRING):
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *ret;
|
19961b | 2017-04-08 | Martin Nilsson | | ret=implode(Pike_sp[-2].u.array,Pike_sp[-1].u.string);
free_string(Pike_sp[-1].u.string);
free_array(Pike_sp[-2].u.array);
SET_SVAL(Pike_sp[-2], T_STRING, 0, string, ret);
Pike_sp--;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | case TWO_TYPES(T_ARRAY,T_ARRAY):
{
struct array *ret;
|
19961b | 2017-04-08 | Martin Nilsson | | ret=implode_array(Pike_sp[-2].u.array, Pike_sp[-1].u.array);
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_array(ret);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | return;
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | }
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | case TWO_TYPES(T_FLOAT,T_FLOAT):
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
Pike_sp[-1].u.float_number *= Pike_sp[0].u.float_number;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | case TWO_TYPES(T_FLOAT,T_INT):
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
Pike_sp[-1].u.float_number *= (FLOAT_TYPE)Pike_sp[0].u.integer;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | return;
case TWO_TYPES(T_INT,T_FLOAT):
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
Pike_sp[-1].u.float_number=
(FLOAT_TYPE) Pike_sp[-1].u.integer * Pike_sp[0].u.float_number;
SET_SVAL_TYPE(Pike_sp[-1], T_FLOAT);
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | return;
case TWO_TYPES(T_INT,T_INT):
|
f30663 | 2012-12-31 | Arne Goedeke | | {
INT_TYPE res;
|
19961b | 2017-04-08 | Martin Nilsson | | if (DO_INT_TYPE_MUL_OVERFLOW(Pike_sp[-2].u.integer, Pike_sp[-1].u.integer, &res))
|
fda0de | 1999-10-08 | Fredrik Noring | | {
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | convert_stack_top_to_bignum();
goto do_lfun_multiply;
|
fda0de | 1999-10-08 | Fredrik Noring | | }
|
031171 | 2013-06-17 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, res);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
|
f30663 | 2012-12-31 | Arne Goedeke | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | do_lfun_multiply:
|
4d4265 | 2016-12-31 | Martin Nilsson | | if(!call_lfun(LFUN_MULTIPLY, LFUN_RMULTIPLY))
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`*", "Multiplication on objects without `* operator.\n", Pike_sp, 2);
|
4d4265 | 2016-12-31 | Martin Nilsson | | return;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
fbff33 | 2016-05-17 | Per Hedbor | |
|
7ed4c8 | 2016-05-17 | Per Hedbor | |
|
fbff33 | 2016-05-17 | Per Hedbor | | PMOD_EXPORT void f_exponent(INT32 args)
{
|
9e10fe | 2020-06-06 | Marcus Comstedt | | FLOAT_ARG_TYPE a, b;
|
fbff33 | 2016-05-17 | Per Hedbor | |
|
7ed4c8 | 2016-05-17 | Per Hedbor | | if(args != 2 )
SIMPLE_WRONG_NUM_ARGS_ERROR("`**",2);
|
fbff33 | 2016-05-17 | Per Hedbor | |
|
19961b | 2017-04-08 | Martin Nilsson | | switch( TWO_TYPES(TYPEOF(Pike_sp[-2]), TYPEOF(Pike_sp[-1])) )
|
7ed4c8 | 2016-05-17 | Per Hedbor | | {
case TWO_TYPES(T_FLOAT,T_FLOAT):
|
19961b | 2017-04-08 | Martin Nilsson | | a = Pike_sp[-2].u.float_number;
b = Pike_sp[-1].u.float_number;
|
7ed4c8 | 2016-05-17 | Per Hedbor | | goto res_is_powf;
|
fbff33 | 2016-05-17 | Per Hedbor | |
|
7ed4c8 | 2016-05-17 | Per Hedbor | | case TWO_TYPES(T_FLOAT,T_INT):
|
19961b | 2017-04-08 | Martin Nilsson | | a = Pike_sp[-2].u.float_number;
|
9e10fe | 2020-06-06 | Marcus Comstedt | | b = (FLOAT_ARG_TYPE)Pike_sp[-1].u.integer;
|
7ed4c8 | 2016-05-17 | Per Hedbor | | goto res_is_powf;
|
fbff33 | 2016-05-17 | Per Hedbor | |
|
7ed4c8 | 2016-05-17 | Per Hedbor | | case TWO_TYPES(T_INT,T_FLOAT):
|
9e10fe | 2020-06-06 | Marcus Comstedt | | a = (FLOAT_ARG_TYPE)Pike_sp[-2].u.integer;
b = (FLOAT_ARG_TYPE)Pike_sp[-1].u.float_number;
|
fbff33 | 2016-05-17 | Per Hedbor | |
|
7ed4c8 | 2016-05-17 | Per Hedbor | | res_is_powf:
{
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp-=2;
|
9e10fe | 2020-06-06 | Marcus Comstedt | | #if SIZEOF_FLOAT_TYPE > SIZEOF_DOUBLE
push_float( powl( a, b ) );
#else
push_float( pow( a, b ) );
#endif
|
725903 | 2016-05-17 | Per Hedbor | | return;
|
7ed4c8 | 2016-05-17 | Per Hedbor | | }
default:
stack_swap();
convert_stack_top_to_bignum();
stack_swap();
|
5f5084 | 2018-02-12 | Marcus Comstedt | |
|
fbff33 | 2016-05-17 | Per Hedbor | |
|
7ed4c8 | 2016-05-17 | Per Hedbor | | case TWO_TYPES(T_OBJECT,T_INT):
|
5f6ffc | 2016-05-18 | Per Hedbor | | case TWO_TYPES(T_OBJECT,T_FLOAT):
|
7ed4c8 | 2016-05-17 | Per Hedbor | | case TWO_TYPES(T_OBJECT,T_OBJECT):
|
5f6ffc | 2016-05-18 | Per Hedbor | | case TWO_TYPES(T_INT,T_OBJECT):
case TWO_TYPES(T_FLOAT,T_OBJECT):
|
7ed4c8 | 2016-05-17 | Per Hedbor | | if( !call_lfun( LFUN_POW, LFUN_RPOW ) )
|
5f6ffc | 2016-05-18 | Per Hedbor | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if( TYPEOF(Pike_sp[-2]) != PIKE_T_OBJECT )
|
5f6ffc | 2016-05-18 | Per Hedbor | | {
stack_swap();
convert_stack_top_to_bignum();
stack_swap();
if( call_lfun( LFUN_POW, LFUN_RPOW ) )
return;
}
Pike_error("Illegal argument 1 to `** (object missing implementation of `**).\n");
}
|
7ed4c8 | 2016-05-17 | Per Hedbor | | return;
}
|
fbff33 | 2016-05-17 | Per Hedbor | | }
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Multiplication/repetition/implosion.
*!
*! 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)@}. Longer @expr{*@} expressions are
*! normally optimized to one call, so e.g. @expr{a*b*c@} becomes
*! @expr{predef::`*(a,b,c)@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! If there's a single argument, that argument will be returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! If the first argument is an object that implements @[lfun::`*()],
*! that function will be called with the rest of the arguments.
*!
*! If there are more than two arguments, the result will be
|
9fcd24 | 2002-05-31 | Martin Nilsson | | *! @expr{`*(`*(@[arg1], @[arg2]), @@@[extras])@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! If @[arg2] is an object that implements @[lfun::``*()], that
*! function will be called with @[arg1] as the single argument.
*!
*! Otherwise the result will be as follows:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg1
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type array
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg2
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type int|float
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! The result will be @[arg1] concatenated @[arg2] times.
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type string|array
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! The result will be the elements of @[arg1] concatenated with
*! @[arg2] interspersed.
*! @endmixed
*! @type string
*! The result will be @[arg1] concatenated @[arg2] times.
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type int|float
|
9fcd24 | 2002-05-31 | Martin Nilsson | | *! The result will be @expr{@[arg1] * @[arg2]@}, and will be a
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! float if either @[arg1] or @[arg2] is a float.
*! @endmixed
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
*! @note
*! In Pike 7.0 and earlier the multiplication order was unspecified.
*!
*! @seealso
|
fe9d71 | 2002-11-26 | Henrik Grubbström (Grubba) | | *! @[`+()], @[`-()], @[`/()], @[lfun::`*()], @[lfun::``*()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_multiply(INT32 args)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
switch(args)
{
|
06bd61 | 2016-01-26 | Martin Nilsson | | case 0: SIMPLE_WRONG_NUM_ARGS_ERROR("`*", 1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | case 1: return;
case 2: o_multiply(); return;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | default:
{
|
0c6097 | 2000-09-22 | Henrik Grubbström (Grubba) | | INT32 i = -args, j = -1;
while(i < j) {
|
19961b | 2017-04-08 | Martin Nilsson | | struct svalue tmp = Pike_sp[i];
Pike_sp[i++] = Pike_sp[j];
Pike_sp[j--] = tmp;
|
0c6097 | 2000-09-22 | Henrik Grubbström (Grubba) | | }
while(--args > 0) {
stack_swap();
o_multiply();
}
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
}
static int generate_multiply(node *n)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | switch(count_args(CDR(n)))
{
case 1:
do_docode(CDR(n),0);
return 1;
case 2:
do_docode(CDR(n),0);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_MULTIPLY);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
default:
return 0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_divide(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-2]) != TYPEOF(Pike_sp[-1]) && !float_promote())
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
if(call_lfun(LFUN_DIVIDE, LFUN_RDIVIDE))
return;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TWO_TYPES(TYPEOF(Pike_sp[-2]), TYPEOF(Pike_sp[-1])))
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | {
case TWO_TYPES(T_STRING,T_INT):
{
struct array *a;
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | INT_TYPE len;
ptrdiff_t size,e,pos=0;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | len=Pike_sp[-1].u.integer;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(!len)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_DIVISION_BY_ZERO_ERROR("`/");
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
if(len<0)
{
len=-len;
|
19961b | 2017-04-08 | Martin Nilsson | | size=Pike_sp[-2].u.string->len / len;
pos+=Pike_sp[-2].u.string->len % len;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | }else{
|
19961b | 2017-04-08 | Martin Nilsson | | size=Pike_sp[-2].u.string->len / len;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }
a=allocate_array(size);
for(e=0;e<size;e++)
{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[e], T_STRING, 0, string,
|
19961b | 2017-04-08 | Martin Nilsson | | string_slice(Pike_sp[-2].u.string, pos,len));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | pos+=len;
}
a->type_field=BIT_STRING;
pop_n_elems(2);
push_array(a);
return;
}
case TWO_TYPES(T_STRING,T_FLOAT):
{
struct array *a;
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | ptrdiff_t size, pos, last, e;
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | FLOAT_ARG_TYPE len;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | len=Pike_sp[-1].u.float_number;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(len==0.0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_DIVISION_BY_ZERO_ERROR("`/");
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
if(len<0)
{
len=-len;
|
19961b | 2017-04-08 | Martin Nilsson | | size=(ptrdiff_t)ceil( ((double)Pike_sp[-2].u.string->len) / len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | for(last=Pike_sp[-2].u.string->len,e=0;e<size-1;e++)
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | pos=Pike_sp[-2].u.string->len - (ptrdiff_t)((e+1)*len+0.5);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[size-1-e], T_STRING, 0, string,
|
19961b | 2017-04-08 | Martin Nilsson | | string_slice(Pike_sp[-2].u.string, pos, last-pos));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | last=pos;
}
pos=0;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[0], T_STRING, 0, string,
|
19961b | 2017-04-08 | Martin Nilsson | | string_slice(Pike_sp[-2].u.string, pos, last-pos));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }else{
|
19961b | 2017-04-08 | Martin Nilsson | | size=(ptrdiff_t)ceil( ((double)Pike_sp[-2].u.string->len) / len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | for(last=0,e=0;e<size-1;e++)
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | {
|
bd6739 | 2015-10-14 | Martin Nilsson | | pos = (ptrdiff_t)((e+1)*len+0.5);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[e], T_STRING, 0, string,
|
19961b | 2017-04-08 | Martin Nilsson | | string_slice(Pike_sp[-2].u.string, last, pos-last));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | last=pos;
}
|
19961b | 2017-04-08 | Martin Nilsson | | pos=Pike_sp[-2].u.string->len;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[e], T_STRING, 0, string,
|
19961b | 2017-04-08 | Martin Nilsson | | string_slice(Pike_sp[-2].u.string, last, pos-last));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }
a->type_field=BIT_STRING;
pop_n_elems(2);
push_array(a);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | return;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }
|
13670c | 2015-05-25 | Martin Nilsson | |
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
case TWO_TYPES(T_ARRAY, T_INT):
{
struct array *a;
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | ptrdiff_t size,e,pos;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | INT_TYPE len=Pike_sp[-1].u.integer;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(!len)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_DIVISION_BY_ZERO_ERROR("`/");
|
a5a649 | 2011-03-03 | Martin Stjernholm | |
if (!Pike_sp[-2].u.array->size) {
pop_n_elems (2);
ref_push_array (&empty_array);
return;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(len<0)
{
|
6f4940 | 1998-07-31 | Henrik Grubbström (Grubba) | | len = -len;
|
19961b | 2017-04-08 | Martin Nilsson | | pos = Pike_sp[-2].u.array->size % len;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | }else{
|
6f4940 | 1998-07-31 | Henrik Grubbström (Grubba) | | pos = 0;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }
|
19961b | 2017-04-08 | Martin Nilsson | | size = Pike_sp[-2].u.array->size / len;
|
6f4940 | 1998-07-31 | Henrik Grubbström (Grubba) | |
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
for(e=0;e<size;e++)
{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[e], T_ARRAY, 0, array,
|
19961b | 2017-04-08 | Martin Nilsson | | friendly_slice_array(Pike_sp[-2].u.array, pos, pos+len));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | pos+=len;
}
a->type_field=BIT_ARRAY;
pop_n_elems(2);
push_array(a);
return;
}
case TWO_TYPES(T_ARRAY,T_FLOAT):
{
struct array *a;
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | ptrdiff_t last,pos,e,size;
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | FLOAT_ARG_TYPE len;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | len=Pike_sp[-1].u.float_number;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(len==0.0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_DIVISION_BY_ZERO_ERROR("`/");
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
a5a649 | 2011-03-03 | Martin Stjernholm | | if (!Pike_sp[-2].u.array->size) {
pop_n_elems (2);
ref_push_array (&empty_array);
return;
}
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(len<0)
{
len=-len;
|
19961b | 2017-04-08 | Martin Nilsson | | size = (ptrdiff_t)ceil( ((double)Pike_sp[-2].u.array->size) / len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | for(last=Pike_sp[-2].u.array->size,e=0;e<size-1;e++)
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | pos=Pike_sp[-2].u.array->size - (ptrdiff_t)((e+1)*len+0.5);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[size-1-e], T_ARRAY, 0, array,
|
19961b | 2017-04-08 | Martin Nilsson | | friendly_slice_array(Pike_sp[-2].u.array, pos, last));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | last=pos;
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[0], T_ARRAY, 0, array,
|
19961b | 2017-04-08 | Martin Nilsson | | slice_array(Pike_sp[-2].u.array, 0, last));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }else{
|
19961b | 2017-04-08 | Martin Nilsson | | size = (ptrdiff_t)ceil( ((double)Pike_sp[-2].u.array->size) / len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | for(last=0,e=0;e<size-1;e++)
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | {
|
61014a | 2000-09-26 | Henrik Wallin | | pos = (ptrdiff_t)((e+1)*len+0.5);
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[e], T_ARRAY, 0, array,
|
19961b | 2017-04-08 | Martin Nilsson | | friendly_slice_array(Pike_sp[-2].u.array, last, pos));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | last=pos;
}
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(a->item[e], T_ARRAY, 0, array,
|
19961b | 2017-04-08 | Martin Nilsson | | slice_array(Pike_sp[-2].u.array, last, Pike_sp[-2].u.array->size));
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }
a->type_field=BIT_ARRAY;
pop_n_elems(2);
push_array(a);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | return;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`/", "Division on different types.\n", Pike_sp, 2);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-2]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
4d4265 | 2016-12-31 | Martin Nilsson | | if(!call_lfun(LFUN_DIVIDE,LFUN_RDIVIDE))
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`/", "Division on objects without `/ operator.\n", Pike_sp, 2);
|
2a8925 | 2016-12-30 | Martin Nilsson | | return;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_STRING:
{
struct array *ret;
|
19961b | 2017-04-08 | Martin Nilsson | | ret=explode(Pike_sp[-2].u.string,Pike_sp[-1].u.string);
free_string(Pike_sp[-2].u.string);
free_string(Pike_sp[-1].u.string);
SET_SVAL(Pike_sp[-2], T_ARRAY, 0, array, ret);
Pike_sp--;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
{
|
19961b | 2017-04-08 | Martin Nilsson | | struct array *ret=explode_array(Pike_sp[-2].u.array, Pike_sp[-1].u.array);
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_array(ret);
return;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_FLOAT:
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.float_number == 0.0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_DIVISION_BY_ZERO_ERROR("`/");
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
Pike_sp[-1].u.float_number /= Pike_sp[0].u.float_number;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
case T_INT:
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | {
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | INT_TYPE tmp;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
19961b | 2017-04-08 | Martin Nilsson | | if (Pike_sp[-1].u.integer == 0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_DIVISION_BY_ZERO_ERROR("`/");
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | if(INT_TYPE_DIV_OVERFLOW(Pike_sp[-2].u.integer, Pike_sp[-1].u.integer))
|
08b980 | 1999-10-30 | Fredrik Noring | | {
stack_swap();
convert_stack_top_to_bignum();
stack_swap();
|
b0f528 | 2019-08-09 | Henrik Grubbström (Grubba) | | if (LIKELY(call_lfun(LFUN_DIVIDE,LFUN_RDIVIDE))) {
return;
}
Pike_fatal("Failed to call `/() in bignum.\n");
|
08b980 | 1999-10-30 | Fredrik Noring | | }
else
|
19961b | 2017-04-08 | Martin Nilsson | | tmp = Pike_sp[-2].u.integer/Pike_sp[-1].u.integer;
Pike_sp--;
|
c93f0e | 1997-12-03 | Fredrik Hübinette (Hubbe) | |
|
08b980 | 1999-10-30 | Fredrik Noring | |
|
6e34c6 | 2003-11-13 | Martin Stjernholm | |
|
19961b | 2017-04-08 | Martin Nilsson | | if((Pike_sp[-1].u.integer<0) != (Pike_sp[0].u.integer<0))
if(tmp*Pike_sp[0].u.integer!=Pike_sp[-1].u.integer)
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | tmp--;
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, tmp);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | }
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`/", "Bad argument 1.\n", Pike_sp, 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
441e21 | 2002-12-30 | Henrik Grubbström (Grubba) | | *! @decl array(string) `/(string arg1, string arg2)
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @decl array(array) `/(array arg1, array arg2)
*! @decl float `/(float arg1, int|float arg2)
*! @decl float `/(int arg1, float arg2)
*! @decl int `/(int arg1, int arg2)
*! @decl mixed `/(mixed arg1, mixed arg2, mixed ... extras)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Division/split.
*!
*! 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)@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! If there are more than two arguments, the result will be
|
9fcd24 | 2002-05-31 | Martin Nilsson | | *! @expr{`/(`/(@[arg1], @[arg2]), @@@[extras])@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! 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.
*!
*! Otherwise the result will be as follows:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg1
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type string
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg2
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type int|float
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! The result will be and array of @[arg1] split in segments
*! of length @[arg2]. If @[arg2] is negative the splitting
*! will start from the end of @[arg1].
*! @type string
*! The result will be an array of @[arg1] split at each
*! occurrence of @[arg2]. Note that the segments that
*! matched against @[arg2] will not be in the result.
*! @endmixed
*! @type array
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg2
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type int|float
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! The result will be and array of @[arg1] split in segments
*! of length @[arg2]. If @[arg2] is negative the splitting
*! will start from the end of @[arg1].
*! @type array
*! The result will be an array of @[arg1] split at each
*! occurrence of @[arg2]. Note that the elements that
*! matched against @[arg2] will not be in the result.
*! @endmixed
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type float|int
|
9fcd24 | 2002-05-31 | Martin Nilsson | | *! The result will be @expr{@[arg1] / @[arg2]@}. If both arguments
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! are int, the result will be truncated to an int. Otherwise the
*! result will be a float.
*! @endmixed
|
b8d9a0 | 2003-01-15 | Johan Sundström | | *! @note
|
7f95db | 2003-01-15 | Martin Nilsson | | *! Unlike in some languages, the function f(x) = x/n (x and n integers)
*! behaves in a well-defined way and is always rounded down. When you
*! increase x, f(x) will increase with one for each n:th increment. For
*! all x, (x + n) / n = x/n + 1; crossing
|
b8d9a0 | 2003-01-15 | Johan Sundström | | *! zero is not special. This also means that / and % are compatible, so
*! that a = b*(a/b) + a%b for all a and b.
*! @seealso
*! @[`%]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_divide(INT32 args)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | switch(args)
{
|
13670c | 2015-05-25 | Martin Nilsson | | case 0:
|
06bd61 | 2016-01-26 | Martin Nilsson | | case 1: SIMPLE_WRONG_NUM_ARGS_ERROR("`/", 2);
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | case 2: o_divide(); break;
default:
{
INT32 e;
|
19961b | 2017-04-08 | Martin Nilsson | | struct svalue *s=Pike_sp-args;
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | push_svalue(s);
for(e=1;e<args;e++)
{
push_svalue(s+e);
o_divide();
}
|
19961b | 2017-04-08 | Martin Nilsson | | assign_svalue(s,Pike_sp-1);
pop_n_elems(Pike_sp-s-1);
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
static int generate_divide(node *n)
{
if(count_args(CDR(n))==2)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
5e4442 | 2001-02-25 | Fredrik Hübinette (Hubbe) | | do_docode(CDR(n),DO_NOT_COPY_TOPLEVEL);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_DIVIDE);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_mod(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | if(TYPEOF(Pike_sp[-2]) != TYPEOF(Pike_sp[-1]) && !float_promote())
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
|
34e278 | 2013-01-11 | Arne Goedeke | | do_lfun_modulo:
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(call_lfun(LFUN_MOD, LFUN_RMOD))
return;
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TWO_TYPES(TYPEOF(Pike_sp[-2]), TYPEOF(Pike_sp[-1])))
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | {
case TWO_TYPES(T_STRING,T_INT):
{
|
19961b | 2017-04-08 | Martin Nilsson | | struct pike_string *s=Pike_sp[-2].u.string;
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | ptrdiff_t tmp,base;
|
19961b | 2017-04-08 | Martin Nilsson | | if(!Pike_sp[-1].u.integer)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_MODULO_BY_ZERO_ERROR("`%");
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.integer<0)
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | tmp=s->len % -Pike_sp[-1].u.integer;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | base=0;
}else{
|
19961b | 2017-04-08 | Martin Nilsson | | tmp=s->len % Pike_sp[-1].u.integer;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | base=s->len - tmp;
}
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | s=string_slice(s, base, tmp);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
push_string(s);
return;
}
case TWO_TYPES(T_ARRAY,T_INT):
{
|
19961b | 2017-04-08 | Martin Nilsson | | struct array *a=Pike_sp[-2].u.array;
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | ptrdiff_t tmp,base;
|
19961b | 2017-04-08 | Martin Nilsson | | if(!Pike_sp[-1].u.integer)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_MODULO_BY_ZERO_ERROR("`%");
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.integer<0)
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | tmp=a->size % -Pike_sp[-1].u.integer;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | base=0;
}else{
|
19961b | 2017-04-08 | Martin Nilsson | | tmp=a->size % Pike_sp[-1].u.integer;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | base=a->size - tmp;
}
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=slice_array(a,base,base+tmp);
pop_n_elems(2);
push_array(a);
return;
}
}
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`%", "Modulo on different types.\n", Pike_sp, 2);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-2]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
2a8925 | 2016-12-30 | Martin Nilsson | | if(!call_lfun(LFUN_MOD,LFUN_RMOD))
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`%", "Modulo on objects without `% operator.\n", Pike_sp, 2);
|
2a8925 | 2016-12-30 | Martin Nilsson | | return;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_FLOAT:
{
FLOAT_TYPE foo;
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.float_number == 0.0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_MODULO_BY_ZERO_ERROR("`%");
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
foo = (FLOAT_TYPE)(Pike_sp[-1].u.float_number / Pike_sp[0].u.float_number);
foo = (FLOAT_TYPE)(Pike_sp[-1].u.float_number -
Pike_sp[0].u.float_number * floor(foo));
Pike_sp[-1].u.float_number=foo;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
case T_INT:
|
34e278 | 2013-01-11 | Arne Goedeke | | {
int of = 0;
|
19961b | 2017-04-08 | Martin Nilsson | | INT_TYPE a = Pike_sp[-2].u.integer,
b = Pike_sp[-1].u.integer;
|
34e278 | 2013-01-11 | Arne Goedeke | | INT_TYPE res;
if (b == 0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_MODULO_BY_ZERO_ERROR("`%");
|
34e278 | 2013-01-11 | Arne Goedeke | | if(a>=0)
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | {
|
34e278 | 2013-01-11 | Arne Goedeke | | if(b>=0)
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | {
|
34e278 | 2013-01-11 | Arne Goedeke | | res = a % b;
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | }else{
|
34e278 | 2013-01-11 | Arne Goedeke | |
|
fe6269 | 2014-01-11 | Arne Goedeke | | of = DO_INT_TYPE_ADD_OVERFLOW(a, ~b, &res)
|| DO_INT_TYPE_MOD_OVERFLOW(res, b, &res)
|| DO_INT_TYPE_SUB_OVERFLOW(res, ~b, &res);
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | }
}else{
|
34e278 | 2013-01-11 | Arne Goedeke | | if(b>=0)
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | {
|
34e278 | 2013-01-11 | Arne Goedeke | |
|
fe6269 | 2014-01-11 | Arne Goedeke | | of = DO_INT_TYPE_MOD_OVERFLOW(~a, b, &res)
|| DO_INT_TYPE_ADD_OVERFLOW(b, ~res, &res);
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | }else{
|
34e278 | 2013-01-11 | Arne Goedeke | |
|
fe6269 | 2014-01-11 | Arne Goedeke | | of = DO_INT_TYPE_MOD_OVERFLOW(a, b, &res);
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | }
}
|
34e278 | 2013-01-11 | Arne Goedeke | | if (of) {
stack_swap();
convert_stack_top_to_bignum();
stack_swap();
goto do_lfun_modulo;
}
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp--;
SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, res);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
|
34e278 | 2013-01-11 | Arne Goedeke | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`%", "Bad argument 1.\n", Pike_sp, 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Modulo.
*!
*! 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)@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! If @[arg1] is an object that implements @[lfun::`%()] then
*! that function will be called with @[arg2] as the single argument.
*!
*! If @[arg2] is an object that implements @[lfun::``%()] then
*! that function will be called with @[arg2] as the single argument.
*!
*! Otherwise the result will be as follows:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg1
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type string|array
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! If @[arg2] is positive, the result will be the last
|
9fcd24 | 2002-05-31 | Martin Nilsson | | *! @expr{`%(@[sizeof](@[arg1]), @[arg2])@} elements of @[arg1].
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! If @[arg2] is negative, the result will be the first
|
9fcd24 | 2002-05-31 | Martin Nilsson | | *! @expr{`%(@[sizeof](@[arg1]), -@[arg2])@} elements of @[arg1].
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type int|float
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! The result will be
|
9fcd24 | 2002-05-31 | Martin Nilsson | | *! @expr{@[arg1] - @[arg2]*@[floor](@[arg1]/@[arg2])@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! The result will be a float if either @[arg1] or @[arg2] is
*! a float, and an int otherwise.
*! @endmixed
|
b8d9a0 | 2003-01-15 | Johan Sundström | | *!
*! For numbers, this means that
*! @ol
*! @item
|
cf559f | 2015-10-08 | Henrik Grubbström (Grubba) | | *! @expr{a % b@} always has the same sign as @expr{b@}
*! (typically @expr{b@} is positive;
*! array size, rsa modulo, etc, and @expr{a@} varies a
*! lot more than @expr{b@}).
|
b8d9a0 | 2003-01-15 | Johan Sundström | | *! @item
|
cf559f | 2015-10-08 | Henrik Grubbström (Grubba) | | *! The function @expr{f(x) = x % n@} behaves in a sane way;
*! as @expr{x@} increases, @expr{f(x)@} cycles through the
*! values @expr{0,1, ..., n-1, 0, ...@}. Nothing
|
b8d9a0 | 2003-01-15 | Johan Sundström | | *! strange happens when you cross zero.
*! @item
|
cf559f | 2015-10-08 | Henrik Grubbström (Grubba) | | *! The @expr{%@} operator implements the binary "mod" operation,
*! as defined by Donald Knuth (see the Art of Computer Programming,
*! 1.2.4). It should be noted that Pike treats %-by-0 as an error
*! rather than returning 0, though.
|
b8d9a0 | 2003-01-15 | Johan Sundström | | *! @item
|
cf559f | 2015-10-08 | Henrik Grubbström (Grubba) | | *! @expr{/@} and @expr{%@} are compatible, so that
*! @expr{a == b*@[floor](a/b) + a%b@} for all @expr{a@} and @expr{b@}.
|
b8d9a0 | 2003-01-15 | Johan Sundström | | *! @endol
*! @seealso
|
cf559f | 2015-10-08 | Henrik Grubbström (Grubba) | | *! @[`/], @[floor()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_mod(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 2)
SIMPLE_WRONG_NUM_ARGS_ERROR("`%", 2);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | o_mod();
}
static int generate_mod(node *n)
{
if(count_args(CDR(n))==2)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
5e4442 | 2001-02-25 | Fredrik Hübinette (Hubbe) | | do_docode(CDR(n),DO_NOT_COPY_TOPLEVEL);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_MOD);
|
384f22 | 2008-08-28 | Henrik Grubbström (Grubba) | | modify_stack_depth(-1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_not(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, !Pike_sp[-1].u.integer);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | break;
case T_FUNCTION:
case T_OBJECT:
|
19961b | 2017-04-08 | Martin Nilsson | | if(UNSAFE_IS_ZERO(Pike_sp-1))
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | {
pop_stack();
push_int(1);
}else{
pop_stack();
push_int(0);
}
break;
default:
|
19961b | 2017-04-08 | Martin Nilsson | | free_svalue(Pike_sp-1);
SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, 0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Logical not.
*!
*! Every expression with the @expr{!@} operator becomes a call to
*! this function, i.e. @expr{!a@} is the same as
*! @expr{predef::`!(a)@}.
*!
*! It's also used when necessary to test truth on objects, i.e. in
*! a statement @expr{if (o) ...@} where @expr{o@} is an object, the
*! test becomes the equivalent of @expr{!!o@} so that any
*! @[lfun::`!()] the object might have gets called.
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @returns
*! If @[arg] is an object that implements @[lfun::`!()], that function
*! will be called.
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! If @[arg] is @expr{0@} (zero), a destructed object, or a function in a
*! destructed object, @expr{1@} will be returned.
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Otherwise @expr{0@} (zero) will be returned.
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @note
*! No float is considered false, not even @expr{0.0@}.
*!
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @seealso
*! @[`==()], @[`!=()], @[lfun::`!()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_not(INT32 args)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 1)
SIMPLE_WRONG_NUM_ARGS_ERROR("`!", 1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | o_not();
}
static int generate_not(node *n)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | if(count_args(CDR(n))==1)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | do_docode(CDR(n),DO_NOT_COPY);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_NOT);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_compl(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
16c23f | 2016-12-31 | Martin Nilsson | | if(!call_lhs_lfun(LFUN_COMPL,1))
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`~", "Complement on object without `~ operator.\n", Pike_sp, 1);
|
16c23f | 2016-12-31 | Martin Nilsson | | stack_pop_keep_top();
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | break;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, ~Pike_sp[-1].u.integer);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | break;
case T_FLOAT:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp[-1].u.float_number = (FLOAT_TYPE) -1.0 - Pike_sp[-1].u.float_number;
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | break;
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | case T_TYPE:
type_stack_mark();
|
19961b | 2017-04-08 | Martin Nilsson | | if (Pike_sp[-1].u.type->type == T_NOT) {
push_finished_type(Pike_sp[-1].u.type->car);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | } else {
|
19961b | 2017-04-08 | Martin Nilsson | | push_finished_type(Pike_sp[-1].u.type);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | push_type(T_NOT);
}
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | pop_stack();
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(pop_unfinished_type());
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | break;
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | case T_FUNCTION:
case T_PROGRAM:
{
|
19961b | 2017-04-08 | Martin Nilsson | | struct program *p = program_from_svalue(Pike_sp - 1);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if (!p) {
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`~", "Bad argument.\n", Pike_sp, 1);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | push_type(T_NOT);
pop_stack();
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | push_type_value(pop_unfinished_type());
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
break;
|
fc0bb5 | 1997-02-13 | Niels Möller | | case T_STRING:
{
struct pike_string *s;
|
080b1a | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t len, i;
|
fc0bb5 | 1997-02-13 | Niels Möller | |
|
19961b | 2017-04-08 | Martin Nilsson | | if(Pike_sp[-1].u.string->size_shift) {
|
212c39 | 2018-02-25 | Martin Nilsson | | bad_arg_error("`~", 1, 1, "string(0)", Pike_sp-1,
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | "Expected 8-bit string.\n");
}
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | |
|
19961b | 2017-04-08 | Martin Nilsson | | len = Pike_sp[-1].u.string->len;
|
fc0bb5 | 1997-02-13 | Niels Möller | | s = begin_shared_string(len);
for (i=0; i<len; i++)
|
19961b | 2017-04-08 | Martin Nilsson | | s->str[i] = ~ Pike_sp[-1].u.string->str[i];
|
fc0bb5 | 1997-02-13 | Niels Möller | | pop_n_elems(1);
push_string(end_shared_string(s));
break;
}
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | default:
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`~", "Bad argument.\n", Pike_sp, 1);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Complement/inversion.
*!
*! Every expression with the @expr{~@} operator becomes a call to
*! this function, i.e. @expr{~a@} is the same as
*! @expr{predef::`~(a)@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! The result will be as follows:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type object
*! If @[arg] implements @[lfun::`~()], that function will be called.
*! @type int
*! The bitwise inverse of @[arg] will be returned.
*! @type float
|
9fcd24 | 2002-05-31 | Martin Nilsson | | *! The result will be @expr{-1.0 - @[arg]@}.
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type type|program
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! The type inverse of @[arg] will be returned.
*! @type string
|
c7b7dd | 2001-10-28 | Martin Nilsson | | *! If @[arg] only contains characters in the range 0 - 255 (8-bit),
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! a string containing the corresponding 8-bit inverses will be
*! returned.
*! @endmixed
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`!()], @[lfun::`~()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_compl(INT32 args)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
|
06bd61 | 2016-01-26 | Martin Nilsson | | if(args != 1)
SIMPLE_WRONG_NUM_ARGS_ERROR("`~", 1);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | o_compl();
}
static int generate_compl(node *n)
{
if(count_args(CDR(n))==1)
{
|
e021fe | 2008-04-14 | Henrik Grubbström (Grubba) | | struct compilation *c = THIS_COMPILATION;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | do_docode(CDR(n),DO_NOT_COPY);
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_COMPL);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_negate(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
19961b | 2017-04-08 | Martin Nilsson | | switch(TYPEOF(Pike_sp[-1]))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
ff0d46 | 1999-10-15 | Fredrik Noring | | do_lfun_negate:
|
16c23f | 2016-12-31 | Martin Nilsson | | if(!call_lhs_lfun(LFUN_SUBTRACT,1))
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`-", "Negate on object without `- operator.\n", Pike_sp, 1);
|
16c23f | 2016-12-31 | Martin Nilsson | | stack_pop_keep_top();
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_FLOAT:
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp[-1].u.float_number=-Pike_sp[-1].u.float_number;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_INT:
|
19961b | 2017-04-08 | Martin Nilsson | | if(INT_TYPE_NEG_OVERFLOW(Pike_sp[-1].u.integer))
|
ff0d46 | 1999-10-15 | Fredrik Noring | | {
convert_stack_top_to_bignum();
goto do_lfun_negate;
}
|
19961b | 2017-04-08 | Martin Nilsson | | SET_SVAL(Pike_sp[-1], T_INT, NUMBER_NUMBER, integer, -Pike_sp[-1].u.integer);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
|
13670c | 2015-05-25 | Martin Nilsson | | default:
|
19961b | 2017-04-08 | Martin Nilsson | | PIKE_ERROR("`-", "Bad argument to unary minus.\n", Pike_sp, 1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
408a1e | 2004-10-30 | Martin Stjernholm | | static void string_or_array_range (int bound_types,
struct svalue *ind,
INT_TYPE low,
INT_TYPE high)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
408a1e | 2004-10-30 | Martin Stjernholm | | INT32 from, to, len;
|
8a586b | 1997-01-27 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(*ind) == T_STRING)
|
408a1e | 2004-10-30 | Martin Stjernholm | | len = ind->u.string->len;
else {
#ifdef PIKE_DEBUG
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (!ind || TYPEOF(*ind) != T_ARRAY) Pike_fatal ("Invalid ind svalue.\n");
|
408a1e | 2004-10-30 | Martin Stjernholm | | #endif
len = ind->u.array->size;
|
8a586b | 1997-01-27 | Fredrik Hübinette (Hubbe) | | }
|
408a1e | 2004-10-30 | Martin Stjernholm | | if (bound_types & RANGE_LOW_OPEN)
from = 0;
else {
|
07cc18 | 2008-09-04 | Marcus Comstedt | | if (bound_types & RANGE_LOW_FROM_END) {
if (low >= len) from = 0;
else if (low < 0) from = len;
else from = len - 1 - low;
} else {
if (low < 0) from = 0;
else if (low > len) from = len;
else from = low;
}
|
408a1e | 2004-10-30 | Martin Stjernholm | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
408a1e | 2004-10-30 | Martin Stjernholm | | if (bound_types & RANGE_HIGH_OPEN)
to = len;
else {
|
07cc18 | 2008-09-04 | Marcus Comstedt | | if (bound_types & RANGE_HIGH_FROM_END) {
if (high > len - from) to = from;
else if (high <= 0) to = len;
else to = len - high;
} else {
if (high < from) to = from;
else if (high >= len) to = len;
else to = high + 1;
}
|
408a1e | 2004-10-30 | Martin Stjernholm | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(*ind) == T_STRING) {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s;
|
408a1e | 2004-10-30 | Martin Stjernholm | | if (from == 0 && to == len) return;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
408a1e | 2004-10-30 | Martin Stjernholm | | s=string_slice(ind->u.string, from, to-from);
free_string(ind->u.string);
ind->u.string=s;
}
else {
struct array *a;
a = slice_array(ind->u.array, from, to);
free_array(ind->u.array);
ind->u.array=a;
}
}
static int call_old_range_lfun (int bound_types, struct object *o,
struct svalue *low, struct svalue *high)
{
struct svalue end_pos;
ONERROR uwp;
int f;
if ((f = FIND_LFUN (o->prog, LFUN_INDEX)) == -1)
return 1;
if (bound_types & (RANGE_LOW_FROM_END|RANGE_HIGH_FROM_END)) {
int f2 = FIND_LFUN (o->prog, LFUN__SIZEOF);
if (f2 == -1)
return 2;
apply_low (o, f2, 0);
push_int (1);
o_subtract();
|
19961b | 2017-04-08 | Martin Nilsson | | move_svalue (&end_pos, --Pike_sp);
|
408a1e | 2004-10-30 | Martin Stjernholm | | SET_ONERROR (uwp, do_free_svalue, &end_pos);
}
switch (bound_types & (RANGE_LOW_FROM_BEG|RANGE_LOW_FROM_END|RANGE_LOW_OPEN)) {
case RANGE_LOW_FROM_BEG:
|
19961b | 2017-04-08 | Martin Nilsson | | move_svalue (Pike_sp++, low);
|
0c21e5 | 2008-03-29 | Martin Stjernholm | | mark_free_svalue (low);
|
408a1e | 2004-10-30 | Martin Stjernholm | | break;
case RANGE_LOW_OPEN:
push_int (0);
break;
default:
push_svalue (&end_pos);
|
19961b | 2017-04-08 | Martin Nilsson | | move_svalue (Pike_sp++, low);
|
0c21e5 | 2008-03-29 | Martin Stjernholm | | mark_free_svalue (low);
|
408a1e | 2004-10-30 | Martin Stjernholm | | o_subtract();
break;
}
switch (bound_types & (RANGE_HIGH_FROM_BEG|RANGE_HIGH_FROM_END|RANGE_HIGH_OPEN)) {
case RANGE_HIGH_FROM_BEG:
|
19961b | 2017-04-08 | Martin Nilsson | | move_svalue (Pike_sp++, high);
|
0c21e5 | 2008-03-29 | Martin Stjernholm | | mark_free_svalue (high);
|
408a1e | 2004-10-30 | Martin Stjernholm | | break;
case RANGE_HIGH_OPEN:
push_int (MAX_INT_TYPE);
break;
default:
push_svalue (&end_pos);
|
19961b | 2017-04-08 | Martin Nilsson | | move_svalue (Pike_sp++, high);
|
0c21e5 | 2008-03-29 | Martin Stjernholm | | mark_free_svalue (high);
|
408a1e | 2004-10-30 | Martin Stjernholm | | o_subtract();
break;
}
if (bound_types & (RANGE_LOW_FROM_END|RANGE_HIGH_FROM_END)) {
UNSET_ONERROR (uwp);
free_svalue (&end_pos);
if (!o->prog)
return 3;
}
apply_low (o, f, 2);
return 0;
}
static const char *range_func_name (int bound_types)
{
switch (bound_types) {
case RANGE_LOW_FROM_BEG|RANGE_HIGH_FROM_BEG: return "arg1[arg2..arg3]";
case RANGE_LOW_FROM_BEG|RANGE_HIGH_FROM_END: return "arg1[arg2..<arg3]";
case RANGE_LOW_FROM_BEG|RANGE_HIGH_OPEN: return "arg1[arg2..]";
case RANGE_LOW_FROM_END|RANGE_HIGH_FROM_BEG: return "arg1[<arg2..arg3]";
case RANGE_LOW_FROM_END|RANGE_HIGH_FROM_END: return "arg1[<arg2..<arg3]";
case RANGE_LOW_FROM_END|RANGE_HIGH_OPEN: return "arg1[<arg2..]";
case RANGE_LOW_OPEN|RANGE_HIGH_FROM_BEG: return "arg1[..arg2]";
case RANGE_LOW_OPEN|RANGE_HIGH_FROM_END: return "arg1[..<arg2]";
case RANGE_LOW_OPEN|RANGE_HIGH_OPEN: return "arg1[..]";
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
408a1e | 2004-10-30 | Martin Stjernholm | | default:
Pike_fatal ("Unexpected bound_types.\n");
|
62260a | 1996-11-26 | Fredrik Hübinette (Hubbe) | | #endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
f402aa | 2016-12-08 | Martin Nilsson | | UNREACHABLE(return "Unexpected bound_types");
|
408a1e | 2004-10-30 | Martin Stjernholm | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
408a1e | 2004-10-30 | Martin Stjernholm | | PMOD_EXPORT void o_range2 (int bound_types)
{
struct svalue *ind, *low, *high;
|
19961b | 2017-04-08 | Martin Nilsson | | high = bound_types & RANGE_HIGH_OPEN ? Pike_sp : Pike_sp - 1;
|
408a1e | 2004-10-30 | Martin Stjernholm | | low = bound_types & RANGE_LOW_OPEN ? high : high - 1;
ind = low - 1;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch (TYPEOF(*ind)) {
|
408a1e | 2004-10-30 | Martin Stjernholm | | case T_OBJECT: {
struct object *o = ind->u.object;
int f;
if (!o->prog)
bad_arg_error (range_func_name (bound_types),
|
212c39 | 2018-02-25 | Martin Nilsson | | Pike_sp - ind, 1, "object", ind,
|
408a1e | 2004-10-30 | Martin Stjernholm | | "Cannot call `[..] in destructed object.\n");
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((f = FIND_LFUN(o->prog->inherits[SUBTYPEOF(*ind)].prog,
|
9793b7 | 2004-12-18 | Henrik Grubbström (Grubba) | | LFUN_RANGE)) != -1) {
|
408a1e | 2004-10-30 | Martin Stjernholm | | struct svalue h;
if (!(bound_types & RANGE_HIGH_OPEN)) {
move_svalue (&h, high);
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp = high;
|
408a1e | 2004-10-30 | Martin Stjernholm | | }
if (bound_types & RANGE_LOW_FROM_BEG)
push_int (INDEX_FROM_BEG);
else if (bound_types & RANGE_LOW_OPEN) {
push_int (0);
push_int (OPEN_BOUND);
}
else
push_int (INDEX_FROM_END);
if (bound_types & RANGE_HIGH_FROM_BEG) {
|
19961b | 2017-04-08 | Martin Nilsson | | move_svalue (Pike_sp++, &h);
|
408a1e | 2004-10-30 | Martin Stjernholm | | push_int (INDEX_FROM_BEG);
}
else if (bound_types & RANGE_HIGH_OPEN) {
push_int (0);
push_int (OPEN_BOUND);
}
else {
|
19961b | 2017-04-08 | Martin Nilsson | | move_svalue (Pike_sp++, &h);
|
408a1e | 2004-10-30 | Martin Stjernholm | | push_int (INDEX_FROM_END);
}
apply_low (o, f, 4);
stack_pop_keep_top();
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
408a1e | 2004-10-30 | Martin Stjernholm | | else
switch (call_old_range_lfun (bound_types, o, low, high)) {
case 1:
bad_arg_error (range_func_name (bound_types),
|
212c39 | 2018-02-25 | Martin Nilsson | | Pike_sp - ind, 1, "object", ind,
|
408a1e | 2004-10-30 | Martin Stjernholm | | "Object got neither `[..] nor `[].\n");
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
408a1e | 2004-10-30 | Martin Stjernholm | | case 2:
bad_arg_error (range_func_name (bound_types),
|
212c39 | 2018-02-25 | Martin Nilsson | | Pike_sp - ind, 1, "object", ind,
|
408a1e | 2004-10-30 | Martin Stjernholm | | "Object got no `[..] and there is no _sizeof to "
"translate the from-the-end index to use `[].\n");
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
408a1e | 2004-10-30 | Martin Stjernholm | | case 3:
bad_arg_error (range_func_name (bound_types),
|
212c39 | 2018-02-25 | Martin Nilsson | | 3, 1, "object", ind,
|
408a1e | 2004-10-30 | Martin Stjernholm | | "Cannot call `[..] in destructed object.\n");
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
408a1e | 2004-10-30 | Martin Stjernholm | | default:
free_svalue (ind);
|
19961b | 2017-04-08 | Martin Nilsson | | move_svalue (ind, Pike_sp - 1);
|
408a1e | 2004-10-30 | Martin Stjernholm | |
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp = ind + 1;
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
408a1e | 2004-10-30 | Martin Stjernholm | | }
break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
408a1e | 2004-10-30 | Martin Stjernholm | | case T_STRING:
case T_ARRAY: {
|
ec51ce | 2006-04-25 | David Hedbor | | INT_TYPE l=0, h=0;
|
408a1e | 2004-10-30 | Martin Stjernholm | | if (!(bound_types & RANGE_LOW_OPEN)) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(*low) != T_INT)
|
408a1e | 2004-10-30 | Martin Stjernholm | | bad_arg_error (range_func_name (bound_types),
|
212c39 | 2018-02-25 | Martin Nilsson | | Pike_sp - ind, 2, "int", low,
|
408a1e | 2004-10-30 | Martin Stjernholm | | "Bad lower bound. Expected int, got %s.\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | get_name_of_type (TYPEOF(*low)));
|
408a1e | 2004-10-30 | Martin Stjernholm | | l = low->u.integer;
}
if (!(bound_types & RANGE_HIGH_OPEN)) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(*high) != T_INT)
|
408a1e | 2004-10-30 | Martin Stjernholm | | bad_arg_error (range_func_name (bound_types),
|
212c39 | 2018-02-25 | Martin Nilsson | | Pike_sp - ind, high - ind + 1, "int", high,
|
408a1e | 2004-10-30 | Martin Stjernholm | | "Bad upper bound. Expected int, got %s.\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | get_name_of_type (TYPEOF(*high)));
|
408a1e | 2004-10-30 | Martin Stjernholm | | h = high->u.integer;
}
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp = ind + 1;
|
408a1e | 2004-10-30 | Martin Stjernholm | |
string_or_array_range (bound_types, ind, l, h);
break;
}
default:
bad_arg_error (range_func_name (bound_types),
|
212c39 | 2018-02-25 | Martin Nilsson | | Pike_sp - ind, 1, "string|array|object", ind,
|
408a1e | 2004-10-30 | Martin Stjernholm | | "Cannot use [..] on a %s. Expected string, array or object.\n",
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | get_name_of_type (TYPEOF(*ind)));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
408a1e | 2004-10-30 | Martin Stjernholm | | }
|
dfbf4c | 2011-12-05 | Arne Goedeke | | *! @item @expr{`[..] (a, i, Pike.INDEX_FROM_BEG, j, Pike.INDEX_FROM_BEG)@}
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Calls @expr{a->`[] (i, j)@}
|
dfbf4c | 2011-12-05 | Arne Goedeke | | *! @item @expr{`[..] (a, i, Pike.INDEX_FROM_BEG, j, Pike.INDEX_FROM_END)@}
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Calls @expr{a->`[] (i, a->_sizeof()-1-j)@}
|
dfbf4c | 2011-12-05 | Arne Goedeke | | *! @item @expr{`[..] (a, i, Pike.INDEX_FROM_BEG, 0, Pike.OPEN_BOUND)@}
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Calls @expr{a->`[] (i, @[Int.NATIVE_MAX])@}
|
dfbf4c | 2011-12-05 | Arne Goedeke | | *! @item @expr{`[..] (a, i, Pike.INDEX_FROM_END, j, Pike.INDEX_FROM_BEG)@}
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Calls @expr{a->`[] (a->_sizeof()-1-i, j)@}
|
dfbf4c | 2011-12-05 | Arne Goedeke | | *! @item @expr{`[..] (a, i, Pike.INDEX_FROM_END, j, Pike.INDEX_FROM_END)@}
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Calls @expr{a->`[] (a->_sizeof()-1-i, a->_sizeof()-1-j)@},
*! except that @expr{a->_sizeof()@} is called only once.
|
dfbf4c | 2011-12-05 | Arne Goedeke | | *! @item @expr{`[..] (a, i, Pike.INDEX_FROM_END, 0, Pike.OPEN_BOUND)@}
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Calls @expr{a->`[] (a->_sizeof()-1-i, @[Int.NATIVE_MAX])@}
|
dfbf4c | 2011-12-05 | Arne Goedeke | | *! @item @expr{`[..] (a, 0, Pike.OPEN_BOUND, j, Pike.INDEX_FROM_BEG)@}
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Calls @expr{a->`[] (0, j)@}
|
dfbf4c | 2011-12-05 | Arne Goedeke | | *! @item @expr{`[..] (a, 0, Pike.OPEN_BOUND, j, Pike.INDEX_FROM_END)@}
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Calls @expr{a->`[] (0, a->_sizeof()-1-j)@}
|
dfbf4c | 2011-12-05 | Arne Goedeke | | *! @item @expr{`[..] (a, 0, Pike.OPEN_BOUND, 0, Pike.OPEN_BOUND)@}
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Calls @expr{a->`[] (0, @[Int.NATIVE_MAX])@}
*! @enddl
*!
*! Note that @[Int.NATIVE_MAX] might be replaced with an even
*! larger integer in the future.
*! @endmixed
*!
*! @seealso
*! @[lfun::`[..]], @[`[]]
*/
PMOD_EXPORT void f_range(INT32 args)
{
struct svalue *ind;
if (args != 5)
SIMPLE_WRONG_NUM_ARGS_ERROR ("predef::`[..]", 5);
|
19961b | 2017-04-08 | Martin Nilsson | | ind = Pike_sp - 5;
|
408a1e | 2004-10-30 | Martin Stjernholm | |
#define CALC_BOUND_TYPES(bound_types) do { \
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(ind[2]) != T_INT) \
|
408a1e | 2004-10-30 | Martin Stjernholm | | SIMPLE_ARG_TYPE_ERROR ("predef::`[..]", 3, "int"); \
switch (ind[2].u.integer) { \
case INDEX_FROM_BEG: bound_types = RANGE_LOW_FROM_BEG; break; \
case INDEX_FROM_END: bound_types = RANGE_LOW_FROM_END; break; \
case OPEN_BOUND: bound_types = RANGE_LOW_OPEN; break; \
default: \
SIMPLE_ARG_ERROR ("predef::`[..]", 3, "Unrecognized bound type."); \
} \
\
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(ind[4]) != T_INT) \
|
408a1e | 2004-10-30 | Martin Stjernholm | | SIMPLE_ARG_TYPE_ERROR ("predef::`[..]", 5, "int"); \
switch (ind[4].u.integer) { \
case INDEX_FROM_BEG: bound_types |= RANGE_HIGH_FROM_BEG; break; \
case INDEX_FROM_END: bound_types |= RANGE_HIGH_FROM_END; break; \
case OPEN_BOUND: bound_types |= RANGE_HIGH_OPEN; break; \
default: \
SIMPLE_ARG_ERROR ("predef::`[..]", 5, "Unrecognized bound type."); \
} \
} while (0)
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | switch (TYPEOF(*ind)) {
|
408a1e | 2004-10-30 | Martin Stjernholm | | case T_OBJECT: {
struct object *o = ind->u.object;
int f;
if (!o->prog)
SIMPLE_ARG_ERROR ("predef::`[..]", 1,
"Cannot call `[..] in destructed object.\n");
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if ((f = FIND_LFUN(o->prog->inherits[SUBTYPEOF(*ind)].prog,
|
9793b7 | 2004-12-18 | Henrik Grubbström (Grubba) | | LFUN_RANGE)) != -1) {
|
408a1e | 2004-10-30 | Martin Stjernholm | | apply_low (o, f, 4);
stack_pop_keep_top();
}
else {
int bound_types;
CALC_BOUND_TYPES (bound_types);
switch (call_old_range_lfun (bound_types, o, ind + 1, ind + 3)) {
case 1:
SIMPLE_ARG_ERROR ("predef::`[..]", 1,
"Object got neither `[..] nor `[].\n");
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
408a1e | 2004-10-30 | Martin Stjernholm | | case 2:
SIMPLE_ARG_ERROR ("predef::`[..]", 1,
"Object got no `[..] and there is no _sizeof to "
"translate the from-the-end index to use `[].\n");
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
408a1e | 2004-10-30 | Martin Stjernholm | | case 3:
SIMPLE_ARG_ERROR ("predef::`[..]", 1,
"Cannot call `[..] in destructed object.\n");
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
408a1e | 2004-10-30 | Martin Stjernholm | | default:
free_svalue (ind);
|
19961b | 2017-04-08 | Martin Nilsson | | move_svalue (ind, Pike_sp - 1);
|
408a1e | 2004-10-30 | Martin Stjernholm | |
|
19961b | 2017-04-08 | Martin Nilsson | | Pike_sp = ind + 1;
|
fb8cc0 | 2015-05-01 | Henrik Grubbström (Grubba) | | break;
|
408a1e | 2004-10-30 | Martin Stjernholm | | }
}
break;
}
case T_STRING:
case T_ARRAY: {
|
ec51ce | 2006-04-25 | David Hedbor | | INT_TYPE l=0, h=0;
|
408a1e | 2004-10-30 | Martin Stjernholm | | int bound_types;
CALC_BOUND_TYPES (bound_types);
if (!(bound_types & RANGE_LOW_OPEN)) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(ind[1]) != T_INT)
|
408a1e | 2004-10-30 | Martin Stjernholm | | SIMPLE_ARG_TYPE_ERROR ("predef::`[..]", 2, "int");
l = ind[1].u.integer;
}
if (!(bound_types & RANGE_HIGH_OPEN)) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(ind[3]) != T_INT)
|
408a1e | 2004-10-30 | Martin Stjernholm | | SIMPLE_ARG_TYPE_ERROR ("predef::`[..]", 4, "int");
h = ind[3].u.integer;
}
pop_n_elems (4);
string_or_array_range (bound_types, ind, l, h);
break;
}
default:
SIMPLE_ARG_TYPE_ERROR ("predef::`[..]", 1, "string|array|object");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
408a1e | 2004-10-30 | Martin Stjernholm | | *! @decl function `[](int arg, string index)
*! @decl int `[](string arg, int index)
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @decl mixed `[](array arg, int index)
*! @decl mixed `[](array arg, mixed index)
*! @decl mixed `[](mapping arg, mixed index)
*! @decl int(0..1) `[](multiset arg, mixed index)
*! @decl mixed `[](program arg, string index)
*! @decl mixed `[](object arg, mixed start, mixed end)
*! @decl string `[](string arg, int start, int end)
*! @decl array `[](array arg, int start, int end)
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! Indexing.
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *!
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! This is the function form of expressions with the @expr{[]@}
*! operator, i.e. @expr{a[i]@} is the same as
*! @expr{predef::`[](a,i)@}.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
|
408a1e | 2004-10-30 | Martin Stjernholm | | *! If @[arg] is an object that implements @[lfun::`[]()], that
*! function is called with the @[index] argument.
*!
*! Otherwise, the action depends on the type of @[arg]:
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type object
|
30c061 | 2008-06-29 | M |