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"
|
4fd947 | 1997-07-09 | Fredrik Hübinette (Hubbe) | | RCSID("$Id: operators.c,v 1.14.2.1 1997/07/09 07:45:01 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"
#include "memory.h"
#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"
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
#define COMPARISON(ID,NAME,EXPR) \
void ID(INT32 args) \
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | { \
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | int i; \
if(args > 2) \
pop_n_elems(args-2); \
else if(args < 2) \
error("Too few arguments to %s\n",NAME); \
i=EXPR; \
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(2); \
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | push_int(i); \
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
COMPARISON(f_eq,"`==", is_eq(sp-2,sp-1))
COMPARISON(f_ne,"`!=",!is_eq(sp-2,sp-1))
COMPARISON(f_lt,"`<" , is_lt(sp-2,sp-1))
COMPARISON(f_le,"`<=",!is_gt(sp-2,sp-1))
COMPARISON(f_gt,"`>" , is_gt(sp-2,sp-1))
COMPARISON(f_ge,"`>=",!is_lt(sp-2,sp-1))
|
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) \
error("Operator %s called in destructed object.\n",lfun_names[OP]); \
if(sp[-args].u.object->prog->lfuns[OP] == -1) \
error("No operator %s in object.\n",lfun_names[OP]); \
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) | | {
INT32 e,size;
TYPE_FIELD types;
types=0;
for(e=-args;e<0;e++) types|=1<<sp[e].type;
switch(types)
{
default:
if(args)
{
switch(sp[-args].type)
{
case T_OBJECT:
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | CALL_OPERATOR(LFUN_ADD,args);
return;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_PROGRAM:
case T_FUNCTION:
error("Bad argument 1 to summation\n");
}
}
error("Incompatible types to sum() or +\n");
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;
}
}
|
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;
}
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | static int float_promote()
{
if(sp[-2].type==T_INT)
{
sp[-2].u.float_number=(FLOAT_TYPE)sp[-2].u.integer;
sp[-2].type=T_FLOAT;
}
if(sp[-1].type==T_INT)
{
sp[-1].u.float_number=(FLOAT_TYPE)sp[-1].u.integer;
sp[-1].type=T_FLOAT;
}
return sp[-2].type == sp[-1].type;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void o_subtract()
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if (sp[-2].type != sp[-1].type &&
!float_promote() &&
sp[-2].type != T_OBJECT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | error("Subtract on different types.\n");
|
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:
error("Bad argument 1 to subtraction.\n");
}
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_minus(INT32 args)
{
switch(args)
{
case 0: error("Too few arguments to `-\n");
case 1: o_negate(); break;
case 2: o_subtract(); break;
default: error("Too many arguments to `-\n");
}
}
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;
}
void o_and()
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != sp[-2].type &&
sp[-2].type != T_OBJECT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | error("Bitwise and on different types.\n");
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)
error("Bitwise AND on strings of different lengths.\n");
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:
error("Bitwise and on illegal type.\n");
}
}
|
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)
{
case 0: error("Too few arguments to `&\n");
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;
}
}
void o_or()
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != sp[-2].type &&
sp[-2].type != T_OBJECT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | error("Bitwise or on different types.\n");
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)
error("Bitwise OR on strings of different lengths.\n");
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:
error("Bitwise or on illegal type.\n");
}
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_or(INT32 args)
{
switch(args)
{
case 0: error("Too few arguments to `|\n");
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;
}
}
void o_xor()
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != sp[-2].type &&
sp[-2].type != T_OBJECT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | error("Bitwise xor on different types.\n");
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)
error("Bitwise XOR on strings of different lengths.\n");
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:
error("Bitwise xor on illegal type.\n");
}
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_xor(INT32 args)
{
switch(args)
{
case 0: error("Too few arguments to `^\n");
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;
}
}
void o_lsh()
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != T_INT)
{
if(sp[-2].type == T_OBJECT)
{
CALL_OPERATOR(LFUN_LSH,2);
return;
}
error("Bad argument 1 to <<\n");
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != T_INT) error("Bad argument 2 to <<\n");
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)
error("Bad number of args to `<<\n");
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;
}
void o_rsh()
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != T_INT)
{
if(sp[-2].type == T_OBJECT)
{
CALL_OPERATOR(LFUN_RSH,2);
return;
}
error("Bad argument 1 to >>\n");
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(sp[-1].type != T_INT) error("Bad argument 2 to >>\n");
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)
error("Bad number of args to `>>\n");
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))
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void o_multiply()
|
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) | | {
|
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);
break;
}
|
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:
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type == T_OBJECT)
{
CALL_OPERATOR(LFUN_MULTIPLY,2);
return;
}
|
bce86c | 1996-02-25 | Fredrik Hübinette (Hubbe) | | error("Bad arguments to multiply.\n");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_multiply(INT32 args)
{
switch(args)
{
case 0: error("Too few arguments to `*\n");
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) | | }
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void o_divide()
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type!=sp[-1].type &&
!float_promote() &&
sp[-2].type != T_OBJECT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | error("Division on different types.\n");
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)
error("Division by zero.\n");
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)
error("Division by zero\n");
sp--;
|
806a2c | 1997-04-28 | Fredrik Hübinette (Hubbe) | |
tmp=sp[-1].u.integer / sp[0].u.integer;
if(tmp<0)
if(tmp * sp[0].u.integer > sp[-1].u.integer)
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:
error("Bad argument 1 to divide.\n");
}
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_divide(INT32 args)
{
if(args != 2)
error("Bad number of args to `/\n");
o_divide();
}
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;
}
void o_mod()
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != sp[-1].type &&
!float_promote() &&
sp[-2].type != T_OBJECT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | error("Modulo on different types.\n");
|
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)
error("Modulo by zero.\n");
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:
if (sp[-1].u.integer == 0) error("Modulo by zero.\n");
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{
sp[-1].u.integer=sp[0].u.integer+(sp[-1].u.integer % -sp[0].u.integer);
}
}else{
if(sp[0].u.integer>=0)
{
sp[-1].u.integer=sp[0].u.integer-(-sp[-1].u.integer % sp[0].u.integer);
}else{
sp[-1].u.integer=-(-sp[-1].u.integer % -sp[0].u.integer);
}
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return;
default:
error("Bad argument 1 to modulo.\n");
}
}
|
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)
error("Bad number of args to `%%\n");
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;
}
void o_not()
|
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)
{
if(args != 1) error("Bad number of args to `!\n");
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) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void o_compl()
|
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:
error("Bad argument to ~\n");
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void f_compl(INT32 args)
{
if(args != 1) error("Bad number of args to `~\n");
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;
}
void o_negate()
|
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:
error("Bad argument to unary minus\n");
}
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void o_range()
|
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)
{
CALL_OPERATOR(LFUN_INDEX, 2);
return;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(sp[-2].type != T_INT)
error("Bad argument 1 to [ .. ]\n");
if(sp[-1].type != T_INT)
error("Bad argument 2 to [ .. ]\n");
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:
|
85f019 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | error("[ .. ] on non-scalar type.\n");
|
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:
error("Too few arguments to `[]\n");
break;
case 2:
if(sp[-1].type==T_STRING) sp[-1].subtype=0;
o_index();
break;
case 3:
o_range();
break;
default:
|
24697f | 1997-03-12 | Henrik Grubbström (Grubba) | | error("Too many arguments to `[]\n");
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | | }
}
void f_arrow(INT32 args)
{
switch(args)
{
case 0:
case 1:
error("Too few arguments to `->\n");
break;
case 2:
if(sp[-1].type==T_STRING)
sp[-1].subtype=1;
o_index();
break;
default:
|
24697f | 1997-03-12 | Henrik Grubbström (Grubba) | | error("Too many arguments to `->\n");
|
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)
error("Too few arguments to sizeof()\n");
|
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;
}
|
4fd947 | 1997-07-09 | Fredrik Hübinette (Hubbe) | | void f_call_function(INT32 args)
{
mega_apply(APPLY_STACK,args,0,0);
}
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;
}
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | void init_operators()
{
|
9f6847 | 1997-03-08 | Fredrik Hübinette (Hubbe) | | add_efun2("`[]",f_index,
"function(string,int:int)|function(object,string:mixed)|function(array,int:mixed)|function(mapping,mixed:mixed)|function(multiset,mixed:int)|function(string,int,int:string)|function(array,int,int:array)",OPT_TRY_OPTIMIZE,0,0);
add_efun2("`->",f_arrow,
"function(object|mapping|multiset,string:mixed)",OPT_TRY_OPTIMIZE,0,0);
|
8a630c | 1996-04-13 | Fredrik Hübinette (Hubbe) | | add_efun2("`==",f_eq,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
add_efun2("`!=",f_ne,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | add_efun2("`!",f_not,"function(mixed:int)",OPT_TRY_OPTIMIZE,0,generate_not);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | #define CMP_TYPE "function(object,mixed:int)|function(mixed,object:int)|function(int|float,int|float:int)|function(string,string:int)"
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) | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | add_efun2("`+",f_add,"function(object,mixed...:mixed)|function(int...:int)|!function(int...:mixed)&function(int|float...:float)|!function(int|float...:mixed)&function(string|int|float...:string)|function(array...:array)|function(mapping...:mapping)|function(multiset...:multiset)",OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | add_efun2("`-",f_minus,"function(object,mixed...:mixed)|function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(multiset,multiset:multiset)|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) | |
|
fc0bb5 | 1997-02-13 | Niels Möller | | #define LOG_TYPE "function(object,mixed...:mixed)|function(int...:int)|function(mapping...:mapping)|function(multiset...:multiset)|function(array...:array)|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) | |
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | #define SHIFT_TYPE "function(object,mixed: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);
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | add_efun2("`*",f_multiply,"function(array(array),array:array)|function(object,mixed...:mixed)|function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | add_efun2("`/",f_divide,"function(array,array:array(array))|function(object,mixed:mixed)|function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",OPT_TRY_OPTIMIZE,0,generate_divide);
|
07c073 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
add_efun2("`%",f_mod,"function(object,mixed:mixed)|function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",OPT_TRY_OPTIMIZE,0,generate_mod);
|
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);
|
4fd947 | 1997-07-09 | 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);
|
7bd0ea | 1996-02-19 | Fredrik Hübinette (Hubbe) | | }
|
4fd947 | 1997-07-09 | Fredrik Hübinette (Hubbe) | |
|