cb22561995-10-11Fredrik Hübinette (Hubbe) /*\
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License)
cb22561995-10-11Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
54db6c1999-03-27Henrik Grubbström (Grubba) /**/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
b788cd1998-07-04Henrik Grubbström (Grubba) #include <math.h>
080b1a2000-08-10Henrik Grubbström (Grubba) RCSID("$Id: operators.c,v 1.98 2000/08/10 17:44:56 grubba Exp $");
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "interpret.h" #include "svalue.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "multiset.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "mapping.h" #include "array.h" #include "stralloc.h" #include "opcodes.h" #include "operators.h" #include "language.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "error.h"
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) #include "docode.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "constants.h"
8a630c1996-04-13Fredrik Hübinette (Hubbe) #include "peep.h" #include "lex.h"
07c0731996-06-21Fredrik Hübinette (Hubbe) #include "program.h" #include "object.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "pike_types.h"
19aaeb1998-05-25Fredrik Hübinette (Hubbe) #include "module_support.h"
0bc4cf1998-10-13Fredrik Hübinette (Hubbe) #include "pike_macros.h"
fda0de1999-10-08Fredrik Noring #include "bignum.h"
89c4452000-04-12Henrik Grubbström (Grubba) #include "builtin_functions.h"
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
54db6c1999-03-27Henrik Grubbström (Grubba) #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")
5b4dd31998-02-23Fredrik Hübinette (Hubbe) #define COMPARISON(ID,NAME,FUN) \
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void ID(INT32 args) \
5b4dd31998-02-23Fredrik Hübinette (Hubbe) { \ int i; \ switch(args) \ { \ case 0: case 1: \
54db6c1999-03-27Henrik Grubbström (Grubba)  SIMPLE_TOO_FEW_ARGS_ERROR(NAME, 2); \
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  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); \ } \
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_ne(INT32 args)
5b4dd31998-02-23Fredrik Hübinette (Hubbe) { 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)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
07c0731996-06-21Fredrik Hübinette (Hubbe) #define CALL_OPERATOR(OP, args) \ if(!sp[-args].u.object->prog) \
54db6c1999-03-27Henrik Grubbström (Grubba)  bad_arg_error(lfun_names[OP], sp-args, args, 1, "object", sp-args, \ "Called in destructed object.\n"); \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(FIND_LFUN(sp[-args].u.object->prog,OP) == -1) \
54db6c1999-03-27Henrik Grubbström (Grubba)  bad_arg_error(lfun_names[OP], sp-args, args, 1, "object", sp-args, \ "Operator not in object.\n"); \
07c0731996-06-21Fredrik Hübinette (Hubbe)  apply_lfun(sp[-args].u.object, OP, args-1); \ free_svalue(sp-2); \ sp[-2]=sp[-1]; \
41e2cb1999-10-24Henrik Grubbström (Grubba)  sp--; \ dmalloc_touch_svalue(sp);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_add(INT32 args)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
70b4311998-02-27Fredrik Hübinette (Hubbe)  INT_TYPE e,size;
5267b71995-08-09Fredrik Hübinette (Hubbe)  TYPE_FIELD types; types=0; for(e=-args;e<0;e++) types|=1<<sp[e].type; switch(types) { default:
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(!args)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
54db6c1999-03-27Henrik Grubbström (Grubba)  SIMPLE_TOO_FEW_ARGS_ERROR("`+", 1);
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  }else{ if(types & BIT_OBJECT)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
ee37801999-02-09Fredrik Hübinette (Hubbe)  if(sp[-args].type == T_OBJECT && sp[-args].u.object->prog)
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  {
ee37801999-02-09Fredrik Hübinette (Hubbe)  if(sp[-args].u.object->refs==1 && FIND_LFUN(sp[-args].u.object->prog,LFUN_ADD_EQ) != -1) { apply_lfun(sp[-args].u.object, LFUN_ADD_EQ, args-1);
110b3f1999-10-29Fredrik Hübinette (Hubbe)  stack_unlink(1);
ee37801999-02-09Fredrik Hübinette (Hubbe)  return; } if(FIND_LFUN(sp[-args].u.object->prog,LFUN_ADD) != -1) { apply_lfun(sp[-args].u.object, LFUN_ADD, args-1); free_svalue(sp-2); sp[-2]=sp[-1]; sp--;
41e2cb1999-10-24Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
ee37801999-02-09Fredrik Hübinette (Hubbe)  return; }
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  } for(e=1;e<args;e++) { if(sp[e-args].type == T_OBJECT && sp[e-args].u.object->prog &&
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  FIND_LFUN(sp[e-args].u.object->prog,LFUN_RADD) != -1)
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  { struct svalue *tmp=sp+e-args; check_stack(e); assign_svalues_no_free(sp, sp-args, e, -1); sp+=e; apply_lfun(tmp->u.object, LFUN_RADD, e);
a7b26a2000-03-01Fredrik Hübinette (Hubbe)  if(args - e > 1)
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  { assign_svalue(tmp, sp-1); pop_stack(); f_add(args - e); assign_svalue(sp-e-1,sp-1); pop_n_elems(e); }else{ assign_svalue(sp-args-1,sp-1); pop_n_elems(args); } return; } } } }
07c0731996-06-21Fredrik Hübinette (Hubbe) 
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  switch(sp[-args].type) {
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_PROGRAM: case T_FUNCTION:
54db6c1999-03-27Henrik Grubbström (Grubba)  SIMPLE_BAD_ARG_ERROR("`+", 1, "string|object|int|float|array|mapping|multiset");
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
54db6c1999-03-27Henrik Grubbström (Grubba)  bad_arg_error("`+", sp-args, args, 1, "string|object|int|float|array|mapping|multiset", sp-args, "Incompatible types\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; /* compiler hint */ case BIT_STRING: {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *r;
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  PCHARP buf;
e4b2252000-08-09Henrik Grubbström (Grubba)  ptrdiff_t tmp;
3e625c1998-10-11Fredrik Hübinette (Hubbe)  int max_shift=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3e625c1998-10-11Fredrik Hübinette (Hubbe)  if(args==1) return; size=0; for(e=-args;e<0;e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
3e625c1998-10-11Fredrik Hübinette (Hubbe)  size+=sp[e].u.string->len; if(sp[e].u.string->size_shift > max_shift) max_shift=sp[e].u.string->size_shift;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
66769e1999-11-04Fredrik Hübinette (Hubbe)  if(size == sp[-args].u.string->len) { pop_n_elems(args-1); return; }
3e625c1998-10-11Fredrik Hübinette (Hubbe)  tmp=sp[-args].u.string->len; r=new_realloc_shared_string(sp[-args].u.string,size,max_shift); sp[-args].type=T_INT;
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  buf=MKPCHARP_STR_OFF(r,tmp);
3e625c1998-10-11Fredrik Hübinette (Hubbe)  for(e=-args+1;e<0;e++) {
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  pike_string_cpy(buf,sp[e].u.string); INC_PCHARP(buf,sp[e].u.string->len);
3e625c1998-10-11Fredrik Hübinette (Hubbe)  } sp[-args].u.string=end_shared_string(r); sp[-args].type=T_STRING; for(e=-args+1;e<0;e++) free_string(sp[e].u.string); sp-=args-1;
8a630c1996-04-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; } case BIT_STRING | BIT_INT: case BIT_STRING | BIT_FLOAT: case BIT_STRING | BIT_FLOAT | BIT_INT: {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *r;
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  PCHARP buf;
3e625c1998-10-11Fredrik Hübinette (Hubbe)  char buffer[50]; int max_shift=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  size=0; for(e=-args;e<0;e++) { switch(sp[e].type) { case T_STRING: size+=sp[e].u.string->len;
3e625c1998-10-11Fredrik Hübinette (Hubbe)  if(sp[e].u.string->size_shift > max_shift) max_shift=sp[e].u.string->size_shift;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case T_INT: size+=14; break; case T_FLOAT: size+=22; break; } }
3e625c1998-10-11Fredrik Hübinette (Hubbe)  r=begin_wide_shared_string(size,max_shift);
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  buf=MKPCHARP_STR(r);
5267b71995-08-09Fredrik Hübinette (Hubbe)  size=0; for(e=-args;e<0;e++) { switch(sp[e].type) { case T_STRING:
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  pike_string_cpy(buf,sp[e].u.string); INC_PCHARP(buf,sp[e].u.string->len);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; case T_INT:
3e625c1998-10-11Fredrik Hübinette (Hubbe)  sprintf(buffer,"%ld",(long)sp[e].u.integer); goto append_buffer;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_FLOAT:
3e625c1998-10-11Fredrik Hübinette (Hubbe)  sprintf(buffer,"%f",(double)sp[e].u.float_number); append_buffer: switch(max_shift) {
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  case 0: convert_0_to_0((p_wchar0 *)buf.ptr,buffer,strlen(buffer)); break; case 1:
01a9572000-02-03Henrik Grubbström (Grubba)  convert_0_to_1((p_wchar1 *)buf.ptr,(p_wchar0 *)buffer, strlen(buffer));
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  break; case 2:
01a9572000-02-03Henrik Grubbström (Grubba)  convert_0_to_2((p_wchar2 *)buf.ptr,(p_wchar0 *)buffer, strlen(buffer));
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  break;
3e625c1998-10-11Fredrik Hübinette (Hubbe)  }
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  INC_PCHARP(buf,strlen(buffer));
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  r->len=SUBTRACT_PCHARP(buf,MKPCHARP_STR(r));
3e625c1998-10-11Fredrik Hübinette (Hubbe)  low_set_index(r,r->len,0); r=end_shared_string(r);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(args); push_string(r); break; } case BIT_INT:
fda0de1999-10-08Fredrik Noring #ifdef AUTO_BIGNUM size = 0; for(e = -args; e < 0; e++) {
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  if(INT_TYPE_ADD_OVERFLOW(sp[e].u.integer, size))
fda0de1999-10-08Fredrik Noring  {
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  convert_svalue_to_bignum(sp-args); f_add(args); return;
fda0de1999-10-08Fredrik Noring  } else {
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  size += sp[e].u.integer;
fda0de1999-10-08Fredrik Noring  } }
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  sp-=args; push_int(size);
fda0de1999-10-08Fredrik Noring #else
5267b71995-08-09Fredrik Hübinette (Hubbe)  size=0; for(e=-args; e<0; e++) size+=sp[e].u.integer; sp-=args-1; sp[-1].u.integer=size;
fda0de1999-10-08Fredrik Noring #endif /* AUTO_BIGNUM */
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; 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; }
482fb51999-03-12Per Hedbor  case BIT_FLOAT|BIT_INT:
bce86c1996-02-25Fredrik Hübinette (Hubbe)  { 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;
a650f21996-03-22Fredrik Hübinette (Hubbe)  sp[-1].type=T_FLOAT;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  sp[-1].u.float_number=sum; break; }
ee37801999-02-09Fredrik Hübinette (Hubbe)  case BIT_ARRAY|BIT_INT: { if(IS_UNDEFINED(sp-args)) { int e; struct array *a; for(e=1;e<args;e++) if(sp[e-args].type != T_ARRAY)
54db6c1999-03-27Henrik Grubbström (Grubba)  SIMPLE_BAD_ARG_ERROR("`+", e+1, "array");
482fb51999-03-12Per Hedbor 
ee37801999-02-09Fredrik Hübinette (Hubbe)  a=add_arrays(sp-args+1,args-1); pop_n_elems(args); push_array(a); return; }
54db6c1999-03-27Henrik Grubbström (Grubba)  if (sp[-args].type == T_INT) { int e; for(e=1;e<args;e++) if (sp[e-args].type != T_INT) SIMPLE_BAD_ARG_ERROR("`+", e+1, "int"); } else { int e; for(e=0;e<args;e++) if (sp[e-args].type != T_ARRAY) SIMPLE_BAD_ARG_ERROR("`+", e+1, "array"); } /* Probably not reached, but... */ bad_arg_error("`+", sp-args, args, 1, "array", sp-args, "trying to add integers and arrays.\n");
ee37801999-02-09Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case BIT_ARRAY: { struct array *a; a=add_arrays(sp-args,args); pop_n_elems(args); push_array(a); break; }
482fb51999-03-12Per Hedbor  case BIT_MAPPING|BIT_INT: { if(IS_UNDEFINED(sp-args)) { int e; struct mapping *a; for(e=1;e<args;e++) if(sp[e-args].type != T_MAPPING)
54db6c1999-03-27Henrik Grubbström (Grubba)  SIMPLE_BAD_ARG_ERROR("`+", e+1, "mapping");
482fb51999-03-12Per Hedbor  a=add_mappings(sp-args+1,args-1); pop_n_elems(args); push_mapping(a); return; }
54db6c1999-03-27Henrik Grubbström (Grubba)  if (sp[-args].type == T_INT) { int e; for(e=1;e<args;e++) if (sp[e-args].type != T_INT) SIMPLE_BAD_ARG_ERROR("`+", e+1, "int"); } else { int e; for(e=0;e<args;e++) if (sp[e-args].type != T_MAPPING) SIMPLE_BAD_ARG_ERROR("`+", e+1, "mapping"); } /* Probably not reached, but... */ bad_arg_error("`+", sp-args, args, 1, "mapping", sp-args, "Trying to add integers and mappings.\n");
482fb51999-03-12Per Hedbor  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case BIT_MAPPING: { struct mapping *m; m = add_mappings(sp - args, args); pop_n_elems(args); push_mapping(m); break; }
06983f1996-09-22Fredrik Hübinette (Hubbe)  case BIT_MULTISET:
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct multiset *l;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
06983f1996-09-22Fredrik Hübinette (Hubbe)  l = add_multisets(sp - args, args);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(args);
06983f1996-09-22Fredrik Hübinette (Hubbe)  push_multiset(l);
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; } } }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) static int generate_sum(node *n) {
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  node **first_arg, **second_arg;
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  switch(count_args(CDR(n))) { case 1: do_docode(CDR(n),0); return 1; case 2:
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  first_arg=my_get_arg(&_CDR(n), 0); second_arg=my_get_arg(&_CDR(n), 1);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  do_docode(CDR(n),DO_NOT_COPY);
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  if(first_arg[0]->type == float_type_string && second_arg[0]->type == float_type_string) { emit0(F_ADD_FLOATS); } else if(first_arg[0]->type == int_type_string && second_arg[0]->type == int_type_string) { emit0(F_ADD_INTS); } else { emit0(F_ADD); }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; default: return 0; } }
e104411998-06-05Fredrik Hübinette (Hubbe) static node *optimize_eq(node *n) { node **first_arg, **second_arg, *ret; if(count_args(CDR(n))==2) {
f807f01999-11-11Henrik Grubbström (Grubba)  first_arg=my_get_arg(&_CDR(n), 0);
177c561999-11-11Henrik Grubbström (Grubba)  second_arg=my_get_arg(&_CDR(n), 1);
e104411998-06-05Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
e104411998-06-05Fredrik Hübinette (Hubbe)  if(!first_arg || !second_arg) fatal("Couldn't find argument!\n"); #endif if(node_is_false(*first_arg) && !node_may_overload(*second_arg,LFUN_EQ)) { ret=*second_arg;
01b2c21999-11-22Henrik Grubbström (Grubba)  ADD_NODE_REF(*second_arg);
e104411998-06-05Fredrik Hübinette (Hubbe)  return mkopernode("`!",ret,0); } if(node_is_false(*second_arg) && !node_may_overload(*first_arg,LFUN_EQ)) { ret=*first_arg;
01b2c21999-11-22Henrik Grubbström (Grubba)  ADD_NODE_REF(*first_arg);
e104411998-06-05Fredrik Hübinette (Hubbe)  return mkopernode("`!",ret,0); } } return 0; } static node *optimize_not(node *n) { node **first_arg, **more_args; int e; if(count_args(CDR(n))==1) {
f807f01999-11-11Henrik Grubbström (Grubba)  first_arg=my_get_arg(&_CDR(n), 0);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
e104411998-06-05Fredrik Hübinette (Hubbe)  if(!first_arg) fatal("Couldn't find argument!\n"); #endif if(node_is_true(*first_arg)) return mkintnode(0); if(node_is_false(*first_arg)) return mkintnode(1);
f807f01999-11-11Henrik Grubbström (Grubba) #define TMP_OPT(X,Y) do { \ if((more_args=is_call_to(*first_arg, X))) \ { \ node *tmp=*more_args; \
01b2c21999-11-22Henrik Grubbström (Grubba)  ADD_NODE_REF(*more_args); \
f807f01999-11-11Henrik Grubbström (Grubba)  return mkopernode(Y,tmp,0); \ } } while(0)
e104411998-06-05Fredrik Hübinette (Hubbe)  TMP_OPT(f_eq, "`!="); TMP_OPT(f_ne, "`=="); TMP_OPT(f_lt, "`>="); TMP_OPT(f_gt, "`<="); TMP_OPT(f_le, "`>"); TMP_OPT(f_ge, "`<"); #undef TMP_OPT
89c4452000-04-12Henrik Grubbström (Grubba)  if((more_args = is_call_to(*first_arg, f_search)) && (count_args(*more_args) == 2)) { node *search_args = *more_args; if ((search_args->token == F_ARG_LIST) && CAR(search_args) && (CAR(search_args)->type == string_type_string) && CDR(search_args) && (CDR(search_args)->type == string_type_string)) { /* !search(string a, string b) => has_prefix(a, b) */ ADD_NODE_REF(*more_args); return mkefuncallnode("has_prefix", search_args); } }
e104411998-06-05Fredrik Hübinette (Hubbe)  } return 0; }
6930181996-02-25Fredrik Hübinette (Hubbe) static node *optimize_binary(node *n) { node **first_arg, **second_arg, *ret; if(count_args(CDR(n))==2) {
f807f01999-11-11Henrik Grubbström (Grubba)  first_arg=my_get_arg(&_CDR(n), 0); second_arg=my_get_arg(&_CDR(n), 1);
6930181996-02-25Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
6930181996-02-25Fredrik Hübinette (Hubbe)  if(!first_arg || !second_arg) fatal("Couldn't find argument!\n"); #endif
bce86c1996-02-25Fredrik Hübinette (Hubbe)  if((*second_arg)->type == (*first_arg)->type && compile_type_to_runtime_type((*second_arg)->type) != T_MIXED)
6930181996-02-25Fredrik Hübinette (Hubbe)  { 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));
01b2c21999-11-22Henrik Grubbström (Grubba)  ADD_NODE_REF(CAR(n)); ADD_NODE_REF(CDR(*first_arg)); ADD_NODE_REF(*second_arg);
6930181996-02-25Fredrik Hübinette (Hubbe)  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)));
01b2c21999-11-22Henrik Grubbström (Grubba)  ADD_NODE_REF(CAR(n)); ADD_NODE_REF(*first_arg); ADD_NODE_REF(CDR(*second_arg));
6930181996-02-25Fredrik Hübinette (Hubbe)  return ret; } } } return 0; }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) static int generate_comparison(node *n) { if(count_args(CDR(n))==2) {
4c573c1996-08-03Fredrik Hübinette (Hubbe)  if(do_docode(CDR(n),DO_NOT_COPY) != 2) fatal("Count args was wrong in generate_comparison.\n");
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  if(CAR(n)->u.sval.u.efun->function == f_eq)
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_EQ);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  else if(CAR(n)->u.sval.u.efun->function == f_ne)
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_NE);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  else if(CAR(n)->u.sval.u.efun->function == f_lt)
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_LT);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  else if(CAR(n)->u.sval.u.efun->function == f_le)
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_LE);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  else if(CAR(n)->u.sval.u.efun->function == f_gt)
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_GT);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  else if(CAR(n)->u.sval.u.efun->function == f_ge)
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_GE);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  else fatal("Couldn't generate comparison!\n"); return 1; } return 0; }
be478c1997-08-30Henrik Grubbström (Grubba) static int float_promote(void)
bce86c1996-02-25Fredrik Hübinette (Hubbe) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-2].type==T_INT && sp[-1].type==T_FLOAT)
bce86c1996-02-25Fredrik Hübinette (Hubbe)  { sp[-2].u.float_number=(FLOAT_TYPE)sp[-2].u.integer; sp[-2].type=T_FLOAT;
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  return 1;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  }
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  else if(sp[-1].type==T_INT && sp[-2].type==T_FLOAT)
bce86c1996-02-25Fredrik Hübinette (Hubbe)  { sp[-1].u.float_number=(FLOAT_TYPE)sp[-1].u.integer; sp[-1].type=T_FLOAT;
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  return 1; }
e924491999-12-14Fredrik Hübinette (Hubbe)  #ifdef AUTO_BIGNUM if(is_bignum_object_in_svalue(sp-2) && sp[-1].type==T_FLOAT) { stack_swap(); push_constant_text(tFloat); stack_swap(); f_cast(); stack_swap(); return 1; } else if(is_bignum_object_in_svalue(sp-1) && sp[-2].type==T_FLOAT) { push_constant_text(tFloat); stack_swap(); f_cast(); return 1; } #endif
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  return 0; } static int call_lfun(int left, int right) { if(sp[-2].type == T_OBJECT && sp[-2].u.object->prog &&
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  FIND_LFUN(sp[-2].u.object->prog,left) != -1)
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  { apply_lfun(sp[-2].u.object, left, 1); free_svalue(sp-2); sp[-2]=sp[-1]; sp--;
41e2cb1999-10-24Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  return 1;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  }
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-1].type == T_OBJECT && sp[-1].u.object->prog &&
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  FIND_LFUN(sp[-1].u.object->prog,right) != -1)
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  { push_svalue(sp-2); apply_lfun(sp[-2].u.object, right, 1); free_svalue(sp-3); sp[-3]=sp[-1]; sp--;
41e2cb1999-10-24Henrik Grubbström (Grubba)  dmalloc_touch_svalue(sp);
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  pop_stack(); return 1; } return 0;
bce86c1996-02-25Fredrik Hübinette (Hubbe) }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
aa17e32000-04-12Mirar (Pontus Hagland) 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);
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_subtract(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if (sp[-2].type != sp[-1].type && !float_promote()) { if(call_lfun(LFUN_SUBTRACT, LFUN_RSUBTRACT)) return;
aa17e32000-04-12Mirar (Pontus Hagland)  if (sp[-2].type==T_MAPPING) switch (sp[-1].type) { case T_ARRAY: { struct mapping *m; m=merge_mapping_array_unordered(sp[-2].u.mapping, sp[-1].u.array, PIKE_ARRAY_OP_SUB); pop_n_elems(2); push_mapping(m); return; } case T_MULTISET: { struct mapping *m; m=merge_mapping_array_ordered(sp[-2].u.mapping, sp[-1].u.multiset->ind, PIKE_ARRAY_OP_SUB); pop_n_elems(2); push_mapping(m); return; } }
b341a61999-11-04Fredrik Hübinette (Hubbe)  bad_arg_error("`-", sp-2, 2, 2, get_name_of_type(sp[-2].type),
54db6c1999-03-27Henrik Grubbström (Grubba)  sp-1, "Subtract on different types.\n");
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
07c0731996-06-21Fredrik Hübinette (Hubbe)  switch(sp[-2].type)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
07c0731996-06-21Fredrik Hübinette (Hubbe)  case T_OBJECT: CALL_OPERATOR(LFUN_SUBTRACT,2); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_ARRAY: { struct array *a; check_array_for_destruct(sp[-2].u.array); check_array_for_destruct(sp[-1].u.array); a = subtract_arrays(sp[-2].u.array, sp[-1].u.array); pop_n_elems(2); push_array(a); return; } case T_MAPPING: { struct mapping *m;
71f3a21998-11-22Fredrik Hübinette (Hubbe)  m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping,PIKE_ARRAY_OP_SUB);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(2); push_mapping(m); return; }
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct multiset *l;
71f3a21998-11-22Fredrik Hübinette (Hubbe)  l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, PIKE_ARRAY_OP_SUB);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(2);
06983f1996-09-22Fredrik Hübinette (Hubbe)  push_multiset(l);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; } case T_FLOAT: sp--; sp[-1].u.float_number -= sp[0].u.float_number; return; case T_INT:
ff0d461999-10-15Fredrik Noring #ifdef AUTO_BIGNUM if(INT_TYPE_SUB_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) { convert_stack_top_to_bignum(); f_minus(2); return; } #endif /* AUTO_BIGNUM */
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp--; sp[-1].u.integer -= sp[0].u.integer; return; case T_STRING: {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s,*ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  s=make_shared_string("");
fb5c4f1996-03-24Fredrik Hübinette (Hubbe)  ret=string_replace(sp[-2].u.string,sp[-1].u.string,s); free_string(sp[-2].u.string);
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_string(sp[-1].u.string); free_string(s);
fb5c4f1996-03-24Fredrik Hübinette (Hubbe)  sp[-2].u.string=ret; sp--;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; } default:
54db6c1999-03-27Henrik Grubbström (Grubba)  { int args = 2; SIMPLE_BAD_ARG_ERROR("`-", 1, "int|float|string|mapping|multiset|array|object"); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_minus(INT32 args)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) { switch(args) {
54db6c1999-03-27Henrik Grubbström (Grubba)  case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`-", 1);
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  case 1: o_negate(); break; case 2: o_subtract(); break; 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); }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  } } static int generate_minus(node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  switch(count_args(CDR(n))) { case 1: do_docode(CDR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_NEGATE);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; case 2: do_docode(CDR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_SUBTRACT);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; } return 0; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_and(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-1].type != sp[-2].type) {
aa17e32000-04-12Mirar (Pontus Hagland)  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))) { if (sp[-2].type != T_TYPE) { struct program *p = program_from_svalue(sp - 2); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`&", 1, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); free_svalue(sp - 2); sp[-2].u.string = pop_unfinished_type(); sp[-2].type = T_TYPE;
dc7d491999-12-15Henrik Grubbström (Grubba)  }
aa17e32000-04-12Mirar (Pontus Hagland)  if (sp[-1].type != T_TYPE) { struct program *p = program_from_svalue(sp - 1); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`&", 2, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); free_svalue(sp - 1); sp[-1].u.string = pop_unfinished_type(); sp[-1].type = T_TYPE;
dc7d491999-12-15Henrik Grubbström (Grubba)  }
aa17e32000-04-12Mirar (Pontus Hagland)  } else if (sp[-2].type==T_MAPPING) switch (sp[-1].type) { case T_ARRAY: { struct mapping *m; m=merge_mapping_array_unordered(sp[-2].u.mapping, sp[-1].u.array, PIKE_ARRAY_OP_AND); pop_n_elems(2); push_mapping(m); return; } case T_MULTISET: { struct mapping *m; m=merge_mapping_array_ordered(sp[-2].u.mapping, sp[-1].u.multiset->ind, PIKE_ARRAY_OP_AND); pop_n_elems(2); push_mapping(m); return; } } else { int args = 2; SIMPLE_BAD_ARG_ERROR("`&", 2, get_name_of_type(sp[-2].type)); }
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(sp[-2].type) {
07c0731996-06-21Fredrik Hübinette (Hubbe)  case T_OBJECT: CALL_OPERATOR(LFUN_AND,2); break;
fc0bb51997-02-13Niels Möller 
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_INT: sp--; sp[-1].u.integer &= sp[0].u.integer; break; case T_MAPPING: { struct mapping *m;
71f3a21998-11-22Fredrik Hübinette (Hubbe)  m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, PIKE_ARRAY_OP_AND);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(2); push_mapping(m); return; }
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct multiset *l;
71f3a21998-11-22Fredrik Hübinette (Hubbe)  l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, PIKE_ARRAY_OP_AND);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(2);
06983f1996-09-22Fredrik Hübinette (Hubbe)  push_multiset(l);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; } case T_ARRAY: { struct array *a; a=and_arrays(sp[-2].u.array, sp[-1].u.array); pop_n_elems(2); push_array(a); return; }
fc0bb51997-02-13Niels Möller 
3db0d21999-12-13Henrik Grubbström (Grubba)  case T_TYPE: { struct pike_string *t; t = and_pike_types(sp[-2].u.string, sp[-1].u.string); pop_n_elems(2); push_string(t);
e06e101999-12-15Henrik Grubbström (Grubba)  sp[-1].type = T_TYPE;
3db0d21999-12-13Henrik Grubbström (Grubba)  return; }
dc7d491999-12-15Henrik Grubbström (Grubba)  case T_FUNCTION: case T_PROGRAM: { struct program *p; struct pike_string *a; struct pike_string *b; struct pike_string *t; p = program_from_svalue(sp - 2); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`&", 1, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); a = pop_unfinished_type(); p = program_from_svalue(sp - 1); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`&", 2, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); b = pop_unfinished_type(); t = and_pike_types(a, b); pop_n_elems(2); push_string(t); sp[-1].type = T_TYPE; free_string(a); free_string(b); return; }
0bc4cf1998-10-13Fredrik Hübinette (Hubbe) #define STRING_BITOP(OP,STROP) \ case T_STRING: \ { \ struct pike_string *s; \
e4b2252000-08-09Henrik Grubbström (Grubba)  ptrdiff_t len, i; \
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  \ len = sp[-2].u.string->len; \ if (len != sp[-1].u.string->len) \ PIKE_ERROR("`" #OP, "Bitwise "STROP \ " on strings of different lengths.\n", sp, 2); \ if(!sp[-2].u.string->size_shift && !sp[-1].u.string->size_shift) \ { \ s = begin_shared_string(len); \ for (i=0; i<len; i++) \ s->str[i] = sp[-2].u.string->str[i] OP sp[-1].u.string->str[i]; \ }else{ \ s = begin_wide_shared_string(len, \ MAXIMUM(sp[-2].u.string->size_shift, \ sp[-1].u.string->size_shift)); \ for (i=0; i<len; i++) \ low_set_index(s,i,index_shared_string(sp[-2].u.string,i) OP \ index_shared_string(sp[-1].u.string,i)); \ } \ pop_n_elems(2); \ push_string(end_shared_string(s)); \ return; \ } STRING_BITOP(&,"AND")
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`&", "Bitwise and on illegal type.\n", sp, 2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
3c04e81997-03-13Fredrik Hübinette (Hubbe) /* This function is used to speed up or/xor/and on * arrays multisets and mappings. This is done by * calling the operator for each pair of arguments * first, then recursively doing the same on the * results until only one value remains. */
adbb781998-09-18Fredrik Hübinette (Hubbe) static void r_speedup(INT32 args, void (*func)(void)) { int num; struct svalue tmp; ONERROR err; switch(args) { case 3: func(); case 2: func(); case 1: return; default: r_speedup((args+1)>>1,func); tmp=*--sp; SET_ONERROR(err,do_free_svalue,&tmp); r_speedup(args>>1,func); UNSET_ONERROR(err); sp++[0]=tmp; func(); } }
3c04e81997-03-13Fredrik Hübinette (Hubbe) static void speedup(INT32 args, void (*func)(void)) { switch(sp[-args].type) {
c2769b1999-10-01Fredrik Hübinette (Hubbe)  /* This method can be used for types where a op b === b op a */
adbb781998-09-18Fredrik Hübinette (Hubbe)  case T_MULTISET:
3c04e81997-03-13Fredrik Hübinette (Hubbe)  {
adbb781998-09-18Fredrik Hübinette (Hubbe)  int e=-1; while(args > 1)
3c04e81997-03-13Fredrik Hübinette (Hubbe)  {
adbb781998-09-18Fredrik Hübinette (Hubbe)  struct svalue tmp; func(); args--; e++; if(e - args >= -1) { e=0; }else{ tmp=sp[e-args]; sp[e-args]=sp[-1]; sp[-1]=tmp; }
3c04e81997-03-13Fredrik Hübinette (Hubbe)  }
adbb781998-09-18Fredrik Hübinette (Hubbe)  return;
3c04e81997-03-13Fredrik Hübinette (Hubbe)  }
adbb781998-09-18Fredrik Hübinette (Hubbe) 
c2769b1999-10-01Fredrik Hübinette (Hubbe)  /* Binary balanced tree method for types where * a op b may or may not be equal to b op a */ case T_ARRAY:
adbb781998-09-18Fredrik Hübinette (Hubbe)  case T_MAPPING: r_speedup(args,func); return;
3c04e81997-03-13Fredrik Hübinette (Hubbe) 
adbb781998-09-18Fredrik Hübinette (Hubbe)  default: while(--args > 0) func();
3c04e81997-03-13Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_and(INT32 args)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) { switch(args) {
54db6c1999-03-27Henrik Grubbström (Grubba)  case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`&", 1);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  case 1: return; case 2: o_and(); return;
07c0731996-06-21Fredrik Hübinette (Hubbe)  default: if(sp[-args].type == T_OBJECT) { CALL_OPERATOR(LFUN_AND, args); }else{
3c04e81997-03-13Fredrik Hübinette (Hubbe)  speedup(args, o_and);
07c0731996-06-21Fredrik Hübinette (Hubbe)  }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  } } static int generate_and(node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  switch(count_args(CDR(n))) { case 1: do_docode(CDR(n),0); return 1; case 2: do_docode(CDR(n),0);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_AND);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; default: return 0; } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_or(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-1].type != sp[-2].type) {
dc7d491999-12-15Henrik Grubbström (Grubba)  if(call_lfun(LFUN_OR, LFUN_ROR)) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  return;
dc7d491999-12-15Henrik Grubbström (Grubba)  } 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) { struct program *p = program_from_svalue(sp - 2); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`|", 1, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); free_svalue(sp - 2); sp[-2].u.string = pop_unfinished_type(); sp[-2].type = T_TYPE; } if (sp[-1].type != T_TYPE) { struct program *p = program_from_svalue(sp - 1); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`|", 2, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); free_svalue(sp - 1); sp[-1].u.string = pop_unfinished_type(); sp[-1].type = T_TYPE; } } else {
54db6c1999-03-27Henrik Grubbström (Grubba)  int args = 2;
b341a61999-11-04Fredrik Hübinette (Hubbe)  SIMPLE_BAD_ARG_ERROR("`|", 2, get_name_of_type(sp[-2].type));
54db6c1999-03-27Henrik Grubbström (Grubba)  }
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(sp[-2].type) {
07c0731996-06-21Fredrik Hübinette (Hubbe)  case T_OBJECT: CALL_OPERATOR(LFUN_OR,2); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_INT: sp--; sp[-1].u.integer |= sp[0].u.integer; break; case T_MAPPING: { struct mapping *m;
71f3a21998-11-22Fredrik Hübinette (Hubbe)  m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, PIKE_ARRAY_OP_OR);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(2); push_mapping(m); return; }
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct multiset *l;
71f3a21998-11-22Fredrik Hübinette (Hubbe)  l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, PIKE_ARRAY_OP_OR);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(2);
06983f1996-09-22Fredrik Hübinette (Hubbe)  push_multiset(l);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; } case T_ARRAY: { struct array *a;
7b1a741999-08-14Fredrik Hübinette (Hubbe)  a=merge_array_with_order(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_OR);
c1d3f21999-08-16Fredrik Hübinette (Hubbe)  pop_n_elems(2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  push_array(a); return; }
3db0d21999-12-13Henrik Grubbström (Grubba)  case T_TYPE: { struct pike_string *t; t = or_pike_types(sp[-2].u.string, sp[-1].u.string, 0); pop_n_elems(2); push_string(t); sp[-1].type = T_TYPE; return; }
dc7d491999-12-15Henrik Grubbström (Grubba)  case T_FUNCTION: case T_PROGRAM: { struct program *p; struct pike_string *a; struct pike_string *b; struct pike_string *t; p = program_from_svalue(sp - 2); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`|", 1, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); a = pop_unfinished_type(); p = program_from_svalue(sp - 1); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`|", 2, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); b = pop_unfinished_type(); t = or_pike_types(a, b, 0); pop_n_elems(2); push_string(t); sp[-1].type = T_TYPE; free_string(a); free_string(b); return; }
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  STRING_BITOP(|,"OR")
fc0bb51997-02-13Niels Möller 
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`|", "Bitwise or on illegal type.\n", sp, 2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_or(INT32 args)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) { switch(args) {
54db6c1999-03-27Henrik Grubbström (Grubba)  case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`|", 1);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  case 1: return; case 2: o_or(); return;
07c0731996-06-21Fredrik Hübinette (Hubbe)  default: if(sp[-args].type==T_OBJECT) { CALL_OPERATOR(LFUN_OR, args); } else {
3c04e81997-03-13Fredrik Hübinette (Hubbe)  speedup(args, o_or);
07c0731996-06-21Fredrik Hübinette (Hubbe)  }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  } } static int generate_or(node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  switch(count_args(CDR(n))) { case 1: do_docode(CDR(n),0); return 1; case 2: do_docode(CDR(n),0);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_OR);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; default: return 0; } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_xor(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-1].type != sp[-2].type) {
dc7d491999-12-15Henrik Grubbström (Grubba)  if(call_lfun(LFUN_XOR, LFUN_RXOR)) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  return;
dc7d491999-12-15Henrik Grubbström (Grubba)  } 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) { struct program *p = program_from_svalue(sp - 2); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`^", 1, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); free_svalue(sp - 2); sp[-2].u.string = pop_unfinished_type(); sp[-2].type = T_TYPE; } if (sp[-1].type != T_TYPE) { struct program *p = program_from_svalue(sp - 1); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`^", 2, "type"); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); free_svalue(sp - 1); sp[-1].u.string = pop_unfinished_type(); sp[-1].type = T_TYPE; } } else {
54db6c1999-03-27Henrik Grubbström (Grubba)  int args = 2;
b341a61999-11-04Fredrik Hübinette (Hubbe)  SIMPLE_BAD_ARG_ERROR("`^", 2, get_name_of_type(sp[-2].type));
54db6c1999-03-27Henrik Grubbström (Grubba)  }
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(sp[-2].type) {
07c0731996-06-21Fredrik Hübinette (Hubbe)  case T_OBJECT: CALL_OPERATOR(LFUN_XOR,2); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_INT: sp--; sp[-1].u.integer ^= sp[0].u.integer; break; case T_MAPPING: { struct mapping *m;
71f3a21998-11-22Fredrik Hübinette (Hubbe)  m=merge_mappings(sp[-2].u.mapping, sp[-1].u.mapping, PIKE_ARRAY_OP_XOR);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(2); push_mapping(m); return; }
06983f1996-09-22Fredrik Hübinette (Hubbe)  case T_MULTISET:
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct multiset *l;
71f3a21998-11-22Fredrik Hübinette (Hubbe)  l=merge_multisets(sp[-2].u.multiset, sp[-1].u.multiset, PIKE_ARRAY_OP_XOR);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_n_elems(2);
06983f1996-09-22Fredrik Hübinette (Hubbe)  push_multiset(l);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; } case T_ARRAY: { struct array *a;
7b1a741999-08-14Fredrik Hübinette (Hubbe)  a=merge_array_with_order(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_XOR);
c1d3f21999-08-16Fredrik Hübinette (Hubbe)  pop_n_elems(2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  push_array(a); return; }
fc0bb51997-02-13Niels Möller 
dc7d491999-12-15Henrik Grubbström (Grubba)  case T_FUNCTION: case T_PROGRAM: { struct program *p; p = program_from_svalue(sp - 1); if (!p) { int args = 2; SIMPLE_BAD_ARG_ERROR("`^", 2, "type"); } type_stack_mark();
9495d81999-12-15Henrik Grubbström (Grubba)  push_type_int(p->id);
dc7d491999-12-15Henrik Grubbström (Grubba)  push_type(0); push_type(T_OBJECT); pop_stack(); push_string(pop_unfinished_type()); sp[-1].type = T_TYPE; stack_swap(); p = program_from_svalue(sp - 1); if (!p) { int args = 2; stack_swap(); SIMPLE_BAD_ARG_ERROR("`^", 1, "type"); } type_stack_mark();
9495d81999-12-15Henrik Grubbström (Grubba)  push_type_int(p->id);
dc7d491999-12-15Henrik Grubbström (Grubba)  push_type(0); push_type(T_OBJECT); pop_stack(); push_string(pop_unfinished_type()); sp[-1].type = T_TYPE; } /* FALL_THROUGH */
3db0d21999-12-13Henrik Grubbström (Grubba)  case T_TYPE: {
0e801c1999-12-13Henrik Grubbström (Grubba)  /* a ^ b == (a&~b)|(~a&b) */
3db0d21999-12-13Henrik Grubbström (Grubba)  struct pike_string *a; struct pike_string *b; copy_shared_string(a, sp[-2].u.string); copy_shared_string(b, sp[-1].u.string);
0e801c1999-12-13Henrik Grubbström (Grubba)  o_compl(); /* ~b */ o_and(); /* a&~b */
3db0d21999-12-13Henrik Grubbström (Grubba)  push_string(a); sp[-1].type = T_TYPE;
0e801c1999-12-13Henrik Grubbström (Grubba)  o_compl(); /* ~a */
3db0d21999-12-13Henrik Grubbström (Grubba)  push_string(b); sp[-1].type = T_TYPE;
0e801c1999-12-13Henrik Grubbström (Grubba)  o_and(); /* ~a&b */ o_or(); /* (a&~b)|(~a&b) */
3db0d21999-12-13Henrik Grubbström (Grubba)  return; }
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  STRING_BITOP(^,"XOR")
fc0bb51997-02-13Niels Möller 
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`^", "Bitwise XOR on illegal type.\n", sp, 2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_xor(INT32 args)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) { switch(args) {
54db6c1999-03-27Henrik Grubbström (Grubba)  case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`^", 1);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  case 1: return; case 2: o_xor(); return;
07c0731996-06-21Fredrik Hübinette (Hubbe)  default: if(sp[-args].type==T_OBJECT) { CALL_OPERATOR(LFUN_XOR, args); } else {
3c04e81997-03-13Fredrik Hübinette (Hubbe)  speedup(args, o_xor);
07c0731996-06-21Fredrik Hübinette (Hubbe)  }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  } } static int generate_xor(node *n) { switch(count_args(CDR(n))) { case 1: do_docode(CDR(n),0); return 1; case 2: do_docode(CDR(n),0);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_XOR);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; default: return 0; } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_lsh(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
ff0d461999-10-15Fredrik Noring #ifdef AUTO_BIGNUM if(INT_TYPE_LSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) convert_stack_top_to_bignum(); #endif /* AUTO_BIGNUM */
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-1].type != T_INT || sp[-2].type != T_INT)
07c0731996-06-21Fredrik Hübinette (Hubbe)  {
54db6c1999-03-27Henrik Grubbström (Grubba)  int args = 2;
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(call_lfun(LFUN_LSH, LFUN_RLSH))
07c0731996-06-21Fredrik Hübinette (Hubbe)  return;
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-2].type != T_INT)
54db6c1999-03-27Henrik Grubbström (Grubba)  SIMPLE_BAD_ARG_ERROR("`<<", 1, "int|object"); SIMPLE_BAD_ARG_ERROR("`<<", 2, "int|object");
07c0731996-06-21Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp--;
8a630c1996-04-13Fredrik Hübinette (Hubbe)  sp[-1].u.integer = sp[-1].u.integer << sp->u.integer;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_lsh(INT32 args)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
54db6c1999-03-27Henrik Grubbström (Grubba)  if(args != 2) { /* FIXME: Not appropriate if too many args. */ SIMPLE_TOO_FEW_ARGS_ERROR("`<<", 2); }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  o_lsh(); } static int generate_lsh(node *n) { if(count_args(CDR(n))==2) { do_docode(CDR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_LSH);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; } return 0; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_rsh(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-2].type != T_INT || sp[-1].type != T_INT)
07c0731996-06-21Fredrik Hübinette (Hubbe)  {
54db6c1999-03-27Henrik Grubbström (Grubba)  int args = 2;
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(call_lfun(LFUN_RSH, LFUN_RRSH))
07c0731996-06-21Fredrik Hübinette (Hubbe)  return;
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-2].type != T_INT)
54db6c1999-03-27Henrik Grubbström (Grubba)  SIMPLE_BAD_ARG_ERROR("`>>", 1, "int|object"); SIMPLE_BAD_ARG_ERROR("`>>", 2, "int|object");
07c0731996-06-21Fredrik Hübinette (Hubbe)  }
ff0d461999-10-15Fredrik Noring  #ifdef AUTO_BIGNUM if(INT_TYPE_RSH_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) { sp--; sp[-1].u.integer = 0; return; } #endif /* AUTO_BIGNUM */
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp--;
8a630c1996-04-13Fredrik Hübinette (Hubbe)  sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_rsh(INT32 args)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
54db6c1999-03-27Henrik Grubbström (Grubba)  if(args != 2) { /* FIXME: Not appropriate if too many args. */ SIMPLE_TOO_FEW_ARGS_ERROR("`>>", 2); }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  o_rsh(); } static int generate_rsh(node *n) { if(count_args(CDR(n))==2)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  do_docode(CDR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_RSH);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; } return 0; }
bce86c1996-02-25Fredrik Hübinette (Hubbe)  #define TWO_TYPES(X,Y) (((X)<<8)|(Y))
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_multiply(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
54db6c1999-03-27Henrik Grubbström (Grubba)  int args = 2;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  switch(TWO_TYPES(sp[-2].type,sp[-1].type))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
1b61661998-02-19Fredrik Hübinette (Hubbe)  case TWO_TYPES(T_ARRAY, T_INT): { struct array *ret; struct svalue *pos; INT32 e; if(sp[-1].u.integer < 0)
54db6c1999-03-27Henrik Grubbström (Grubba)  SIMPLE_BAD_ARG_ERROR("`*", 2, "int(0..)");
1b61661998-02-19Fredrik Hübinette (Hubbe)  ret=allocate_array(sp[-2].u.array->size * sp[-1].u.integer); pos=ret->item; for(e=0;e<sp[-1].u.integer;e++,pos+=sp[-2].u.array->size) assign_svalues_no_free(pos, sp[-2].u.array->item, sp[-2].u.array->size, sp[-2].u.array->type_field); ret->type_field=sp[-2].u.array->type_field; pop_n_elems(2); push_array(ret); return; } case TWO_TYPES(T_STRING, T_INT): { struct pike_string *ret; char *pos;
e4b2252000-08-09Henrik Grubbström (Grubba)  INT_TYPE e; ptrdiff_t len;
1b61661998-02-19Fredrik Hübinette (Hubbe)  if(sp[-1].u.integer < 0)
54db6c1999-03-27Henrik Grubbström (Grubba)  SIMPLE_BAD_ARG_ERROR("`*", 2, "int(0..)");
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  ret=begin_wide_shared_string(sp[-2].u.string->len * sp[-1].u.integer, sp[-2].u.string->size_shift);
1b61661998-02-19Fredrik Hübinette (Hubbe)  pos=ret->str;
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  len=sp[-2].u.string->len << sp[-2].u.string->size_shift; for(e=0;e<sp[-1].u.integer;e++,pos+=len) MEMCPY(pos,sp[-2].u.string->str,len);
1b61661998-02-19Fredrik Hübinette (Hubbe)  pop_n_elems(2);
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  push_string(low_end_shared_string(ret));
1b61661998-02-19Fredrik Hübinette (Hubbe)  return; }
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case TWO_TYPES(T_ARRAY,T_STRING):
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *ret;
fb5c4f1996-03-24Fredrik Hübinette (Hubbe)  ret=implode(sp[-2].u.array,sp[-1].u.string); free_string(sp[-1].u.string); free_array(sp[-2].u.array); sp[-2].type=T_STRING; sp[-2].u.string=ret;
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp--; return; }
f5466b1997-02-18Fredrik Hübinette (Hubbe)  case TWO_TYPES(T_ARRAY,T_ARRAY): { struct array *ret; ret=implode_array(sp[-2].u.array, sp[-1].u.array); pop_n_elems(2); push_array(ret);
1b61661998-02-19Fredrik Hübinette (Hubbe)  return;
f5466b1997-02-18Fredrik Hübinette (Hubbe)  }
bce86c1996-02-25Fredrik Hübinette (Hubbe)  case TWO_TYPES(T_FLOAT,T_FLOAT):
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp--; sp[-1].u.float_number *= sp[0].u.float_number; return;
bce86c1996-02-25Fredrik Hübinette (Hubbe)  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):
fda0de1999-10-08Fredrik Noring #ifdef AUTO_BIGNUM
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  if(INT_TYPE_MUL_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer))
fda0de1999-10-08Fredrik Noring  {
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  convert_stack_top_to_bignum(); goto do_lfun_multiply;
fda0de1999-10-08Fredrik Noring  } #endif /* AUTO_BIGNUM */
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp--; sp[-1].u.integer *= sp[0].u.integer; return; default:
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  do_lfun_multiply:
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(call_lfun(LFUN_MULTIPLY, LFUN_RMULTIPLY))
07c0731996-06-21Fredrik Hübinette (Hubbe)  return;
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`*", "Bad arguments.\n", sp, 2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_multiply(INT32 args)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) { switch(args) {
54db6c1999-03-27Henrik Grubbström (Grubba)  case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`*", 1);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  case 1: return; case 2: o_multiply(); return;
07c0731996-06-21Fredrik Hübinette (Hubbe)  default: if(sp[-args].type==T_OBJECT) { CALL_OPERATOR(LFUN_MULTIPLY, args); } else { while(--args > 0) o_multiply(); }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  } } static int generate_multiply(node *n) { switch(count_args(CDR(n))) { case 1: do_docode(CDR(n),0); return 1; case 2: do_docode(CDR(n),0);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_MULTIPLY);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; default: return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_divide(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-2].type!=sp[-1].type && !float_promote()) { if(call_lfun(LFUN_DIVIDE, LFUN_RDIVIDE)) return;
1b61661998-02-19Fredrik Hübinette (Hubbe)  switch(TWO_TYPES(sp[-2].type,sp[-1].type)) { case TWO_TYPES(T_STRING,T_INT): { struct array *a;
e4b2252000-08-09Henrik Grubbström (Grubba)  INT_TYPE len; ptrdiff_t size,e,pos=0;
1b61661998-02-19Fredrik Hübinette (Hubbe)  len=sp[-1].u.integer; if(!len)
54db6c1999-03-27Henrik Grubbström (Grubba)  OP_DIVISION_BY_ZERO_ERROR("`/");
1b61661998-02-19Fredrik Hübinette (Hubbe)  if(len<0) { len=-len;
d429a71998-02-24Fredrik Hübinette (Hubbe)  size=sp[-2].u.string->len / len; pos+=sp[-2].u.string->len % len; }else{ size=sp[-2].u.string->len / len;
1b61661998-02-19Fredrik Hübinette (Hubbe)  } a=allocate_array(size); for(e=0;e<size;e++) {
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  a->item[e].u.string=string_slice(sp[-2].u.string, pos,len);
1b61661998-02-19Fredrik Hübinette (Hubbe)  a->item[e].type=T_STRING; pos+=len; } a->type_field=BIT_STRING; pop_n_elems(2); push_array(a); return; } case TWO_TYPES(T_STRING,T_FLOAT): { struct array *a;
e4b2252000-08-09Henrik Grubbström (Grubba)  ptrdiff_t size, pos, last, e;
1b61661998-02-19Fredrik Hübinette (Hubbe)  double len; len=sp[-1].u.float_number; if(len==0.0)
54db6c1999-03-27Henrik Grubbström (Grubba)  OP_DIVISION_BY_ZERO_ERROR("`/");
1b61661998-02-19Fredrik Hübinette (Hubbe)  if(len<0) { len=-len;
e4b2252000-08-09Henrik Grubbström (Grubba)  size=(ptrdiff_t)ceil( ((double)sp[-2].u.string->len) / len);
1b61661998-02-19Fredrik Hübinette (Hubbe)  a=allocate_array(size);
d429a71998-02-24Fredrik Hübinette (Hubbe)  for(last=sp[-2].u.string->len,e=0;e<size-1;e++)
1b61661998-02-19Fredrik Hübinette (Hubbe)  {
080b1a2000-08-10Henrik Grubbström (Grubba)  pos=sp[-2].u.string->len - (ptrdiff_t)((e+1)*len);
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  a->item[size-1-e].u.string=string_slice(sp[-2].u.string, pos, last-pos);
d429a71998-02-24Fredrik Hübinette (Hubbe)  a->item[size-1-e].type=T_STRING;
1b61661998-02-19Fredrik Hübinette (Hubbe)  last=pos; } pos=0;
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  a->item[0].u.string=string_slice(sp[-2].u.string, pos, last-pos);
d429a71998-02-24Fredrik Hübinette (Hubbe)  a->item[0].type=T_STRING;
1b61661998-02-19Fredrik Hübinette (Hubbe)  }else{
080b1a2000-08-10Henrik Grubbström (Grubba)  size=(ptrdiff_t)ceil( ((double)sp[-2].u.string->len) / len);
1b61661998-02-19Fredrik Hübinette (Hubbe)  a=allocate_array(size);
d429a71998-02-24Fredrik Hübinette (Hubbe)  for(last=0,e=0;e<size-1;e++)
1b61661998-02-19Fredrik Hübinette (Hubbe)  { pos=(INT32)((e+1)*len);
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  a->item[e].u.string=string_slice(sp[-2].u.string, last, pos-last);
d429a71998-02-24Fredrik Hübinette (Hubbe)  a->item[e].type=T_STRING;
1b61661998-02-19Fredrik Hübinette (Hubbe)  last=pos; }
d429a71998-02-24Fredrik Hübinette (Hubbe)  pos=sp[-2].u.string->len;
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  a->item[e].u.string=string_slice(sp[-2].u.string, last, pos-last);
d429a71998-02-24Fredrik Hübinette (Hubbe)  a->item[e].type=T_STRING;
1b61661998-02-19Fredrik Hübinette (Hubbe)  } a->type_field=BIT_STRING; pop_n_elems(2); push_array(a);
d429a71998-02-24Fredrik Hübinette (Hubbe)  return;
1b61661998-02-19Fredrik Hübinette (Hubbe)  } case TWO_TYPES(T_ARRAY, T_INT): { struct array *a;
e4b2252000-08-09Henrik Grubbström (Grubba)  ptrdiff_t size,e,len,pos;
1b61661998-02-19Fredrik Hübinette (Hubbe)  len=sp[-1].u.integer; if(!len)
54db6c1999-03-27Henrik Grubbström (Grubba)  OP_DIVISION_BY_ZERO_ERROR("`/");
6e27f61998-07-31Fredrik Hübinette (Hubbe) 
1b61661998-02-19Fredrik Hübinette (Hubbe)  if(len<0) {
6f49401998-07-31Henrik Grubbström (Grubba)  len = -len; pos = sp[-2].u.array->size % len;
d429a71998-02-24Fredrik Hübinette (Hubbe)  }else{
6f49401998-07-31Henrik Grubbström (Grubba)  pos = 0;
1b61661998-02-19Fredrik Hübinette (Hubbe)  }
6f49401998-07-31Henrik Grubbström (Grubba)  size = sp[-2].u.array->size / len;
1b61661998-02-19Fredrik Hübinette (Hubbe)  a=allocate_array(size); for(e=0;e<size;e++) { a->item[e].u.array=friendly_slice_array(sp[-2].u.array, pos, pos+len); pos+=len;
6e27f61998-07-31Fredrik Hübinette (Hubbe)  a->item[e].type=T_ARRAY;
1b61661998-02-19Fredrik Hübinette (Hubbe)  } a->type_field=BIT_ARRAY; pop_n_elems(2); push_array(a); return; } case TWO_TYPES(T_ARRAY,T_FLOAT): { struct array *a;
e4b2252000-08-09Henrik Grubbström (Grubba)  ptrdiff_t last,pos,e,size;
1b61661998-02-19Fredrik Hübinette (Hubbe)  double len; len=sp[-1].u.float_number; if(len==0.0)
54db6c1999-03-27Henrik Grubbström (Grubba)  OP_DIVISION_BY_ZERO_ERROR("`/");
1b61661998-02-19Fredrik Hübinette (Hubbe)  if(len<0) { len=-len;
e4b2252000-08-09Henrik Grubbström (Grubba)  size = (ptrdiff_t)ceil( ((double)sp[-2].u.array->size) / len);
1b61661998-02-19Fredrik Hübinette (Hubbe)  a=allocate_array(size);
d429a71998-02-24Fredrik Hübinette (Hubbe)  for(last=sp[-2].u.array->size,e=0;e<size-1;e++)
1b61661998-02-19Fredrik Hübinette (Hubbe)  {
080b1a2000-08-10Henrik Grubbström (Grubba)  pos=sp[-2].u.array->size - (ptrdiff_t)((e+1)*len);
d429a71998-02-24Fredrik Hübinette (Hubbe)  a->item[size-1-e].u.array=friendly_slice_array(sp[-2].u.array,
1b61661998-02-19Fredrik Hübinette (Hubbe)  pos, last);
d429a71998-02-24Fredrik Hübinette (Hubbe)  a->item[size-1-e].type=T_ARRAY;
1b61661998-02-19Fredrik Hübinette (Hubbe)  last=pos; }
d429a71998-02-24Fredrik Hübinette (Hubbe)  a->item[0].u.array=slice_array(sp[-2].u.array,
1b61661998-02-19Fredrik Hübinette (Hubbe)  0, last);
d429a71998-02-24Fredrik Hübinette (Hubbe)  a->item[0].type=T_ARRAY;
1b61661998-02-19Fredrik Hübinette (Hubbe)  }else{
080b1a2000-08-10Henrik Grubbström (Grubba)  size = (ptrdiff_t)ceil( ((double)sp[-2].u.array->size) / len);
1b61661998-02-19Fredrik Hübinette (Hubbe)  a=allocate_array(size);
d429a71998-02-24Fredrik Hübinette (Hubbe)  for(last=0,e=0;e<size-1;e++)
1b61661998-02-19Fredrik Hübinette (Hubbe)  {
080b1a2000-08-10Henrik Grubbström (Grubba)  pos = (ptrdiff_t)((e+1)*len);
1b61661998-02-19Fredrik Hübinette (Hubbe)  a->item[e].u.array=friendly_slice_array(sp[-2].u.array, last, pos);
d429a71998-02-24Fredrik Hübinette (Hubbe)  a->item[e].type=T_ARRAY;
1b61661998-02-19Fredrik Hübinette (Hubbe)  last=pos; } a->item[e].u.array=slice_array(sp[-2].u.array, last,
d429a71998-02-24Fredrik Hübinette (Hubbe)  sp[-2].u.array->size); a->item[e].type=T_ARRAY;
1b61661998-02-19Fredrik Hübinette (Hubbe)  } a->type_field=BIT_ARRAY; pop_n_elems(2); push_array(a);
d429a71998-02-24Fredrik Hübinette (Hubbe)  return;
1b61661998-02-19Fredrik Hübinette (Hubbe)  } }
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`/", "Division on different types.\n", sp, 2);
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  switch(sp[-2].type) {
07c0731996-06-21Fredrik Hübinette (Hubbe)  case T_OBJECT:
08b9801999-10-30Fredrik Noring  do_lfun_division:
07c0731996-06-21Fredrik Hübinette (Hubbe)  CALL_OPERATOR(LFUN_DIVIDE,2); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_STRING: { struct array *ret;
fb5c4f1996-03-24Fredrik Hübinette (Hubbe)  ret=explode(sp[-2].u.string,sp[-1].u.string); free_string(sp[-2].u.string);
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_string(sp[-1].u.string);
fb5c4f1996-03-24Fredrik Hübinette (Hubbe)  sp[-2].type=T_ARRAY; sp[-2].u.array=ret; sp--;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; }
f5466b1997-02-18Fredrik Hübinette (Hubbe)  case T_ARRAY: { struct array *ret=explode_array(sp[-2].u.array, sp[-1].u.array); pop_n_elems(2); push_array(ret); return; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_FLOAT: if(sp[-1].u.float_number == 0.0)
54db6c1999-03-27Henrik Grubbström (Grubba)  OP_DIVISION_BY_ZERO_ERROR("`/");
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp--; sp[-1].u.float_number /= sp[0].u.float_number; return; case T_INT:
806a2c1997-04-28Fredrik Hübinette (Hubbe)  {
e4b2252000-08-09Henrik Grubbström (Grubba)  INT_TYPE tmp;
08b9801999-10-30Fredrik Noring 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if (sp[-1].u.integer == 0)
54db6c1999-03-27Henrik Grubbström (Grubba)  OP_DIVISION_BY_ZERO_ERROR("`/");
806a2c1997-04-28Fredrik Hübinette (Hubbe) 
08b9801999-10-30Fredrik Noring  if(INT_TYPE_DIV_OVERFLOW(sp[-2].u.integer, sp[-1].u.integer)) { #ifdef AUTO_BIGNUM stack_swap(); convert_stack_top_to_bignum(); stack_swap(); goto do_lfun_division; #else /* It's not possible to do MININT/-1 (it gives FPU exception on some CPU:s), thus we return what MININT*-1 returns: MININT. */ tmp = sp[-2].u.integer; #endif /* AUTO_BIGNUM */ } else tmp = sp[-2].u.integer/sp[-1].u.integer; sp--;
c93f0e1997-12-03Fredrik Hübinette (Hubbe) 
08b9801999-10-30Fredrik Noring  /* What is this trying to solve? /Noring */
c93f0e1997-12-03Fredrik Hübinette (Hubbe)  if((sp[-1].u.integer<0) != (sp[0].u.integer<0)) if(tmp*sp[0].u.integer!=sp[-1].u.integer)
806a2c1997-04-28Fredrik Hübinette (Hubbe)  tmp--; sp[-1].u.integer=tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  return;
806a2c1997-04-28Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`/", "Bad argument 1.\n", sp, 2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_divide(INT32 args)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) {
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  switch(args) { case 0:
54db6c1999-03-27Henrik Grubbström (Grubba)  case 1: SIMPLE_TOO_FEW_ARGS_ERROR("`/", 2);
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  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); } }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) } static int generate_divide(node *n) { if(count_args(CDR(n))==2) { do_docode(CDR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_DIVIDE);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; } return 0; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_mod(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  if(sp[-2].type != sp[-1].type && !float_promote()) { if(call_lfun(LFUN_MOD, LFUN_RMOD)) return;
1b61661998-02-19Fredrik Hübinette (Hubbe)  switch(TWO_TYPES(sp[-2].type,sp[-1].type)) { case TWO_TYPES(T_STRING,T_INT): { struct pike_string *s=sp[-2].u.string;
e4b2252000-08-09Henrik Grubbström (Grubba)  ptrdiff_t tmp,base;
1b61661998-02-19Fredrik Hübinette (Hubbe)  if(!sp[-1].u.integer)
54db6c1999-03-27Henrik Grubbström (Grubba)  OP_MODULO_BY_ZERO_ERROR("`%");
1b61661998-02-19Fredrik Hübinette (Hubbe) 
d429a71998-02-24Fredrik Hübinette (Hubbe)  tmp=sp[-1].u.integer; if(tmp<0) { tmp=s->len % -tmp; base=0; }else{ tmp=s->len % tmp; base=s->len - tmp; }
0bc4cf1998-10-13Fredrik Hübinette (Hubbe)  s=string_slice(s, base, tmp);
1b61661998-02-19Fredrik Hübinette (Hubbe)  pop_n_elems(2); push_string(s); return; } case TWO_TYPES(T_ARRAY,T_INT): { struct array *a=sp[-2].u.array; INT32 tmp,base; if(!sp[-1].u.integer)
54db6c1999-03-27Henrik Grubbström (Grubba)  OP_MODULO_BY_ZERO_ERROR("`%");
1b61661998-02-19Fredrik Hübinette (Hubbe) 
d429a71998-02-24Fredrik Hübinette (Hubbe)  tmp=sp[-1].u.integer; if(tmp<0) { tmp=a->size % -tmp; base=0; }else{ tmp=a->size % tmp; base=a->size - tmp; }
1b61661998-02-19Fredrik Hübinette (Hubbe)  a=slice_array(a,base,base+tmp); pop_n_elems(2); push_array(a); return; } }
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`%", "Modulo on different types.\n", sp, 2);
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
07c0731996-06-21Fredrik Hübinette (Hubbe)  switch(sp[-2].type)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
07c0731996-06-21Fredrik Hübinette (Hubbe)  case T_OBJECT: CALL_OPERATOR(LFUN_MOD,2); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_FLOAT: { FLOAT_TYPE foo; if(sp[-1].u.float_number == 0.0)
54db6c1999-03-27Henrik Grubbström (Grubba)  OP_MODULO_BY_ZERO_ERROR("`%");
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp--; foo=sp[-1].u.float_number / sp[0].u.float_number; foo=sp[-1].u.float_number - sp[0].u.float_number * floor(foo); sp[-1].u.float_number=foo; return; } case T_INT:
54db6c1999-03-27Henrik Grubbström (Grubba)  if (sp[-1].u.integer == 0) OP_MODULO_BY_ZERO_ERROR("`%");
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp--;
806a2c1997-04-28Fredrik Hübinette (Hubbe)  if(sp[-1].u.integer>=0) { if(sp[0].u.integer>=0) { sp[-1].u.integer %= sp[0].u.integer; }else{
9024ae1997-09-11Fredrik Hübinette (Hubbe)  sp[-1].u.integer=((sp[-1].u.integer+~sp[0].u.integer)%-sp[0].u.integer)-~sp[0].u.integer;
806a2c1997-04-28Fredrik Hübinette (Hubbe)  } }else{ if(sp[0].u.integer>=0) {
9024ae1997-09-11Fredrik Hübinette (Hubbe)  sp[-1].u.integer=sp[0].u.integer+~((~sp[-1].u.integer) % sp[0].u.integer);
806a2c1997-04-28Fredrik Hübinette (Hubbe)  }else{ sp[-1].u.integer=-(-sp[-1].u.integer % -sp[0].u.integer); } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  return; default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`%", "Bad argument 1.\n", sp, 2);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_mod(INT32 args)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
54db6c1999-03-27Henrik Grubbström (Grubba)  if(args != 2) { /* FIXME: Not appropriate when too many args. */ SIMPLE_TOO_FEW_ARGS_ERROR("`%", 2); }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  o_mod(); } static int generate_mod(node *n) { if(count_args(CDR(n))==2)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  do_docode(CDR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_MOD);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; } return 0; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_not(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
07c0731996-06-21Fredrik Hübinette (Hubbe)  switch(sp[-1].type)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
07c0731996-06-21Fredrik Hübinette (Hubbe)  case T_INT:
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp[-1].u.integer = !sp[-1].u.integer;
07c0731996-06-21Fredrik Hübinette (Hubbe)  break; case T_FUNCTION: case T_OBJECT: if(IS_ZERO(sp-1)) { pop_stack(); push_int(1); }else{ pop_stack(); push_int(0); } break; default: free_svalue(sp-1); sp[-1].type=T_INT; sp[-1].u.integer=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_not(INT32 args)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) {
54db6c1999-03-27Henrik Grubbström (Grubba)  if(args != 1) { /* FIXME: Not appropriate with too many args. */ SIMPLE_TOO_FEW_ARGS_ERROR("`!", 1); }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  o_not(); } static int generate_not(node *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  if(count_args(CDR(n))==1) { do_docode(CDR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_NOT);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; } return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_compl(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { switch(sp[-1].type) {
07c0731996-06-21Fredrik Hübinette (Hubbe)  case T_OBJECT: CALL_OPERATOR(LFUN_COMPL,1); break;
8a630c1996-04-13Fredrik Hübinette (Hubbe)  case T_INT: sp[-1].u.integer = ~ sp[-1].u.integer; break; case T_FLOAT: sp[-1].u.float_number = -1.0 - sp[-1].u.float_number; break;
0e801c1999-12-13Henrik Grubbström (Grubba)  case T_TYPE: type_stack_mark();
dc7d491999-12-15Henrik Grubbström (Grubba)  if (EXTRACT_UCHAR(sp[-1].u.string->str) == T_NOT) { push_unfinished_type(sp[-1].u.string->str + 1); } else { push_unfinished_type(sp[-1].u.string->str); push_type(T_NOT); }
0e801c1999-12-13Henrik Grubbström (Grubba)  pop_stack(); push_string(pop_unfinished_type()); sp[-1].type = T_TYPE; break;
dc7d491999-12-15Henrik Grubbström (Grubba)  case T_FUNCTION: case T_PROGRAM: { /* !object(p) */ struct program *p = program_from_svalue(sp - 1); if (!p) { PIKE_ERROR("`~", "Bad argument.\n", sp, 1); } type_stack_mark(); push_type_int(p->id); push_type(0); push_type(T_OBJECT); push_type(T_NOT); pop_stack(); push_string(pop_unfinished_type()); sp[-1].type = T_TYPE; } break;
fc0bb51997-02-13Niels Möller  case T_STRING: { struct pike_string *s;
080b1a2000-08-10Henrik Grubbström (Grubba)  ptrdiff_t len, i;
fc0bb51997-02-13Niels Möller 
54db6c1999-03-27Henrik Grubbström (Grubba)  if(sp[-1].u.string->size_shift) { bad_arg_error("`~", sp-1, 1, 1, "string(0)", sp-1, "Expected 8-bit string.\n"); }
0bc4cf1998-10-13Fredrik Hübinette (Hubbe) 
fc0bb51997-02-13Niels Möller  len = sp[-1].u.string->len; s = begin_shared_string(len); for (i=0; i<len; i++) s->str[i] = ~ sp[-1].u.string->str[i]; pop_n_elems(1); push_string(end_shared_string(s)); break; }
8a630c1996-04-13Fredrik Hübinette (Hubbe)  default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`~", "Bad argument.\n", sp, 1);
8a630c1996-04-13Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_compl(INT32 args)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) {
54db6c1999-03-27Henrik Grubbström (Grubba)  if(args != 1) { /* FIXME: Not appropriate with too many args. */ SIMPLE_TOO_FEW_ARGS_ERROR("`~", 1); }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  o_compl(); } static int generate_compl(node *n) { if(count_args(CDR(n))==1) { do_docode(CDR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_COMPL);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe)  return 1; } return 0; }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_negate(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { switch(sp[-1].type) {
07c0731996-06-21Fredrik Hübinette (Hubbe)  case T_OBJECT:
ff0d461999-10-15Fredrik Noring  do_lfun_negate:
07c0731996-06-21Fredrik Hübinette (Hubbe)  CALL_OPERATOR(LFUN_SUBTRACT,1); break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  case T_FLOAT: sp[-1].u.float_number=-sp[-1].u.float_number; return; case T_INT:
ff0d461999-10-15Fredrik Noring #ifdef AUTO_BIGNUM if(INT_TYPE_NEG_OVERFLOW(sp[-1].u.integer)) { convert_stack_top_to_bignum(); goto do_lfun_negate; } #endif /* AUTO_BIGNUM */
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp[-1].u.integer = - sp[-1].u.integer; return; default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`-", "Bad argument to unary minus.\n", sp, 1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void o_range(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
146a322000-08-03Henrik Grubbström (Grubba)  ptrdiff_t from,to;
8a586b1997-01-27Fredrik Hübinette (Hubbe)  if(sp[-3].type==T_OBJECT) {
8856131997-10-10Fredrik Hübinette (Hubbe)  CALL_OPERATOR(LFUN_INDEX, 3);
8a586b1997-01-27Fredrik Hübinette (Hubbe)  return; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(sp[-2].type != T_INT)
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`[]", "Bad argument 2 to [ .. ]\n", sp, 3);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(sp[-1].type != T_INT)
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`[]", "Bad argument 3 to [ .. ]\n", sp, 3);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
146a322000-08-03Henrik Grubbström (Grubba)  from = sp[-2].u.integer; if(from<0) from = 0; to = sp[-1].u.integer; if(to<from-1) to = from-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  sp-=2; switch(sp[-1].type) { case T_STRING: {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
22e81d2000-08-03Henrik Grubbström (Grubba)  if(to >= sp[-1].u.string->len-1)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { if(from==0) return;
146a322000-08-03Henrik Grubbström (Grubba)  to = sp[-1].u.string->len-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(from>to+1) from=to+1; }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
62260a1996-11-26Fredrik Hübinette (Hubbe)  if(from < 0 || (to-from+1) < 0) fatal("Error in o_range.\n"); #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
3e625c1998-10-11Fredrik Hübinette (Hubbe)  s=string_slice(sp[-1].u.string, from, to-from+1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_string(sp[-1].u.string); sp[-1].u.string=s; break; } case T_ARRAY: { struct array *a;
22e81d2000-08-03Henrik Grubbström (Grubba)  if(to >= sp[-1].u.array->size-1)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
146a322000-08-03Henrik Grubbström (Grubba)  to = sp[-1].u.array->size-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(from>to+1) from=to+1; }
e4b2252000-08-09Henrik Grubbström (Grubba)  a = slice_array(sp[-1].u.array, from, to+1);
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_array(sp[-1].u.array); sp[-1].u.array=a; break; } default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`[]", "[ .. ] on non-scalar type.\n", sp, 3);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_index(INT32 args)
9f68471997-03-08Fredrik Hübinette (Hubbe) { switch(args) { case 0: case 1:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`[]", "Too few arguments.\n", sp, args);
9f68471997-03-08Fredrik Hübinette (Hubbe)  break; case 2: if(sp[-1].type==T_STRING) sp[-1].subtype=0; o_index(); break; case 3: o_range(); break; default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`[]", "Too many arguments.\n", sp, args);
9f68471997-03-08Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_arrow(INT32 args)
9f68471997-03-08Fredrik Hübinette (Hubbe) { switch(args) { case 0: case 1:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`->", "Too few arguments.\n", sp, args);
9f68471997-03-08Fredrik Hübinette (Hubbe)  break; case 2: if(sp[-1].type==T_STRING) sp[-1].subtype=1; o_index(); break; default:
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("`->", "Too many arguments.\n", sp, args);
9f68471997-03-08Fredrik Hübinette (Hubbe)  } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_index_assign(INT32 args)
912f171999-08-16Martin Stjernholm { switch (args) { case 0: case 1: case 2: PIKE_ERROR("`[]=", "Too few arguments.\n", sp, args); break; case 3:
4856a81999-08-17Martin Stjernholm  if(sp[-2].type==T_STRING) sp[-2].subtype=0; assign_lvalue (sp-3, sp-1);
912f171999-08-16Martin Stjernholm  assign_svalue (sp-3, sp-1); pop_n_elems (args-1); break; default: PIKE_ERROR("`[]=", "Too many arguments.\n", sp, args); } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_arrow_assign(INT32 args)
4856a81999-08-17Martin Stjernholm { 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); } }
1f21332000-07-28Fredrik Hübinette (Hubbe) PMOD_EXPORT void f_sizeof(INT32 args)
4c573c1996-08-03Fredrik Hübinette (Hubbe) { INT32 tmp; if(args<1)
aa366d1998-04-16Fredrik Hübinette (Hubbe)  PIKE_ERROR("sizeof", "Too few arguments.\n", sp, args);
4c573c1996-08-03Fredrik Hübinette (Hubbe) 
06983f1996-09-22Fredrik Hübinette (Hubbe)  tmp=pike_sizeof(sp-args);
4c573c1996-08-03Fredrik Hübinette (Hubbe)  pop_n_elems(args); push_int(tmp); } static int generate_sizeof(node *n) { node **arg; if(count_args(CDR(n)) != 1) return 0; if(do_docode(CDR(n),DO_NOT_COPY) != 1) fatal("Count args was wrong in sizeof().\n");
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_SIZEOF);
4c573c1996-08-03Fredrik Hübinette (Hubbe)  return 1; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) static int generate_call_function(node *n) { node **arg;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_MARK);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  do_docode(CDR(n),DO_NOT_COPY);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  emit0(F_CALL_FUNCTION);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return 1; }
19aaeb1998-05-25Fredrik Hübinette (Hubbe) struct program *string_assignment_program; #undef THIS
60d9872000-03-23Fredrik Hübinette (Hubbe) #define THIS ((struct string_assignment_storage *)(CURRENT_STORAGE))
19aaeb1998-05-25Fredrik Hübinette (Hubbe) static void f_string_assignment_index(INT32 args) {
65a5492000-08-10Per Hedbor  INT_TYPE i;
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  get_all_args("string[]",args,"%i",&i); if(i<0) i+=THIS->s->len; if(i<0) i+=THIS->s->len; if(i<0 || i>=THIS->s->len) error("Index %d is out of range 0 - %d.\n", i, THIS->s->len-1); else
b987f91998-10-12Fredrik Hübinette (Hubbe)  i=index_shared_string(THIS->s,i);
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  pop_n_elems(args); push_int(i); } static void f_string_assignment_assign_index(INT32 args) {
65a5492000-08-10Per Hedbor  INT_TYPE i,j;
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  union anything *u; get_all_args("string[]=",args,"%i%i",&i,&j); if((u=get_pointer_if_this_type(THIS->lval, T_STRING))) { free_string(THIS->s); if(i<0) i+=u->string->len; if(i<0 || i>=u->string->len) error("String index out of range %ld\n",(long)i); u->string=modify_shared_string(u->string,i,j); copy_shared_string(THIS->s, u->string); }else{ lvalue_to_svalue_no_free(sp,THIS->lval); sp++; if(sp[-1].type != T_STRING) error("string[]= failed.\n"); if(i<0) i+=sp[-1].u.string->len; if(i<0 || i>=sp[-1].u.string->len) error("String index out of range %ld\n",(long)i); sp[-1].u.string=modify_shared_string(sp[-1].u.string,i,j); assign_lvalue(THIS->lval, sp-1); pop_stack(); } pop_n_elems(args); push_int(j); } static void init_string_assignment_storage(struct object *o) { THIS->lval[0].type=T_INT; THIS->lval[1].type=T_INT; THIS->s=0; } static void exit_string_assignment_storage(struct object *o) { free_svalues(THIS->lval, 2, BIT_MIXED); if(THIS->s) free_string(THIS->s); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
be478c1997-08-30Henrik Grubbström (Grubba) void init_operators(void)
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) {
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(string,int:int)|function(object,string:mixed)|function(array(0=mixed),int:0)|function(mapping(mixed:1=mixed),mixed:1)|function(multiset,mixed:int)|function(string,int,int:string)|function(array(2=mixed),int,int:array(2))|function(program:mixed) */ ADD_EFUN2("`[]",f_index,tOr7(tFunc(tStr tInt,tInt),tFunc(tObj tStr,tMix),tFunc(tArr(tSetvar(0,tMix)) tInt,tVar(0)),tFunc(tMap(tMix,tSetvar(1,tMix)) tMix,tVar(1)),tFunc(tMultiset tMix,tInt),tFunc(tStr tInt tInt,tStr),tOr(tFunc(tArr(tSetvar(2,tMix)) tInt tInt,tArr(tVar(2))),tFunc(tPrg,tMix))),OPT_TRY_OPTIMIZE,0,0);
9f68471997-03-08Fredrik Hübinette (Hubbe) 
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(array(object|mapping|multiset|array),string:array(mixed))|function(object|mapping|multiset|program,string:mixed) */ ADD_EFUN2("`->",f_arrow,tOr(tFunc(tArr(tOr4(tObj,tMapping,tMultiset,tArray)) tStr,tArr(tMix)),tFunc(tOr4(tObj,tMapping,tMultiset,tPrg) tStr,tMix)),OPT_TRY_OPTIMIZE,0,0);
9f68471997-03-08Fredrik Hübinette (Hubbe) 
912f171999-08-16Martin Stjernholm  ADD_EFUN("`[]=", f_index_assign,
4856a81999-08-17Martin Stjernholm  tOr4(tFunc(tObj tStr tSetvar(0,tMix), tVar(0)),
912f171999-08-16Martin Stjernholm  tFunc(tArr(tSetvar(1,tMix)) tInt tVar(1), tVar(1)), tFunc(tMap(tSetvar(2,tMix), tSetvar(3,tMix)) tVar(2) tVar(3), tVar(3)), tFunc(tSet(tSetvar(4,tMix)) tVar(4) tSetvar(5,tMix), tVar(5))),
6f1d412000-04-08Henrik Grubbström (Grubba)  OPT_SIDE_EFFECT|OPT_TRY_OPTIMIZE);
912f171999-08-16Martin Stjernholm 
4856a81999-08-17Martin Stjernholm  ADD_EFUN("`->=", f_arrow_assign, tOr3(tFunc(tArr(tOr4(tArray,tObj,tMultiset,tMapping)) tStr tSetvar(0,tMix), tVar(0)), tFunc(tOr(tObj, tMultiset) tStr tSetvar(1,tMix), tVar(1)), tFunc(tMap(tMix, tSetvar(2,tMix)) tStr tVar(2), tVar(2))),
6f1d412000-04-08Henrik Grubbström (Grubba)  OPT_SIDE_EFFECT|OPT_TRY_OPTIMIZE);
4856a81999-08-17Martin Stjernholm 
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(mixed...:int) */
563fdc1999-12-27Henrik Grubbström (Grubba)  ADD_EFUN2("`==",f_eq, tOr5(tFuncV(tOr(tInt,tFloat) tOr(tInt,tFloat), tOr(tInt,tFloat),tInt01),
9bab981999-12-27Henrik Grubbström (Grubba)  tFuncV(tSetvar(0,tOr4(tString,tMapping,tMultiset,tArray)) tVar(0), tVar(0),tInt01),
8018a71999-12-27Henrik Grubbström (Grubba)  tFuncV(tOr3(tObj,tProgram,tFunction) tMix,tMix,tInt01), tFuncV(tMix tOr3(tObj,tProgram,tFunction),tMix,tInt01),
563fdc1999-12-27Henrik Grubbström (Grubba)  tFuncV(tType tType,tOr3(tProgram,tFunction,tType),tInt01)),
25c28d1999-12-29Henrik Grubbström (Grubba)  OPT_WEAK_TYPE|OPT_TRY_OPTIMIZE,optimize_eq,generate_comparison);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(mixed...:int) */
563fdc1999-12-27Henrik Grubbström (Grubba)  ADD_EFUN2("`!=",f_ne, tOr5(tFuncV(tOr(tInt,tFloat) tOr(tInt,tFloat), tOr(tInt,tFloat),tInt01),
9bab981999-12-27Henrik Grubbström (Grubba)  tFuncV(tSetvar(0,tOr4(tString,tMapping,tMultiset,tArray)) tVar(0), tVar(0),tInt01),
8018a71999-12-27Henrik Grubbström (Grubba)  tFuncV(tOr3(tObj,tProgram,tFunction) tMix,tMix,tInt01), tFuncV(tMix tOr3(tObj,tProgram,tFunction),tMix,tInt01),
563fdc1999-12-27Henrik Grubbström (Grubba)  tFuncV(tType tType,tOr3(tProgram,tFunction,tType),tInt01)),
25c28d1999-12-29Henrik Grubbström (Grubba)  OPT_WEAK_TYPE|OPT_TRY_OPTIMIZE,0,generate_comparison);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(mixed:int) */
563fdc1999-12-27Henrik Grubbström (Grubba)  ADD_EFUN2("`!",f_not,tFuncV(tMix,tVoid,tInt01), OPT_TRY_OPTIMIZE,optimize_not,generate_not);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
dc7d491999-12-15Henrik Grubbström (Grubba) #define CMP_TYPE "!function(!(object|mixed)...:mixed)&function(mixed...:int(0..1))|function(int|float...:int(0..1))|function(string...:int(0..1))|function(type|program,type|program,type|program...:int(0..1))"
07c0731996-06-21Fredrik Hübinette (Hubbe)  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);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
76db651999-05-25Mirar (Pontus Hagland)  ADD_EFUN2("`+",f_add,
5da6a21999-12-11Henrik Grubbström (Grubba)  tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction),
ad08af1999-05-25Mirar (Pontus Hagland)  tFuncV(tInt,tInt,tInt), tIfnot(tFuncV(tInt,tInt,tMix), tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)), tIfnot(tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tMix), tFuncV(tOr3(tStr,tInt,tFlt), tOr3(tStr,tInt,tFlt),tStr)), tFuncV(tSetvar(0,tArray),tSetvar(1,tArray), tOr(tVar(0),tVar(1))), tFuncV(tSetvar(0,tMapping),tSetvar(1,tMapping), tOr(tVar(0),tVar(1))), tFuncV(tSetvar(0,tMultiset),tSetvar(1,tMultiset), tOr(tVar(0),tVar(1)))),
9e52381998-03-01Fredrik Hübinette (Hubbe)  OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
76db651999-05-25Mirar (Pontus Hagland)  ADD_EFUN2("`-",f_minus,
5da6a21999-12-11Henrik Grubbström (Grubba)  tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction),
76db651999-05-25Mirar (Pontus Hagland)  tFuncV(tInt,tInt,tInt), tIfnot(tFuncV(tInt,tInt,tMix), tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)), tFuncV(tArr(tSetvar(0,tMix)),tArray,tArr(tVar(0))), tFuncV(tMap(tSetvar(1,tMix),tSetvar(2,tMix)),
aa17e32000-04-12Mirar (Pontus Hagland)  tOr3(tMapping,tArray,tMultiset), tMap(tVar(1),tVar(2))),
76db651999-05-25Mirar (Pontus Hagland)  tFunc(tSet(tSetvar(3,tMix)) tMultiset,tSet(tVar(3))), tFuncV(tStr,tStr,tStr)),
1eaa381998-03-04Fredrik Hübinette (Hubbe)  OPT_TRY_OPTIMIZE,0,generate_minus);
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) 
aa17e32000-04-12Mirar (Pontus Hagland) /* object & mixed -> mixed mixed & object -> mixed int & int -> int array & array -> array multiset & multiset -> multiset mapping & mapping -> mapping string & string -> string type|program & type|program -> type|program mapping & array -> mapping array & mapping -> mapping mapping & multiset -> mapping multiset & mapping -> mapping */ #define F_AND_TYPE(Z) \ tOr(tFunc(tSetvar(0,Z),tVar(0)), \ tIfnot(tFunc(Z,tMix), \ tFuncV(tSetvar(1,Z),tSetvar(2,Z), \ tOr(tVar(1),tVar(2)))))
ef2b4e1999-12-18Martin Stjernholm  ADD_EFUN2("`&",f_and,
aa17e32000-04-12Mirar (Pontus Hagland)  tOr4( tFunc(tSetvar(0,tMix),tVar(0)), tOr(tFuncV(tMix tObj,tMix,tMix), tFuncV(tObj tMix,tMix,tMix)), tOr6( F_AND_TYPE(tInt), F_AND_TYPE(tArray), F_AND_TYPE(tMapping), F_AND_TYPE(tMultiset), F_AND_TYPE(tString), F_AND_TYPE(tOr(tType,tPrg)) ), tIfnot(tFuncV(tNone,tOr(tArray,tMultiset),tMix), tFuncV(tNone, tOr3(tArray,tMultiset,tSetvar(4,tMapping)), tVar(4)) ) ),
ef2b4e1999-12-18Martin Stjernholm  OPT_TRY_OPTIMIZE,optimize_binary,generate_and); #define LOG_TYPE \ tOr7(tOr(tFuncV(tMix tObj,tMix,tMix), \ tFuncV(tObj,tMix,tMix)), \ tFuncV(tInt,tInt,tInt), \ tFuncV(tSetvar(1,tMapping),tSetvar(2,tMapping),tOr(tVar(1),tVar(2))), \ tFuncV(tSetvar(3,tMultiset),tSetvar(4,tMultiset),tOr(tVar(3),tVar(4))), \ tFuncV(tSetvar(5,tArray),tSetvar(6,tArray),tOr(tVar(5),tVar(6))), \ tFuncV(tString,tString,tString), \ tFuncV(tOr(tType,tPrg),tOr(tType,tPrg),tType)) ADD_EFUN2("`|",f_or,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_or); ADD_EFUN2("`^",f_xor,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_xor); #define SHIFT_TYPE \ tOr(tOr(tFuncV(tMix tObj,tMix,tMix), \ tFuncV(tObj tMix,tMix,tMix)), \ tFuncV(tInt,tInt,tInt)) ADD_EFUN2("`<<",f_lsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_lsh); ADD_EFUN2("`>>",f_rsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_rsh);
07c0731996-06-21Fredrik Hübinette (Hubbe) 
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* !function(!object...:mixed)&function(mixed...:mixed)|"
1eaa381998-03-04Fredrik Hübinette (Hubbe)  "function(array(array(1=mixed)),array(1=mixed):array(1))|"
1b61661998-02-19Fredrik Hübinette (Hubbe)  "function(int...:int)|" "!function(int...:mixed)&function(float|int...:float)|" "function(string*,string:string)|"
1eaa381998-03-04Fredrik Hübinette (Hubbe)  "function(array(0=mixed),int:array(0))|"
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  "function(string,int:string) */
ad08af1999-05-25Mirar (Pontus Hagland)  ADD_EFUN2("`*",f_multiply,
5da6a21999-12-11Henrik Grubbström (Grubba)  tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction),
ad08af1999-05-25Mirar (Pontus Hagland)  tFunc(tArr(tArr(tSetvar(1,tMix))) tArr(tSetvar(1,tMix)),tArr(tVar(1))), tFuncV(tInt,tInt,tInt), tIfnot(tFuncV(tInt,tInt,tMix), tFuncV(tOr(tFlt,tInt),tOr(tFlt,tInt),tFlt)), tFunc(tArr(tStr) tStr,tStr), tFunc(tArr(tSetvar(0,tMix)) tInt,tArr(tVar(0))), tFunc(tStr tInt,tStr)),
1b61661998-02-19Fredrik Hübinette (Hubbe)  OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* !function(!object...:mixed)&function(mixed...:mixed)|"
5b4dd31998-02-23Fredrik Hübinette (Hubbe)  "function(int,int...:int)|" "!function(int...:mixed)&function(float|int...:float)|"
1eaa381998-03-04Fredrik Hübinette (Hubbe)  "function(array(0=mixed),array|int|float...:array(array(0)))|"
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  "function(string,string|int|float...:array(string)) */
5da6a21999-12-11Henrik Grubbström (Grubba)  ADD_EFUN2("`/",f_divide,tOr5(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction),tFuncV(tInt,tInt,tInt),tIfnot(tFuncV(tNone,tInt,tMix),tFuncV(tNone,tOr(tFlt,tInt),tFlt)),tFuncV(tArr(tSetvar(0,tMix)),tOr3(tArray,tInt,tFlt),tArr(tArr(tVar(0)))),tFuncV(tStr,tOr3(tStr,tInt,tFlt),tArr(tStr))),
1b61661998-02-19Fredrik Hübinette (Hubbe)  OPT_TRY_OPTIMIZE,0,generate_divide);
07c0731996-06-21Fredrik Hübinette (Hubbe) 
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(mixed,object:mixed)|"
d429a71998-02-24Fredrik Hübinette (Hubbe)  "function(object,mixed:mixed)|" "function(int,int:int)|" "function(string,int:string)|"
1eaa381998-03-04Fredrik Hübinette (Hubbe)  "function(array(0=mixed),int:array(0))|"
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  "!function(int,int:mixed)&function(int|float,int|float:float) */ ADD_EFUN2("`%",f_mod,tOr6(tFunc(tMix tObj,tMix),tFunc(tObj tMix,tMix),tFunc(tInt tInt,tInt),tFunc(tStr tInt,tStr),tFunc(tArr(tSetvar(0,tMix)) tInt,tArr(tVar(0))),tIfnot(tFunc(tInt tInt,tMix),tFunc(tOr(tInt,tFlt) tOr(tInt,tFlt),tFlt))), OPT_TRY_OPTIMIZE,0,generate_mod);
07c0731996-06-21Fredrik Hübinette (Hubbe) 
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(object:mixed)|function(int:int)|function(float:float)|function(string:string) */
0e801c1999-12-13Henrik Grubbström (Grubba)  ADD_EFUN2("`~",f_compl, tOr5(tFunc(tObj,tMix), tFunc(tInt,tInt), tFunc(tFlt,tFlt), tFunc(tStr,tStr),
dc7d491999-12-15Henrik Grubbström (Grubba)  tFunc(tOr(tType,tProgram),tType)),
0e801c1999-12-13Henrik Grubbström (Grubba)  OPT_TRY_OPTIMIZE,0,generate_compl);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(string|multiset|array|mapping|object:int) */ ADD_EFUN2("sizeof", f_sizeof,tFunc(tOr5(tStr,tMultiset,tArray,tMapping,tObj),tInt),0,0,generate_sizeof);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(mixed,mixed ...:mixed) */ ADD_EFUN2("`()",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  /* This one should be removed */
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(mixed,mixed ...:mixed) */ ADD_EFUN2("call_function",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  start_new_program();
90e9781999-01-31Fredrik Hübinette (Hubbe)  ADD_STORAGE(struct string_assignment_storage);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  /* function(int:int) */ ADD_FUNCTION("`[]",f_string_assignment_index,tFunc(tInt,tInt),0); /* function(int,int:int) */ ADD_FUNCTION("`[]=",f_string_assignment_assign_index,tFunc(tInt tInt,tInt),0);
19aaeb1998-05-25Fredrik Hübinette (Hubbe)  set_init_callback(init_string_assignment_storage); set_exit_callback(exit_string_assignment_storage); string_assignment_program=end_program(); }
aa711e1998-06-06Henrik Grubbström (Grubba) void exit_operators(void)
19aaeb1998-05-25Fredrik Hübinette (Hubbe) { if(string_assignment_program) { free_program(string_assignment_program); string_assignment_program=0; }
7bd0ea1996-02-19Fredrik Hübinette (Hubbe) }