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.
75
1999/12/
13
20
:
44
:
15
grubba Exp $");
+
RCSID("$Id: operators.c,v 1.
76
1999/12/
15
00
:
48
:
18
grubba 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"
pike.git/src/operators.c:754:
emit2(F_SUBTRACT); return 1; } return 0; } void o_and(void) { if(sp[-1].type != sp[-2].type) {
-
if(call_lfun(LFUN_AND, LFUN_RAND))
+
if(call_lfun(LFUN_AND, LFUN_RAND))
{
return;
-
{
+
} else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) ||
+
(sp[-1].type == T_FUNCTION)) &&
+
((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) ||
+
(sp[-2].type == T_FUNCTION)))
{
+
if (sp[-2].type != T_TYPE) {
+
struct program *p = program_from_svalue(sp - 2);
+
if (!p) {
int args = 2;
-
+
SIMPLE_BAD_ARG_ERROR("`&", 1, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
free_svalue(sp - 2);
+
sp[-2].u.string = pop_unfinished_type();
+
sp[-2].type = T_TYPE;
+
}
+
if (sp[-1].type != T_TYPE) {
+
struct program *p = program_from_svalue(sp - 1);
+
if (!p) {
+
int args = 2;
+
SIMPLE_BAD_ARG_ERROR("`&", 2, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
free_svalue(sp - 1);
+
sp[-1].u.string = pop_unfinished_type();
+
sp[-1].type = T_TYPE;
+
}
+
} else {
+
int args = 2;
SIMPLE_BAD_ARG_ERROR("`&", 2, get_name_of_type(sp[-2].type)); } } switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_AND,2); break;
pike.git/src/operators.c:810:
case T_TYPE: { struct pike_string *t; t = and_pike_types(sp[-2].u.string, sp[-1].u.string); pop_n_elems(2); push_string(t); sp[-1].type = T_STRING; return; }
+
case T_FUNCTION:
+
case T_PROGRAM:
+
{
+
struct program *p;
+
struct pike_string *a;
+
struct pike_string *b;
+
struct pike_string *t;
+
+
p = program_from_svalue(sp - 2);
+
if (!p) {
+
int args = 2;
+
SIMPLE_BAD_ARG_ERROR("`&", 1, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
a = pop_unfinished_type();
+
+
p = program_from_svalue(sp - 1);
+
if (!p) {
+
int args = 2;
+
SIMPLE_BAD_ARG_ERROR("`&", 2, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
b = pop_unfinished_type();
+
+
t = and_pike_types(a, b);
+
+
pop_n_elems(2);
+
push_string(t);
+
sp[-1].type = T_TYPE;
+
free_string(a);
+
free_string(b);
+
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); \
pike.git/src/operators.c:951:
default: return 0; } } void o_or(void) { if(sp[-1].type != sp[-2].type) {
-
if(call_lfun(LFUN_OR, LFUN_ROR))
+
if(call_lfun(LFUN_OR, LFUN_ROR))
{
return;
-
-
{
+
} else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) ||
+
(sp[-1].type == T_FUNCTION)) &&
+
((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) ||
+
(sp[-2].type == T_FUNCTION)))
{
+
if (sp[-2].type != T_TYPE) {
+
struct program *p = program_from_svalue(sp - 2);
+
if (!p) {
int args = 2;
-
+
SIMPLE_BAD_ARG_ERROR("`|", 1, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
free_svalue(sp - 2);
+
sp[-2].u.string = pop_unfinished_type();
+
sp[-2].type = T_TYPE;
+
}
+
if (sp[-1].type != T_TYPE) {
+
struct program *p = program_from_svalue(sp - 1);
+
if (!p) {
+
int args = 2;
+
SIMPLE_BAD_ARG_ERROR("`|", 2, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
free_svalue(sp - 1);
+
sp[-1].u.string = pop_unfinished_type();
+
sp[-1].type = T_TYPE;
+
}
+
} else {
+
int args = 2;
SIMPLE_BAD_ARG_ERROR("`|", 2, get_name_of_type(sp[-2].type)); } } switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_OR,2); break;
pike.git/src/operators.c:1008:
case T_TYPE: { struct pike_string *t; t = or_pike_types(sp[-2].u.string, sp[-1].u.string, 0); pop_n_elems(2); push_string(t); sp[-1].type = T_TYPE; return; }
+
case T_FUNCTION:
+
case T_PROGRAM:
+
{
+
struct program *p;
+
struct pike_string *a;
+
struct pike_string *b;
+
struct pike_string *t;
+
+
p = program_from_svalue(sp - 2);
+
if (!p) {
+
int args = 2;
+
SIMPLE_BAD_ARG_ERROR("`|", 1, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
a = pop_unfinished_type();
+
+
p = program_from_svalue(sp - 1);
+
if (!p) {
+
int args = 2;
+
SIMPLE_BAD_ARG_ERROR("`|", 2, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
b = pop_unfinished_type();
+
+
t = or_pike_types(a, b, 0);
+
+
pop_n_elems(2);
+
push_string(t);
+
sp[-1].type = T_TYPE;
+
free_string(a);
+
free_string(b);
+
return;
+
}
+
STRING_BITOP(|,"OR") default: PIKE_ERROR("`|", "Bitwise or on illegal type.\n", sp, 2); } } void f_or(INT32 args) { switch(args)
pike.git/src/operators.c:1055:
default: return 0; } } void o_xor(void) { if(sp[-1].type != sp[-2].type) {
-
if(call_lfun(LFUN_XOR, LFUN_RXOR))
+
if(call_lfun(LFUN_XOR, LFUN_RXOR))
{
return;
-
{
+
} else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) ||
+
(sp[-1].type == T_FUNCTION)) &&
+
((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) ||
+
(sp[-2].type == T_FUNCTION)))
{
+
if (sp[-2].type != T_TYPE) {
+
struct program *p = program_from_svalue(sp - 2);
+
if (!p) {
int args = 2;
-
+
SIMPLE_BAD_ARG_ERROR("`^", 1, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
free_svalue(sp - 2);
+
sp[-2].u.string = pop_unfinished_type();
+
sp[-2].type = T_TYPE;
+
}
+
if (sp[-1].type != T_TYPE) {
+
struct program *p = program_from_svalue(sp - 1);
+
if (!p) {
+
int args = 2;
+
SIMPLE_BAD_ARG_ERROR("`^", 2, "type");
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
free_svalue(sp - 1);
+
sp[-1].u.string = pop_unfinished_type();
+
sp[-1].type = T_TYPE;
+
}
+
} else {
+
int args = 2;
SIMPLE_BAD_ARG_ERROR("`^", 2, get_name_of_type(sp[-2].type)); } } switch(sp[-2].type) { case T_OBJECT: CALL_OPERATOR(LFUN_XOR,2); break;
pike.git/src/operators.c:1101:
case T_ARRAY: { struct array *a; a=merge_array_with_order(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_XOR); pop_n_elems(2); push_array(a); return; }
+
case T_FUNCTION:
+
case T_PROGRAM:
+
{
+
struct program *p;
+
+
p = program_from_svalue(sp - 1);
+
if (!p) {
+
int args = 2;
+
SIMPLE_BAD_ARG_ERROR("`^", 2, "type");
+
}
+
type_stack_mark();
+
push_type_int(sp[-1].u.program->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
pop_stack();
+
push_string(pop_unfinished_type());
+
sp[-1].type = T_TYPE;
+
+
stack_swap();
+
+
p = program_from_svalue(sp - 1);
+
if (!p) {
+
int args = 2;
+
stack_swap();
+
SIMPLE_BAD_ARG_ERROR("`^", 1, "type");
+
}
+
type_stack_mark();
+
push_type_int(sp[-1].u.program->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
pop_stack();
+
push_string(pop_unfinished_type());
+
sp[-1].type = T_TYPE;
+
}
+
/* FALL_THROUGH */
case T_TYPE: { /* a ^ b == (a&~b)|(~a&b) */ struct pike_string *a; struct pike_string *b; copy_shared_string(a, sp[-2].u.string); copy_shared_string(b, sp[-1].u.string); o_compl(); /* ~b */ o_and(); /* a&~b */ push_string(a);
pike.git/src/operators.c:1864:
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; case T_TYPE: type_stack_mark();
+
if (EXTRACT_UCHAR(sp[-1].u.string->str) == T_NOT) {
+
push_unfinished_type(sp[-1].u.string->str + 1);
+
} else {
push_unfinished_type(sp[-1].u.string->str); push_type(T_NOT);
-
+
}
pop_stack(); push_string(pop_unfinished_type()); sp[-1].type = T_TYPE; break;
-
+
case T_FUNCTION:
+
case T_PROGRAM:
+
{
+
/* !object(p) */
+
struct program *p = program_from_svalue(sp - 1);
+
if (!p) {
+
PIKE_ERROR("`~", "Bad argument.\n", sp, 1);
+
}
+
type_stack_mark();
+
push_type_int(p->id);
+
push_type(0);
+
push_type(T_OBJECT);
+
push_type(T_NOT);
+
pop_stack();
+
push_string(pop_unfinished_type());
+
sp[-1].type = T_TYPE;
+
}
+
break;
+
case T_STRING: { struct pike_string *s; INT32 len, i; if(sp[-1].u.string->size_shift) { bad_arg_error("`~", sp-1, 1, 1, "string(0)", sp-1, "Expected 8-bit string.\n"); }
pike.git/src/operators.c:2208:
0); /* OPT_ASSIGNMENT|OPT_TRY_OPTIMIZE); ? */ /* function(mixed...:int) */ ADD_EFUN2("`==",f_eq,tFuncV(tNone,tMix,tInt01),OPT_TRY_OPTIMIZE,optimize_eq,generate_comparison); /* function(mixed...:int) */ ADD_EFUN2("`!=",f_ne,tFuncV(tNone,tMix,tInt01),OPT_TRY_OPTIMIZE,0,generate_comparison); /* function(mixed:int) */ add_efun2("`!",f_not,"function(mixed:int(0..1))",OPT_TRY_OPTIMIZE, optimize_not,generate_not);
-
#define CMP_TYPE "!function(!(object|mixed)...:mixed)&function(mixed...:int(0..1))|function(int|float...:int(0..1))|function(string...:int(0..1))|function(type,type,type...:int(0..1))"
+
#define CMP_TYPE "!function(!(object|mixed)...:mixed)&function(mixed...:int(0..1))|function(int|float...:int(0..1))|function(string...:int(0..1))|function(type
|program
,type
|program
,type
|program
...:int(0..1))"
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); ADD_EFUN2("`+",f_add, tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction), tFuncV(tInt,tInt,tInt), tIfnot(tFuncV(tInt,tInt,tMix), tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)),
pike.git/src/operators.c:2242:
tFuncV(tInt,tInt,tInt), tIfnot(tFuncV(tInt,tInt,tMix), tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)), tFuncV(tArr(tSetvar(0,tMix)),tArray,tArr(tVar(0))), tFuncV(tMap(tSetvar(1,tMix),tSetvar(2,tMix)), tMapping,tMap(tVar(1),tVar(2))), tFunc(tSet(tSetvar(3,tMix)) tMultiset,tSet(tVar(3))), tFuncV(tStr,tStr,tStr)), OPT_TRY_OPTIMIZE,0,generate_minus);
-
#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)|function(type,type...:type)"
+
#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)|function(type
|program
,type
|program
...:type)"
add_efun2("`&",f_and,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_and); add_efun2("`|",f_or,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_or); add_efun2("`^",f_xor,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_xor); #define SHIFT_TYPE "function(object,mixed:mixed)|function(mixed,object:mixed)|function(int,int:int)" add_efun2("`<<",f_lsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_lsh);
pike.git/src/operators.c:2297:
"!function(int,int:mixed)&function(int|float,int|float:float) */ ADD_EFUN2("`%",f_mod,tOr6(tFunc(tMix tObj,tMix),tFunc(tObj tMix,tMix),tFunc(tInt tInt,tInt),tFunc(tStr tInt,tStr),tFunc(tArr(tSetvar(0,tMix)) tInt,tArr(tVar(0))),tIfnot(tFunc(tInt tInt,tMix),tFunc(tOr(tInt,tFlt) tOr(tInt,tFlt),tFlt))), OPT_TRY_OPTIMIZE,0,generate_mod); /* function(object:mixed)|function(int:int)|function(float:float)|function(string:string) */ ADD_EFUN2("`~",f_compl, tOr5(tFunc(tObj,tMix), tFunc(tInt,tInt), tFunc(tFlt,tFlt), tFunc(tStr,tStr),
-
tFunc(tType,tType)),
+
tFunc(
tOr(
tType,
tProgram),
tType)),
OPT_TRY_OPTIMIZE,0,generate_compl); /* function(string|multiset|array|mapping|object:int) */ ADD_EFUN2("sizeof", f_sizeof,tFunc(tOr5(tStr,tMultiset,tArray,tMapping,tObj),tInt),0,0,generate_sizeof); /* function(mixed,mixed ...:mixed) */ ADD_EFUN2("`()",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function); /* This one should be removed */ /* function(mixed,mixed ...:mixed) */ ADD_EFUN2("call_function",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);