pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:1:
/*\ ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License) ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" #include <math.h>
-
RCSID("$Id: operators.c,v 1.
42
1998/10/
12
22
:
55
:
10
hubbe Exp $");
+
RCSID("$Id: operators.c,v 1.
43
1998/10/
14
05
:
48
:
45
hubbe Exp $");
#include "interpret.h" #include "svalue.h" #include "multiset.h" #include "mapping.h" #include "array.h" #include "stralloc.h" #include "opcodes.h" #include "operators.h" #include "language.h" #include "pike_memory.h" #include "error.h" #include "docode.h" #include "constants.h" #include "peep.h" #include "lex.h" #include "program.h" #include "object.h" #include "pike_types.h" #include "module_support.h"
-
+
#include "pike_macros.h"
#define COMPARISON(ID,NAME,FUN) \ void ID(INT32 args) \ { \ int i; \ switch(args) \ { \ case 0: case 1: \ PIKE_ERROR(NAME, "Too few arguments\n", sp, args); \ case 2: \
pike.git/src/operators.c:132:
case T_PROGRAM: case T_FUNCTION: PIKE_ERROR("`+", "Bad argument 1\n", sp, args); } PIKE_ERROR("`+", "Incompatible types\n", sp, args); return; /* compiler hint */ case BIT_STRING: { struct pike_string *r;
-
char
*
buf;
+
PCHARP
buf;
INT32 tmp; int max_shift=0; if(args==1) return; size=0; for(e=-args;e<0;e++) { size+=sp[e].u.string->len; if(sp[e].u.string->size_shift > max_shift) max_shift=sp[e].u.string->size_shift; } tmp=sp[-args].u.string->len; r=new_realloc_shared_string(sp[-args].u.string,size,max_shift); sp[-args].type=T_INT;
-
buf=
r->str+
(tmp
<<max_shift
);
+
buf=
MKPCHARP_STR_OFF(
r
,
tmp);
for(e=-args+1;e<0;e++) {
-
pike_string_cpy(buf,
max_shift,
sp[e].u.string);
-
buf+=
sp[e].u.string->len
<< max_shift
;
+
pike_string_cpy(buf,sp[e].u.string);
+
INC_PCHARP(buf,
sp[e].u.string->len
)
;
} 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; break; } case BIT_STRING | BIT_INT: case BIT_STRING | BIT_FLOAT: case BIT_STRING | BIT_FLOAT | BIT_INT: { struct pike_string *r;
-
char
*
buf;
+
PCHARP
buf;
char buffer[50]; int max_shift=0; size=0; for(e=-args;e<0;e++) { switch(sp[e].type) { case T_STRING: size+=sp[e].u.string->len; if(sp[e].u.string->size_shift > max_shift)
pike.git/src/operators.c:193:
size+=14; break; case T_FLOAT: size+=22; break; } } r=begin_wide_shared_string(size,max_shift);
-
buf=r
->str
;
+
buf=
MKPCHARP_STR(
r
)
;
size=0; for(e=-args;e<0;e++) { switch(sp[e].type) { case T_STRING:
-
pike_string_cpy(buf,
max_shift,
sp[e].u.string);
-
buf+=
sp[e].u.string->len
<<max_shift
;
+
pike_string_cpy(buf,sp[e].u.string);
+
INC_PCHARP(buf,
sp[e].u.string->len
)
;
break; case T_INT: sprintf(buffer,"%ld",(long)sp[e].u.integer); goto append_buffer; case T_FLOAT: sprintf(buffer,"%f",(double)sp[e].u.float_number); append_buffer: switch(max_shift) {
-
case 0: convert_0_to_0((p_wchar0 *)buf,buffer,strlen(buffer)); break;
-
case 1: convert_0_to_1((p_wchar1 *)buf,buffer,strlen(buffer)); break;
-
case 2: convert_0_to_2((p_wchar2 *)buf,buffer,strlen(buffer)); break;
+
case 0:
+
convert_0_to_0((p_wchar0 *)buf
.ptr
,buffer,strlen(buffer));
+
break;
+
+
case 1:
+
convert_0_to_1((p_wchar1 *)buf
.ptr
,buffer,strlen(buffer));
+
break;
+
+
case 2:
+
convert_0_to_2((p_wchar2 *)buf
.ptr
,buffer,strlen(buffer));
+
break;
+
}
-
buf+=
strlen(buffer)
<<max_shift
;
+
INC_PCHARP(buf,
strlen(buffer)
)
;
} }
-
r->len=(buf
-
r
->str
)
>>max_shift
;
+
r->len=
SUBTRACT_PCHARP
(buf
,MKPCHARP_STR(
r)
)
;
low_set_index(r,r->len,0); r=end_shared_string(r); pop_n_elems(args); push_string(r); break; } case BIT_INT: size=0; for(e=-args; e<0; e++) size+=sp[e].u.integer;
pike.git/src/operators.c:664:
} 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; }
-
case T_STRING:
-
{
-
struct pike_string *s;
-
INT32 len, i;
+
-
len = sp[-2].u.string->len;
-
if (len != sp[-1].u.string->len)
-
PIKE_ERROR("`
&
", "Bitwise
AND
on strings of different lengths.\n", sp, 2);
-
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;
+
#define
STRING_BITOP(OP,STROP)
\
+
case T_STRING: \
+
{ \
+
struct pike_string *s; \
+
INT32
len
,
i; \
+
\
+
len
= sp[-2].u.string->len;
\
+
if (len != sp[-1].u.string->len)
\
+
PIKE_ERROR("`"
#OP
, "Bitwise
"STROP
\
+
"
on strings of different lengths.\n", sp, 2);
\
+
if(!sp[-2].u.string->size_shift && !sp[-1].u.string->size_shift) \
+
{ \
+
s = begin_shared_string(len);
\
+
for (i=0; i<len; i++)
\
+
s->str[i] = sp[-2].u.string->str[i]
OP
sp[-1].u.string->str[i];
\
+
}else{ \
+
s = begin_wide_shared_string(len, \
+
MAXIMUM(sp[-2].u.string->size_shift, \
+
sp[-1].u.string->size_shift)); \
+
for (i=0; i<len; i++) \
+
low_set_index(s,i,index_shared_string(sp[-2].u.string,i) OP \
+
index_shared_string(sp[-1].u.string,i)); \
+
} \
+
pop_n_elems(2);
\
+
push_string(end_shared_string(s));
\
+
return;
\
}
-
+
+
STRING_BITOP(&,"AND")
+
default: PIKE_ERROR("`&", "Bitwise and on illegal type.\n", sp, 2); } } /* This function is used to speed up or/xor/and on * arrays multisets and mappings. This is done by * calling the operator for each pair of arguments * first, then recursively doing the same on the * results until only one value remains.
pike.git/src/operators.c:830:
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; }
-
case T_
STRING
:
-
{
-
struct pike
_
string *s;
-
INT32 len
,
i;
+
STRING_
BITOP(|
,
"OR")
-
len = sp[-2].u.string->len;
-
if (len != sp[-1].u.string->len)
-
PIKE_ERROR("`|", "Bitwise OR on strings of different lengths.\n", sp, 2);
-
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;
-
}
-
+
default: PIKE_ERROR("`|", "Bitwise or on illegal type.\n", sp, 2); } } void f_or(INT32 args) { switch(args) { case 0: PIKE_ERROR("`|", "Too few arguments.\n", sp, 0);
pike.git/src/operators.c:934:
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; }
-
case T_
STRING
:
-
{
-
struct pike
_
string *s;
-
INT32 len
,
i;
+
STRING_
BITOP(^
,
"XOR")
-
len = sp[-2].u.string->len;
-
if (len != sp[-1].u.string->len)
-
PIKE_ERROR("`^", "Bitwise XOR on strings of different lengths.\n", sp, 2);
-
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;
-
}
-
+
default: PIKE_ERROR("`^", "Bitwise XOR on illegal type.\n", sp, 2); } } void f_xor(INT32 args) { switch(args) { case 0: PIKE_ERROR("`^", "Too few arguments.\n", sp, 0);
pike.git/src/operators.c:1084:
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;
+
INT32 e
,len
;
if(sp[-1].u.integer < 0) PIKE_ERROR("`*", "Cannot multiply string by negative number.\n", sp, 2);
-
ret=begin_shared_string(sp[-2].u.string->len * sp[-1].u.integer);
+
ret=begin_
wide_
shared_string(sp[-2].u.string->len * sp[-1].u.integer
,
+
sp[-2].u.string->size_shift
);
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);
+
len=sp[-2].u.string->len << sp[-2].u.string->size_shift;
+
for(e=0;e<sp[-1].u.integer;e++,pos+=len)
+
MEMCPY(pos,sp[-2].u.string->str,len);
pop_n_elems(2);
-
push_string(end_shared_string(ret));
+
push_string(
low_
end_shared_string(ret));
return; } case TWO_TYPES(T_ARRAY,T_STRING): { struct pike_string *ret; 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;
pike.git/src/operators.c:1194:
if(sp[-2].type!=sp[-1].type && !float_promote()) { if(call_lfun(LFUN_DIVIDE, LFUN_RDIVIDE)) return; 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;
+
INT32 size,e,len
,pos=0
;
len=sp[-1].u.integer; if(!len) PIKE_ERROR("`/", "Division by zero.\n", sp, 2); if(len<0) { len=-len; size=sp[-2].u.string->len / len; pos+=sp[-2].u.string->len % len; }else{ size=sp[-2].u.string->len / len; } a=allocate_array(size); for(e=0;e<size;e++) {
-
a->item[e].u.string=
make_shared_binary_
string(pos,len);
+
a->item[e].u.string=
string
_
slice(sp[-2].u.
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):
pike.git/src/operators.c:1241:
if(len<0) { len=-len; size=(INT32)ceil( ((double)sp[-2].u.string->len) / len); a=allocate_array(size); for(last=sp[-2].u.string->len,e=0;e<size-1;e++) { pos=sp[-2].u.string->len - (INT32)((e+1)*len);
-
a->item[size-1-e].u.string=
make_shared_binary_
string(
-
sp[-2].u.string->str
+
pos,
+
a->item[size-1-e].u.string=
string
_
slice(sp[-2].u.
string
,
+
pos,
last-pos); a->item[size-1-e].type=T_STRING; last=pos; } pos=0;
-
a->item[0].u.string=
make_shared_binary_
string(
-
sp[-2].u.string->str
+
pos,
+
a->item[0].u.string=
string
_
slice(sp[-2].u.
string
,
+
pos,
last-pos); a->item[0].type=T_STRING; }else{ size=(INT32)ceil( ((double)sp[-2].u.string->len) / len); a=allocate_array(size); for(last=0,e=0;e<size-1;e++) { pos=(INT32)((e+1)*len);
-
a->item[e].u.string=
make_shared_binary_
string(
-
sp[-2].u.string->str
+
last,
+
a->item[e].u.string=
string
_
slice(sp[-2].u.
string
,
+
last,
pos-last); a->item[e].type=T_STRING; last=pos; } pos=sp[-2].u.string->len;
-
a->item[e].u.string=
make_shared_binary_
string(
-
sp[-2].u.string->str
+
last,
+
a->item[e].u.string=
string
_
slice(sp[-2].u.
string
,
+
last,
pos-last); a->item[e].type=T_STRING; } a->type_field=BIT_STRING; pop_n_elems(2); push_array(a); return; }
pike.git/src/operators.c:1482:
tmp=sp[-1].u.integer; if(tmp<0) { tmp=s->len % -tmp; base=0; }else{ tmp=s->len % tmp; base=s->len - tmp; }
-
s=
make_shared_binary_
string(s
->str
+
base, tmp);
+
s=
string
_
slice
(s
,
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;
pike.git/src/operators.c:1642:
case T_FLOAT: sp[-1].u.float_number = -1.0 - sp[-1].u.float_number; break; case T_STRING: { struct pike_string *s; INT32 len, i;
+
if(sp[-1].u.string->size_shift)
+
error("`~ cannot handle wide strings.\n");
+
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; } default: