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.92 2000/05/01 03:33:47 hubbe Exp $");
+ RCSID("$Id: operators.c,v 1.93 2000/07/28 17:16:55 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"
pike.git/src/operators.c:29:
#include "pike_macros.h"
#include "bignum.h"
#include "builtin_functions.h"
#define OP_DIVISION_BY_ZERO_ERROR(FUNC) \
math_error(FUNC, sp-2, 2, 0, "Division by zero.\n")
#define OP_MODULO_BY_ZERO_ERROR(FUNC) \
math_error(FUNC, sp-2, 2, 0, "Modulo by zero.\n")
#define COMPARISON(ID,NAME,FUN) \
- void ID(INT32 args) \
+ PMOD_EXPORT void ID(INT32 args) \
{ \
int i; \
switch(args) \
{ \
case 0: case 1: \
SIMPLE_TOO_FEW_ARGS_ERROR(NAME, 2); \
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); \
} \
}
- void f_ne(INT32 args)
+ PMOD_EXPORT 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)
pike.git/src/operators.c:76:
"Called in destructed object.\n"); \
if(FIND_LFUN(sp[-args].u.object->prog,OP) == -1) \
bad_arg_error(lfun_names[OP], sp-args, args, 1, "object", sp-args, \
"Operator not in object.\n"); \
apply_lfun(sp[-args].u.object, OP, args-1); \
free_svalue(sp-2); \
sp[-2]=sp[-1]; \
sp--; \
dmalloc_touch_svalue(sp);
- void f_add(INT32 args)
+ PMOD_EXPORT void f_add(INT32 args)
{
INT_TYPE e,size;
TYPE_FIELD types;
types=0;
for(e=-args;e<0;e++) types|=1<<sp[e].type;
switch(types)
{
default:
pike.git/src/operators.c:681:
}
return 0;
}
struct mapping *merge_mapping_array_ordered(struct mapping *a,
struct array *b, INT32 op);
struct mapping *merge_mapping_array_unordered(struct mapping *a,
struct array *b, INT32 op);
- void o_subtract(void)
+ PMOD_EXPORT void o_subtract(void)
{
if (sp[-2].type != sp[-1].type && !float_promote())
{
if(call_lfun(LFUN_SUBTRACT, LFUN_RSUBTRACT))
return;
if (sp[-2].type==T_MAPPING)
switch (sp[-1].type)
{
case T_ARRAY:
pike.git/src/operators.c:795:
default:
{
int args = 2;
SIMPLE_BAD_ARG_ERROR("`-", 1,
"int|float|string|mapping|multiset|array|object");
}
}
}
- void f_minus(INT32 args)
+ PMOD_EXPORT void f_minus(INT32 args)
{
switch(args)
{
case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`-", 1);
case 1: o_negate(); break;
case 2: o_subtract(); break;
default:
{
INT32 e;
struct svalue *s=sp-args;
pike.git/src/operators.c:835:
return 1;
case 2:
do_docode(CDR(n),DO_NOT_COPY);
emit0(F_SUBTRACT);
return 1;
}
return 0;
}
- void o_and(void)
+ PMOD_EXPORT void o_and(void)
{
if(sp[-1].type != sp[-2].type)
{
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)))
{
pike.git/src/operators.c:1101:
case T_ARRAY:
case T_MAPPING:
r_speedup(args,func);
return;
default:
while(--args > 0) func();
}
}
- void f_and(INT32 args)
+ PMOD_EXPORT void f_and(INT32 args)
{
switch(args)
{
case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`&", 1);
case 1: return;
case 2: o_and(); return;
default:
if(sp[-args].type == T_OBJECT)
{
CALL_OPERATOR(LFUN_AND, args);
pike.git/src/operators.c:1136:
case 2:
do_docode(CDR(n),0);
emit0(F_AND);
return 1;
default:
return 0;
}
}
- void o_or(void)
+ PMOD_EXPORT void o_or(void)
{
if(sp[-1].type != sp[-2].type)
{
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) {
pike.git/src/operators.c:1275:
return;
}
STRING_BITOP(|,"OR")
default:
PIKE_ERROR("`|", "Bitwise or on illegal type.\n", sp, 2);
}
}
- void f_or(INT32 args)
+ PMOD_EXPORT void f_or(INT32 args)
{
switch(args)
{
case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`|", 1);
case 1: return;
case 2: o_or(); return;
default:
if(sp[-args].type==T_OBJECT)
{
CALL_OPERATOR(LFUN_OR, args);
pike.git/src/operators.c:1311:
do_docode(CDR(n),0);
emit0(F_OR);
return 1;
default:
return 0;
}
}
- void o_xor(void)
+ PMOD_EXPORT void o_xor(void)
{
if(sp[-1].type != sp[-2].type)
{
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) {
pike.git/src/operators.c:1454:
return;
}
STRING_BITOP(^,"XOR")
default:
PIKE_ERROR("`^", "Bitwise XOR on illegal type.\n", sp, 2);
}
}
- void f_xor(INT32 args)
+ PMOD_EXPORT void f_xor(INT32 args)
{
switch(args)
{
case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`^", 1);
case 1: return;
case 2: o_xor(); return;
default:
if(sp[-args].type==T_OBJECT)
{
CALL_OPERATOR(LFUN_XOR, args);
pike.git/src/operators.c:1489:
case 2:
do_docode(CDR(n),0);
emit0(F_XOR);
return 1;
default:
return 0;
}
}
- void o_lsh(void)
+ PMOD_EXPORT void o_lsh(void)
{
#ifdef AUTO_BIGNUM
if(INT_TYPE_LSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
convert_stack_top_to_bignum();
#endif /* AUTO_BIGNUM */
if(sp[-1].type != T_INT || sp[-2].type != T_INT)
{
int args = 2;
if(call_lfun(LFUN_LSH, LFUN_RLSH))
return;
if(sp[-2].type != T_INT)
SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|object");
SIMPLE_BAD_ARG_ERROR("`<<", 2, "int|object");
}
sp--;
sp[-1].u.integer = sp[-1].u.integer << sp->u.integer;
}
- void f_lsh(INT32 args)
+ PMOD_EXPORT void f_lsh(INT32 args)
{
if(args != 2) {
/* FIXME: Not appropriate if too many args. */
SIMPLE_TOO_FEW_ARGS_ERROR("`<<", 2);
}
o_lsh();
}
static int generate_lsh(node *n)
{
if(count_args(CDR(n))==2)
{
do_docode(CDR(n),DO_NOT_COPY);
emit0(F_LSH);
return 1;
}
return 0;
}
- void o_rsh(void)
+ PMOD_EXPORT void o_rsh(void)
{
if(sp[-2].type != T_INT || sp[-1].type != T_INT)
{
int args = 2;
if(call_lfun(LFUN_RSH, LFUN_RRSH))
return;
if(sp[-2].type != T_INT)
SIMPLE_BAD_ARG_ERROR("`>>", 1, "int|object");
SIMPLE_BAD_ARG_ERROR("`>>", 2, "int|object");
}
pike.git/src/operators.c:1555: Inside #if defined(AUTO_BIGNUM)
sp--;
sp[-1].u.integer = 0;
return;
}
#endif /* AUTO_BIGNUM */
sp--;
sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer;
}
- void f_rsh(INT32 args)
+ PMOD_EXPORT void f_rsh(INT32 args)
{
if(args != 2) {
/* FIXME: Not appropriate if too many args. */
SIMPLE_TOO_FEW_ARGS_ERROR("`>>", 2);
}
o_rsh();
}
static int generate_rsh(node *n)
{
pike.git/src/operators.c:1577:
{
do_docode(CDR(n),DO_NOT_COPY);
emit0(F_RSH);
return 1;
}
return 0;
}
#define TWO_TYPES(X,Y) (((X)<<8)|(Y))
- void o_multiply(void)
+ PMOD_EXPORT void o_multiply(void)
{
int args = 2;
switch(TWO_TYPES(sp[-2].type,sp[-1].type))
{
case TWO_TYPES(T_ARRAY, T_INT):
{
struct array *ret;
struct svalue *pos;
INT32 e;
if(sp[-1].u.integer < 0)
pike.git/src/operators.c:1678:
default:
do_lfun_multiply:
if(call_lfun(LFUN_MULTIPLY, LFUN_RMULTIPLY))
return;
PIKE_ERROR("`*", "Bad arguments.\n", sp, 2);
}
}
- void f_multiply(INT32 args)
+ PMOD_EXPORT void f_multiply(INT32 args)
{
switch(args)
{
case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`*", 1);
case 1: return;
case 2: o_multiply(); return;
default:
if(sp[-args].type==T_OBJECT)
{
CALL_OPERATOR(LFUN_MULTIPLY, args);
pike.git/src/operators.c:1713:
case 2:
do_docode(CDR(n),0);
emit0(F_MULTIPLY);
return 1;
default:
return 0;
}
}
- void o_divide(void)
+ PMOD_EXPORT void o_divide(void)
{
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):
{
pike.git/src/operators.c:1969:
tmp--;
sp[-1].u.integer=tmp;
return;
}
default:
PIKE_ERROR("`/", "Bad argument 1.\n", sp, 2);
}
}
- void f_divide(INT32 args)
+ PMOD_EXPORT void f_divide(INT32 args)
{
switch(args)
{
case 0:
case 1: SIMPLE_TOO_FEW_ARGS_ERROR("`/", 2);
case 2: o_divide(); break;
default:
{
INT32 e;
struct svalue *s=sp-args;
pike.git/src/operators.c:2003:
{
if(count_args(CDR(n))==2)
{
do_docode(CDR(n),DO_NOT_COPY);
emit0(F_DIVIDE);
return 1;
}
return 0;
}
- void o_mod(void)
+ PMOD_EXPORT void o_mod(void)
{
if(sp[-2].type != sp[-1].type && !float_promote())
{
if(call_lfun(LFUN_MOD, LFUN_RMOD))
return;
switch(TWO_TYPES(sp[-2].type,sp[-1].type))
{
case TWO_TYPES(T_STRING,T_INT):
{
pike.git/src/operators.c:2106:
sp[-1].u.integer=-(-sp[-1].u.integer % -sp[0].u.integer);
}
}
return;
default:
PIKE_ERROR("`%", "Bad argument 1.\n", sp, 2);
}
}
- void f_mod(INT32 args)
+ PMOD_EXPORT void f_mod(INT32 args)
{
if(args != 2) {
/* FIXME: Not appropriate when too many args. */
SIMPLE_TOO_FEW_ARGS_ERROR("`%", 2);
}
o_mod();
}
static int generate_mod(node *n)
{
if(count_args(CDR(n))==2)
{
do_docode(CDR(n),DO_NOT_COPY);
emit0(F_MOD);
return 1;
}
return 0;
}
- void o_not(void)
+ PMOD_EXPORT void o_not(void)
{
switch(sp[-1].type)
{
case T_INT:
sp[-1].u.integer = !sp[-1].u.integer;
break;
case T_FUNCTION:
case T_OBJECT:
if(IS_ZERO(sp-1))
pike.git/src/operators.c:2153:
}
break;
default:
free_svalue(sp-1);
sp[-1].type=T_INT;
sp[-1].u.integer=0;
}
}
- void f_not(INT32 args)
+ PMOD_EXPORT void f_not(INT32 args)
{
if(args != 1) {
/* FIXME: Not appropriate with too many args. */
SIMPLE_TOO_FEW_ARGS_ERROR("`!", 1);
}
o_not();
}
static int generate_not(node *n)
{
if(count_args(CDR(n))==1)
{
do_docode(CDR(n),DO_NOT_COPY);
emit0(F_NOT);
return 1;
}
return 0;
}
- void o_compl(void)
+ PMOD_EXPORT void o_compl(void)
{
switch(sp[-1].type)
{
case T_OBJECT:
CALL_OPERATOR(LFUN_COMPL,1);
break;
case T_INT:
sp[-1].u.integer = ~ sp[-1].u.integer;
break;
pike.git/src/operators.c:2245:
pop_n_elems(1);
push_string(end_shared_string(s));
break;
}
default:
PIKE_ERROR("`~", "Bad argument.\n", sp, 1);
}
}
- void f_compl(INT32 args)
+ PMOD_EXPORT void f_compl(INT32 args)
{
if(args != 1) {
/* FIXME: Not appropriate with too many args. */
SIMPLE_TOO_FEW_ARGS_ERROR("`~", 1);
}
o_compl();
}
static int generate_compl(node *n)
{
if(count_args(CDR(n))==1)
{
do_docode(CDR(n),DO_NOT_COPY);
emit0(F_COMPL);
return 1;
}
return 0;
}
- void o_negate(void)
+ PMOD_EXPORT void o_negate(void)
{
switch(sp[-1].type)
{
case T_OBJECT:
do_lfun_negate:
CALL_OPERATOR(LFUN_SUBTRACT,1);
break;
case T_FLOAT:
sp[-1].u.float_number=-sp[-1].u.float_number;
pike.git/src/operators.c:2294:
}
#endif /* AUTO_BIGNUM */
sp[-1].u.integer = - sp[-1].u.integer;
return;
default:
PIKE_ERROR("`-", "Bad argument to unary minus.\n", sp, 1);
}
}
- void o_range(void)
+ PMOD_EXPORT void o_range(void)
{
INT32 from,to;
if(sp[-3].type==T_OBJECT)
{
CALL_OPERATOR(LFUN_INDEX, 3);
return;
}
if(sp[-2].type != T_INT)
pike.git/src/operators.c:2360:
free_array(sp[-1].u.array);
sp[-1].u.array=a;
break;
}
default:
PIKE_ERROR("`[]", "[ .. ] on non-scalar type.\n", sp, 3);
}
}
- void f_index(INT32 args)
+ PMOD_EXPORT void f_index(INT32 args)
{
switch(args)
{
case 0:
case 1:
PIKE_ERROR("`[]", "Too few arguments.\n", sp, args);
break;
case 2:
if(sp[-1].type==T_STRING) sp[-1].subtype=0;
o_index();
break;
case 3:
o_range();
break;
default:
PIKE_ERROR("`[]", "Too many arguments.\n", sp, args);
}
}
- void f_arrow(INT32 args)
+ PMOD_EXPORT void f_arrow(INT32 args)
{
switch(args)
{
case 0:
case 1:
PIKE_ERROR("`->", "Too few arguments.\n", sp, args);
break;
case 2:
if(sp[-1].type==T_STRING)
sp[-1].subtype=1;
o_index();
break;
default:
PIKE_ERROR("`->", "Too many arguments.\n", sp, args);
}
}
- void f_index_assign(INT32 args)
+ PMOD_EXPORT void f_index_assign(INT32 args)
{
switch (args) {
case 0:
case 1:
case 2:
PIKE_ERROR("`[]=", "Too few arguments.\n", sp, args);
break;
case 3:
if(sp[-2].type==T_STRING) sp[-2].subtype=0;
assign_lvalue (sp-3, sp-1);
assign_svalue (sp-3, sp-1);
pop_n_elems (args-1);
break;
default:
PIKE_ERROR("`[]=", "Too many arguments.\n", sp, args);
}
}
- void f_arrow_assign(INT32 args)
+ PMOD_EXPORT void f_arrow_assign(INT32 args)
{
switch (args) {
case 0:
case 1:
case 2:
PIKE_ERROR("`->=", "Too few arguments.\n", sp, args);
break;
case 3:
if(sp[-2].type==T_STRING) sp[-2].subtype=1;
assign_lvalue (sp-3, sp-1);
assign_svalue (sp-3, sp-1);
pop_n_elems (args-1);
break;
default:
PIKE_ERROR("`->=", "Too many arguments.\n", sp, args);
}
}
- void f_sizeof(INT32 args)
+ PMOD_EXPORT void f_sizeof(INT32 args)
{
INT32 tmp;
if(args<1)
PIKE_ERROR("sizeof", "Too few arguments.\n", sp, args);
tmp=pike_sizeof(sp-args);
pop_n_elems(args);
push_int(tmp);
}