pike.git / src / operators.c

version» Context lines:

pike.git/src/operators.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   /**/   #include "global.h"   #include <math.h> - RCSID("$Id: operators.c,v 1.75 1999/12/13 20:44:15 grubba Exp $"); + RCSID("$Id: operators.c,v 1.76 1999/12/15 00:48:18 grubba Exp $");   #include "interpret.h"   #include "svalue.h"   #include "multiset.h"   #include "mapping.h"   #include "array.h"   #include "stralloc.h"   #include "opcodes.h"   #include "operators.h"   #include "language.h"   #include "pike_memory.h"
pike.git/src/operators.c:754:    emit2(F_SUBTRACT);    return 1;    }    return 0;   }      void o_and(void)   {    if(sp[-1].type != sp[-2].type)    { -  if(call_lfun(LFUN_AND, LFUN_RAND)) +  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; +  } +  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 { +  int args = 2;    SIMPLE_BAD_ARG_ERROR("`&", 2, get_name_of_type(sp[-2].type));    }    }       switch(sp[-2].type)    {    case T_OBJECT:    CALL_OPERATOR(LFUN_AND,2);    break;   
pike.git/src/operators.c:810:    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);    sp[-1].type = T_STRING;    return;    }    +  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; +  } +    #define STRING_BITOP(OP,STROP) \    case T_STRING: \    { \    struct pike_string *s; \    INT32 len, i; \    \    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); \
pike.git/src/operators.c:951:       default:    return 0;    }   }      void o_or(void)   {    if(sp[-1].type != sp[-2].type)    { -  if(call_lfun(LFUN_OR, LFUN_ROR)) +  if(call_lfun(LFUN_OR, LFUN_ROR)) {    return; -  -  { +  } else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) || +  (sp[-1].type == T_FUNCTION)) && +  ((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) || +  (sp[-2].type == T_FUNCTION))) { +  if (sp[-2].type != T_TYPE) { +  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 { +  int args = 2;    SIMPLE_BAD_ARG_ERROR("`|", 2, get_name_of_type(sp[-2].type));    }    }       switch(sp[-2].type)    {    case T_OBJECT:    CALL_OPERATOR(LFUN_OR,2);    break;   
pike.git/src/operators.c:1008:    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;    }    +  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; +  } +     STRING_BITOP(|,"OR")       default:    PIKE_ERROR("`|", "Bitwise or on illegal type.\n", sp, 2);    }   }      void f_or(INT32 args)   {    switch(args)
pike.git/src/operators.c:1055:    default:    return 0;    }   }         void o_xor(void)   {    if(sp[-1].type != sp[-2].type)    { -  if(call_lfun(LFUN_XOR, LFUN_RXOR)) +  if(call_lfun(LFUN_XOR, LFUN_RXOR)) {    return; -  { +  } else if (((sp[-1].type == T_TYPE) || (sp[-1].type == T_PROGRAM) || +  (sp[-1].type == T_FUNCTION)) && +  ((sp[-2].type == T_TYPE) || (sp[-2].type == T_PROGRAM) || +  (sp[-2].type == T_FUNCTION))) { +  if (sp[-2].type != T_TYPE) { +  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 { +  int args = 2;    SIMPLE_BAD_ARG_ERROR("`^", 2, get_name_of_type(sp[-2].type));    }    }       switch(sp[-2].type)    {    case T_OBJECT:    CALL_OPERATOR(LFUN_XOR,2);    break;   
pike.git/src/operators.c:1101:       case T_ARRAY:    {    struct array *a;    a=merge_array_with_order(sp[-2].u.array, sp[-1].u.array, PIKE_ARRAY_OP_XOR);    pop_n_elems(2);    push_array(a);    return;    }    +  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(); +  push_type_int(sp[-1].u.program->id); +  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(); +  push_type_int(sp[-1].u.program->id); +  push_type(0); +  push_type(T_OBJECT); +  pop_stack(); +  push_string(pop_unfinished_type()); +  sp[-1].type = T_TYPE; +  } +  /* FALL_THROUGH */    case T_TYPE:    {    /* a ^ b == (a&~b)|(~a&b) */    struct pike_string *a;    struct pike_string *b;    copy_shared_string(a, sp[-2].u.string);    copy_shared_string(b, sp[-1].u.string);    o_compl(); /* ~b */    o_and(); /* a&~b */    push_string(a);
pike.git/src/operators.c:1864:    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;       case T_TYPE:    type_stack_mark(); +  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); -  +  }    pop_stack();    push_string(pop_unfinished_type());    sp[-1].type = T_TYPE;    break;    -  +  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; +     case T_STRING:    {    struct pike_string *s;    INT32 len, i;       if(sp[-1].u.string->size_shift) {    bad_arg_error("`~", sp-1, 1, 1, "string(0)", sp-1,    "Expected 8-bit string.\n");    }   
pike.git/src/operators.c:2208:    0); /* OPT_ASSIGNMENT|OPT_TRY_OPTIMIZE); ? */       /* function(mixed...:int) */    ADD_EFUN2("`==",f_eq,tFuncV(tNone,tMix,tInt01),OPT_TRY_OPTIMIZE,optimize_eq,generate_comparison);    /* function(mixed...:int) */    ADD_EFUN2("`!=",f_ne,tFuncV(tNone,tMix,tInt01),OPT_TRY_OPTIMIZE,0,generate_comparison);    /* function(mixed:int) */    add_efun2("`!",f_not,"function(mixed:int(0..1))",OPT_TRY_OPTIMIZE,    optimize_not,generate_not);    - #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,type,type...:int(0..1))" + #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))"    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,    tOr7(tIfnot(tFuncV(tNone,tNot(tOr(tObj,tMix)),tMix),tFunction),    tFuncV(tInt,tInt,tInt),    tIfnot(tFuncV(tInt,tInt,tMix),    tFuncV(tOr(tInt,tFlt),tOr(tInt,tFlt),tFlt)),
pike.git/src/operators.c:2242:    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)),    tMapping,tMap(tVar(1),tVar(2))),    tFunc(tSet(tSetvar(3,tMix)) tMultiset,tSet(tVar(3))),    tFuncV(tStr,tStr,tStr)),    OPT_TRY_OPTIMIZE,0,generate_minus);    - #define LOG_TYPE "function(mixed,object...:mixed)|function(object,mixed...:mixed)|function(int...:int)|function(mapping(0=mixed:1=mixed)...:mapping(0:1))|function(multiset(2=mixed)...:multiset(2))|function(array(3=mixed)...:array(3))|function(string...:string)|function(type,type...:type)" + #define LOG_TYPE "function(mixed,object...:mixed)|function(object,mixed...:mixed)|function(int...:int)|function(mapping(0=mixed:1=mixed)...:mapping(0:1))|function(multiset(2=mixed)...:multiset(2))|function(array(3=mixed)...:array(3))|function(string...:string)|function(type|program,type|program...:type)"       add_efun2("`&",f_and,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_and);       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 "function(object,mixed:mixed)|function(mixed,object:mixed)|function(int,int:int)"       add_efun2("`<<",f_lsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_lsh);
pike.git/src/operators.c:2297:    "!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);       /* function(object:mixed)|function(int:int)|function(float:float)|function(string:string) */    ADD_EFUN2("`~",f_compl,    tOr5(tFunc(tObj,tMix),    tFunc(tInt,tInt),    tFunc(tFlt,tFlt),    tFunc(tStr,tStr), -  tFunc(tType,tType)), +  tFunc(tOr(tType,tProgram),tType)),    OPT_TRY_OPTIMIZE,0,generate_compl);    /* function(string|multiset|array|mapping|object:int) */    ADD_EFUN2("sizeof", f_sizeof,tFunc(tOr5(tStr,tMultiset,tArray,tMapping,tObj),tInt),0,0,generate_sizeof);       /* function(mixed,mixed ...:mixed) */    ADD_EFUN2("`()",f_call_function,tFuncV(tMix,tMix,tMix),OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function);       /* This one should be removed */    /* 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);