pike.git / src / operators.c

version» Context lines:

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);   }