pike.git / src / pike_types.c

version» Context lines:

pike.git/src/pike_types.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" - 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"   #include "stralloc.h"   #include "stuff.h"   #include "array.h"   #include "program.h"   #include "constants.h"   #include "object.h"   #include "multiset.h"   #include "mapping.h"   #include "pike_macros.h"   #include "error.h"   #include "las.h"   #include "language.h"   #include "lex.h"   #include "pike_memory.h"   #include "bignum.h" -  + #include "main.h"      /* #define PIKE_TYPE_DEBUG */      int max_correct_args;      static void internal_parse_type(char **s);   static int type_length(char *t);   static int low_pike_types_le(char *a, char *b);      #define TWOT(X,Y) (((X) << 8)+(Y))
pike.git/src/pike_types.c:1407:      /*    * match two type strings, return zero if they don't match, and return    * the part of 'a' that _did_ match if it did.    */   static char *low_match_types(char *a,char *b, int flags)   #ifdef 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(");    low_describe_type(a);    if(type_length(a) + type_length(b) > 10)    {    my_strcat(",\n");    for(e=0;e<indent;e++) my_strcat(" ");    my_strcat(" ");    low_describe_type(b);
pike.git/src/pike_types.c:1461: Inside #if defined(PIKE_TYPE_DEBUG)
   my_strcat("NO_SHORTCUTS");    f = 1;    }    } else {    my_strcat("0");    }    my_strcat(");\n");    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(" ");    my_strcat("= ");    if(a)    low_describe_type(a);    else    my_strcat("NULL");    my_strcat("\n");    fprintf(stderr,"%s",(s=simple_free_buf()));    free(s); -  +  }    return a;   }      static char *low_match_types2(char *a,char *b, int flags)   #endif      {    int correct_args;    char *ret;    if(a == b) return a;
pike.git/src/pike_types.c:1531:    push_unfinished_type_with_markers(b, b_markers);    tmp=pop_unfinished_type();       type_stack_mark();    medium_or_pike_types(a_markers[m], tmp, 0);    if(a_markers[m]) free_string(a_markers[m]);    free_string(tmp);    a_markers[m]=pop_unfinished_type();      #ifdef PIKE_TYPE_DEBUG -  { +  if (l_flag) {    char *s;    int e;    init_buf();    for(e=0;e<indent;e++) my_strcat(" ");    my_strcat("a_markers[");    my_putchar(m+'0');    my_strcat("]=");    low_describe_type(a_markers[m]->str);    my_strcat("\n");    fprintf(stderr,"%s",(s=simple_free_buf()));
pike.git/src/pike_types.c:1615:    type_stack_mark();    push_unfinished_type_with_markers(a, a_markers);    tmp=pop_unfinished_type();       type_stack_mark();    medium_or_pike_types(b_markers[m], tmp, 0);    if(b_markers[m]) free_string(b_markers[m]);    free_string(tmp);    b_markers[m]=pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG -  { +  if (l_flag) {    char *s;    int e;    init_buf();    for(e=0;e<indent;e++) my_strcat(" ");    my_strcat("b_markers[");    my_putchar(m+'0');    my_strcat("]=");    low_describe_type(b_markers[m]->str);    my_strcat("\n");    fprintf(stderr,"%s",(s=simple_free_buf()));
pike.git/src/pike_types.c:1828:    /* object(* 0) matches any object */    if(!extract_type_int(a+2) || !extract_type_int(b+2)) break;       /* 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) */ +  /* 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;    }    }       {    struct program *ap,*bp;    ap=id_to_program(extract_type_int(a+2));    bp=id_to_program(extract_type_int(b+2));       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))    return 0;    }else{    if(!implements(bp,ap))    return 0;    } -  + #endif /* 1 */    }       break;       case T_INT:    {    INT32 amin=extract_type_int(a+1);    INT32 amax=extract_type_int(a+1+sizeof(INT32));       INT32 bmin=extract_type_int(b+1);
pike.git/src/pike_types.c:1907:    * Note that non-destructive operations are assumed.    * ie it's assumed that calling a function(mapping(string|int:string|int):void)    * with a mapping(int:int) won't change the type of the mapping after the    * operation.    */   static int low_pike_types_le(char *a,char *b)   #ifdef 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(");    low_describe_type(a);    if(type_length(a) + type_length(b) > 10)    {    my_strcat(",\n");    for(e=0;e<indent;e++) my_strcat(" ");    my_strcat(" ");    low_describe_type(b);    }else{    my_strcat(", ");    low_describe_type(b);    }    my_strcat(");\n");    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;   }      static int low_pike_types_le2(char *a,char *b)   #endif /* PIKE_TYPE_DEBUG */      {    int ret;    if(a == b) return 1;   
pike.git/src/pike_types.c:1984:    type_stack_mark();    push_unfinished_type_with_markers(b, b_markers);    tmp=pop_unfinished_type();       type_stack_mark();    medium_or_pike_types(a_markers[m], tmp, 0);    if(a_markers[m]) free_string(a_markers[m]);    free_string(tmp);    a_markers[m]=pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG -  { +  if (l_flag) {    char *s;    int e;    init_buf();    for(e=0;e<indent;e++) my_strcat(" ");    my_strcat("a_markers[");    my_putchar(m+'0');    my_strcat("]=");    low_describe_type(a_markers[m]->str);    my_strcat("\n");    fprintf(stderr,"%s",(s=simple_free_buf()));
pike.git/src/pike_types.c:2049:    type_stack_mark();    push_unfinished_type_with_markers(a, a_markers);    tmp=pop_unfinished_type();       type_stack_mark();    medium_or_pike_types(b_markers[m], tmp, 0);    if(b_markers[m]) free_string(b_markers[m]);    free_string(tmp);    b_markers[m]=pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG -  { +  if (l_flag) {    char *s;    int e;    init_buf();    for(e=0;e<indent;e++) my_strcat(" ");    my_strcat("b_markers[");    my_putchar(m+'0');    my_strcat("]=");    low_describe_type(b_markers[m]->str);    my_strcat("\n");    fprintf(stderr,"%s",(s=simple_free_buf()));
pike.git/src/pike_types.c:2130:    {    struct pike_string *s;    if((s=low_object_lfun_type(b, LFUN_CALL)))    return low_pike_types_le(a,s->str);    return 1;    }    }       if(EXTRACT_UCHAR(a) != EXTRACT_UCHAR(b)) return 0;    -  ret=1; +     switch(EXTRACT_UCHAR(a))    {    case T_FUNCTION:    /*    * function(A...:B) <= function(C...:D) iff C <= A && B <= D    */    /*    * function(:int) <= function(int:int)    * function(int|string:int) <= function(int:int)    * function(:int) <= function(:void)
pike.git/src/pike_types.c:2166:       if(EXTRACT_UCHAR(b)==T_MANY)    {    b_tmp=b+1;    }else{    b_tmp=b;    b+=type_length(b);    }       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;    }    }    /* check the 'many' type */    a++;    b++;    if (EXTRACT_UCHAR(a) != T_VOID) {    if (!low_pike_types_le(b, a))    return 0;    }
pike.git/src/pike_types.c:2206: Inside #if 0
  #if 0    if(extract_type_int(a+2) || extract_type_int(b+2))    {    fprintf(stderr,"Type match1: ");    stupid_describe_type(a,type_length(a));    fprintf(stderr,"Type match2: ");    stupid_describe_type(b,type_length(b));    }   #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;       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:    {    INT32 amin=extract_type_int(a+1);    INT32 amax=extract_type_int(a+1+sizeof(INT32));       INT32 bmin=extract_type_int(b+1);    INT32 bmax=extract_type_int(b+1+sizeof(INT32));   
pike.git/src/pike_types.c:2276:    case T_TYPE:    case T_PROGRAM:    case T_ZERO:    case T_VOID:    case T_MIXED:    break;       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)   {    int tmp;    switch(EXTRACT_UCHAR(a))    {    case T_OR:    {    struct pike_string *o1,*o2;
pike.git/src/pike_types.c:2818:    struct pike_string *type)   {    check_type_string(args);    check_type_string(type);    clear_markers();    type_stack_mark();    max_correct_args=0;       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();    return 0;    }   }      INT32 get_max_args(struct pike_string *type)   {    INT32 ret,tmp=max_correct_args;