pike.git / src / operators.c

version» Context lines:

pike.git/src/operators.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: operators.c,v 1.212 2006/08/15 10:43:24 grubba Exp $ + || $Id: operators.c,v 1.213 2006/08/21 18:14:05 grubba Exp $   */      #include "global.h"   #include <math.h>   #include "interpret.h"   #include "svalue.h"   #include "multiset.h"   #include "mapping.h"   #include "array.h"   #include "stralloc.h"
pike.git/src/operators.c:889: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    if(save_sp != sp)    Pike_fatal("Internal error: o_cast() left droppings on stack.\n");   #endif    free_svalue(sp-2);    sp[-2]=sp[-1];    sp--;    dmalloc_touch_svalue(sp);   }    - int low_check_soft_cast(struct pike_type *type, struct object *o, int is_type) + /* Returns 1 if s is a valid in the type type. */ + int low_check_soft_cast(struct svalue *s, struct pike_type *type)   { -  int ret; +     loop: -  if (type->type == PIKE_T_MIXED) return 1; -  if (!o->prog) { -  /* In case o has been destructed during our check. */ -  if (type->type == PIKE_T_ZERO) return 1; -  return 0; -  } +     switch(type->type) { -  case PIKE_T_ZERO: +  case T_MIXED: return 1; +  case T_ZERO: +  switch(s->type) { +  case PIKE_T_INT: +  return !s->u.integer; +  case PIKE_T_FUNCTION: +  if (s->subtype == FUNCTION_BUILTIN) return 0; +  /* FALL_THROUGH */ +  case PIKE_T_OBJECT: +  return !s->u.object->prog; +  }    return 0; -  case PIKE_T_ARRAY: case PIKE_T_MAPPING: case PIKE_T_MULTISET: -  case PIKE_T_OBJECT: case PIKE_T_FUNCTION: case PIKE_T_PROGRAM: -  case PIKE_T_STRING: case PIKE_T_TYPE: case PIKE_T_INT: -  case PIKE_T_FLOAT: -  case T_MANY: -  push_text(get_name_of_type(type->type)); -  apply_low(o, is_type, 1); -  ret = !UNSAFE_IS_ZERO(Pike_sp-1); -  pop_stack(); -  return ret; +  case T_ASSIGN:    case PIKE_T_NAME: -  break; -  case T_NOT: -  return !low_check_soft_cast(type->cdr, o, is_type); +  type = type->cdr; +  goto loop;    case T_AND: -  if (!low_check_soft_cast(type->car, o, is_type)) return 0; -  break; +  if (!low_check_soft_cast(s, type->car)) return 0; +  type = type->cdr; +  goto loop;    case T_OR: -  if (low_check_soft_cast(type->car, o, is_type)) return 1; -  break; -  default: -  return 0; -  } +  if (low_check_soft_cast(s, type->car)) return 1;    type = type->cdr;    goto loop; -  +  case T_NOT: +  return !low_check_soft_cast(s, type->car);    } -  - void o_check_soft_cast(struct svalue *s, struct pike_type *type) +  if (s->type == type->type) { +  if (type->type == PIKE_T_INT) return 1; +  if (type->type == PIKE_T_FLOAT) return 1; +  if (type->type == PIKE_T_STRING) return 1; +  switch(type->type) { +  case PIKE_T_OBJECT:    { -  struct pike_type *sval_type; -  if (s->type == T_OBJECT) { -  int is_type; -  struct object *o; +     struct program *p; -  -  o = s->u.object; -  p = o->prog; -  if (p && ((is_type = FIND_LFUN(p, LFUN__IS_TYPE)) != -1)) { -  int ok = low_check_soft_cast(type, o, is_type); -  if (ok) return; +  /* Common cases. */ +  if (!type->cdr) return 1; +  if (s->u.object->prog->id == CDR_TO_INT(type)) return 1; +  p = id_to_program(CDR_TO_INT(type)); +  if (!p) return 1; +  return implements(s->u.object->prog, p);    } -  +  case PIKE_T_PROGRAM: +  { +  struct program *p; +  /* Common cases. */ +  if (!type->car->cdr) return 1; +  if (s->u.program->id == CDR_TO_INT(type->car)) return 1; +  p = id_to_program(CDR_TO_INT(type->car)); +  if (!p) return 1; +  return implements(s->u.program, p);    } -  +  case PIKE_T_ARRAY: +  { +  struct array *a = s->u.array; +  int i; +  for (i = a->size; i--;) { +  if (!low_check_soft_cast(a->item + i, type->car)) return 0; +  } +  } +  break; +  case PIKE_T_MULTISET: +  /* FIXME: Add code here. */ +  break; +  case PIKE_T_MAPPING: +  /* FIXME: Add code here. */ +  break; +  case PIKE_T_FUNCTION: +  /* FIXME: Add code here. */ +  break; +  case PIKE_T_TYPE: +  /* FIXME: Add code here. */ +  break; +  } +  return 1; +  } +  if (s->type == PIKE_T_OBJECT) { +  int lfun; +  if (!s->u.object->prog) return 0; +  if (type->type == PIKE_T_FUNCTION) { +  if ((lfun = FIND_LFUN(s->u.object->prog, LFUN_CALL)) != -1) { +  /* FIXME: Add code here. */ +  return 1; +  } +  } +  if ((lfun = FIND_LFUN(s->u.object->prog, LFUN__IS_TYPE)) != -1) { +  int ret; +  fprintf(stderr, "_is_type(\"%s\")...", get_name_of_type(type->type)); +  push_text(get_name_of_type(type->type)); +  apply_low(s->u.object, lfun, 1); +  ret = !UNSAFE_IS_ZERO(Pike_sp-1); +  fprintf(stderr, "%d\n", ret); +  pop_stack(); +  return ret; +  } +  return 0; +  } +  if ((s->type == PIKE_T_FUNCTION) && (type->type == PIKE_T_PROGRAM)) { +  /* FIXME: Add code here. */ +  return 1; +  } +  if ((s->type == PIKE_T_FUNCTION) && (type->type == T_MANY)) { +  /* FIXME: Add code here. */ +  return 1; +  }    -  sval_type = get_type_of_svalue(s); -  if (!pike_types_le(sval_type, type)) { -  /* get_type_from_svalue() doesn't return a fully specified type +  return 0; + } +  + void o_check_soft_cast(struct svalue *s, struct pike_type *type) + { +  if (!low_check_soft_cast(s, type)) { +  /* Note: get_type_from_svalue() doesn't return a fully specified type    * for array, mapping and multiset, so we perform a more lenient    * check for them.    */ -  if (!pike_types_le(sval_type, weak_type_string) || -  !match_types(sval_type, type)) { +  struct pike_type *sval_type = get_type_of_svalue(s);    struct pike_string *t1;    struct pike_string *t2;    char *fname = "__soft-cast";    ONERROR tmp1;    ONERROR tmp2;       if (Pike_fp->current_object && Pike_fp->context.prog &&    Pike_fp->current_object->prog) {    /* Look up the function-name */    struct pike_string *name =
pike.git/src/operators.c:986:    bad_arg_error(NULL, Pike_sp-1, 1, 1, t1->str, Pike_sp-1,    "%s(): Soft cast failed. Expected %s, got %s\n",    fname, t1->str, t2->str);    /* NOT_REACHED */    UNSET_ONERROR(tmp2);    UNSET_ONERROR(tmp1);    free_string(t2);    free_string(t1);    }    } -  free_type(sval_type); - } +       #define COMPARISON(ID,NAME,FUN) \   PMOD_EXPORT void ID(INT32 args) \   { \    int i; \    switch(args) \    { \    case 0: case 1: \    SIMPLE_TOO_FEW_ARGS_ERROR(NAME, 2); \    case 2: \