Branch: Tag:

1999-12-12

1999-12-12 18:31:33 by Henrik Grubbström (Grubba) <grubba@grubba.org>

PIKE_TYPE_DEBUG now looks at l_flag.
low_match_types() now has a somewhat more lenient checking of object types.
low_pike_types_le() now has an improved checking of object types.
Implemented strict_check_call().

Rev: src/pike_types.c:1.91

5:   \*/   /**/   #include "global.h" - RCSID("$Id: pike_types.c,v 1.90 1999/12/12 00:26:08 mast Exp $"); + RCSID("$Id: pike_types.c,v 1.91 1999/12/12 18:31:33 grubba Exp $");   #include <ctype.h>   #include "svalue.h"   #include "pike_types.h"
24:   #include "lex.h"   #include "pike_memory.h"   #include "bignum.h" + #include "main.h"      /* #define PIKE_TYPE_DEBUG */   
1414: Inside #if defined(PIKE_TYPE_DEBUG)
  {    int e;    char *s; -  char *low_match_types2(char *a,char *b, int flags); +  static char *low_match_types2(char *a,char *b, int flags);    -  +  if (l_flag) {    init_buf();    for(e=0;e<indent;e++) my_strcat(" ");    my_strcat("low_match_types(");
1468: Inside #if defined(PIKE_TYPE_DEBUG)
   fprintf(stderr,"%s",(s=simple_free_buf()));    free(s);    indent++; +  }       a=low_match_types2(a,b,flags);    -  +  if (l_flag) {    indent--;    init_buf();    for(e=0;e<indent;e++) my_strcat(" ");
1482: Inside #if defined(PIKE_TYPE_DEBUG)
   my_strcat("\n");    fprintf(stderr,"%s",(s=simple_free_buf()));    free(s); -  +  }    return a;   }   
1538:    a_markers[m]=pop_unfinished_type();      #ifdef PIKE_TYPE_DEBUG -  { +  if (l_flag) {    char *s;    int e;    init_buf();
1622:    free_string(tmp);    b_markers[m]=pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG -  { +  if (l_flag) {    char *s;    int e;    init_buf();
1835:    if(EXTRACT_UCHAR(a+1))    {    /* object(1 x) =? object(1 x) */ +  /* FIXME: Ought to check if a inherits b or b inherits a. */    if(extract_type_int(a+2) != extract_type_int(b+2)) return 0;    }else{    /* object(0 *) =? object(0 *) */ -  +  /* FIXME: Ought to check the implements relation */    break;    }    }
1849:       if(!ap || !bp) break;    + #if 1 +  /* FIXME: Temporary kludge. +  * match_types() currently seems to need to be symetric. +  */ +  if (!implements(ap,bp) && !implements(bp,ap)) +  return 0; + #else /* !1 */    if(EXTRACT_UCHAR(a+1))    {    if(!implements(ap,bp))
1857:    if(!implements(bp,ap))    return 0;    } + #endif /* 1 */    }       break;
1914: Inside #if defined(PIKE_TYPE_DEBUG)
  {    int e;    char *s; -  int low_pike_types_le2(char *a,char *b); +  static int low_pike_types_le2(char *a,char *b);    int res;    -  +  if (l_flag) {    init_buf();    for(e=0;e<indent;e++) my_strcat(" ");    my_strcat("low_pike_types_le(");
1935: Inside #if defined(PIKE_TYPE_DEBUG)
   fprintf(stderr,"%s",(s=simple_free_buf()));    free(s);    indent++; +  }       res=low_pike_types_le2(a,b);    -  +  if (l_flag) {    indent--;       for(e=0;e<indent;e++) fprintf(stderr, " ");    fprintf(stderr, "= %d\n", res); -  +  }    return res;   }   
1991:    free_string(tmp);    a_markers[m]=pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG -  { +  if (l_flag) {    char *s;    int e;    init_buf();
2056:    free_string(tmp);    b_markers[m]=pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG -  { +  if (l_flag) {    char *s;    int e;    init_buf();
2137:       if(EXTRACT_UCHAR(a) != EXTRACT_UCHAR(b)) return 0;    -  ret=1; +     switch(EXTRACT_UCHAR(a))    {    case T_FUNCTION:
2173:    }       if (EXTRACT_UCHAR(a_tmp) != T_VOID) { -  if (EXTRACT_UCHAR(b_tmp) == T_VOID) return 0; +  /* if (EXTRACT_UCHAR(b_tmp) == T_VOID) return 0; */    if (!low_pike_types_le(b_tmp, a_tmp)) return 0;    }    }
2213:    }   #endif    +  /* +  * object(0|1 x) <= object(0|1 0) +  * object(0|1 0) <=! object(0|1 !0) +  * object(1 x) <= object(0|1 x) +  * object(1 x) <= object(1 y) iff x inherits y +  * object(0|1 x) <= object(0 y) iff x implements y +  */ +     /* object(* 0) matches any object */    if(!extract_type_int(b+2))    return 1;
2220:    if(!extract_type_int(a+2))    return 0;    +  if ((EXTRACT_UCHAR(a+1) || !EXTRACT_UCHAR(b+1)) && +  (extract_type_int(a+2) == extract_type_int(b+2))) +  return 1;    -  /* object(x *) =? object(x *) */ -  if(EXTRACT_UCHAR(a+1) == EXTRACT_UCHAR(b+1)) -  { -  /* x? */ -  if(EXTRACT_UCHAR(a+1)) -  { -  /* object(1 x) =? object(1 x) */ -  if(extract_type_int(a+2) != extract_type_int(b+2)) return 0; -  }else{ -  /* object(0 *) =? object(0 *) */ -  break; +  if (EXTRACT_UCHAR(b+1)) { +  if (!EXTRACT_UCHAR(a+1)) { +  /* We can't guarantee the inherit relation. */ +  return 0;    }    }       { -  struct program *ap,*bp; -  ap=id_to_program(extract_type_int(a+2)); -  bp=id_to_program(extract_type_int(b+2)); +  struct program *ap = id_to_program(extract_type_int(a+2)); +  struct program *bp = id_to_program(extract_type_int(b+2));    -  if(!ap || !bp) break; -  -  if(EXTRACT_UCHAR(a+1)) -  { -  if(!implements(ap,bp)) +  if (!ap || !bp) { +  /* Shouldn't happen... */    return 0; -  }else{ -  if(!implements(bp,ap)) -  return 0; +     } -  +  if (EXTRACT_UCHAR(b+1)) { +  /* FIXME: Should probably have a better test here. */ +  return low_get_storage(ap, bp) != -1; +  } else { +  return implements(ap, bp);    } -  +  }    break;       case T_INT:
2283:    default:    fatal("error in type string.\n");    } -  return ret; +  return 1;   }      /* -  +  * Check the function parameters. +  * Note: The difference between this function, and pike_types_le() +  * is the more lenient check for T_OR, and the handling of T_ARRAY. +  */ + int strict_check_call(char *fun_type, char *arg_type) + { +  while ((EXTRACT_UCHAR(fun_type) == T_OR) || +  (EXTRACT_UCHAR(fun_type) == T_ARRAY)) { +  if (EXTRACT_UCHAR(fun_type++) == T_OR) { +  int res = strict_check_call(fun_type, arg_type); +  if (res) return res; +  fun_type += type_length(fun_type); +  } +  } +  return low_pike_types_le(fun_type, arg_type); + } +  + /*    * Return the return type from a function call.    */   static int low_get_return_type(char *a,char *b)
2825:       if(low_get_return_type(type->str,args->str))    { +  if (lex.pragmas & ID_STRICT_TYPES) { +  if (type == mixed_type_string) { +  yywarning("Calling mixed."); +  } else if (!strict_check_call(type->str, args->str)) { +  struct pike_string *arg_t = describe_type(args); +  struct pike_string *type_t = describe_type(type); +  yywarning("Arguments not strictly compatible."); +  yywarning("Expected: %s", type_t->str); +  yywarning("Got : %s", arg_t->str); +  free_string(type_t); +  free_string(arg_t); +  } +  }    return pop_unfinished_type();    }else{    pop_stack_mark();