Branch: Tag:

1998-03-01

1998-03-01 11:40:47 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>

better type checking implemented (and a bug in the type checking fixed)

Rev: src/builtin_functions.c:1.76
Rev: src/docode.c:1.33
Rev: src/las.c:1.55
Rev: src/operators.c:1.28
Rev: src/pike_types.c:1.34
Rev: src/program.c:1.65
Rev: src/stralloc.c:1.28
Rev: src/svalue.h:1.13

4:   ||| See the files COPYING and DISCLAIMER for more information.   \*/   #include "global.h" - RCSID("$Id: pike_types.c,v 1.33 1998/02/24 23:01:31 hubbe Exp $"); + RCSID("$Id: pike_types.c,v 1.34 1998/03/01 11:40:47 hubbe Exp $");   #include <ctype.h>   #include "svalue.h"   #include "pike_types.h"
61:   struct pike_string *void_type_string;   struct pike_string *any_type_string;    + static char *a_markers[10],*b_markers[10]; +  + static void clear_markers() + { +  unsigned int e; +  for(e=0;e<NELEM(a_markers);e++) a_markers[e]=b_markers[e]=0; + } +    #ifdef DEBUG   static void CHECK_TYPE(struct pike_string *s)   {
68: Inside #if defined(DEBUG)
   fatal("Type string not shared.\n");       if(type_length(s->str) != s->len) +  { +  stupid_describe_type(s->str,s->len);    fatal("Length of type is wrong.\n");    } -  + }   #else   #define CHECK_TYPE(X)   #endif
100:    fatal("error in type string.\n");    /*NOTREACHED*/    +  break; +  +  case T_ASSIGN: +  t++; +  t+=type_length(t); +  break; +     case T_FUNCTION:    while(EXTRACT_UCHAR(t)!=T_MANY) t+=type_length(t); /* skip arguments */    t++;
114:    case T_NOT:    t+=type_length(t);    +  case '0': +  case '1': +  case '2': +  case '3': +  case '4': +  case '5': +  case '6': +  case '7': +  case '8': +  case '9':    case T_INT:    case T_FLOAT:    case T_STRING:
205:    for(e--;e>=0;e--) push_type(s[e]);   }    + static void push_unfinished_type_with_markers(char *s, char **am) + { +  int e; +  e=type_length(s); +  for(e--;e>=0;e--) +  { +  if(s[e]>='0' && s[e]<='9') +  { +  if(am[s[e]-'0']) +  { +  push_unfinished_type(am[s[e]-'0']); +  }else{ +  push_type(T_MIXED); +  } +  }else{ +  push_type(s[e]); +  } +  } + } +    void push_finished_type(struct pike_string *type)   {    int e;
369:    }    push_type(T_MULTISET);    } +  else if(buf[0]>='0' && buf[0]<='9' && atoi(buf)<10) +  { +  while(ISSPACE(**s)) ++*s; +  if(**s=='=') +  { +  ++*s; +  internal_parse_type(_s); +  push_type(buf[0]); +  push_type(T_ASSIGN); +  }else{ +  push_type(buf[0]); +  } +  }    else    error("Couldn't parse type. (%s)\n",buf);   
476: Inside #if defined(DEBUG)
   if(e) printf(" ");    switch(EXTRACT_UCHAR(a+e))    { +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  printf("%c",EXTRACT_UCHAR(a+e)); +  break; +  +  case T_ASSIGN: printf("="); break;    case T_INT: printf("int"); break;    case T_FLOAT: printf("float"); break;    case T_STRING: printf("string"); break;
513:   {    switch(EXTRACT_UCHAR(t++))    { +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  my_putchar(EXTRACT_UCHAR(t-1)); +  break; +  +  case T_ASSIGN: +  my_putchar('('); +  my_putchar(EXTRACT_UCHAR(t++)); +  my_putchar('='); +  t=low_describe_type(t); +  my_putchar(')'); +  break; +     case T_VOID: my_strcat("void"); break;    case T_MIXED: my_strcat("mixed"); break;    case T_UNKNOWN: my_strcat("unknown"); break;
616:    return free_buf();   }    + static int low_is_same_type(char *a, char *b) + { +  if(type_length(a) != type_length(b)) return 0; +  return !MEMCMP(a,b,type_length(a)); + } +    static TYPE_T low_compile_type_to_runtime_type(char *t)   {    TYPE_T tmp;
627:    if(tmp == low_compile_type_to_runtime_type(t+type_length(t)))    return tmp;    -  case T_MANY: -  case T_UNKNOWN: -  case T_AND: -  case T_NOT: +  default:    return T_MIXED;    -  default: +  case T_ARRAY: +  case T_MAPPING: +  case T_MULTISET: +  +  case T_OBJECT: +  case T_PROGRAM: +  case T_FUNCTION: +  +  case T_STRING: +  case T_INT: +  case T_FLOAT:    return EXTRACT_UCHAR(t);    }   }
674:    return low_match_types(a,b,flags);       case T_NOT: -  if(low_match_types(a+1,b,flags | B_EXACT | NO_MAX_ARGS)) +  if(low_match_types(a+1,b,(flags ^ B_EXACT ) | NO_MAX_ARGS))    return 0;    return a; -  +  +  case T_ASSIGN: +  ret=low_match_types(a+2,b,flags); +  if(ret) +  { +  int m=EXTRACT_UCHAR(a+1)-'0'; +  if(!a_markers[m]) +  a_markers[m]=b; +  else if(!low_is_same_type(a_markers[m], b)) +  a_markers[m]=mixed_type_string->str;    } -  +  return ret;    -  +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  { +  int m=EXTRACT_UCHAR(a)-'0'; +  if(a_markers[m]) +  return low_match_types(a_markers[m], b, flags); +  else +  return low_match_types(mixed_type_string->str, b, flags); +  } +  } +     switch(EXTRACT_UCHAR(b))    {    case T_AND:
696:    return low_match_types(a,b,flags);       case T_NOT: -  if(low_match_types(a,b+1, flags | A_EXACT | NO_MAX_ARGS)) +  if(low_match_types(a,b+1, (flags ^ A_EXACT ) | NO_MAX_ARGS))    return 0;    return a; -  +  +  case T_ASSIGN: +  ret=low_match_types(a,b+2,flags); +  if(ret) +  { +  int m=EXTRACT_UCHAR(b+1)-'0'; +  if(!b_markers[m]) +  b_markers[m]=a; +  else if(!low_is_same_type(b_markers[m], a)) +  b_markers[m]=mixed_type_string->str;    } -  +  return ret;    -  +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  { +  int m=EXTRACT_UCHAR(b)-'0'; +  if(b_markers[m]) +  return low_match_types(a, b_markers[m], flags); +  else +  return low_match_types(a, mixed_type_string->str, flags); +  } +  } +     /* 'mixed' matches anything */    if(EXTRACT_UCHAR(a) == T_MIXED && !(flags & A_EXACT)) return a;    if(EXTRACT_UCHAR(b) == T_MIXED && !(flags & B_EXACT)) return a;
893:    while(EXTRACT_UCHAR(a)!=T_MANY) a+=type_length(a);    a++;    a+=type_length(a); -  push_unfinished_type(a); +  push_unfinished_type_with_markers(a, a_markers );    return 1;       case T_PROGRAM:
914:   {    CHECK_TYPE(a);    CHECK_TYPE(b); +  clear_markers();    return 0!=low_match_types(a->str, b->str,0);   }   
1022:   struct pike_string *index_type(struct pike_string *type, node *n)   {    struct pike_string *t; +  clear_markers();    t=low_index_type(type->str,n);    if(!t) copy_shared_string(t,mixed_type_string);    return t;
1144:   {    CHECK_TYPE(args);    CHECK_TYPE(type); +  clear_markers();    type_stack_mark();    max_correct_args=0;   
1160:   {    INT32 ret,tmp=max_correct_args;    CHECK_TYPE(type); +  clear_markers();    type=check_call(function_type_string, type);    if(type) free_string(type);    ret=max_correct_args;