e576bb | 2002-10-11 | Martin Nilsson | | |
eb82b8 | 2004-04-06 | Martin Nilsson | | || $Id: operators.c,v 1.188 2004/04/06 15:37:55 nilsson Exp $
|
e576bb | 2002-10-11 | Martin Nilsson | | */
|
aedfb1 | 2002-10-09 | Martin Nilsson | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "global.h"
|
b788cd | 1998-07-04 | Henrik Grubbström (Grubba) | | #include <math.h>
|
eb82b8 | 2004-04-06 | Martin Nilsson | | RCSID("$Id: operators.c,v 1.188 2004/04/06 15:37:55 nilsson Exp $");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #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"
#include "opcodes.h"
#include "operators.h"
#include "language.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"
|
37775c | 2004-04-06 | Martin Nilsson | | #include "pike_security.h"
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
6ad237 | 2002-05-11 | Martin Nilsson | | #define sp Pike_sp
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | #define OP_DIVISION_BY_ZERO_ERROR(FUNC) \
math_error(FUNC, sp-2, 2, 0, "Division by zero.\n")
#define OP_MODULO_BY_ZERO_ERROR(FUNC) \
math_error(FUNC, sp-2, 2, 0, "Modulo by zero.\n")
|
6898c0 | 2003-11-14 | Martin Stjernholm | | void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
{
#ifdef PIKE_SECURITY
if(what->type <= MAX_COMPLEX)
if(!CHECK_DATA_SECURITY(what->u.array, SECURITY_BIT_INDEX))
Pike_error("Index permission denied.\n");
#endif
switch(what->type)
{
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:
object_index_no_free(to, what->u.object, ind);
break;
case T_MULTISET: {
int i=multiset_member(what->u.multiset, ind);
to->type=T_INT;
to->subtype=i ? 0 : NUMBER_UNDEFINED;
to->u.integer=i;
break;
}
case T_STRING:
if(ind->type==T_INT)
{
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);
to->type=T_INT;
to->subtype=NUMBER_NUMBER;
to->u.integer=i;
break;
}else{
if (ind->type == T_STRING && !ind->u.string->size_shift)
Pike_error ("Expected integer as string index, got \"%s\".\n",
ind->u.string->str);
else
Pike_error ("Expected integer as string index, got %s.\n",
get_name_of_type (ind->type));
}
case T_PROGRAM:
program_index_no_free(to, what->u.program, ind);
break;
case T_FUNCTION:
{
struct program *p = program_from_svalue(what);
if (p) {
program_index_no_free(to, p, ind);
break;
}
}
#ifdef AUTO_BIGNUM
case T_INT:
if (ind->type == T_STRING) {
INT_TYPE val = what->u.integer;
convert_svalue_to_bignum(what);
index_no_free(to, what, ind);
if(IS_UNDEFINED(to)) {
if (val) {
if (!ind->u.string->size_shift)
Pike_error("Indexing the integer %"PRINTPIKEINT"d "
"with unknown method \"%s\".\n",
val, ind->u.string->str);
else
Pike_error("Indexing the integer %"PRINTPIKEINT"d "
"with a wide string.\n",
val);
} else {
if(!ind->u.string->size_shift)
Pike_error("Indexing the NULL value with \"%s\".\n",
ind->u.string->str);
else
Pike_error("Indexing the NULL value with a wide string.\n");
}
}
break;
}
#endif /* AUTO_BIGNUM */
default:
if (ind->type == T_INT)
Pike_error ("Cannot index %s with %"PRINTPIKEINT"d.\n",
(what->type == T_INT && !what->u.integer)?
"the NULL value":get_name_of_type(what->type),
ind->u.integer);
else if (ind->type == T_FLOAT)
Pike_error ("Cannot index %s with %"PRINTPIKEFLOAT"g.\n",
(what->type == T_INT && !what->u.integer)?
"the NULL value":get_name_of_type(what->type),
ind->u.float_number);
else if (ind->type == T_STRING && !ind->u.string->size_shift)
Pike_error ("Cannot index %s with \"%s\".\n",
(what->type == T_INT && !what->u.integer)?
"the NULL value":get_name_of_type(what->type),
ind->u.string->str);
else
Pike_error ("Cannot index %s with %s.\n",
(what->type == T_INT && !what->u.integer)?
"the NULL value":get_name_of_type(what->type),
get_name_of_type (ind->type));
}
}
void o_index(void)
{
struct svalue s;
index_no_free(&s,sp-2,sp-1);
pop_n_elems(2);
*sp=s;
dmalloc_touch_svalue(sp);
sp++;
dmalloc_touch_svalue(Pike_sp-1);
}
void o_cast_to_int(void)
{
switch(sp[-1].type)
{
case T_OBJECT:
{
struct pike_string *s;
REF_MAKE_CONST_STRING(s, "int");
push_string(s);
if(!sp[-2].u.object->prog)
Pike_error("Cast called on destructed object.\n");
if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1)
Pike_error("No cast method in object.\n");
apply_lfun(sp[-2].u.object, LFUN_CAST, 1);
free_svalue(sp-2);
sp[-2]=sp[-1];
sp--;
dmalloc_touch_svalue(sp);
}
if(sp[-1].type != PIKE_T_INT)
{
if(sp[-1].type == T_OBJECT && sp[-1].u.object->prog)
{
int f=FIND_LFUN(sp[-1].u.object->prog, LFUN__IS_TYPE);
if( f != -1)
{
struct pike_string *s;
REF_MAKE_CONST_STRING(s, "int");
push_string(s);
apply_low(sp[-2].u.object, f, 1);
f=!UNSAFE_IS_ZERO(sp-1);
pop_stack();
if(f) return;
}
}
Pike_error("Cast failed, wanted int, got %s\n",
get_name_of_type(sp[-1].type));
}
break;
case T_FLOAT:
{
int i=DO_NOT_WARN((int)(sp[-1].u.float_number));
#ifdef AUTO_BIGNUM
if((i < 0 ? -i : i) < floor(fabs(sp[-1].u.float_number)))
{
convert_stack_top_to_bignum();
return;
}
else
#endif /* AUTO_BIGNUM */
{
sp[-1].type=T_INT;
sp[-1].u.integer=i;
}
}
break;
case T_STRING:
#ifdef AUTO_BIGNUM
if( sp[-1].u.string->len < 10 &&
!sp[-1].u.string->size_shift )
{
int i=atoi(sp[-1].u.string->str);
free_string(sp[-1].u.string);
sp[-1].type=T_INT;
sp[-1].u.integer=i;
}
else
convert_stack_top_string_to_inumber(10);
return;
#else
{
int i=STRTOL(sp[-1].u.string->str,0,10);
free_string(sp[-1].u.string);
sp[-1].type=T_INT;
sp[-1].u.integer=i;
}
#endif /* AUTO_BIGNUM */
break;
case PIKE_T_INT:
break;
default:
Pike_error("Cannot cast %s to int.\n", get_name_of_type(sp[-1].type));
}
}
void o_cast_to_string(void)
{
char buf[200];
switch(sp[-1].type)
{
case PIKE_T_STRING:
return;
case T_OBJECT:
{
struct pike_string *s;
REF_MAKE_CONST_STRING(s, "string");
push_string(s);
if(!sp[-2].u.object->prog)
Pike_error("Cast called on destructed object.\n");
if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1)
Pike_error("No cast method in object.\n");
apply_lfun(sp[-2].u.object, LFUN_CAST, 1);
free_svalue(sp-2);
sp[-2]=sp[-1];
sp--;
dmalloc_touch_svalue(sp);
}
if(sp[-1].type != PIKE_T_STRING)
{
if(sp[-1].type == T_OBJECT && sp[-1].u.object->prog)
{
int f=FIND_LFUN(sp[-1].u.object->prog, LFUN__IS_TYPE);
if( f != -1)
{
struct pike_string *s;
REF_MAKE_CONST_STRING(s, "string");
push_string(s);
apply_low(sp[-2].u.object, f, 1);
f=!UNSAFE_IS_ZERO(sp-1);
pop_stack();
if(f) return;
}
}
Pike_error("Cast failed, wanted string, got %s\n",
get_name_of_type(sp[-1].type));
}
return;
case T_ARRAY:
{
int i;
struct array *a = sp[-1].u.array;
struct pike_string *s;
int shift = 0;
for(i = a->size; i--; ) {
unsigned INT32 val;
if (a->item[i].type != T_INT) {
Pike_error("cast: Item %d is not an integer.\n", i);
}
val = (unsigned INT32)a->item[i].u.integer;
if (val > 0xff) {
shift = 1;
if (val > 0xffff) {
shift = 2;
while(i--)
if (a->item[i].type != T_INT)
Pike_error("cast: Item %d is not an integer.\n", i);
break;
}
while(i--) {
if (a->item[i].type != T_INT) {
Pike_error("cast: Item %d is not an integer.\n", i);
}
val = (unsigned INT32)a->item[i].u.integer;
if (val > 0xffff) {
shift = 2;
while(i--)
if (a->item[i].type != T_INT)
Pike_error("cast: Item %d is not an integer.\n", i);
break;
}
}
break;
}
}
s = begin_wide_shared_string(a->size, shift);
switch(shift) {
case 0:
for(i = a->size; i--; ) {
s->str[i] = a->item[i].u.integer;
}
break;
case 1:
{
p_wchar1 *str1 = STR1(s);
for(i = a->size; i--; ) {
str1[i] = a->item[i].u.integer;
}
}
break;
case 2:
{
p_wchar2 *str2 = STR2(s);
for(i = a->size; i--; ) {
str2[i] = a->item[i].u.integer;
}
}
break;
default:
free_string(end_shared_string(s));
Pike_fatal("cast: Bad shift: %d.\n", shift);
break;
}
s = end_shared_string(s);
pop_stack();
push_string(s);
}
return;
case T_INT:
sprintf(buf, "%"PRINTPIKEINT"d", sp[-1].u.integer);
break;
case T_FLOAT:
sprintf(buf, "%f", (double)sp[-1].u.float_number);
break;
default:
Pike_error("Cannot cast %s to string.\n", get_name_of_type(sp[-1].type));
}
sp[-1].type = PIKE_T_STRING;
sp[-1].u.string = make_shared_string(buf);
}
void o_cast(struct pike_type *type, INT32 run_time_type)
{
if(run_time_type != sp[-1].type)
{
if(run_time_type == T_MIXED)
return;
if(sp[-1].type == T_OBJECT)
{
struct pike_string *s;
s=describe_type(type);
push_string(s);
if(!sp[-2].u.object->prog)
Pike_error("Cast called on destructed object.\n");
if(FIND_LFUN(sp[-2].u.object->prog,LFUN_CAST) == -1)
Pike_error("No cast method in object.\n");
apply_lfun(sp[-2].u.object, LFUN_CAST, 1);
free_svalue(sp-2);
sp[-2]=sp[-1];
sp--;
dmalloc_touch_svalue(sp);
}else
switch(run_time_type)
{
default:
Pike_error("Cannot perform cast to that type.\n");
case T_MIXED:
return;
case T_MULTISET:
switch(sp[-1].type)
{
case T_ARRAY:
{
extern void f_mkmultiset(INT32);
f_mkmultiset(1);
break;
}
default:
Pike_error("Cannot cast %s to multiset.\n",get_name_of_type(sp[-1].type));
}
break;
case T_MAPPING:
switch(sp[-1].type)
{
case T_ARRAY:
{
struct array *a=sp[-1].u.array;
struct array *b;
struct mapping *m;
INT32 i;
m=allocate_mapping(a->size);
push_mapping(m);
for (i=0; i<a->size; i++)
{
if (ITEM(a)[i].type!=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;
}
default:
Pike_error("Cannot cast %s to mapping.\n",get_name_of_type(sp[-1].type));
}
break;
case T_ARRAY:
switch(sp[-1].type)
{
case T_MAPPING:
{
struct array *a=mapping_to_array(sp[-1].u.mapping);
pop_stack();
push_array(a);
break;
}
case T_STRING:
f_values(1);
break;
case T_MULTISET:
f_indices(1);
break;
default:
Pike_error("Cannot cast %s to array.\n",get_name_of_type(sp[-1].type));
}
break;
case T_INT:
o_cast_to_int();
return;
case T_STRING:
o_cast_to_string();
return;
case T_FLOAT:
{
FLOAT_TYPE f = 0.0;
switch(sp[-1].type)
{
case T_INT:
f=(FLOAT_TYPE)(sp[-1].u.integer);
break;
case T_STRING:
f =
(FLOAT_TYPE)STRTOD_PCHARP(MKPCHARP(sp[-1].u.string->str,
sp[-1].u.string->size_shift),
0);
free_string(sp[-1].u.string);
break;
default:
Pike_error("Cannot cast %s to float.\n",get_name_of_type(sp[-1].type));
}
sp[-1].type=T_FLOAT;
sp[-1].u.float_number=f;
break;
}
case T_OBJECT:
switch(sp[-1].type)
{
case T_STRING: {
struct pike_string *file;
INT32 lineno;
if(Pike_fp->pc &&
(file = low_get_line(Pike_fp->pc, Pike_fp->context.prog, &lineno))) {
push_string(file);
}else{
push_int(0);
}
APPLY_MASTER("cast_to_object",2);
return;
}
case T_FUNCTION:
if (Pike_sp[-1].subtype == 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 {
Pike_sp[-1].type = T_OBJECT;
}
break;
default:
Pike_error("Cannot cast %s to object.\n",get_name_of_type(sp[-1].type));
}
break;
case T_PROGRAM:
switch(sp[-1].type)
{
case T_STRING: {
struct pike_string *file;
INT32 lineno;
if(Pike_fp->pc &&
(file = low_get_line(Pike_fp->pc, Pike_fp->context.prog, &lineno))) {
push_string(file);
}else{
push_int(0);
}
APPLY_MASTER("cast_to_program",2);
return;
}
case T_FUNCTION:
{
struct program *p=program_from_function(sp-1);
if(p)
{
add_ref(p);
pop_stack();
push_program(p);
}else{
pop_stack();
push_int(0);
}
}
return;
default:
Pike_error("Cannot cast %s to a program.\n",get_name_of_type(sp[-1].type));
}
}
}
if(run_time_type != sp[-1].type)
{
if(sp[-1].type == T_OBJECT && sp[-1].u.object->prog)
{
int f=FIND_LFUN(sp[-1].u.object->prog, LFUN__IS_TYPE);
if( f != -1)
{
push_text(get_name_of_type(run_time_type));
apply_low(sp[-2].u.object, f, 1);
f=!UNSAFE_IS_ZERO(sp-1);
pop_stack();
if(f) goto emulated_type_ok;
}
}
Pike_error("Cast failed, wanted %s, got %s\n",
get_name_of_type(run_time_type),
get_name_of_type(sp[-1].type));
}
emulated_type_ok:
if (!type) return;
switch(run_time_type)
{
case T_ARRAY:
{
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;
struct array *tmp=sp[-2].u.array;
DECLARE_CYCLIC();
if((a=(struct array *)BEGIN_CYCLIC(tmp,0)))
{
ref_push_array(a);
}else{
INT32 e;
TYPE_FIELD types = 0;
#ifdef PIKE_DEBUG
struct svalue *save_sp=sp+1;
#endif
push_array(a=allocate_array(tmp->size));
SET_CYCLIC_RET(a);
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);
types |= 1 << ITEM(a)[e].type;
}
a->type_field = types;
#ifdef PIKE_DEBUG
if(save_sp!=sp)
Pike_fatal("o_cast left stack droppings.\n");
#endif
}
END_CYCLIC();
assign_svalue(sp-3,sp-1);
pop_stack();
}
pop_stack();
}
break;
case T_MULTISET:
{
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;
struct multiset *tmp=sp[-2].u.multiset;
DECLARE_CYCLIC();
if((m=(struct multiset *)BEGIN_CYCLIC(tmp,0)))
{
ref_push_multiset(m);
}else{
#ifdef PIKE_DEBUG
struct svalue *save_sp=sp+1;
#endif
ptrdiff_t nodepos;
if (multiset_indval (tmp))
Pike_error ("FIXME: Casting not implemented for multisets with values.\n");
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);
multiset_insert_2 (m, sp - 1, NULL, 0);
pop_stack();
} while ((nodepos = multiset_next (tmp, nodepos)) >= 0);
UNSET_ONERROR (uwp);
sub_msnode_ref (tmp);
}
#ifdef PIKE_DEBUG
if(save_sp!=sp)
Pike_fatal("o_cast left stack droppings.\n");
#endif
}
END_CYCLIC();
assign_svalue(sp-3,sp-1);
pop_stack();
}
pop_stack();
}
break;
case T_MAPPING:
{
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;
struct mapping *tmp=sp[-3].u.mapping;
DECLARE_CYCLIC();
if((m=(struct mapping *)BEGIN_CYCLIC(tmp,0)))
{
ref_push_mapping(m);
}else{
INT32 e;
struct keypair *k;
#ifdef PIKE_DEBUG
struct svalue *save_sp=sp+1;
#endif
push_mapping(m=allocate_mapping(m_sizeof(tmp)));
SET_CYCLIC_RET(m);
MAPPING_LOOP(tmp)
{
push_svalue(& k->ind);
o_cast(itype, run_time_itype);
push_svalue(& k->val);
o_cast(vtype, run_time_vtype);
mapping_insert(m,sp-2,sp-1);
pop_n_elems(2);
}
#ifdef PIKE_DEBUG
if(save_sp!=sp)
Pike_fatal("o_cast left stack droppings.\n");
#endif
}
END_CYCLIC();
assign_svalue(sp-4,sp-1);
pop_stack();
}
pop_n_elems(2);
}
}
}
PMOD_EXPORT void f_cast(void)
{
#ifdef PIKE_DEBUG
struct svalue *save_sp=sp;
if(sp[-2].type != T_TYPE)
Pike_fatal("Cast expression destroyed stack or left droppings! (Type:%d)\n",
sp[-2].type);
#endif
o_cast(sp[-2].u.type,
compile_type_to_runtime_type(sp[-2].u.type));
#ifdef PIKE_DEBUG
if(save_sp != sp)
Pike_fatal("Internal error: o_cast() left droppings on stack.\n");
#endif
free_svalue(sp-2);
sp[-2]=sp[-1];
sp--;
dmalloc_touch_svalue(sp);
}
|
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: \
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | SIMPLE_TOO_FEW_ARGS_ERROR(NAME, 2); \
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | case 2: \
i=FUN (sp-2,sp-1); \
pop_n_elems(2); \
push_int(i); \
break; \
default: \
for(i=1;i<args;i++) \
if(! ( FUN (sp-args+i-1, sp-args+i))) \
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);
o_not();
}
|
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
*! function is called with the second as argument, and the test is
*! 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
*! Successful iff the two floats are numerically equal or if
*! both are NaN.
*! @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
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if the arguments are not strictly decreasing, and
*! @expr{0@} (zero) otherwise.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! This is the inverse of @[`>()].
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`<()], @[`>()], @[`>=()]
*/
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | COMPARISON(f_le,"`<=",!is_gt)
|
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
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! Returns @expr{1@} if the arguments are not strictly increasing, and
*! @expr{0@} (zero) otherwise.
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! This is the inverse of @[`<()].
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[`<=()], @[`>()], @[`<()]
*/
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | COMPARISON(f_ge,"`>=",!is_lt)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
33c958 | 2003-11-10 | Martin Stjernholm | | #define CALL_OPERATOR(OP, args) do { \
int i; \
if(!sp[-args].u.object->prog) \
bad_arg_error(lfun_names[OP], sp-args, args, 1, "object", sp-args, \
"Called in destructed object.\n"); \
if((i = FIND_LFUN(sp[-args].u.object->prog,OP)) == -1) \
bad_arg_error(lfun_names[OP], sp-args, args, 1, "object", sp-args, \
"Operator not in object.\n"); \
apply_low(sp[-args].u.object, i, args-1); \
free_svalue(sp-2); \
sp[-2]=sp[-1]; \
sp--; \
dmalloc_touch_svalue(sp); \
} while (0)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
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) | | {
|
70b431 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | INT_TYPE e,size;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | TYPE_FIELD types;
types=0;
for(e=-args;e<0;e++) types|=1<<sp[e].type;
switch(types)
{
default:
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(!args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | SIMPLE_TOO_FEW_ARGS_ERROR("`+", 1);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }else{
if(types & BIT_OBJECT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
33c958 | 2003-11-10 | Martin Stjernholm | | if (args == 1)
return;
|
ee3780 | 1999-02-09 | Fredrik Hübinette (Hubbe) | | if(sp[-args].type == T_OBJECT && sp[-args].u.object->prog)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
|
33c958 | 2003-11-10 | Martin Stjernholm | | int i;
|
ee3780 | 1999-02-09 | Fredrik Hübinette (Hubbe) | | if(sp[-args].u.object->refs==1 &&
|
33c958 | 2003-11-10 | Martin Stjernholm | | (i = FIND_LFUN(sp[-args].u.object->prog,LFUN_ADD_EQ)) != -1)
|
ee3780 | 1999-02-09 | Fredrik Hübinette (Hubbe) | | {
|
33c958 | 2003-11-10 | Martin Stjernholm | | apply_low(sp[-args].u.object, i, args-1);
|
0d0bab | 2003-04-27 | Martin Stjernholm | | stack_pop_keep_top();
|
ee3780 | 1999-02-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
33c958 | 2003-11-10 | Martin Stjernholm | | if((i = FIND_LFUN(sp[-args].u.object->prog,LFUN_ADD)) != -1)
|
ee3780 | 1999-02-09 | Fredrik Hübinette (Hubbe) | | {
|
33c958 | 2003-11-10 | Martin Stjernholm | | apply_low(sp[-args].u.object, i, args-1);
|
ee3780 | 1999-02-09 | Fredrik Hübinette (Hubbe) | | free_svalue(sp-2);
sp[-2]=sp[-1];
sp--;
|
41e2cb | 1999-10-24 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(sp);
|
ee3780 | 1999-02-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
33c958 | 2003-11-10 | Martin Stjernholm | |
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | for(e=1;e<args;e++)
{
|
33c958 | 2003-11-10 | Martin Stjernholm | | int i;
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[e-args].type == T_OBJECT &&
sp[e-args].u.object->prog &&
|
33c958 | 2003-11-10 | Martin Stjernholm | | (i = FIND_LFUN(sp[e-args].u.object->prog,LFUN_RADD)) != -1)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
struct svalue *tmp=sp+e-args;
check_stack(e);
assign_svalues_no_free(sp, sp-args, e, -1);
sp+=e;
|
33c958 | 2003-11-10 | Martin Stjernholm | | apply_low(tmp->u.object, i, e);
|
a7b26a | 2000-03-01 | Fredrik Hübinette (Hubbe) | | if(args - e > 1)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
assign_svalue(tmp, sp-1);
pop_stack();
f_add(args - e);
assign_svalue(sp-e-1,sp-1);
pop_n_elems(e);
}else{
assign_svalue(sp-args-1,sp-1);
pop_n_elems(args);
}
return;
}
}
}
}
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | switch(sp[-args].type)
{
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_PROGRAM:
case T_FUNCTION:
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("`+", 1,
"string|object|int|float|array|mapping|multiset");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | bad_arg_error("`+", sp-args, args, 1,
"string|object|int|float|array|mapping|multiset", sp-args,
"Incompatible types\n");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
case BIT_STRING:
{
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *r;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | PCHARP buf;
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | ptrdiff_t tmp;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | int max_shift=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | if(args==1) return;
size=0;
for(e=-args;e<0;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | size+=sp[e].u.string->len;
if(sp[e].u.string->size_shift > max_shift)
max_shift=sp[e].u.string->size_shift;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
66769e | 1999-11-04 | Fredrik Hübinette (Hubbe) | |
if(size == sp[-args].u.string->len)
{
pop_n_elems(args-1);
return;
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
tmp=sp[-args].u.string->len;
r=new_realloc_shared_string(sp[-args].u.string,size,max_shift);
sp[-args].type=T_INT;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | buf=MKPCHARP_STR_OFF(r,tmp);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | for(e=-args+1;e<0;e++)
{
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | pike_string_cpy(buf,sp[e].u.string);
INC_PCHARP(buf,sp[e].u.string->len);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | }
|
d029c1 | 2001-02-03 | Fredrik Hübinette (Hubbe) | | sp[-args].u.string=low_end_shared_string(r);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | sp[-args].type=T_STRING;
for(e=-args+1;e<0;e++) free_string(sp[e].u.string);
sp-=args-1;
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
}
case BIT_STRING | BIT_INT:
case BIT_STRING | BIT_FLOAT:
case BIT_STRING | BIT_FLOAT | BIT_INT:
{
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *r;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | PCHARP buf;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | char buffer[50];
int max_shift=0;
|
d67c6d | 2000-09-22 | Henrik Grubbström (Grubba) | |
if ((sp[-args].type != T_STRING) && (sp[1-args].type != T_STRING)) {
struct svalue *save_sp = sp;
for (e=-args; e < 0; e++) {
if (save_sp[e].type == T_STRING)
break;
*(sp++) = save_sp[e];
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(Pike_sp-1);
|
d67c6d | 2000-09-22 | Henrik Grubbström (Grubba) | | }
f_add(args+e);
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(Pike_sp-1);
|
d67c6d | 2000-09-22 | Henrik Grubbström (Grubba) | | save_sp[--e] = *(--sp);
#ifdef PIKE_DEBUG
if (sp != save_sp) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("f_add(): Lost track of stack %p != %p\n", sp, save_sp);
|
d67c6d | 2000-09-22 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
f_add(-e);
#ifdef PIKE_DEBUG
if (sp != save_sp + 1 + e) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("f_add(): Lost track of stack (2) %p != %p\n",
|
d67c6d | 2000-09-22 | Henrik Grubbström (Grubba) | | sp, save_sp + 1 + e);
}
#endif /* PIKE_DEBUG */
save_sp[-args] = sp[-1];
sp = save_sp + 1 - args;
return;
} else {
e = -args;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | size=0;
for(e=-args;e<0;e++)
{
switch(sp[e].type)
{
case T_STRING:
size+=sp[e].u.string->len;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | if(sp[e].u.string->size_shift > max_shift)
max_shift=sp[e].u.string->size_shift;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
case T_INT:
size+=14;
break;
case T_FLOAT:
size+=22;
break;
}
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
r=begin_wide_shared_string(size,max_shift);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | buf=MKPCHARP_STR(r);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | size=0;
for(e=-args;e<0;e++)
{
switch(sp[e].type)
{
case T_STRING:
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | pike_string_cpy(buf,sp[e].u.string);
INC_PCHARP(buf,sp[e].u.string->len);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
case T_INT:
|
01f9cc | 2003-11-13 | Martin Stjernholm | | sprintf(buffer,"%"PRINTPIKEINT"d",sp[e].u.integer);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | goto append_buffer;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
case T_FLOAT:
|
01f9cc | 2003-11-13 | Martin Stjernholm | | sprintf(buffer,"%"PRINTPIKEFLOAT"f",sp[e].u.float_number);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | append_buffer:
switch(max_shift)
{
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | case 0:
convert_0_to_0((p_wchar0 *)buf.ptr,buffer,strlen(buffer));
break;
case 1:
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | convert_0_to_1((p_wchar1 *)buf.ptr,(p_wchar0 *)buffer,
strlen(buffer));
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | break;
case 2:
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | convert_0_to_2((p_wchar2 *)buf.ptr,(p_wchar0 *)buffer,
strlen(buffer));
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | break;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | }
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | INC_PCHARP(buf,strlen(buffer));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
494968 | 2001-09-25 | Henrik Grubbström (Grubba) | | r = realloc_unlinked_string(r, SUBTRACT_PCHARP(buf, MKPCHARP_STR(r)));
r = low_end_shared_string(r);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_string(r);
break;
}
case BIT_INT:
|
fda0de | 1999-10-08 | Fredrik Noring | | #ifdef AUTO_BIGNUM
size = 0;
for(e = -args; e < 0; e++)
{
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | if(INT_TYPE_ADD_OVERFLOW(sp[e].u.integer, size))
|
fda0de | 1999-10-08 | Fredrik Noring | | {
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | convert_svalue_to_bignum(sp-args);
f_add(args);
return;
|
fda0de | 1999-10-08 | Fredrik Noring | | }
else
{
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | size += sp[e].u.integer;
|
fda0de | 1999-10-08 | Fredrik Noring | | }
}
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | sp-=args;
push_int(size);
|
fda0de | 1999-10-08 | Fredrik Noring | | #else
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | size=0;
for(e=-args; e<0; e++) size+=sp[e].u.integer;
sp-=args-1;
sp[-1].u.integer=size;
|
fda0de | 1999-10-08 | Fredrik Noring | | #endif /* AUTO_BIGNUM */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
case BIT_FLOAT:
{
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | FLOAT_ARG_TYPE sum;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sum=0.0;
for(e=-args; e<0; e++) sum+=sp[e].u.float_number;
sp-=args-1;
sp[-1].u.float_number=sum;
break;
}
|
482fb5 | 1999-03-12 | Per Hedbor | | case BIT_FLOAT|BIT_INT:
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | FLOAT_ARG_TYPE sum;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | sum=0.0;
for(e=-args; e<0; e++)
{
if(sp[e].type==T_FLOAT)
{
sum+=sp[e].u.float_number;
}else{
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | sum+=(FLOAT_ARG_TYPE)sp[e].u.integer;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | }
}
sp-=args-1;
|
a650f2 | 1996-03-22 | Fredrik Hübinette (Hubbe) | | sp[-1].type=T_FLOAT;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | sp[-1].u.float_number=sum;
break;
}
|
09cae2 | 2003-11-12 | Martin Stjernholm | | #define ADD_WITH_UNDEFINED(TYPE, T_TYPEID, ADD_FUNC, PUSH_FUNC) do { \
int e; \
if (sp[-args].type == T_INT) { \
if(IS_UNDEFINED(sp-args)) \
{ \
struct TYPE *x; \
\
for(e=1;e<args;e++) \
if(sp[e-args].type != T_TYPEID) \
SIMPLE_ARG_TYPE_ERROR("`+", e+1, #TYPE); \
\
x = ADD_FUNC(sp-args+1,args-1); \
pop_n_elems(args); \
PUSH_FUNC(x); \
return; \
} \
\
for(e=1;e<args;e++) \
if (sp[e-args].type != T_INT) \
SIMPLE_ARG_TYPE_ERROR("`+", e+1, "int"); \
} \
\
else { \
for(e=1;e<args;e++) \
if (sp[e-args].type != T_TYPEID) \
SIMPLE_ARG_TYPE_ERROR("`+", e+1, #TYPE); \
} \
\
DO_IF_DEBUG (Pike_fatal ("Shouldn't be reached.\n")); \
} while (0)
|
ee3780 | 1999-02-09 | Fredrik Hübinette (Hubbe) | |
|
09cae2 | 2003-11-12 | Martin Stjernholm | | #define ADD(TYPE, ADD_FUNC, PUSH_FUNC) do { \
struct TYPE *x = ADD_FUNC (sp - args, args); \
pop_n_elems (args); \
PUSH_FUNC (x); \
return; \
} while (0)
case BIT_ARRAY|BIT_INT:
ADD_WITH_UNDEFINED (array, T_ARRAY, add_arrays, push_array);
|
ee3780 | 1999-02-09 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case BIT_ARRAY:
|
09cae2 | 2003-11-12 | Martin Stjernholm | | ADD (array, add_arrays, push_array);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
482fb5 | 1999-03-12 | Per Hedbor | | case BIT_MAPPING|BIT_INT:
|
09cae2 | 2003-11-12 | Martin Stjernholm | | ADD_WITH_UNDEFINED (mapping, T_MAPPING, add_mappings, push_mapping);
|
482fb5 | 1999-03-12 | Per Hedbor | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case BIT_MAPPING:
|
09cae2 | 2003-11-12 | Martin Stjernholm | | ADD (mapping, add_mappings, push_mapping);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
09cae2 | 2003-11-12 | Martin Stjernholm | | case BIT_MULTISET|BIT_INT:
ADD_WITH_UNDEFINED (multiset, T_MULTISET, add_multisets, push_multiset);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | case BIT_MULTISET:
|
09cae2 | 2003-11-12 | Martin Stjernholm | | ADD (multiset, add_multisets, push_multiset);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
09cae2 | 2003-11-12 | Martin Stjernholm | | #undef ADD_WITH_UNDEFINED
#undef ADD
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | static int generate_sum(node *n)
{
|
a2b70a | 2000-04-30 | Fredrik Hübinette (Hubbe) | | node **first_arg, **second_arg;
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | switch(count_args(CDR(n)))
{
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);
|
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);
}
else if(first_arg[0]->type == int_type_string &&
second_arg[0]->type == int_type_string)
{
emit0(F_ADD_INTS);
}
else
{
emit0(F_ADD);
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
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
if(node_is_false(*first_arg) && !node_may_overload(*second_arg,LFUN_EQ))
{
ret=*second_arg;
|
01b2c2 | 1999-11-22 | Henrik Grubbström (Grubba) | | ADD_NODE_REF(*second_arg);
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | return mkopernode("`!",ret,0);
}
if(node_is_false(*second_arg) && !node_may_overload(*first_arg,LFUN_EQ))
{
ret=*first_arg;
|
01b2c2 | 1999-11-22 | Henrik Grubbström (Grubba) | | ADD_NODE_REF(*first_arg);
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | return mkopernode("`!",ret,0);
}
|
ffa452 | 2001-05-11 | Henrik Grubbström (Grubba) | |
if (((*second_arg)->token == F_CONSTANT) &&
((*second_arg)->u.sval.type == T_STRING) &&
((*first_arg)->token == F_RANGE) &&
(CADR(*first_arg)->token == F_CONSTANT) &&
(CADR(*first_arg)->u.sval.type == T_INT) &&
(!(CADR(*first_arg)->u.sval.u.integer)) &&
(CDDR(*first_arg)->token == F_CONSTANT) &&
(CDDR(*first_arg)->u.sval.type == T_INT)) {
INT_TYPE c = CDDR(*first_arg)->u.sval.u.integer;
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 if ((*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 {
ADD_NODE_REF2(CAR(*first_arg),
ret = mknode(F_COMMA_EXPR, CAR(*first_arg), mkintnode(0));
);
return ret;
}
}
|
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, "`==");
TMP_OPT(f_lt, "`>=");
TMP_OPT(f_gt, "`<=");
TMP_OPT(f_le, "`>");
TMP_OPT(f_ge, "`<");
#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) &&
(CAR(search_args)->type == string_type_string) &&
CDR(search_args) &&
(CDR(search_args)->type == string_type_string)) {
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++) {
if (match_types(object_type_string, (*arg)->type)) {
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;
if(count_args(CDR(n))==2)
{
|
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))
{
|
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;
}
if((*second_arg)->token == F_APPLY &&
CAR(*second_arg)->token == F_CONSTANT &&
is_eq(& CAR(*second_arg)->u.sval, & CAR(n)->u.sval))
{
|
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;
}
}
}
return 0;
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | static int generate_comparison(node *n)
{
if(count_args(CDR(n))==2)
{
|
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
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Couldn't generate comparison!\n");
|
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) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type==T_INT && sp[-1].type==T_FLOAT)
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
sp[-2].u.float_number=(FLOAT_TYPE)sp[-2].u.integer;
sp[-2].type=T_FLOAT;
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return 1;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | }
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | else if(sp[-1].type==T_INT && sp[-2].type==T_FLOAT)
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | {
sp[-1].u.float_number=(FLOAT_TYPE)sp[-1].u.integer;
sp[-1].type=T_FLOAT;
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return 1;
}
|
e92449 | 1999-12-14 | Fredrik Hübinette (Hubbe) | |
#ifdef AUTO_BIGNUM
if(is_bignum_object_in_svalue(sp-2) && sp[-1].type==T_FLOAT)
{
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;
}
else if(is_bignum_object_in_svalue(sp-1) && sp[-2].type==T_FLOAT)
{
|
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;
}
#endif
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return 0;
}
static int call_lfun(int left, int right)
{
|
33c958 | 2003-11-10 | Martin Stjernholm | | int i;
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type == T_OBJECT &&
sp[-2].u.object->prog &&
|
33c958 | 2003-11-10 | Martin Stjernholm | | (i = FIND_LFUN(sp[-2].u.object->prog,left)) != -1)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
|
33c958 | 2003-11-10 | Martin Stjernholm | | apply_low(sp[-2].u.object, i, 1);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | free_svalue(sp-2);
sp[-2]=sp[-1];
sp--;
|
41e2cb | 1999-10-24 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(sp);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return 1;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | }
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type == T_OBJECT &&
sp[-1].u.object->prog &&
|
33c958 | 2003-11-10 | Martin Stjernholm | | (i = FIND_LFUN(sp[-1].u.object->prog,right)) != -1)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
push_svalue(sp-2);
|
33c958 | 2003-11-10 | Martin Stjernholm | | apply_low(sp[-2].u.object, i, 1);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | free_svalue(sp-3);
sp[-3]=sp[-1];
sp--;
|
41e2cb | 1999-10-24 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(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) | |
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | struct mapping *merge_mapping_array_ordered(struct mapping *a,
struct array *b, INT32 op);
struct mapping *merge_mapping_array_unordered(struct mapping *a,
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) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if (sp[-2].type != sp[-1].type && !float_promote())
{
if(call_lfun(LFUN_SUBTRACT, LFUN_RSUBTRACT))
return;
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | |
if (sp[-2].type==T_MAPPING)
switch (sp[-1].type)
{
case T_ARRAY:
{
struct mapping *m;
m=merge_mapping_array_unordered(sp[-2].u.mapping,
sp[-1].u.array,
PIKE_ARRAY_OP_SUB);
pop_n_elems(2);
push_mapping(m);
return;
}
case T_MULTISET:
{
struct mapping *m;
|
5b15bb | 2001-12-10 | Martin Stjernholm | | int got_cmp_less = !!multiset_get_cmp_less (sp[-1].u.multiset);
struct array *ind = multiset_indices (sp[-1].u.multiset);
pop_stack();
push_array (ind);
if (got_cmp_less)
m=merge_mapping_array_unordered(sp[-2].u.mapping,
sp[-1].u.array,
PIKE_ARRAY_OP_SUB);
else
m=merge_mapping_array_ordered(sp[-2].u.mapping,
sp[-1].u.array,
PIKE_ARRAY_OP_SUB);
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | pop_n_elems(2);
push_mapping(m);
return;
}
}
|
b341a6 | 1999-11-04 | Fredrik Hübinette (Hubbe) | | bad_arg_error("`-", sp-2, 2, 2, get_name_of_type(sp[-2].type),
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | sp-1, "Subtract on different types.\n");
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | switch(sp[-2].type)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
CALL_OPERATOR(LFUN_SUBTRACT,2);
break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
{
struct array *a;
check_array_for_destruct(sp[-2].u.array);
check_array_for_destruct(sp[-1].u.array);
a = subtract_arrays(sp[-2].u.array, sp[-1].u.array);
pop_n_elems(2);
push_array(a);
return;
}
case T_MAPPING:
{
struct mapping *m;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | m=merge_mappings(sp[-2].u.mapping, 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;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, 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:
sp--;
sp[-1].u.float_number -= sp[0].u.float_number;
return;
case T_INT:
|
ff0d46 | 1999-10-15 | Fredrik Noring | | #ifdef AUTO_BIGNUM
if(INT_TYPE_SUB_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
{
convert_stack_top_to_bignum();
f_minus(2);
return;
}
#endif /* AUTO_BIGNUM */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
sp[-1].u.integer -= sp[0].u.integer;
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("");
|
fb5c4f | 1996-03-24 | Fredrik Hübinette (Hubbe) | | ret=string_replace(sp[-2].u.string,sp[-1].u.string,s);
free_string(sp[-2].u.string);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | free_string(sp[-1].u.string);
free_string(s);
|
fb5c4f | 1996-03-24 | Fredrik Hübinette (Hubbe) | | sp[-2].u.string=ret;
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;
SIMPLE_BAD_ARG_ERROR("`-", 1,
"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
*! 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.
*!
*! @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)
{
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`-", 1);
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | case 1: o_negate(); break;
case 2: o_subtract(); break;
default:
{
INT32 e;
struct svalue *s=sp-args;
push_svalue(s);
for(e=1;e<args;e++)
{
push_svalue(s+e);
o_subtract();
}
assign_svalue(s,sp-1);
pop_n_elems(sp-s-1);
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
}
static int generate_minus(node *n)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
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);
|
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) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != sp[-2].type)
{
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | if(call_lfun(LFUN_AND, LFUN_RAND))
return;
else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) ||
(sp[-1].type == T_FUNCTION)) &&
((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) ||
(sp[-2].type == T_FUNCTION)))
{
if (sp[-2].type != T_TYPE)
{
struct program *p = program_from_svalue(sp - 2);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`&", 1, "type");
}
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | free_svalue(sp - 2);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | sp[-2].u.type = pop_unfinished_type();
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | sp[-2].type = T_TYPE;
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | if (sp[-1].type != T_TYPE)
{
struct program *p = program_from_svalue(sp - 1);
if (!p)
{
int args = 2;
SIMPLE_BAD_ARG_ERROR("`&", 2, "type");
}
type_stack_mark();
|
361142 | 2001-02-20 | Henrik Grubbström (Grubba) | | push_object_type(0, p->id);
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | free_svalue(sp - 1);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | sp[-1].u.type = pop_unfinished_type();
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | sp[-1].type = T_TYPE;
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | }
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | }
else if (sp[-2].type==T_MAPPING)
switch (sp[-1].type)
{
case T_ARRAY:
{
struct mapping *m;
m=merge_mapping_array_unordered(sp[-2].u.mapping,
sp[-1].u.array,
PIKE_ARRAY_OP_AND);
pop_n_elems(2);
push_mapping(m);
return;
}
case T_MULTISET:
{
struct mapping *m;
|
5b15bb | 2001-12-10 | Martin Stjernholm | | int got_cmp_less = !!multiset_get_cmp_less (sp[-1].u.multiset);
struct array *ind = multiset_indices (sp[-1].u.multiset);
pop_stack();
push_array (ind);
if (got_cmp_less)
m=merge_mapping_array_unordered(sp[-2].u.mapping,
sp[-1].u.array,
PIKE_ARRAY_OP_AND);
else
m=merge_mapping_array_ordered(sp[-2].u.mapping,
sp[-1].u.array,
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;
SIMPLE_BAD_ARG_ERROR("`&", 2, "mapping");
}
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | }
else
{
int args = 2;
SIMPLE_BAD_ARG_ERROR("`&", 2, get_name_of_type(sp[-2].type));
}
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
switch(sp[-2].type)
{
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
CALL_OPERATOR(LFUN_AND,2);
break;
|
fc0bb5 | 1997-02-13 | Niels Möller | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_INT:
sp--;
sp[-1].u.integer &= sp[0].u.integer;
break;
case T_MAPPING:
{
struct mapping *m;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | m=merge_mappings(sp[-2].u.mapping, 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;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, 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;
}
case T_ARRAY:
{
struct array *a;
a=and_arrays(sp[-2].u.array, sp[-1].u.array);
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;
t = and_pike_types(sp[-2].u.type, 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) | |
p = program_from_svalue(sp - 2);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`&", 1, "type");
}
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();
p = program_from_svalue(sp - 1);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`&", 2, "type");
}
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: \
{ \
struct pike_string *s; \
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | ptrdiff_t len, i; \
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | \
len = sp[-2].u.string->len; \
if (len != sp[-1].u.string->len) \
PIKE_ERROR("`" #OP, "Bitwise "STROP \
" on strings of different lengths.\n", sp, 2); \
if(!sp[-2].u.string->size_shift && !sp[-1].u.string->size_shift) \
{ \
s = begin_shared_string(len); \
for (i=0; i<len; i++) \
s->str[i] = sp[-2].u.string->str[i] OP sp[-1].u.string->str[i]; \
}else{ \
s = begin_wide_shared_string(len, \
MAXIMUM(sp[-2].u.string->size_shift, \
sp[-1].u.string->size_shift)); \
for (i=0; i<len; i++) \
low_set_index(s,i,index_shared_string(sp[-2].u.string,i) OP \
index_shared_string(sp[-1].u.string,i)); \
} \
pop_n_elems(2); \
push_string(end_shared_string(s)); \
return; \
}
STRING_BITOP(&,"AND")
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
fd9501 | 2002-12-12 | Martin Nilsson | | PIKE_ERROR("`&", "Bitwise AND on illegal type.\n", 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)
{
case 3: func();
case 2: func();
case 1: return;
default:
r_speedup((args+1)>>1,func);
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(Pike_sp-1);
|
adbb78 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | tmp=*--sp;
SET_ONERROR(err,do_free_svalue,&tmp);
r_speedup(args>>1,func);
UNSET_ONERROR(err);
sp++[0]=tmp;
func();
}
}
|
3c04e8 | 1997-03-13 | Fredrik Hübinette (Hubbe) | | static void speedup(INT32 args, void (*func)(void))
{
switch(sp[-args].type)
{
|
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
*! @[`==] and, in the case of mappings, @[hash_value]).
*! @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) | | *!
*! @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)
{
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | case 0: SIMPLE_TOO_FEW_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:
if(sp[-args].type == T_OBJECT)
{
CALL_OPERATOR(LFUN_AND, args);
}else{
|
3c04e8 | 1997-03-13 | Fredrik Hübinette (Hubbe) | | speedup(args, o_and);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
}
static int generate_and(node *n)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
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);
|
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) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != sp[-2].type)
{
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if(call_lfun(LFUN_OR, LFUN_ROR)) {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return;
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | } else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) ||
(sp[-1].type == T_FUNCTION)) &&
((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) ||
(sp[-2].type == T_FUNCTION))) {
if (sp[-2].type != T_TYPE) {
struct program *p = program_from_svalue(sp - 2);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`|", 1, "type");
}
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) | | free_svalue(sp - 2);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | sp[-2].u.type = pop_unfinished_type();
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | sp[-2].type = T_TYPE;
}
if (sp[-1].type != T_TYPE) {
struct program *p = program_from_svalue(sp - 1);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`|", 2, "type");
}
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) | | free_svalue(sp - 1);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | sp[-1].u.type = pop_unfinished_type();
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | sp[-1].type = T_TYPE;
}
} else {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | int args = 2;
|
b341a6 | 1999-11-04 | Fredrik Hübinette (Hubbe) | | SIMPLE_BAD_ARG_ERROR("`|", 2, get_name_of_type(sp[-2].type));
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | }
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
switch(sp[-2].type)
{
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
CALL_OPERATOR(LFUN_OR,2);
break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_INT:
sp--;
sp[-1].u.integer |= sp[0].u.integer;
break;
case T_MAPPING:
{
struct mapping *m;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | m=merge_mappings(sp[-2].u.mapping, 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;
|
33c958 | 2003-11-10 | Martin Stjernholm | | l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, 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;
}
case T_ARRAY:
{
struct array *a;
|
33c958 | 2003-11-10 | Martin Stjernholm | | a=merge_array_with_order(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_OR_LEFT);
|
c1d3f2 | 1999-08-16 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | push_array(a);
return;
}
|
3db0d2 | 1999-12-13 | Henrik Grubbström (Grubba) | | case T_TYPE:
{
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | struct pike_type *t;
t = or_pike_types(sp[-2].u.type, 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) | |
p = program_from_svalue(sp - 2);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`|", 1, "type");
}
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();
p = program_from_svalue(sp - 1);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`|", 2, "type");
}
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:
|
fd9501 | 2002-12-12 | Martin Nilsson | | PIKE_ERROR("`|", "Bitwise OR on illegal type.\n", 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].
*! @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
*! @[arg1] (according to @[`==]). The order between the
*! elements that come from the same argument is kept.
*!
*! 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
*! @[arg2] that doesn't already occur in @[arg1] (according to
*! @[`==]). Subsequences with orderwise equal entries (i.e.
*! where @[`<] returns false) are handled just like the array
*! case above.
*! @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) | | *!
*! @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)
{
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | case 0: SIMPLE_TOO_FEW_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:
if(sp[-args].type==T_OBJECT)
{
CALL_OPERATOR(LFUN_OR, args);
} else {
|
3c04e8 | 1997-03-13 | Fredrik Hübinette (Hubbe) | | speedup(args, o_or);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
}
static int generate_or(node *n)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
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);
|
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) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != sp[-2].type)
{
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | if(call_lfun(LFUN_XOR, LFUN_RXOR)) {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | return;
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | } else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) ||
(sp[-1].type == T_FUNCTION)) &&
((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) ||
(sp[-2].type == T_FUNCTION))) {
if (sp[-2].type != T_TYPE) {
struct program *p = program_from_svalue(sp - 2);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`^", 1, "type");
}
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) | | free_svalue(sp - 2);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | sp[-2].u.type = pop_unfinished_type();
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | sp[-2].type = T_TYPE;
}
if (sp[-1].type != T_TYPE) {
struct program *p = program_from_svalue(sp - 1);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`^", 2, "type");
}
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) | | free_svalue(sp - 1);
|
07f543 | 2001-02-21 | Henrik Grubbström (Grubba) | | sp[-1].u.type = pop_unfinished_type();
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | sp[-1].type = T_TYPE;
}
} else {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | int args = 2;
|
b341a6 | 1999-11-04 | Fredrik Hübinette (Hubbe) | | SIMPLE_BAD_ARG_ERROR("`^", 2, get_name_of_type(sp[-2].type));
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | }
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
switch(sp[-2].type)
{
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
CALL_OPERATOR(LFUN_XOR,2);
break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_INT:
sp--;
sp[-1].u.integer ^= sp[0].u.integer;
break;
case T_MAPPING:
{
struct mapping *m;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | m=merge_mappings(sp[-2].u.mapping, 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;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, 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;
}
case T_ARRAY:
{
struct array *a;
|
7b1a74 | 1999-08-14 | Fredrik Hübinette (Hubbe) | | a=merge_array_with_order(sp[-2].u.array, 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;
p = program_from_svalue(sp - 1);
if (!p) {
int args = 2;
SIMPLE_BAD_ARG_ERROR("`^", 2, "type");
}
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();
p = program_from_svalue(sp - 1);
if (!p) {
int args = 2;
stack_swap();
SIMPLE_BAD_ARG_ERROR("`^", 1, "type");
}
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) | | }
|
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;
|
be6fec | 2001-04-01 | Henrik Grubbström (Grubba) | | copy_pike_type(a, sp[-2].u.type);
copy_pike_type(b, 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:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`^", "Bitwise XOR on illegal type.\n", 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]
*! that doesn't occur in @[arg1] (according to @[`==]). The
*! order between the elements that come from the same argument
*! is kept.
*!
*! 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
*! @[hash_value] and @[`==]). Subsequences with orderwise equal
*! 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) | | *!
*! @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)
{
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | case 0: SIMPLE_TOO_FEW_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:
if(sp[-args].type==T_OBJECT)
{
CALL_OPERATOR(LFUN_XOR, args);
} else {
|
3c04e8 | 1997-03-13 | Fredrik Hübinette (Hubbe) | | speedup(args, o_xor);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
}
static int generate_xor(node *n)
{
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);
|
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) | | {
|
ff0d46 | 1999-10-15 | Fredrik Noring | | #ifdef AUTO_BIGNUM
|
c214f4 | 2002-06-17 | Henrik Grubbström (Grubba) | | if ((sp[-1].type == T_INT) && (sp[-2].type == T_INT) &&
INT_TYPE_LSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
|
ff0d46 | 1999-10-15 | Fredrik Noring | | convert_stack_top_to_bignum();
#endif /* AUTO_BIGNUM */
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != T_INT || sp[-2].type != T_INT)
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | int args = 2;
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(call_lfun(LFUN_LSH, LFUN_RLSH))
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | return;
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != T_INT)
|
966231 | 2002-08-02 | Johan Sundström | | SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|object");
|
b01963 | 2002-10-15 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("`<<", 2, "int(0..)|object");
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
34d4be | 2001-03-18 | Henrik Grubbström (Grubba) | | #ifndef AUTO_BIGNUM
if (sp[-1].u.integer > 31) {
sp--;
sp[-1].u.integer = 0;
return;
}
#endif /* !AUTO_BIGNUM */
|
b01963 | 2002-10-15 | Henrik Grubbström (Grubba) | | if (sp[-1].u.integer < 0) {
|
66c939 | 2002-10-15 | Henrik Grubbström (Grubba) | | int args = 2;
|
b01963 | 2002-10-15 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("`<<", 2, "int(0..)|object");
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | sp[-1].u.integer = sp[-1].u.integer << sp->u.integer;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
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) | | *!
|
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) | | {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | if(args != 2) {
SIMPLE_TOO_FEW_ARGS_ERROR("`<<", 2);
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | o_lsh();
}
static int generate_lsh(node *n)
{
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);
|
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) | | {
|
ba1830 | 2002-04-20 | Johan Sundström | | if(sp[-2].type != T_INT || sp[-1].type != T_INT)
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | int args = 2;
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(call_lfun(LFUN_RSH, LFUN_RRSH))
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | return;
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != T_INT)
|
966231 | 2002-08-02 | Johan Sundström | | SIMPLE_BAD_ARG_ERROR("`>>", 1, "int|object");
|
b01963 | 2002-10-15 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("`>>", 2, "int(0..)|object");
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
ba1830 | 2002-04-20 | Johan Sundström | |
|
b01963 | 2002-10-15 | Henrik Grubbström (Grubba) | | if (sp[-1].u.integer < 0) {
|
66c939 | 2002-10-15 | Henrik Grubbström (Grubba) | | int args = 2;
|
b01963 | 2002-10-15 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("`>>", 2, "int(0..)|object");
|
ba1830 | 2002-04-20 | Johan Sundström | | }
|
b01963 | 2002-10-15 | Henrik Grubbström (Grubba) | |
if(
#ifdef AUTO_BIGNUM
(INT_TYPE_RSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
|
ba1830 | 2002-04-20 | Johan Sundström | | #else /* !AUTO_BIGNUM */
|
b01963 | 2002-10-15 | Henrik Grubbström (Grubba) | | (sp[-1].u.integer > 31)
#endif /* AUTO_BIGNUM */
)
{
|
ba1830 | 2002-04-20 | Johan Sundström | | sp--;
if (sp[-1].u.integer < 0) {
sp[-1].u.integer = -1;
} else {
sp[-1].u.integer = 0;
}
return;
}
sp--;
sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
b90e55 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
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) | | *!
|
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) | | {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | if(args != 2) {
SIMPLE_TOO_FEW_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) | | {
|
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);
|
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;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | switch(TWO_TYPES(sp[-2].type,sp[-1].type))
|
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;
if(sp[-1].u.integer < 0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("`*", 2, "int(0..)");
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | ret=allocate_array(sp[-2].u.array->size * sp[-1].u.integer);
pos=ret->item;
for(e=0;e<sp[-1].u.integer;e++,pos+=sp[-2].u.array->size)
assign_svalues_no_free(pos,
sp[-2].u.array->item,
sp[-2].u.array->size,
sp[-2].u.array->type_field);
ret->type_field=sp[-2].u.array->type_field;
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;
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | if(sp[-1].u.float_number < 0)
SIMPLE_BAD_ARG_ERROR("`*", 2, "float(0..)");
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | |
src = sp[-2].u.array;
delta = src->size;
asize = (ptrdiff_t)floor(delta * sp[-1].u.float_number + 0.5);
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;
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | if(sp[-1].u.float_number < 0)
SIMPLE_BAD_ARG_ERROR("`*", 2, "float(0..)");
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | src = sp[-2].u.string;
len = (ptrdiff_t)floor(src->len * sp[-1].u.float_number + 0.5);
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) {
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | MEMCPY(pos, src->str, delta);
pos += delta;
len -= delta;
|
fa95e6 | 2000-10-15 | Henrik Grubbström (Grubba) | | while (len > delta) {
|
7c46f2 | 2000-10-15 | Henrik Grubbström (Grubba) | | MEMCPY(pos, ret->str, delta);
pos += delta;
len -= delta;
delta <<= 1;
}
if (len) {
MEMCPY(pos, ret->str, len);
}
} else if (len) {
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;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(sp[-1].u.integer < 0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | SIMPLE_BAD_ARG_ERROR("`*", 2, "int(0..)");
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | ret=begin_wide_shared_string(sp[-2].u.string->len * sp[-1].u.integer,
sp[-2].u.string->size_shift);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | pos=ret->str;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | len=sp[-2].u.string->len << sp[-2].u.string->size_shift;
for(e=0;e<sp[-1].u.integer;e++,pos+=len)
MEMCPY(pos,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;
|
fb5c4f | 1996-03-24 | Fredrik Hübinette (Hubbe) | | ret=implode(sp[-2].u.array,sp[-1].u.string);
free_string(sp[-1].u.string);
free_array(sp[-2].u.array);
sp[-2].type=T_STRING;
sp[-2].u.string=ret;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
return;
}
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | case TWO_TYPES(T_ARRAY,T_ARRAY):
{
struct array *ret;
ret=implode_array(sp[-2].u.array, sp[-1].u.array);
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):
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
sp[-1].u.float_number *= sp[0].u.float_number;
return;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | case TWO_TYPES(T_FLOAT,T_INT):
sp--;
sp[-1].u.float_number *= (FLOAT_TYPE)sp[0].u.integer;
return;
case TWO_TYPES(T_INT,T_FLOAT):
sp--;
sp[-1].u.float_number=
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | (FLOAT_TYPE) sp[-1].u.integer * sp[0].u.float_number;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | sp[-1].type=T_FLOAT;
return;
case TWO_TYPES(T_INT,T_INT):
|
fda0de | 1999-10-08 | Fredrik Noring | | #ifdef AUTO_BIGNUM
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | if(INT_TYPE_MUL_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
|
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 | | }
#endif /* AUTO_BIGNUM */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
sp[-1].u.integer *= sp[0].u.integer;
return;
default:
|
e37a3e | 1999-10-09 | Fredrik Hübinette (Hubbe) | | do_lfun_multiply:
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(call_lfun(LFUN_MULTIPLY, LFUN_RMULTIPLY))
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | return;
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`*", "Bad arguments.\n", sp, 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
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)
{
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | case 0: SIMPLE_TOO_FEW_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:
if(sp[-args].type==T_OBJECT)
{
CALL_OPERATOR(LFUN_MULTIPLY, args);
} else {
|
0c6097 | 2000-09-22 | Henrik Grubbström (Grubba) | | INT32 i = -args, j = -1;
while(i < j) {
struct svalue tmp = sp[i];
sp[i++] = sp[j];
sp[j--] = tmp;
}
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)
{
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);
|
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) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type!=sp[-1].type && !float_promote())
{
if(call_lfun(LFUN_DIVIDE, LFUN_RDIVIDE))
return;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
switch(TWO_TYPES(sp[-2].type,sp[-1].type))
{
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) | |
len=sp[-1].u.integer;
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;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | size=sp[-2].u.string->len / len;
pos+=sp[-2].u.string->len % len;
}else{
size=sp[-2].u.string->len / len;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }
a=allocate_array(size);
for(e=0;e<size;e++)
{
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | a->item[e].u.string=string_slice(sp[-2].u.string, pos,len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a->item[e].type=T_STRING;
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) | |
len=sp[-1].u.float_number;
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;
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | size=(ptrdiff_t)ceil( ((double)sp[-2].u.string->len) / len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | for(last=sp[-2].u.string->len,e=0;e<size-1;e++)
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | {
|
61014a | 2000-09-26 | Henrik Wallin | | pos=sp[-2].u.string->len - (ptrdiff_t)((e+1)*len+0.5);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | a->item[size-1-e].u.string=string_slice(sp[-2].u.string,
pos,
last-pos);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[size-1-e].type=T_STRING;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | last=pos;
}
pos=0;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | a->item[0].u.string=string_slice(sp[-2].u.string,
pos,
last-pos);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[0].type=T_STRING;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }else{
|
080b1a | 2000-08-10 | Henrik Grubbström (Grubba) | | size=(ptrdiff_t)ceil( ((double)sp[-2].u.string->len) / len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
|
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 = DO_NOT_WARN((ptrdiff_t)((e+1)*len+0.5));
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | a->item[e].u.string=string_slice(sp[-2].u.string,
last,
pos-last);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[e].type=T_STRING;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | last=pos;
}
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | pos=sp[-2].u.string->len;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | a->item[e].u.string=string_slice(sp[-2].u.string,
last,
pos-last);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[e].type=T_STRING;
|
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) | | }
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) | |
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | INT_TYPE len=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("`/");
|
6e27f6 | 1998-07-31 | Fredrik Hübinette (Hubbe) | |
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(len<0)
{
|
6f4940 | 1998-07-31 | Henrik Grubbström (Grubba) | | len = -len;
pos = 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) | | }
|
6f4940 | 1998-07-31 | Henrik Grubbström (Grubba) | | size = sp[-2].u.array->size / len;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
for(e=0;e<size;e++)
{
a->item[e].u.array=friendly_slice_array(sp[-2].u.array,
pos,
pos+len);
pos+=len;
|
6e27f6 | 1998-07-31 | Fredrik Hübinette (Hubbe) | | a->item[e].type=T_ARRAY;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }
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) | |
len=sp[-1].u.float_number;
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;
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | size = (ptrdiff_t)ceil( ((double)sp[-2].u.array->size) / len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | for(last=sp[-2].u.array->size,e=0;e<size-1;e++)
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | {
|
61014a | 2000-09-26 | Henrik Wallin | | pos=sp[-2].u.array->size - (ptrdiff_t)((e+1)*len+0.5);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[size-1-e].u.array=friendly_slice_array(sp[-2].u.array,
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | pos,
last);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[size-1-e].type=T_ARRAY;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | last=pos;
}
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[0].u.array=slice_array(sp[-2].u.array,
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | 0,
last);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[0].type=T_ARRAY;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | }else{
|
080b1a | 2000-08-10 | Henrik Grubbström (Grubba) | | size = (ptrdiff_t)ceil( ((double)sp[-2].u.array->size) / len);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a=allocate_array(size);
|
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);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a->item[e].u.array=friendly_slice_array(sp[-2].u.array,
last,
pos);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[e].type=T_ARRAY;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | last=pos;
}
a->item[e].u.array=slice_array(sp[-2].u.array,
last,
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | sp[-2].u.array->size);
a->item[e].type=T_ARRAY;
|
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) | | }
}
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`/", "Division on different types.\n", sp, 2);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
switch(sp[-2].type)
{
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
08b980 | 1999-10-30 | Fredrik Noring | | do_lfun_division:
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | CALL_OPERATOR(LFUN_DIVIDE,2);
break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_STRING:
{
struct array *ret;
|
fb5c4f | 1996-03-24 | Fredrik Hübinette (Hubbe) | | ret=explode(sp[-2].u.string,sp[-1].u.string);
free_string(sp[-2].u.string);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | free_string(sp[-1].u.string);
|
fb5c4f | 1996-03-24 | Fredrik Hübinette (Hubbe) | | sp[-2].type=T_ARRAY;
sp[-2].u.array=ret;
sp--;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
}
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | case T_ARRAY:
{
struct array *ret=explode_array(sp[-2].u.array, sp[-1].u.array);
pop_n_elems(2);
push_array(ret);
return;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_FLOAT:
if(sp[-1].u.float_number == 0.0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_DIVISION_BY_ZERO_ERROR("`/");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
sp[-1].u.float_number /= sp[0].u.float_number;
return;
case T_INT:
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | {
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | INT_TYPE tmp;
|
08b980 | 1999-10-30 | Fredrik Noring | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if (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) | |
|
08b980 | 1999-10-30 | Fredrik Noring | | if(INT_TYPE_DIV_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
{
#ifdef AUTO_BIGNUM
stack_swap();
convert_stack_top_to_bignum();
stack_swap();
goto do_lfun_division;
#else
tmp = sp[-2].u.integer;
#endif /* AUTO_BIGNUM */
}
else
tmp = sp[-2].u.integer/sp[-1].u.integer;
sp--;
|
c93f0e | 1997-12-03 | Fredrik Hübinette (Hubbe) | |
|
08b980 | 1999-10-30 | Fredrik Noring | |
|
6e34c6 | 2003-11-13 | Martin Stjernholm | |
|
c93f0e | 1997-12-03 | Fredrik Hübinette (Hubbe) | | if((sp[-1].u.integer<0) != (sp[0].u.integer<0))
if(tmp*sp[0].u.integer!=sp[-1].u.integer)
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | tmp--;
sp[-1].u.integer=tmp;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
default:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`/", "Bad argument 1.\n", 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)
{
case 0:
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | case 1: SIMPLE_TOO_FEW_ARGS_ERROR("`/", 2);
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | case 2: o_divide(); break;
default:
{
INT32 e;
struct svalue *s=sp-args;
push_svalue(s);
for(e=1;e<args;e++)
{
push_svalue(s+e);
o_divide();
}
assign_svalue(s,sp-1);
pop_n_elems(sp-s-1);
}
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
static int generate_divide(node *n)
{
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_DIVIDE);
|
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) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != sp[-1].type && !float_promote())
{
if(call_lfun(LFUN_MOD, LFUN_RMOD))
return;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | switch(TWO_TYPES(sp[-2].type,sp[-1].type))
{
case TWO_TYPES(T_STRING,T_INT):
{
struct pike_string *s=sp[-2].u.string;
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | ptrdiff_t tmp,base;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(!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) | |
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | if(sp[-1].u.integer<0)
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | {
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | tmp=s->len % -sp[-1].u.integer;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | base=0;
}else{
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | tmp=s->len % 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):
{
struct array *a=sp[-2].u.array;
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | ptrdiff_t tmp,base;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | if(!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) | |
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | if(sp[-1].u.integer<0)
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | {
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | tmp=a->size % -sp[-1].u.integer;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | base=0;
}else{
|
6e34c6 | 2003-11-13 | Martin Stjernholm | | tmp=a->size % 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;
}
}
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`%", "Modulo on different types.\n", sp, 2);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | switch(sp[-2].type)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
CALL_OPERATOR(LFUN_MOD,2);
break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_FLOAT:
{
FLOAT_TYPE foo;
if(sp[-1].u.float_number == 0.0)
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | OP_MODULO_BY_ZERO_ERROR("`%");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
|
a5cd6a | 2001-09-24 | Henrik Grubbström (Grubba) | | foo = DO_NOT_WARN((FLOAT_TYPE)(sp[-1].u.float_number /
sp[0].u.float_number));
foo = DO_NOT_WARN((FLOAT_TYPE)(sp[-1].u.float_number -
sp[0].u.float_number * floor(foo)));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp[-1].u.float_number=foo;
return;
}
case T_INT:
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | if (sp[-1].u.integer == 0)
OP_MODULO_BY_ZERO_ERROR("`%");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | if(sp[-1].u.integer>=0)
{
if(sp[0].u.integer>=0)
{
sp[-1].u.integer %= sp[0].u.integer;
}else{
|
9024ae | 1997-09-11 | Fredrik Hübinette (Hubbe) | | sp[-1].u.integer=((sp[-1].u.integer+~sp[0].u.integer)%-sp[0].u.integer)-~sp[0].u.integer;
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | }
}else{
if(sp[0].u.integer>=0)
{
|
9024ae | 1997-09-11 | Fredrik Hübinette (Hubbe) | | sp[-1].u.integer=sp[0].u.integer+~((~sp[-1].u.integer) % sp[0].u.integer);
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | }else{
sp[-1].u.integer=-(-sp[-1].u.integer % -sp[0].u.integer);
}
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
default:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`%", "Bad argument 1.\n", 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
*! a % b always has the same sign as b (typically b is positive;
*! array size, rsa modulo, etc, and a varies a lot more than b).
*! @item
*! The function f(x) = x % n behaves in a sane way; as x increases,
*! f(x) cycles through the values 0,1, ..., n-1, 0, .... Nothing
*! strange happens when you cross zero.
*! @item
*! The % 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.
*! @item
*! / and % are compatible, so that a = b*(a/b) + a%b for all a and b.
*! @endol
*! @seealso
*! @[`/]
|
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) | | {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | if(args != 2) {
SIMPLE_TOO_FEW_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) | | {
|
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);
|
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) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | switch(sp[-1].type)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_INT:
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp[-1].u.integer = !sp[-1].u.integer;
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | break;
case T_FUNCTION:
case T_OBJECT:
|
9f516a | 2001-12-16 | Martin Stjernholm | | if(UNSAFE_IS_ZERO(sp-1))
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | {
pop_stack();
push_int(1);
}else{
pop_stack();
push_int(0);
}
break;
default:
free_svalue(sp-1);
sp[-1].type=T_INT;
sp[-1].u.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) | | {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | if(args != 1) {
SIMPLE_TOO_FEW_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)
{
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) | | {
switch(sp[-1].type)
{
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
CALL_OPERATOR(LFUN_COMPL,1);
break;
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | case T_INT:
sp[-1].u.integer = ~ sp[-1].u.integer;
break;
case T_FLOAT:
sp[-1].u.float_number = -1.0 - sp[-1].u.float_number;
break;
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | case T_TYPE:
type_stack_mark();
|
1a94cc | 2001-02-26 | Henrik Grubbström (Grubba) | | if (sp[-1].u.type->type == T_NOT) {
push_finished_type(sp[-1].u.type->car);
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | } else {
|
1a94cc | 2001-02-26 | Henrik Grubbström (Grubba) | | push_finished_type(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:
{
struct program *p = program_from_svalue(sp - 1);
if (!p) {
PIKE_ERROR("`~", "Bad argument.\n", sp, 1);
}
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 | |
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | if(sp[-1].u.string->size_shift) {
bad_arg_error("`~", sp-1, 1, 1, "string(0)", sp-1,
"Expected 8-bit string.\n");
}
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | |
|
fc0bb5 | 1997-02-13 | Niels Möller | | len = sp[-1].u.string->len;
s = begin_shared_string(len);
for (i=0; i<len; i++)
s->str[i] = ~ sp[-1].u.string->str[i];
pop_n_elems(1);
push_string(end_shared_string(s));
break;
}
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | default:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`~", "Bad argument.\n", 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) | | {
|
54db6c | 1999-03-27 | Henrik Grubbström (Grubba) | | if(args != 1) {
SIMPLE_TOO_FEW_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)
{
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) | | {
switch(sp[-1].type)
{
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | case T_OBJECT:
|
ff0d46 | 1999-10-15 | Fredrik Noring | | do_lfun_negate:
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | CALL_OPERATOR(LFUN_SUBTRACT,1);
break;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_FLOAT:
sp[-1].u.float_number=-sp[-1].u.float_number;
return;
case T_INT:
|
ff0d46 | 1999-10-15 | Fredrik Noring | | #ifdef AUTO_BIGNUM
if(INT_TYPE_NEG_OVERFLOW(sp[-1].u.integer))
{
convert_stack_top_to_bignum();
goto do_lfun_negate;
}
#endif /* AUTO_BIGNUM */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp[-1].u.integer = - sp[-1].u.integer;
return;
default:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`-", "Bad argument to unary minus.\n", sp, 1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void o_range(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
01f9cc | 2003-11-13 | Martin Stjernholm | | INT_TYPE from, to;
|
8a586b | 1997-01-27 | Fredrik Hübinette (Hubbe) | |
if(sp[-3].type==T_OBJECT)
{
|
885613 | 1997-10-10 | Fredrik Hübinette (Hubbe) | | CALL_OPERATOR(LFUN_INDEX, 3);
|
8a586b | 1997-01-27 | Fredrik Hübinette (Hubbe) | | return;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != T_INT)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`[]", "Bad argument 2 to [ .. ]\n", sp, 3);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
if(sp[-1].type != T_INT)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`[]", "Bad argument 3 to [ .. ]\n", sp, 3);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
146a32 | 2000-08-03 | Henrik Grubbström (Grubba) | | from = sp[-2].u.integer;
if(from<0) from = 0;
to = sp[-1].u.integer;
if(to<from-1) to = from-1;
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(Pike_sp-1);
dmalloc_touch_svalue(Pike_sp-2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp-=2;
switch(sp[-1].type)
{
case T_STRING:
{
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s;
|
22e81d | 2000-08-03 | Henrik Grubbström (Grubba) | | if(to >= sp[-1].u.string->len-1)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
if(from==0) return;
|
146a32 | 2000-08-03 | Henrik Grubbström (Grubba) | | to = sp[-1].u.string->len-1;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
if(from>to+1) from=to+1;
}
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
62260a | 1996-11-26 | Fredrik Hübinette (Hubbe) | | if(from < 0 || (to-from+1) < 0)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Error in o_range.\n");
|
62260a | 1996-11-26 | Fredrik Hübinette (Hubbe) | | #endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | s=string_slice(sp[-1].u.string, from, to-from+1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | free_string(sp[-1].u.string);
sp[-1].u.string=s;
break;
}
case T_ARRAY:
{
struct array *a;
|
22e81d | 2000-08-03 | Henrik Grubbström (Grubba) | | if(to >= sp[-1].u.array->size-1)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
146a32 | 2000-08-03 | Henrik Grubbström (Grubba) | | to = sp[-1].u.array->size-1;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
if(from>to+1) from=to+1;
}
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | a = slice_array(sp[-1].u.array, from, to+1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | free_array(sp[-1].u.array);
sp[-1].u.array=a;
break;
}
default:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`[]", "[ .. ] on non-scalar type.\n", sp, 3);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
7bd0ea | 1996-02-19 | 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 | | *! Index/subrange.
*!
*! Every non-lvalue expression with the @expr{[]@} operator becomes
*! a call to this function, i.e. @expr{a[i]@} is the same as
*! @expr{predef::`[](a,i)@} and @expr{a[i..j]@} is the same as
*! @expr{predef::`[](a,i,j)@}. If the lower limit @expr{i@} is left
*! out, @expr{0@} is passed to the function. If the upper limit
*! @expr{j@} is left out, @[Int.NATIVE_MAX] is passed to the
*! function, but that might be changed to an even larger number in
*! the future.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! If @[arg] is an object that implements @[lfun::`[]()], that function
*! will be called with the rest of the arguments.
*!
*! If there are 2 arguments the result will be as follows:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type object
*! The non-static (ie public) symbol named @[index] will be looked up
*! in @[arg].
*! @type int
*! The bignum function named @[index] will be looked up in @[arg].
*! @type array
*! If @[index] is an int, index number @[index] of @[arg] will be
*! returned. Otherwise an array of all elements in @[arg] indexed
*! with @[index] will be returned.
*! @type mapping
*! If @[index] exists in @[arg] the corresponding value will be
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! returned. Otherwise @expr{UNDEFINED@} will be returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type multiset
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! If @[index] exists in @[arg], @expr{1@} will be returned.
*! Otherwise @expr{UNDEFINED@} will be returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type string
*! The character (int) at index @[index] in @[arg] will be returned.
*! @type program
*! The non-static (ie public) constant symbol @[index] will be
*! looked up in @[arg].
*! @endmixed
*!
*! Otherwise if there are 3 arguments the result will be as follows:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type string
*! A string with the characters between @[start] and @[end] (inclusive)
*! in @[arg] will be returned.
*! @type array
*! An array with the elements between @[start] and @[end] (inclusive)
*! in @[arg] will be returned.
*! @endmixed
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @note
*! An indexing expression in an lvalue context, i.e. where the
*! index is being assigned a new value, uses @[`[]=] instead of
*! this function.
*!
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @seealso
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @[`->()], @[lfun::`[]()], @[`[]=]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_index(INT32 args)
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | | {
switch(args)
{
case 0:
case 1:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`[]", "Too few arguments.\n", sp, args);
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | | break;
case 2:
if(sp[-1].type==T_STRING) sp[-1].subtype=0;
o_index();
break;
case 3:
o_range();
break;
default:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`[]", "Too many arguments.\n", sp, args);
|
9f6847 | 1997-03-08 | 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 | | *! Arrow index.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Every non-lvalue expression with the @expr{->@} operator becomes
*! a call to this function. @expr{a->b@} is the same as
*! @expr{predef::`^(a,"b")@} where @expr{"b"@} is the symbol
*! @expr{b@} in string form.
*!
*! This function behaves like @[`[]], except that the index is
*! passed literally as a string instead of being evaluated.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! If @[arg] is an object that implements @[lfun::`->()], that function
*! will be called with @[index] as the single argument.
*!
*! Otherwise the result will be as follows:
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type object
*! The non-static (ie public) symbol named @[index] will be looked up
*! in @[arg].
*! @type int
*! The bignum function named @[index] will be looked up in @[arg].
*! @type array
*! An array of all elements in @[arg] arrow indexed with @[index]
*! will be returned.
*! @type mapping
*! If @[index] exists in @[arg] the corresponding value will be
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! returned. Otherwise @expr{UNDEFINED@} will be returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type multiset
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! If @[index] exists in @[arg], @expr{1@} will be returned.
*! Otherwise @expr{UNDEFINED@} will be returned.
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type program
*! The non-static (ie public) constant symbol @[index] will be
*! looked up in @[arg].
*! @endmixed
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @note
*! In an expression @expr{a->b@}, the symbol @expr{b@} can be any
*! token that matches the identifier syntax - keywords are
*! disregarded in that context.
*!
*! @note
*! An arrow indexing expression in an lvalue context, i.e. where
*! the index is being assigned a new value, uses @[`->=] instead of
*! this function.
*!
|
8d1b86 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @seealso
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @[`[]()], @[lfun::`->()], @[::`->()], @[`->=]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_arrow(INT32 args)
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | | {
switch(args)
{
case 0:
case 1:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`->", "Too few arguments.\n", sp, args);
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | | break;
case 2:
if(sp[-1].type==T_STRING)
sp[-1].subtype=1;
o_index();
break;
default:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`->", "Too many arguments.\n", sp, args);
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | | }
}
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Index assignment.
*!
*! Every lvalue expression with the @expr{[]@} operator becomes a
*! call to this function, i.e. @expr{a[b]=c@} is the same as
*! @expr{predef::`[]=(a,b,c)@}.
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! If @[arg] is an object that implements @[lfun::`[]=()], that function
*! will be called with @[index] and @[val] as the arguments.
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type object
*! The non-static (ie public) variable named @[index] will be looked up
*! in @[arg], and assigned @[val].
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type array|mapping
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! Index @[index] in @[arg] will be assigned @[val].
*! @type multiset
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! If @[val] is @expr{0@} (zero), one occurrance of @[index] in
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @[arg] will be removed. Otherwise @[index] will be added
*! to @[arg] if it is not already there.
*! @endmixed
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! @[val] will be returned.
*!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @note
*! An indexing expression in a non-lvalue context, i.e. where the
*! index is being queried instead of assigned, uses @[`[]] instead
*! of this function.
*!
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @seealso
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @[`->=()], @[lfun::`[]=()], @[`[]]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_index_assign(INT32 args)
|
912f17 | 1999-08-16 | Martin Stjernholm | | {
switch (args) {
case 0:
case 1:
case 2:
PIKE_ERROR("`[]=", "Too few arguments.\n", sp, args);
break;
case 3:
|
4856a8 | 1999-08-17 | Martin Stjernholm | | if(sp[-2].type==T_STRING) sp[-2].subtype=0;
assign_lvalue (sp-3, sp-1);
|
912f17 | 1999-08-16 | Martin Stjernholm | | assign_svalue (sp-3, sp-1);
pop_n_elems (args-1);
break;
default:
PIKE_ERROR("`[]=", "Too many arguments.\n", sp, args);
}
}
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Arrow index assignment.
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Every lvalue expression with the @expr{->@} operator becomes a
*! call to this function, i.e. @expr{a->b=c@} is the same as
*! @expr{predef::`->=(a,"b",c)@} where @expr{"b"@} is the symbol
*! @expr{b@} in string form.
*!
*! This function behaves like @[`[]=], except that the index is
*! passed literally as a string instead of being evaluated.
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! If @[arg] is an object that implements @[lfun::`->=()], that function
*! will be called with @[index] and @[val] as the arguments.
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
|
b00d6d | 2001-07-27 | Martin Nilsson | | *! @mixed arg
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @type object
*! The non-static (ie public) variable named @[index] will be looked up
*! in @[arg], and assigned @[val].
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type array|mapping
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! Index @[index] in @[arg] will be assigned @[val].
*! @type multiset
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! If @[val] is @expr{0@} (zero), one occurrance of @[index] in
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! @[arg] will be removed. Otherwise @[index] will be added
*! to @[arg] if it is not already there.
*! @endmixed
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! @[val] will be returned.
*!
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @note
*! In an expression @expr{a->b=c@}, the symbol @expr{b@} can be any
*! token that matches the identifier syntax - keywords are
*! disregarded in that context.
*!
*! @note
*! An arrow indexing expression in a non-lvalue context, i.e. where
*! the index is being queried instead of assigned, uses @[`->]
*! instead of this function.
*!
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *! @seealso
|
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! @[`[]=()], @[lfun::`->=()], @[`->]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_arrow_assign(INT32 args)
|
4856a8 | 1999-08-17 | Martin Stjernholm | | {
switch (args) {
case 0:
case 1:
case 2:
PIKE_ERROR("`->=", "Too few arguments.\n", sp, args);
break;
case 3:
if(sp[-2].type==T_STRING) sp[-2].subtype=1;
assign_lvalue (sp-3, sp-1);
assign_svalue (sp-3, sp-1);
pop_n_elems (args-1);
break;
default:
PIKE_ERROR("`->=", "Too many arguments.\n", sp, args);
}
}
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | |
dfceb0 | 2003-11-10 | Martin Stjernholm | | *! Size query.
|
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 string
*! The number of characters in @[arg] will be returned.
|
fefa0e | 2002-05-30 | Henrik Grubbström (Grubba) | | *! @type array|multiset
|
28984e | 2001-05-09 | Henrik Grubbström (Grubba) | | *! The number of elements in @[arg] will be returned.
*! @type mapping
*! The number of key-value pairs in @[arg] will be returned.
*! @type object
*! If @[arg] implements @[lfun::_sizeof()], that function will
*! be called. Otherwise the number of non-static (ie public)
*! symbols in @[arg] will be returned.
*! @endmixed
|
d07e18 | 2001-02-08 | Henrik Grubbström (Grubba) | | *!
*! @seealso
*! @[lfun::_sizeof()]
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_sizeof(INT32 args)
|
4c573c | 1996-08-03 | Fredrik Hübinette (Hubbe) | | {
INT32 tmp;
if(args<1)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("sizeof", "Too few arguments.\n", sp, args);
|
4c573c | 1996-08-03 | Fredrik Hübinette (Hubbe) | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | tmp=pike_sizeof(sp-args);
|
4c573c | 1996-08-03 | Fredrik Hübinette (Hubbe) | |
pop_n_elems(args);
push_int(tmp);
}
|
79d2b4 | 2001-05-19 | Henrik Grubbström (Grubba) | | static node *optimize_sizeof(node *n)
{
if (CDR(n) && (CDR(n)->token == F_APPLY) &&
(CADR(n)) && (CADR(n)->token == F_CONSTANT) &&
(CADR(n)->u.sval.type == T_FUNCTION) &&
(CADR(n)->u.sval.subtype == FUNCTION_BUILTIN)) {
extern struct program *string_split_iterator_program;
if ((CADR(n)->u.sval.u.efun->function == f_divide) &&
CDDR(n) && (CDDR(n)->token == F_ARG_LIST) &&
CADDR(n) && (CADDR(n)->type == string_type_string) &&
CDDDR(n) && (CDDDR(n)->token == F_CONSTANT) &&
(CDDDR(n)->u.sval.type == T_STRING) &&
(CDDDR(n)->u.sval.u.string->len == 1)) {
p_wchar2 split = index_shared_string(CDDDR(n)->u.sval.u.string, 0);
|
eed2da | 2001-06-11 | Henrik Grubbström (Grubba) | |
|
79d2b4 | 2001-05-19 | Henrik Grubbström (Grubba) | |
ADD_NODE_REF2(CADDR(n),
return mkefuncallnode("sizeof",
mkapplynode(mkprgnode(string_split_iterator_program),
mknode(F_ARG_LIST, CADDR(n),
mkintnode(split))));
);
}
if ((CADR(n)->u.sval.u.efun->function == f_minus) &&
CDDR(n) && (CDDR(n)->token == F_ARG_LIST) &&
CADDR(n) && (CADDR(n)->token == F_APPLY) &&
CAADDR(n) && (CAADDR(n)->token == F_CONSTANT) &&
(CAADDR(n)->u.sval.type == T_FUNCTION) &&
(CAADDR(n)->u.sval.subtype == FUNCTION_BUILTIN) &&
(CAADDR(n)->u.sval.u.efun->function == f_divide) &&
CDADDR(n) && (CDADDR(n)->token == F_ARG_LIST) &&
CADADDR(n) && (CADADDR(n)->type == string_type_string) &&
CDDADDR(n) && (CDDADDR(n)->token == F_CONSTANT) &&
(CDDADDR(n)->u.sval.type == T_STRING) &&
(CDDADDR(n)->u.sval.u.string->len == 1) &&
CDDDR(n)) {
if (((CDDDR(n)->token == F_CONSTANT) &&
(CDDDR(n)->u.sval.type == T_ARRAY) &&
(CDDDR(n)->u.sval.u.array->size == 1) &&
(CDDDR(n)->u.sval.u.array->item[0].type == T_STRING) &&
(CDDDR(n)->u.sval.u.array->item[0].u.string->len == 0)) ||
((CDDDR(n)->token == F_APPLY) &&
CADDDR(n) && (CADDDR(n)->token == F_CONSTANT) &&
(CADDDR(n)->u.sval.type == T_FUNCTION) &&
(CADDDR(n)->u.sval.subtype == FUNCTION_BUILTIN) &&
(CADDDR(n)->u.sval.u.efun->function == f_allocate) &&
CDDDDR(n) && (CDDDDR(n)->token == F_ARG_LIST) &&
CADDDDR(n) && (CADDDDR(n)->token == F_CONSTANT) &&
(CADDDDR(n)->u.sval.type == T_INT) &&
(CADDDDR(n)->u.sval.u.integer == 1) &&
CDDDDDR(n) && (CDDDDDR(n)->token == F_CONSTANT) &&
(CDDDDDR(n)->u.sval.type == T_STRING) &&
(CDDDDDR(n)->u.sval.u.string->len == 0))) {
p_wchar2 split = index_shared_string(CDDADDR(n)->u.sval.u.string, 0);
ADD_NODE_REF2(CADADDR(n),
return mkefuncallnode("sizeof",
mkapplynode(mkprgnode(string_split_iterator_program),
mknode(F_ARG_LIST, CADADDR(n),
mknode(F_ARG_LIST,
mkintnode(split),
mkintnode(1)))));
);
}
}
}
return NULL;
}
|
4c573c | 1996-08-03 | Fredrik Hübinette (Hubbe) | | static int generate_sizeof(node *n)
{
if(count_args(CDR(n)) != 1) return 0;
if(do_docode(CDR(n),DO_NOT_COPY) != 1)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Count args was wrong in sizeof().\n");
|
a96ce9 | 2000-04-19 | Fredrik Hübinette (Hubbe) | | emit0(F_SIZEOF);
|
4c573c | 1996-08-03 | Fredrik Hübinette (Hubbe) | | return 1;
}
|
4f20e9 | 2001-01-25 | Fredrik Hübinette (Hubbe) | | extern int generate_call_function(node *n);
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | |
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | struct program *string_assignment_program;
#undef THIS
|
60d987 | 2000-03-23 | Fredrik Hübinette (Hubbe) | | #define THIS ((struct string_assignment_storage *)(CURRENT_STORAGE))
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | |
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | static void f_string_assignment_index(INT32 args)
{
|
639cfa | 2003-05-15 | Martin Stjernholm | | ptrdiff_t len = THIS->s->len;
INT_TYPE i, p;
get_all_args("string[]",args,"%i",&p);
i = p < 0 ? p + len : p;
if(i<0 || i>=len)
|
b99d88 | 2003-05-15 | Martin Stjernholm | | Pike_error("Index %"PRINTPIKEINT"d is out of string range "
|
639cfa | 2003-05-15 | Martin Stjernholm | | "%"PRINTPTRDIFFT"d..%"PRINTPTRDIFFT"d.\n",
p, -len, len - 1);
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | else
|
b987f9 | 1998-10-12 | Fredrik Hübinette (Hubbe) | | i=index_shared_string(THIS->s,i);
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_int(i);
}
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | |
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | static void f_string_assignment_assign_index(INT32 args)
{
|
639cfa | 2003-05-15 | Martin Stjernholm | | INT_TYPE p, i, j;
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | union anything *u;
|
639cfa | 2003-05-15 | Martin Stjernholm | | ptrdiff_t len;
get_all_args("string[]=",args,"%i%i",&p,&j);
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | if((u=get_pointer_if_this_type(THIS->lval, T_STRING)))
{
|
639cfa | 2003-05-15 | Martin Stjernholm | | len = u->string->len;
i = p < 0 ? p + len : p;
if(i<0 || i>=len)
|
b99d88 | 2003-05-15 | Martin Stjernholm | | Pike_error("Index %"PRINTPIKEINT"d is out of string range "
|
639cfa | 2003-05-15 | Martin Stjernholm | | "%"PRINTPTRDIFFT"d..%"PRINTPTRDIFFT"d.\n",
p, -len, len - 1);
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | free_string(THIS->s);
u->string=modify_shared_string(u->string,i,j);
copy_shared_string(THIS->s, u->string);
|
639cfa | 2003-05-15 | Martin Stjernholm | | }
else{
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | lvalue_to_svalue_no_free(sp,THIS->lval);
sp++;
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | dmalloc_touch_svalue(Pike_sp-1);
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != T_STRING) Pike_error("string[]= failed.\n");
|
639cfa | 2003-05-15 | Martin Stjernholm | | len = sp[-1].u.string->len;
i = p < 0 ? p + len : p;
if(i<0 || i>=len)
|
b99d88 | 2003-05-15 | Martin Stjernholm | | Pike_error("Index %"PRINTPIKEINT"d is out of string range "
|
639cfa | 2003-05-15 | Martin Stjernholm | | "%"PRINTPTRDIFFT"d..%"PRINTPTRDIFFT"d.\n",
p, -len, len - 1);
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | sp[-1].u.string=modify_shared_string(sp[-1].u.string,i,j);
assign_lvalue(THIS->lval, sp-1);
pop_stack();
}
|
639cfa | 2003-05-15 | Martin Stjernholm | |
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_int(j);
}
static void init_string_assignment_storage(struct object *o)
{
THIS->lval[0].type=T_INT;
THIS->lval[1].type=T_INT;
THIS->s=0;
}
static void exit_string_assignment_storage(struct object *o)
{
free_svalues(THIS->lval, 2, BIT_MIXED);
if(THIS->s)
free_string(THIS->s);
}
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | |
|
f09ec9 | 2001-02-07 | Henrik Grubbström (Grubba) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void init_operators(void)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`[]",f_index,tOr7(tFunc(tStr tInt,tInt),tFunc(tObj tStr,tMix),tFunc(tArr(tSetvar(0,tMix)) tInt,tVar(0)),tFunc(tMap(tMix,tSetvar(1,tMix)) tMix,tVar(1)),tFunc(tMultiset tMix,tInt),tFunc(tStr tInt tInt,tStr),tOr(tFunc(tArr(tSetvar(2,tMix)) tInt tInt,tArr(tVar(2))),tFunc(tPrg(tObj),tMix))),OPT_TRY_OPTIMIZE,0,0);
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`->",f_arrow,tOr(tFunc(tArr(tOr4(tObj,tMapping,tMultiset,tArray)) tStr,tArr(tMix)),tFunc(tOr4(tObj,tMapping,tMultiset,tPrg(tObj)) tStr,tMix)),OPT_TRY_OPTIMIZE,0,0);
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | |
|
912f17 | 1999-08-16 | Martin Stjernholm | | ADD_EFUN("`[]=", f_index_assign,
|
4856a8 | 1999-08-17 | Martin Stjernholm | | tOr4(tFunc(tObj tStr tSetvar(0,tMix), tVar(0)),
|
912f17 | 1999-08-16 | Martin Stjernholm | | tFunc(tArr(tSetvar(1,tMix)) tInt tVar(1), tVar(1)),
tFunc(tMap(tSetvar(2,tMix), tSetvar(3,tMix)) tVar(2) tVar(3), tVar(3)),
tFunc(tSet(tSetvar(4,tMix)) tVar(4) tSetvar(5,tMix), tVar(5))),
|
6f1d41 | 2000-04-08 | Henrik Grubbström (Grubba) | | OPT_SIDE_EFFECT|OPT_TRY_OPTIMIZE);
|
912f17 | 1999-08-16 | Martin Stjernholm | |
|
4856a8 | 1999-08-17 | Martin Stjernholm | | ADD_EFUN("`->=", f_arrow_assign,
tOr3(tFunc(tArr(tOr4(tArray,tObj,tMultiset,tMapping)) tStr tSetvar(0,tMix), tVar(0)),
tFunc(tOr(tObj, tMultiset) tStr tSetvar(1,tMix), tVar(1)),
tFunc(tMap(tMix, tSetvar(2,tMix)) tStr tVar(2), tVar(2))),
|
6f1d41 | 2000-04-08 | Henrik Grubbström (Grubba) | | OPT_SIDE_EFFECT|OPT_TRY_OPTIMIZE);
|
4856a8 | 1999-08-17 | Martin Stjernholm | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
563fdc | 1999-12-27 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`==",f_eq,
tOr5(tFuncV(tOr(tInt,tFloat) tOr(tInt,tFloat),
tOr(tInt,tFloat),tInt01),
|
9bab98 | 1999-12-27 | Henrik Grubbström (Grubba) | | tFuncV(tSetvar(0,tOr4(tString,tMapping,tMultiset,tArray))
tVar(0), tVar(0),tInt01),
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | tFuncV(tOr3(tObj,tPrg(tObj),tFunction) tMix,tMix,tInt01),
tFuncV(tMix tOr3(tObj,tPrg(tObj),tFunction),tMix,tInt01),
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | tFuncV(tType(tMix) tType(tMix),
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | tOr3(tPrg(tObj),tFunction,tType(tMix)),tInt01)),
|
25c28d | 1999-12-29 | Henrik Grubbström (Grubba) | | OPT_WEAK_TYPE|OPT_TRY_OPTIMIZE,optimize_eq,generate_comparison);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
563fdc | 1999-12-27 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`!=",f_ne,
tOr5(tFuncV(tOr(tInt,tFloat) tOr(tInt,tFloat),
tOr(tInt,tFloat),tInt01),
|
9bab98 | 1999-12-27 | Henrik Grubbström (Grubba) | | tFuncV(tSetvar(0,tOr4(tString,tMapping,tMultiset,tArray))
tVar(0), tVar(0),tInt01),
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | tFuncV(tOr3(tObj,tPrg(tObj),tFunction) tMix,tMix,tInt01),
tFuncV(tMix tOr3(tObj,tPrg(tObj),tFunction),tMix,tInt01),
|
54f8ac | 2001-03-17 | Henrik Grubbström (Grubba) | | tFuncV(tType(tMix) tType(tMix),
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | tOr3(tPrg(tObj),tFunction,tType(tMix)),tInt01)),
|
25c28d | 1999-12-29 | Henrik Grubbström (Grubba) | | OPT_WEAK_TYPE|OPT_TRY_OPTIMIZE,0,generate_comparison);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
563fdc | 1999-12-27 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`!",f_not,tFuncV(tMix,tVoid,tInt01),
OPT_TRY_OPTIMIZE,optimize_not,generate_not);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
dc7d49 | 1999-12-15 | Henrik Grubbström (Grubba) | | #define CMP_TYPE "!function(!(object|mixed)...:mixed)&function(mixed...:int(0..1))|function(int|float...:int(0..1))|function(string...:int(0..1))|function(type|program,type|program,type|program...:int(0..1))"
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | add_efun2("`<", f_lt,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);
add_efun2("`<=",f_le,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);
add_efun2("`>", f_gt,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);
add_efun2("`>=",f_ge,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
76db65 | 1999-05-25 | Mirar (Pontus Hagland) | | ADD_EFUN2("`+",f_add,
|
5da6a2 | 1999-12-11 | Henrik Grubbström (Grubba) | | tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction),
|
ad08af | 1999-05-25 | Mirar (Pontus Hagland) | | tFuncV(tInt,tInt,tInt),
|
db1efe | 2000-12-15 | Henrik Grubbström (Grubba) | | tIfnot(tFuncV(tNone, tNot(tFlt), tMix),
|
ad08af | 1999-05-25 | Mirar (Pontus Hagland) | | tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)),
|
db1efe | 2000-12-15 | Henrik Grubbström (Grubba) | | tIfnot(tFuncV(tNone, tNot(tStr), tMix),
|
ad08af | 1999-05-25 | Mirar (Pontus Hagland) | | tFuncV(tOr3(tStr,tInt,tFlt),
tOr3(tStr,tInt,tFlt),tStr)),
tFuncV(tSetvar(0,tArray),tSetvar(1,tArray),
tOr(tVar(0),tVar(1))),
tFuncV(tSetvar(0,tMapping),tSetvar(1,tMapping),
tOr(tVar(0),tVar(1))),
tFuncV(tSetvar(0,tMultiset),tSetvar(1,tMultiset),
tOr(tVar(0),tVar(1)))),
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | | OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
|
76db65 | 1999-05-25 | Mirar (Pontus Hagland) | |
ADD_EFUN2("`-",f_minus,
|
5da6a2 | 1999-12-11 | Henrik Grubbström (Grubba) | | tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction),
|
76db65 | 1999-05-25 | Mirar (Pontus Hagland) | | tFuncV(tInt,tInt,tInt),
|
4106cc | 2000-12-08 | Henrik Grubbström (Grubba) | | tIfnot(tFuncV(tNone,tNot(tFlt),tMix),
|
76db65 | 1999-05-25 | Mirar (Pontus Hagland) | | tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)),
tFuncV(tArr(tSetvar(0,tMix)),tArray,tArr(tVar(0))),
tFuncV(tMap(tSetvar(1,tMix),tSetvar(2,tMix)),
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | tOr3(tMapping,tArray,tMultiset),
tMap(tVar(1),tVar(2))),
|
76db65 | 1999-05-25 | Mirar (Pontus Hagland) | | tFunc(tSet(tSetvar(3,tMix)) tMultiset,tSet(tVar(3))),
tFuncV(tStr,tStr,tStr)),
|
1eaa38 | 1998-03-04 | Fredrik Hübinette (Hubbe) | | OPT_TRY_OPTIMIZE,0,generate_minus);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | |
#define F_AND_TYPE(Z) \
tOr(tFunc(tSetvar(0,Z),tVar(0)), \
tIfnot(tFunc(Z,tMix), \
tFuncV(tSetvar(1,Z),tSetvar(2,Z), \
tOr(tVar(1),tVar(2)))))
|
ef2b4e | 1999-12-18 | Martin Stjernholm | | ADD_EFUN2("`&",f_and,
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | tOr4(
tFunc(tSetvar(0,tMix),tVar(0)),
tOr(tFuncV(tMix tObj,tMix,tMix),
tFuncV(tObj tMix,tMix,tMix)),
tOr6( F_AND_TYPE(tInt),
F_AND_TYPE(tArray),
F_AND_TYPE(tMapping),
F_AND_TYPE(tMultiset),
F_AND_TYPE(tString),
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | F_AND_TYPE(tOr(tType(tMix),tPrg(tObj))) ),
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | |
|
db1efe | 2000-12-15 | Henrik Grubbström (Grubba) | | tIfnot(tFuncV(tNone, tNot(tMapping), tMix),
|
aa17e3 | 2000-04-12 | Mirar (Pontus Hagland) | | tFuncV(tNone,
tOr3(tArray,tMultiset,tSetvar(4,tMapping)),
tVar(4)) )
),
|
ef2b4e | 1999-12-18 | Martin Stjernholm | | OPT_TRY_OPTIMIZE,optimize_binary,generate_and);
#define LOG_TYPE \
tOr7(tOr(tFuncV(tMix tObj,tMix,tMix), \
tFuncV(tObj,tMix,tMix)), \
tFuncV(tInt,tInt,tInt), \
tFuncV(tSetvar(1,tMapping),tSetvar(2,tMapping),tOr(tVar(1),tVar(2))), \
tFuncV(tSetvar(3,tMultiset),tSetvar(4,tMultiset),tOr(tVar(3),tVar(4))), \
tFuncV(tSetvar(5,tArray),tSetvar(6,tArray),tOr(tVar(5),tVar(6))), \
tFuncV(tString,tString,tString), \
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | tFuncV(tOr(tType(tMix),tPrg(tObj)),tOr(tType(tMix),tPrg(tObj)),tType(tMix)))
|
ef2b4e | 1999-12-18 | Martin Stjernholm | |
ADD_EFUN2("`|",f_or,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_or);
ADD_EFUN2("`^",f_xor,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_xor);
#define SHIFT_TYPE \
|
f9dd10 | 2003-01-26 | Martin Nilsson | | tOr(tAnd(tNot(tFuncV(tNone, tNot(tObj), tMix)), \
tOr(tFunc(tMix tObj,tMix), \
tFunc(tObj tMix,tMix))), \
tFunc(tInt tInt,tInt))
|
ef2b4e | 1999-12-18 | Martin Stjernholm | |
|
9d4cae | 2002-06-17 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`<<", f_lsh, SHIFT_TYPE, OPT_TRY_OPTIMIZE,
may_have_side_effects, generate_lsh);
ADD_EFUN2("`>>", f_rsh, SHIFT_TYPE, OPT_TRY_OPTIMIZE,
may_have_side_effects, generate_rsh);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | | |
1eaa38 | 1998-03-04 | Fredrik Hübinette (Hubbe) | | "function(array(array(1=mixed)),array(1=mixed):array(1))|"
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | "function(int...:int)|"
"!function(int...:mixed)&function(float|int...:float)|"
"function(string*,string:string)|"
|
1eaa38 | 1998-03-04 | Fredrik Hübinette (Hubbe) | | "function(array(0=mixed),int:array(0))|"
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | "function(array(0=mixed),float:array(0))|"
"function(string,int:string)
"function(string,float:string)
*/
|
4106cc | 2000-12-08 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`*", f_multiply,
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | tOr9(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction),
|
ad08af | 1999-05-25 | Mirar (Pontus Hagland) | | tFunc(tArr(tArr(tSetvar(1,tMix)))
tArr(tSetvar(1,tMix)),tArr(tVar(1))),
tFuncV(tInt,tInt,tInt),
|
4106cc | 2000-12-08 | Henrik Grubbström (Grubba) | | tIfnot(tFuncV(tNone,tNot(tFlt),tMix),
|
ad08af | 1999-05-25 | Mirar (Pontus Hagland) | | tFuncV(tOr(tFlt,tInt),tOr(tFlt,tInt),tFlt)),
tFunc(tArr(tStr) tStr,tStr),
tFunc(tArr(tSetvar(0,tMix)) tInt,tArr(tVar(0))),
|
3a3bc3 | 2000-09-26 | Henrik Wallin | | tFunc(tArr(tSetvar(0,tMix)) tFlt,tArr(tVar(0))),
tFunc(tStr tInt,tStr),
tFunc(tStr tFlt,tStr)),
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | | |
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | "function(int,int...:int)|"
"!function(int...:mixed)&function(float|int...:float)|"
|
1eaa38 | 1998-03-04 | Fredrik Hübinette (Hubbe) | | "function(array(0=mixed),array|int|float...:array(array(0)))|"
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | | "function(string,string|int|float...:array(string)) */
|
4106cc | 2000-12-08 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`/", f_divide,
tOr5(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction),
tFuncV(tInt, tInt, tInt),
tIfnot(tFuncV(tNone, tNot(tFlt), tMix),
tFuncV(tOr(tFlt,tInt),tOr(tFlt,tInt),tFlt)),
tFuncV(tArr(tSetvar(0,tMix)),
tOr3(tArray,tInt,tFlt),
tArr(tArr(tVar(0)))),
tFuncV(tStr,tOr3(tStr,tInt,tFlt),tArr(tStr))),
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | OPT_TRY_OPTIMIZE,0,generate_divide);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | | |
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | "function(object,mixed:mixed)|"
"function(int,int:int)|"
"function(string,int:string)|"
|
1eaa38 | 1998-03-04 | Fredrik Hübinette (Hubbe) | | "function(array(0=mixed),int:array(0))|"
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | | "!function(int,int:mixed)&function(int|float,int|float:float) */
|
db1efe | 2000-12-15 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`%", f_mod,
tOr6(tFunc(tMix tObj,tMix),
tFunc(tObj tMix,tMix),
tFunc(tInt tInt,tInt),
tFunc(tStr tInt,tStr),
tFunc(tArr(tSetvar(0,tMix)) tInt,tArr(tVar(0))),
tIfnot(tFuncV(tNone, tNot(tFlt), tMix),
tFunc(tOr(tInt,tFlt) tOr(tInt,tFlt),tFlt))),
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | | OPT_TRY_OPTIMIZE,0,generate_mod);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | ADD_EFUN2("`~",f_compl,
|
0158bf | 2001-03-17 | Henrik Grubbström (Grubba) | | tOr6(tFunc(tObj,tMix),
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | tFunc(tInt,tInt),
tFunc(tFlt,tFlt),
tFunc(tStr,tStr),
|
0158bf | 2001-03-17 | Henrik Grubbström (Grubba) | | tFunc(tType(tSetvar(0, tMix)), tType(tNot(tVar(0)))),
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | tFunc(tPrg(tObj), tType(tMix))),
|
0e801c | 1999-12-13 | Henrik Grubbström (Grubba) | | OPT_TRY_OPTIMIZE,0,generate_compl);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
57773f | 2001-02-05 | Henrik Grubbström (Grubba) | | ADD_EFUN2("sizeof", f_sizeof,
tFunc(tOr5(tStr,tMultiset,tArray,tMapping,tObj),tInt),
|
79d2b4 | 2001-05-19 | Henrik Grubbström (Grubba) | | OPT_TRY_OPTIMIZE, optimize_sizeof, generate_sizeof);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
ADD_EFUN2("`()",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
ADD_EFUN2("call_function",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | |
start_new_program();
|
90e978 | 1999-01-31 | Fredrik Hübinette (Hubbe) | | ADD_STORAGE(struct string_assignment_storage);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
2ff960 | 2000-08-31 | Henrik Grubbström (Grubba) | | ADD_FUNCTION2("`[]", f_string_assignment_index, tFunc(tInt,tInt), 0,
OPT_EXTERNAL_DEPEND);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
2ff960 | 2000-08-31 | Henrik Grubbström (Grubba) | | ADD_FUNCTION2("`[]=", f_string_assignment_assign_index,
tFunc(tInt tInt,tInt), 0, OPT_SIDE_EFFECT);
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | set_init_callback(init_string_assignment_storage);
set_exit_callback(exit_string_assignment_storage);
string_assignment_program=end_program();
}
|
aa711e | 1998-06-06 | Henrik Grubbström (Grubba) | | void exit_operators(void)
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | {
if(string_assignment_program)
{
free_program(string_assignment_program);
string_assignment_program=0;
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
|
6898c0 | 2003-11-14 | Martin Stjernholm | |
void o_breakpoint(void)
{
}
|