pike.git / src / operators.c

version» Context lines:

pike.git/src/operators.c:14:   #include "opcodes.h"   #include "operators.h"   #include "language.h"   #include "memory.h"   #include "error.h"   #include "docode.h"   #include "add_efun.h"      #define COMPARISON(ID,NAME,EXPR) \   void ID(INT32 args) \ - {\ + { \    int i; \    if(args > 2) \    pop_n_elems(args-2); \    else if(args < 2) \    error("Too few arguments to %s\n",NAME); \    i=EXPR; \    pop_n_elems(2); \    sp->type=T_INT; \    sp->u.integer=i; \    sp++; \
pike.git/src/operators.c:211:    case 2:    do_docode(CDR(n),DO_NOT_COPY);    ins_f_byte(F_ADD);    return 1;       default:    return 0;    }   }    + static node *optimize_binary(node *n) + { +  node **first_arg, **second_arg, *ret; +  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((*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)); +  CAR(n)=0; +  CDR(*first_arg)=0; +  *second_arg=0; +  +  return ret; +  } +  +  if((*second_arg)->token == F_APPLY && +  CAR(*second_arg)->token == F_CONSTANT && +  is_eq(& CAR(*second_arg)->u.sval, & CAR(n)->u.sval)) +  { +  ret=mknode(F_APPLY, +  CAR(n), +  mknode(F_ARG_LIST, +  *first_arg, +  CDR(*second_arg))); +  CAR(n)=0; +  *first_arg=0; +  CDR(*second_arg)=0; +  +  return ret; +  } +  } +  } +  return 0; + } +  +    static int generate_comparison(node *n)   {    if(count_args(CDR(n))==2)    {    do_docode(CDR(n),DO_NOT_COPY);       if(CAR(n)->u.sval.u.efun->function == f_eq)    ins_f_byte(F_EQ);    else if(CAR(n)->u.sval.u.efun->function == f_ne)    ins_f_byte(F_NE);
pike.git/src/operators.c:643:    }   }      void f_multiply(INT32 args)   {    switch(args)    {    case 0: error("Too few arguments to `*\n");    case 1: return;    case 2: o_multiply(); return; -  case 3: while(--args > 0) o_multiply(); +  default: while(--args > 0) o_multiply();    }   }      static int generate_multiply(node *n)   {    switch(count_args(CDR(n)))    {    case 1:    do_docode(CDR(n),0);    return 1;
pike.git/src/operators.c:895:    break;    }       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_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,0,generate_sum); +  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_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_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,0,generate_and); +  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,0,generate_or); +  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,0,generate_xor); +  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,0,generate_multiply); +  add_efun2("`*",f_multiply,"function(int...:int)|function(float...: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_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);      }