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 <math.h>   #include "global.h" - RCSID("$Id: operators.c,v 1.24 1998/02/20 01:00:42 hubbe Exp $"); + RCSID("$Id: operators.c,v 1.25 1998/02/23 23:24:03 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"   #include "error.h"   #include "docode.h"   #include "constants.h"   #include "peep.h"   #include "lex.h"   #include "program.h"   #include "object.h"   #include "pike_types.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); \ -  push_int(i); \ + #define COMPARISON(ID,NAME,FUN) \ + void ID(INT32 args) \ + { \ +  int i; \ +  switch(args) \ +  { \ +  case 0: case 1: \ +  error("Too few arguments to %s\n",NAME); \ +  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); \ +  } \   }    - COMPARISON(f_eq,"`==", is_eq(sp-2,sp-1)) - COMPARISON(f_ne,"`!=",!is_eq(sp-2,sp-1)) - COMPARISON(f_lt,"`<" , is_lt(sp-2,sp-1)) - COMPARISON(f_le,"`<=",!is_gt(sp-2,sp-1)) - COMPARISON(f_gt,"`>" , is_gt(sp-2,sp-1)) - COMPARISON(f_ge,"`>=",!is_lt(sp-2,sp-1)) + 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)    -  +    #define CALL_OPERATOR(OP, args) \    if(!sp[-args].u.object->prog) \    error("Operator %s called in destructed object.\n",lfun_names[OP]); \    if(FIND_LFUN(sp[-args].u.object->prog,OP) == -1) \    error("No operator %s in object.\n",lfun_names[OP]); \    apply_lfun(sp[-args].u.object, OP, args-1); \    free_svalue(sp-2); \    sp[-2]=sp[-1]; \    sp--;   
pike.git/src/operators.c:489:    }   }      void f_minus(INT32 args)   {    switch(args)    {    case 0: error("Too few arguments to `-\n");    case 1: o_negate(); break;    case 2: o_subtract(); break; -  default: error("Too many arguments to `-\n"); +  default: +  { +  INT32 e; +  struct svalue *s=sp-args; +  push_svalue(s); +  for(e=1;e<args;e++) +  { +  push_svalue(s+e); +  o_subtract();    } -  +  assign_svalue(s,sp-1); +  pop_n_elems(sp-s-1);    } -  +  } + }      static int generate_minus(node *n)   {    switch(count_args(CDR(n)))    {    case 1:    do_docode(CDR(n),DO_NOT_COPY);    emit2(F_NEGATE);    return 1;   
pike.git/src/operators.c:1280:    return;    }       default:    error("Bad argument 1 to divide.\n");    }   }      void f_divide(INT32 args)   { -  if(args != 2) -  error("Bad number of args to `/\n"); +  switch(args) +  { +  case 0: +  case 1: error("Too few arguments to `/\n"); +  case 2: o_divide(); break; +  default: +  { +  INT32 e; +  struct svalue *s=sp-args; +  push_svalue(s); +  for(e=1;e<args;e++) +  { +  push_svalue(s+e);    o_divide();    } -  +  assign_svalue(s,sp-1); +  pop_n_elems(sp-s-1); +  } +  } + }      static int generate_divide(node *n)   {    if(count_args(CDR(n))==2)    {    do_docode(CDR(n),DO_NOT_COPY);    emit2(F_DIVIDE);    return 1;    }    return 0;
pike.git/src/operators.c:1662:         void init_operators(void)   {    add_efun2("`[]",f_index,    "function(string,int:int)|function(object,string:mixed)|function(array,int:mixed)|function(mapping,mixed:mixed)|function(multiset,mixed:int)|function(string,int,int:string)|function(array,int,int:array)",OPT_TRY_OPTIMIZE,0,0);       add_efun2("`->",f_arrow,    "function(array(object|mapping|multiset|array)|object|mapping|multiset,string:mixed)",OPT_TRY_OPTIMIZE,0,0);    -  add_efun2("`==",f_eq,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison); -  add_efun2("`!=",f_ne,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison); +  add_efun2("`==",f_eq,"function(mixed...:int)",OPT_TRY_OPTIMIZE,0,generate_comparison); +  add_efun2("`!=",f_ne,"function(mixed...:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);    add_efun2("`!",f_not,"function(mixed:int)",OPT_TRY_OPTIMIZE,0,generate_not);    - #define CMP_TYPE "function(object,mixed:int)|function(mixed,object:int)|function(int|float,int|float:int)|function(string,string:int)" + #define CMP_TYPE "!function(!object...:mixed)&function(mixed...:int)|function(int|float...:int)|function(string...:int)"    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,"!function(!object...:mixed)&function(mixed...:mixed)|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(multiset...:multiset)",OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);       add_efun2("`-",f_minus,"!function(!object...:mixed)&function(mixed...:mixed)|function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(multiset,multiset:multiset)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",OPT_TRY_OPTIMIZE,0,generate_minus);      #define LOG_TYPE "function(mixed,object...:mixed)|function(object,mixed...:mixed)|function(int...:int)|function(mapping...:mapping)|function(multiset...:multiset)|function(array...:array)|function(string...:string)"
pike.git/src/operators.c:1701:    "!function(!object...:mixed)&function(mixed...:mixed)|"    "function(array(array),array:array)|"    "function(int...:int)|"    "!function(int...:mixed)&function(float|int...:float)|"    "function(string*,string:string)|"    "function(array,int:array)|"    "function(string,int:string)",    OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply);       add_efun2("`/",f_divide, -  "function(mixed,object:mixed)|" -  "function(array,array|int|float:array(array))|" -  "function(object,mixed:mixed)|" -  "function(int,int:int)|" -  "function(float|int,float:float)|" -  "function(float,int:float)|" -  "function(string,string|int|float:string*)", +  "!function(!object...:mixed)&function(mixed...:mixed)|" +  "function(int,int...:int)|" +  "!function(int...:mixed)&function(float|int...:float)|" +  "function(array,array|int|float...:array(array))|" +  "function(string,string|int|float...:array(string))",    OPT_TRY_OPTIMIZE,0,generate_divide);       add_efun2("`%",f_mod,"function(mixed,object:mixed)|function(object,mixed:mixed)|function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",OPT_TRY_OPTIMIZE,0,generate_mod);       add_efun2("`~",f_compl,"function(object:mixed)|function(int:int)|function(float:float)|function(string:string)",OPT_TRY_OPTIMIZE,0,generate_compl);    add_efun2("sizeof", f_sizeof, "function(string|multiset|array|mapping|object:int)",0,0,generate_sizeof);       add_efun2("`()",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);       /* This one should be removed */    add_efun2("call_function",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);   }