pike.git / src / operators.c

version» Context lines:

pike.git/src/operators.c:162:    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;    }    +  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; +  sp[-1].u.float_number=sum; +  break; +  } +     case BIT_ARRAY:    {    struct array *a;    a=add_arrays(sp-args,args);    pop_n_elems(args);    push_array(a);    break;    }       case BIT_MAPPING:
pike.git/src/operators.c:224:    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    -  if((*second_arg)->type == (*first_arg)->type) +  if((*second_arg)->type == (*first_arg)->type && +  compile_type_to_runtime_type((*second_arg)->type) != T_MIXED)    {    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));
pike.git/src/operators.c:288:    ins_f_byte(F_GT);    else if(CAR(n)->u.sval.u.efun->function == f_ge)    ins_f_byte(F_GE);    else    fatal("Couldn't generate comparison!\n");    return 1;    }    return 0;   }    + 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; + } +    void o_subtract()   { -  if (sp[-2].type != sp[-1].type ) +  if (sp[-2].type != sp[-1].type && !float_promote())    error("Subtract on different types.\n");       switch(sp[-1].type)    {    case T_ARRAY:    {    struct array *a;       check_array_for_destruct(sp[-2].u.array);    check_array_for_destruct(sp[-1].u.array);
pike.git/src/operators.c:652:   {    if(count_args(CDR(n))==2)    {    do_docode(CDR(n),DO_NOT_COPY);    ins_f_byte(F_RSH);    return 1;    }    return 0;   }    +  + #define TWO_TYPES(X,Y) (((X)<<8)|(Y))   void o_multiply()   { -  switch(sp[-2].type) +  switch(TWO_TYPES(sp[-2].type,sp[-1].type))    { -  case T_ARRAY: -  if(sp[-1].type!=T_STRING) +  case TWO_TYPES(T_ARRAY,T_STRING):    { -  error("Bad argument 2 to multiply.\n"); -  }else{ +     struct lpc_string *ret;    sp--;    ret=implode(sp[-1].u.array,sp[0].u.string);    free_string(sp[0].u.string);    free_array(sp[-1].u.array);    sp[-1].type=T_STRING;    sp[-1].u.string=ret;    return;    }    -  case T_FLOAT: -  if(sp[-1].type!=T_FLOAT) error("Bad argument 2 to multiply.\n"); +  case TWO_TYPES(T_FLOAT,T_FLOAT):    sp--;    sp[-1].u.float_number *= sp[0].u.float_number;    return;    -  case T_INT: -  if(sp[-1].type!=T_INT) error("Bad argument 2 to multiply.\n"); +  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): +  sp--;    sp[-1].u.integer *= sp[0].u.integer;    return;       default: -  error("Bad argument 1 to multiply.\n"); +  error("Bad arguments to multiply.\n");    }   }      void f_multiply(INT32 args)   {    switch(args)    {    case 0: error("Too few arguments to `*\n");    case 1: return;    case 2: o_multiply(); return;
pike.git/src/operators.c:719:    ins_f_byte(F_MULTIPLY);    return 1;       default:    return 0;    }   }      void o_divide()   { -  if(sp[-2].type!=sp[-1].type) +  if(sp[-2].type!=sp[-1].type && !float_promote())    error("Division on different types.\n");       switch(sp[-2].type)    {    case T_STRING:    {    struct array *ret;    sp--;    ret=explode(sp[-1].u.string,sp[0].u.string);    free_string(sp[-1].u.string);
pike.git/src/operators.c:775:    {    do_docode(CDR(n),DO_NOT_COPY);    ins_f_byte(F_DIVIDE);    return 1;    }    return 0;   }      void o_mod()   { -  if(sp[-2].type != sp[-1].type) +  if(sp[-2].type != sp[-1].type && !float_promote())    error("Modulo on different types.\n");       switch(sp[-1].type)    {    case T_FLOAT:    {    FLOAT_TYPE foo;    if(sp[-1].u.float_number == 0.0)    error("Modulo by zero.\n");    sp--;
pike.git/src/operators.c:949:       default:    error("[ .. ] can only be done on strings and arrays.\n");    }   }      void init_operators()   {    add_efun2("`==",f_eq,"function(mixed,mixed:int)",0,0,generate_comparison);    add_efun2("`!=",f_ne,"function(mixed,mixed:int)",0,0,generate_comparison); -  add_efun2("`<", f_lt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison); -  add_efun2("`<=",f_le,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison); -  add_efun2("`>", f_gt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison); -  add_efun2("`>=",f_ge,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison); +  add_efun2("`<", f_lt,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison); +  add_efun2("`<=",f_le,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison); +  add_efun2("`>", f_gt,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison); +  add_efun2("`>=",f_ge,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison);    -  add_efun2("`+",f_add,"function(int ...:int)|function(float ...:float)|function(string,string|int|float ...:string)|function(string,string|int|float ...:string)|function(int|float,string,string|int|float:string)|function(array ...:array)|function(mapping ...:mapping)|function(list...:list)",0,optimize_binary,generate_sum); +  add_efun2("`+",f_add,"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(list...:list)",0,optimize_binary,generate_sum);    -  add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float,float:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus); +  add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus);       add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_and);       add_efun2("`|",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_or);       add_efun2("`^",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_xor);       add_efun2("`<<",f_lsh,"function(int,int:int)",0,0,generate_lsh);    add_efun2("`>>",f_rsh,"function(int,int:int)",0,0,generate_rsh);    -  add_efun2("`*",f_multiply,"function(int...:int)|function(float...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply); +  add_efun2("`*",f_multiply,"function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply);    -  add_efun2("`/",f_divide,"function(int,int:int)|function(float,float:float)|function(string,string:string*)",0,0,generate_divide); +  add_efun2("`/",f_divide,"function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",0,0,generate_divide);       add_efun2("`%",f_mod,"function(int,int:int)|function(float,float:float)",0,0,generate_mod);       add_efun2("`!",f_not,"function(mixed:int)",0,0,generate_not);    add_efun2("`~",f_compl,"function(int:int)",0,0,generate_compl); -  +    }