cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | |
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | ||| This file a part of Pike, and is copyright by Fredrik Hubinette
||| Pike is distributed as GPL (General Public License)
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | ||| See the files COPYING and DISCLAIMER for more information.
\*/
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include <math.h>
#include "global.h"
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | RCSID("$Id: operators.c,v 1.35 1998/06/06 03:22:15 hubbe 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"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "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"
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | #define COMPARISON(ID,NAME,FUN) \
void ID(INT32 args) \
{ \
int i; \
switch(args) \
{ \
case 0: case 1: \
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR(NAME, "Too few arguments\n", sp, args); \
|
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) | | }
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | void f_ne(INT32 args)
{
f_eq(args);
o_not();
}
COMPARISON(f_eq,"`==", is_eq)
COMPARISON(f_lt,"`<" , is_lt)
COMPARISON(f_le,"`<=",!is_gt)
COMPARISON(f_gt,"`>" , is_gt)
COMPARISON(f_ge,"`>=",!is_lt)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | #define CALL_OPERATOR(OP, args) \
if(!sp[-args].u.object->prog) \
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR(lfun_names[OP], "Called in destructed object.\n", sp, args); \
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | if(FIND_LFUN(sp[-args].u.object->prog,OP) == -1) \
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR(lfun_names[OP], "Operator not in object.\n", sp, args); \
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | apply_lfun(sp[-args].u.object, OP, args-1); \
free_svalue(sp-2); \
sp[-2]=sp[-1]; \
sp--;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | 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) | | {
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`+", "Too few arguments\n", sp, args);
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | }else{
if(types & BIT_OBJECT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-args].type == T_OBJECT &&
sp[-args].u.object->prog &&
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | FIND_LFUN(sp[-args].u.object->prog,LFUN_ADD) != -1)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
apply_lfun(sp[-args].u.object, LFUN_ADD, args-1);
free_svalue(sp-2);
sp[-2]=sp[-1];
sp--;
return;
}
for(e=1;e<args;e++)
{
if(sp[e-args].type == T_OBJECT &&
sp[e-args].u.object->prog &&
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | 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;
apply_lfun(tmp->u.object, LFUN_RADD, e);
if(args - e > 2)
{
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:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`+", "Bad argument 1\n", sp, args);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`+", "Incompatible types\n", sp, args);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
case BIT_STRING:
{
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *r;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | char *buf;
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | INT32 tmp;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | switch(args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | case 1: return;
default:
size=0;
for(e=-args;e<0;e++) size+=sp[e].u.string->len;
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | tmp=sp[-args].u.string->len;
r=realloc_shared_string(sp[-args].u.string,size);
sp[-args].type=T_INT;
buf=r->str+tmp;
for(e=-args+1;e<0;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
MEMCPY(buf,sp[e].u.string->str,sp[e].u.string->len);
buf+=sp[e].u.string->len;
}
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | sp[-args].u.string=end_shared_string(r);
sp[-args].type=T_STRING;
for(e=-args+1;e<0;e++) free_string(sp[e].u.string);
sp-=args-1;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
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;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | char *buf,*str;
size=0;
for(e=-args;e<0;e++)
{
switch(sp[e].type)
{
case T_STRING:
size+=sp[e].u.string->len;
break;
case T_INT:
size+=14;
break;
case T_FLOAT:
size+=22;
break;
}
}
str=buf=xalloc(size+1);
size=0;
for(e=-args;e<0;e++)
{
switch(sp[e].type)
{
case T_STRING:
MEMCPY(buf,sp[e].u.string->str,sp[e].u.string->len);
buf+=sp[e].u.string->len;
break;
case T_INT:
|
908133 | 1995-08-21 | David Hedbor | | sprintf(buf,"%ld",(long)sp[e].u.integer);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | buf+=strlen(buf);
break;
case T_FLOAT:
sprintf(buf,"%f",(double)sp[e].u.float_number);
buf+=strlen(buf);
break;
}
}
r=make_shared_binary_string(str,buf-str);
free(str);
pop_n_elems(args);
push_string(r);
break;
}
case BIT_INT:
size=0;
for(e=-args; e<0; e++) size+=sp[e].u.integer;
sp-=args-1;
sp[-1].u.integer=size;
break;
case BIT_FLOAT:
{
FLOAT_TYPE sum;
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;
}
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | case BIT_FLOAT | BIT_INT:
{
FLOAT_TYPE sum;
sum=0.0;
for(e=-args; e<0; e++)
{
if(sp[e].type==T_FLOAT)
{
sum+=sp[e].u.float_number;
}else{
sum+=(FLOAT_TYPE)sp[e].u.integer;
}
}
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;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case BIT_ARRAY:
{
struct array *a;
a=add_arrays(sp-args,args);
pop_n_elems(args);
push_array(a);
break;
}
case BIT_MAPPING:
{
struct mapping *m;
m = add_mappings(sp - args, args);
pop_n_elems(args);
push_mapping(m);
break;
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | case BIT_MULTISET:
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct multiset *l;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | l = add_multisets(sp - args, args);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | push_multiset(l);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
}
}
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | static int generate_sum(node *n)
{
switch(count_args(CDR(n)))
{
case 1:
do_docode(CDR(n),0);
return 1;
case 2:
do_docode(CDR(n),DO_NOT_COPY);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(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)
{
first_arg=my_get_arg(&CDR(n), 0);
second_arg=my_get_arg(&CDR(n), 1);
#ifdef DEBUG
if(!first_arg || !second_arg)
fatal("Couldn't find argument!\n");
#endif
if(node_is_false(*first_arg) && !node_may_overload(*second_arg,LFUN_EQ))
{
ret=*second_arg;
*second_arg=0;
return mkopernode("`!",ret,0);
}
if(node_is_false(*second_arg) && !node_may_overload(*first_arg,LFUN_EQ))
{
ret=*first_arg;
*first_arg=0;
return mkopernode("`!",ret,0);
}
}
return 0;
}
static node *optimize_not(node *n)
{
node **first_arg, **more_args;
int e;
if(count_args(CDR(n))==1)
{
first_arg=my_get_arg(&CDR(n), 0);
#ifdef DEBUG
if(!first_arg)
fatal("Couldn't find argument!\n");
#endif
if(node_is_true(*first_arg)) return mkintnode(0);
if(node_is_false(*first_arg)) return mkintnode(1);
#define TMP_OPT(X,Y) do { \
if((more_args=is_call_to(*first_arg, X))) \
{ \
node *tmp=*more_args; \
*more_args=0; \
return mkopernode(Y,tmp,0); \
} } while(0)
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
}
return 0;
}
|
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)
{
first_arg=my_get_arg(&CDR(n), 0);
second_arg=my_get_arg(&CDR(n), 1);
#ifdef DEBUG
if(!first_arg || !second_arg)
fatal("Couldn't find argument!\n");
#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))
{
ret=mknode(F_APPLY,
CAR(n),
mknode(F_ARG_LIST,
CDR(*first_arg),
*second_arg));
CAR(n)=0;
CDR(*first_arg)=0;
*second_arg=0;
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))
{
ret=mknode(F_APPLY,
CAR(n),
mknode(F_ARG_LIST,
*first_arg,
CDR(*second_arg)));
CAR(n)=0;
*first_arg=0;
CDR(*second_arg)=0;
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)
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)
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_EQ);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_ne)
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_NE);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_lt)
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_LT);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_le)
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_LE);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_gt)
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_GT);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else if(CAR(n)->u.sval.u.efun->function == f_ge)
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_GE);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | else
fatal("Couldn't generate comparison!\n");
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;
}
return 0;
}
static int call_lfun(int left, int right)
{
if(sp[-2].type == T_OBJECT &&
sp[-2].u.object->prog &&
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | FIND_LFUN(sp[-2].u.object->prog,left) != -1)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
apply_lfun(sp[-2].u.object, left, 1);
free_svalue(sp-2);
sp[-2]=sp[-1];
sp--;
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 &&
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | FIND_LFUN(sp[-1].u.object->prog,right) != -1)
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | {
push_svalue(sp-2);
apply_lfun(sp[-2].u.object, right, 1);
free_svalue(sp-3);
sp[-3]=sp[-1];
sp--;
pop_stack();
return 1;
}
return 0;
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | 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;
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`-", "Subtract 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_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;
m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping,OP_SUB);
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;
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, 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:
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;
}
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) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_minus(INT32 args)
{
switch(args)
{
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | case 0: PIKE_ERROR("`-", "Too few arguments.\n", sp, 0);
|
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);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_NEGATE);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
case 2:
do_docode(CDR(n),DO_NOT_COPY);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_SUBTRACT);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | 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)
{
if(call_lfun(LFUN_AND, LFUN_RAND))
return;
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`&", "Bitwise and 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:
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;
m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, OP_AND);
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;
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, 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 | | case T_STRING:
{
struct pike_string *s;
INT32 len, i;
len = sp[-2].u.string->len;
if (len != sp[-1].u.string->len)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`&", "Bitwise AND on strings of different lengths.\n", sp, 2);
|
fc0bb5 | 1997-02-13 | Niels Möller | | s = begin_shared_string(len);
for (i=0; i<len; i++)
s->str[i] = sp[-2].u.string->str[i] & sp[-1].u.string->str[i];
pop_n_elems(2);
push_string(end_shared_string(s));
return;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | 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) | |
static void speedup(INT32 args, void (*func)(void))
{
switch(sp[-args].type)
{
case T_MAPPING:
case T_ARRAY:
case T_MULTISET:
{
int e=-1;
while(args > 1)
{
struct svalue tmp;
func();
args--;
e++;
if(e - args >= -1)
{
e=0;
}else{
tmp=sp[e-args];
sp[e-args]=sp[-1];
sp[-1]=tmp;
}
}
return;
}
default:
while(--args > 0) func();
}
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_and(INT32 args)
{
switch(args)
{
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | case 0: PIKE_ERROR("`&", "Too few arguments.\n", sp, 0);
|
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);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_AND);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
default:
return 0;
}
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | 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)
{
if(call_lfun(LFUN_OR, LFUN_ROR))
return;
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`|", "Bitwise or 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:
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;
m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, OP_OR);
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;
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, OP_OR);
|
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=merge_array_without_order(sp[-2].u.array, sp[-1].u.array, OP_OR);
pop_n_elems(2);
push_array(a);
return;
}
|
fc0bb5 | 1997-02-13 | Niels Möller | | case T_STRING:
{
struct pike_string *s;
INT32 len, i;
len = sp[-2].u.string->len;
if (len != sp[-1].u.string->len)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`|", "Bitwise OR on strings of different lengths.\n", sp, 2);
|
fc0bb5 | 1997-02-13 | Niels Möller | | s = begin_shared_string(len);
for (i=0; i<len; i++)
s->str[i] = sp[-2].u.string->str[i] | sp[-1].u.string->str[i];
pop_n_elems(2);
push_string(end_shared_string(s));
return;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | default:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`|", "Bitwise or on illegal type.\n", sp, 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_or(INT32 args)
{
switch(args)
{
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | case 0: PIKE_ERROR("`|", "Too few arguments.\n", sp, 0);
|
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);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_OR);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
default:
return 0;
}
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | 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)
{
if(call_lfun(LFUN_XOR, LFUN_RXOR))
return;
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`^", "Bitwise XOR 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:
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;
m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, OP_XOR);
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;
l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, 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;
a=merge_array_without_order(sp[-2].u.array, sp[-1].u.array, OP_XOR);
pop_n_elems(2);
push_array(a);
return;
}
|
fc0bb5 | 1997-02-13 | Niels Möller | |
case T_STRING:
{
struct pike_string *s;
INT32 len, i;
len = sp[-2].u.string->len;
if (len != sp[-1].u.string->len)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`^", "Bitwise XOR on strings of different lengths.\n", sp, 2);
|
fc0bb5 | 1997-02-13 | Niels Möller | | s = begin_shared_string(len);
for (i=0; i<len; i++)
s->str[i] = sp[-2].u.string->str[i] ^ sp[-1].u.string->str[i];
pop_n_elems(2);
push_string(end_shared_string(s));
return;
}
|
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) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_xor(INT32 args)
{
switch(args)
{
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | case 0: PIKE_ERROR("`^", "Too few arguments.\n", sp, 0);
|
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);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_XOR);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
default:
return 0;
}
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void o_lsh(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
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) | | {
|
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)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`<<", "Bad argument 1.\n", sp, 2);
PIKE_ERROR("`<<", "Bad argument 2.\n", sp, 2);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
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) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_lsh(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | if(args != 2)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`<<", "Bad number of args.\n", sp, args);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | o_lsh();
}
static int generate_lsh(node *n)
{
if(count_args(CDR(n))==2)
{
do_docode(CDR(n),DO_NOT_COPY);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_LSH);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void o_rsh(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != T_INT || sp[-1].type != T_INT)
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | {
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(call_lfun(LFUN_RSH, LFUN_RRSH))
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | return;
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != T_INT)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`>>", "Bad argument 1.\n", sp, 2);
PIKE_ERROR("`>>", "Bad argument 2.\n", sp, 2);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | }
|
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) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_rsh(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | if(args != 2)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`>>", "Bad number of args.\n", sp, args);
|
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);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(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))
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void o_multiply(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
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)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`*", "Cannot multiply array by negative number.\n", sp, 2);
|
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;
}
case TWO_TYPES(T_STRING, T_INT):
{
struct pike_string *ret;
char *pos;
INT32 e;
if(sp[-1].u.integer < 0)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`*", "Cannot multiply string by negative number.\n", sp, 2);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | ret=begin_shared_string(sp[-2].u.string->len * sp[-1].u.integer);
pos=ret->str;
for(e=0;e<sp[-1].u.integer;e++,pos+=sp[-2].u.string->len)
MEMCPY(pos,sp[-2].u.string->str,sp[-2].u.string->len);
pop_n_elems(2);
push_string(end_shared_string(ret));
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=
(FLOAT_TYPE) sp[-1].u.integer * (FLOAT_TYPE)sp[0].u.float_number;
sp[-1].type=T_FLOAT;
return;
case TWO_TYPES(T_INT,T_INT):
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
sp[-1].u.integer *= sp[0].u.integer;
return;
default:
|
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) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_multiply(INT32 args)
{
switch(args)
{
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | case 0: PIKE_ERROR("`*", "Too few arguments.\n", sp, 0);
|
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 {
while(--args > 0) o_multiply();
}
|
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);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_MULTIPLY);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
default:
return 0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | 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;
char *pos=sp[-2].u.string->str;
INT32 size,e,len;
len=sp[-1].u.integer;
if(!len)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`/", "Division by zero.\n", sp, 2);
|
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++)
{
a->item[e].u.string=make_shared_binary_string(pos,len);
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;
INT32 last,pos,e,size;
double len;
len=sp[-1].u.float_number;
if(len==0.0)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`/", "Division by zero.\n", sp, 2);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
if(len<0)
{
len=-len;
size=(INT32)ceil( ((double)sp[-2].u.string->len) / len);
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) | | {
pos=sp[-2].u.string->len - (INT32)((e+1)*len);
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[size-1-e].u.string=make_shared_binary_string(
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | sp[-2].u.string->str + 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;
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | a->item[0].u.string=make_shared_binary_string(
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | sp[-2].u.string->str + 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{
size=(INT32)ceil( ((double)sp[-2].u.string->len) / len);
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) | | {
pos=(INT32)((e+1)*len);
a->item[e].u.string=make_shared_binary_string(
sp[-2].u.string->str + 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;
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | a->item[e].u.string=make_shared_binary_string(
sp[-2].u.string->str + 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;
INT32 size,e,len,pos=0;
len=sp[-1].u.integer;
if(!len)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`/", "Division by zero.\n", sp, 2);
|
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.array->size / len;
pos+=sp[-2].u.array->size % len;
}else{
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);
a->item[e].type=T_ARRAY;
pos+=len;
}
a->type_field=BIT_ARRAY;
pop_n_elems(2);
push_array(a);
return;
}
case TWO_TYPES(T_ARRAY,T_FLOAT):
{
struct array *a;
INT32 last,pos,e,size;
double len;
len=sp[-1].u.float_number;
if(len==0.0)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`/", "Division by zero.\n", sp, 2);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
if(len<0)
{
len=-len;
size=(INT32)ceil( ((double)sp[-2].u.array->size) / len);
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) | | {
pos=sp[-2].u.array->size - (INT32)((e+1)*len);
|
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{
size=(INT32)ceil( ((double)sp[-2].u.array->size) / len);
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) | | {
pos=(INT32)((e+1)*len);
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:
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)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`/", "Division by zero.\n", sp, 2);
|
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) | | {
INT32 tmp;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if (sp[-1].u.integer == 0)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`/", "Division by zero\n", sp, 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | |
|
c93f0e | 1997-12-03 | Fredrik Hübinette (Hubbe) | | tmp=sp[-1].u.integer/sp[0].u.integer;
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--;
|
c93f0e | 1997-12-03 | Fredrik Hübinette (Hubbe) | |
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | | 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) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_divide(INT32 args)
{
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | switch(args)
{
case 0:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | case 1: PIKE_ERROR("`/", "Too few arguments to `/\n", sp, args);
|
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)
{
do_docode(CDR(n),DO_NOT_COPY);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_DIVIDE);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | 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;
INT32 tmp,base;
if(!sp[-1].u.integer)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`%", "Modulo by zero.\n", sp, 2);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | tmp=sp[-1].u.integer;
if(tmp<0)
{
tmp=s->len % -tmp;
base=0;
}else{
tmp=s->len % tmp;
base=s->len - tmp;
}
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | s=make_shared_binary_string(s->str + base, tmp);
pop_n_elems(2);
push_string(s);
return;
}
case TWO_TYPES(T_ARRAY,T_INT):
{
struct array *a=sp[-2].u.array;
INT32 tmp,base;
if(!sp[-1].u.integer)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`%", "Modulo by zero.\n", sp, 2);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | |
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | tmp=sp[-1].u.integer;
if(tmp<0)
{
tmp=a->size % -tmp;
base=0;
}else{
tmp=a->size % tmp;
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)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`%", "Modulo by zero.\n", sp, 2);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | sp--;
foo=sp[-1].u.float_number / sp[0].u.float_number;
foo=sp[-1].u.float_number - sp[0].u.float_number * floor(foo);
sp[-1].u.float_number=foo;
return;
}
case T_INT:
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | if (sp[-1].u.integer == 0) PIKE_ERROR("`%", "Modulo by zero.\n", sp, 2);
|
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) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_mod(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | if(args != 2)
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | PIKE_ERROR("`%", "Bad number of args\n", sp, args);
|
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) | | {
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | do_docode(CDR(n),DO_NOT_COPY);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_MOD);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | 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:
if(IS_ZERO(sp-1))
{
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) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_not(INT32 args)
{
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | if(args != 1) PIKE_ERROR("`!", "Bad number of args.\n", sp, args);
|
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);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_NOT);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | 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;
|
fc0bb5 | 1997-02-13 | Niels Möller | | case T_STRING:
{
struct pike_string *s;
INT32 len, i;
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) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_compl(INT32 args)
{
|
aa366d | 1998-04-16 | Fredrik Hübinette (Hubbe) | | if(args != 1) PIKE_ERROR("`~", "Bad number of args.\n", sp, args);
|
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);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | emit2(F_COMPL);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | return 1;
}
return 0;
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | 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:
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:
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) | | }
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void o_range(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
INT32 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) | |
from=sp[-2].u.integer;
if(from<0) from=0;
to=sp[-1].u.integer;
if(to<from-1) to=from-1;
sp-=2;
switch(sp[-1].type)
{
case T_STRING:
{
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(to>=sp[-1].u.string->len-1)
{
if(from==0) return;
to=sp[-1].u.string->len-1;
if(from>to+1) from=to+1;
}
|
62260a | 1996-11-26 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(from < 0 || (to-from+1) < 0)
fatal("Error in o_range.\n");
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
s=make_shared_binary_string(sp[-1].u.string->str+from,to-from+1);
free_string(sp[-1].u.string);
sp[-1].u.string=s;
break;
}
case T_ARRAY:
{
struct array *a;
if(to>=sp[-1].u.array->size-1)
{
to=sp[-1].u.array->size-1;
if(from>to+1) from=to+1;
}
a=slice_array(sp[-1].u.array,from,to+1);
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) | |
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | | void f_index(INT32 args)
{
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) | | }
}
void f_arrow(INT32 args)
{
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) | | }
}
|
4c573c | 1996-08-03 | Fredrik Hübinette (Hubbe) | | void f_sizeof(INT32 args)
{
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);
}
static int generate_sizeof(node *n)
{
node **arg;
if(count_args(CDR(n)) != 1) return 0;
if(do_docode(CDR(n),DO_NOT_COPY) != 1)
fatal("Count args was wrong in sizeof().\n");
emit2(F_SIZEOF);
return 1;
}
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | static int generate_call_function(node *n)
{
node **arg;
emit2(F_MARK);
do_docode(CDR(n),DO_NOT_COPY);
emit2(F_CALL_FUNCTION);
return 1;
}
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | | struct program *string_assignment_program;
#undef THIS
#define THIS ((struct string_assignment_storage *)(fp->current_storage))
static void f_string_assignment_index(INT32 args)
{
INT32 i;
get_all_args("string[]",args,"%i",&i);
if(i<0) i+=THIS->s->len;
if(i<0)
i+=THIS->s->len;
if(i<0 || i>=THIS->s->len)
error("Index %d is out of range 0 - %d.\n", i, THIS->s->len-1);
else
i=EXTRACT_UCHAR(THIS->s->str + i);
pop_n_elems(args);
push_int(i);
}
static void f_string_assignment_assign_index(INT32 args)
{
INT32 i,j;
union anything *u;
get_all_args("string[]=",args,"%i%i",&i,&j);
if((u=get_pointer_if_this_type(THIS->lval, T_STRING)))
{
free_string(THIS->s);
if(i<0) i+=u->string->len;
if(i<0 || i>=u->string->len)
error("String index out of range %ld\n",(long)i);
u->string=modify_shared_string(u->string,i,j);
copy_shared_string(THIS->s, u->string);
}else{
lvalue_to_svalue_no_free(sp,THIS->lval);
sp++;
if(sp[-1].type != T_STRING) error("string[]= failed.\n");
if(i<0) i+=sp[-1].u.string->len;
if(i<0 || i>=sp[-1].u.string->len)
error("String index out of range %ld\n",(long)i);
sp[-1].u.string=modify_shared_string(sp[-1].u.string,i,j);
assign_lvalue(THIS->lval, sp-1);
pop_stack();
}
pop_n_elems(args);
push_int(j);
}
static void init_string_assignment_storage(struct object *o)
{
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) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void init_operators(void)
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | {
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | | add_efun2("`[]",f_index,
|
0503c3 | 1998-05-25 | Henrik Grubbström (Grubba) | | "function(string,int:int)|function(object,string:mixed)|function(array(0=mixed),int:0)|function(mapping(mixed:1=mixed),mixed:1)|function(multiset,mixed:int)|function(string,int,int:string)|function(array(2=mixed),int,int:array(2))|function(program:mixed)",OPT_TRY_OPTIMIZE,0,0);
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | |
add_efun2("`->",f_arrow,
|
0503c3 | 1998-05-25 | Henrik Grubbström (Grubba) | | "function(array(object|mapping|multiset|array),string:array(mixed))|function(object|mapping|multiset|program,string:mixed)",OPT_TRY_OPTIMIZE,0,0);
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | |
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | add_efun2("`==",f_eq,"function(mixed...:int)",OPT_TRY_OPTIMIZE,optimize_eq,generate_comparison);
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | add_efun2("`!=",f_ne,"function(mixed...:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
|
e10441 | 1998-06-05 | Fredrik Hübinette (Hubbe) | | add_efun2("`!",f_not,"function(mixed:int)",OPT_TRY_OPTIMIZE,optimize_not,generate_not);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | #define CMP_TYPE "!function(!object...:mixed)&function(mixed...:int)|function(int|float...:int)|function(string...:int)"
|
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) | |
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | | add_efun2("`+",f_add,
"!function(!object...:mixed)&function(mixed...:mixed)|"
"function(int...:int)|"
"!function(int...:mixed)&function(int|float...:float)|"
"!function(int|float...:mixed)&function(string|int|float...:string)|"
"function(0=array...:0)|"
"function(mapping(1=mixed:2=mixed)...:mapping(1:2))|"
"function(3=multiset...:3)",
OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
1eaa38 | 1998-03-04 | Fredrik Hübinette (Hubbe) | | add_efun2("`-",f_minus,
"!function(!object...:mixed)&function(mixed...:mixed)|"
"function(int:int)|"
"function(float:float)|"
"function(array(0=mixed),array:array(0))|"
"function(mapping(1=mixed:2=mixed),mapping:mapping(1:2))|"
"function(multiset(3=mixed),multiset:multiset(3))|"
"function(float|int,float:float)|"
"function(float,int:float)|"
"function(int,int:int)|"
"function(string,string:string)",
OPT_TRY_OPTIMIZE,0,generate_minus);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
1eaa38 | 1998-03-04 | Fredrik Hübinette (Hubbe) | | #define LOG_TYPE "function(mixed,object...:mixed)|function(object,mixed...:mixed)|function(int...:int)|function(mapping(0=mixed:1=mixed)...:mapping(0:1))|function(multiset(2=mixed)...:multiset(2))|function(array(3=mixed)...:array(3))|function(string...:string)"
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | add_efun2("`&",f_and,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_and);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | add_efun2("`|",f_or,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_or);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | add_efun2("`^",f_xor,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_xor);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | #define SHIFT_TYPE "function(object,mixed:mixed)|function(mixed,object:mixed)|function(int,int:int)"
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | add_efun2("`<<",f_lsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_lsh);
add_efun2("`>>",f_rsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_rsh);
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | add_efun2("`*",f_multiply,
"!function(!object...:mixed)&function(mixed...:mixed)|"
|
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))|"
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | "function(string,int:string)",
OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply);
add_efun2("`/",f_divide,
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | "!function(!object...:mixed)&function(mixed...:mixed)|"
"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)))|"
|
5b4dd3 | 1998-02-23 | Fredrik Hübinette (Hubbe) | | "function(string,string|int|float...:array(string))",
|
1b6166 | 1998-02-19 | Fredrik Hübinette (Hubbe) | | OPT_TRY_OPTIMIZE,0,generate_divide);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | add_efun2("`%",f_mod,
"function(mixed,object:mixed)|"
"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))|"
|
d429a7 | 1998-02-24 | Fredrik Hübinette (Hubbe) | | "!function(int,int:mixed)&function(int|float,int|float:float)"
,OPT_TRY_OPTIMIZE,0,generate_mod);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
fc0bb5 | 1997-02-13 | Niels Möller | | add_efun2("`~",f_compl,"function(object:mixed)|function(int:int)|function(float:float)|function(string:string)",OPT_TRY_OPTIMIZE,0,generate_compl);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | add_efun2("sizeof", f_sizeof, "function(string|multiset|array|mapping|object:int)",0,0,generate_sizeof);
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | |
add_efun2("`()",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);
add_efun2("call_function",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);
|
19aaeb | 1998-05-25 | Fredrik Hübinette (Hubbe) | |
start_new_program();
add_storage(sizeof(struct string_assignment_storage));
add_function("`[]",f_string_assignment_index,"function(int:int)",0);
add_function("`[]=",f_string_assignment_assign_index,"function(int,int:int)",0);
set_init_callback(init_string_assignment_storage);
set_exit_callback(exit_string_assignment_storage);
string_assignment_program=end_program();
}
void exit_operators()
{
if(string_assignment_program)
{
free_program(string_assignment_program);
string_assignment_program=0;
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
|