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.71 1999/11/23 23:28:18 hubbe Exp $"); + RCSID("$Id: pike_types.c,v 1.72 1999/11/24 21:44:02 hubbe 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"    -  + /* #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))   #define EXTRACT_TWOT(X,Y) TWOT(EXTRACT_UCHAR(X), EXTRACT_UCHAR(Y))      /*
pike.git/src/pike_types.c:254:    {    switch(c=EXTRACT_UCHAR(s+e))    {   #if 1    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    if(am[c-'0'])    {    push_finished_type_backwards(am[c-'0']);    }else{ -  push_type(T_MIXED); +  push_type(T_ZERO);    }    break;   #endif -  +  case T_ASSIGN: +  push_type(c); +  push_type(EXTRACT_UCHAR(s+ ++e)); +  break;       case T_INT:    push_type(c);    for(d=0;d<(int)sizeof(INT32)*2;d++)    push_type(EXTRACT_UCHAR(s+ ++e));    break;       case T_OBJECT:    push_type(c);    for(d=0;d<(int)sizeof(INT32)+1;d++) push_type(EXTRACT_UCHAR(s+ ++e));
pike.git/src/pike_types.c:944:   }      static void very_low_or_pike_types(char *to_push, char *not_push)   {    while(EXTRACT_UCHAR(to_push)==T_OR)    {    to_push++;    very_low_or_pike_types(to_push, not_push);    to_push+=type_length(to_push);    } +  /* FIXME: +  * this might use the 'le' operator +  */ +     if(!low_find_exact_type_match(to_push, not_push, T_OR))    {    push_unfinished_type(to_push);    push_type(T_OR);    }   }      static void low_or_pike_types(char *t1, char *t2)   {    if(!t1)
pike.git/src/pike_types.c:1219:    i=FIND_LFUN(p, lfun);    if(i==-1) return 0;    return ID_FROM_INT(p, i)->type;   }      #define A_EXACT 1   #define B_EXACT 2   #define NO_MAX_ARGS 4   #define NO_SHORTCUTS 8    +  + #ifdef PIKE_TYPE_DEBUG + static int indent=0; + #endif +    /*    * 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); +  +  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); +  }else{ +  my_strcat(", "); +  low_describe_type(b); +  } +  my_strcat(");\n"); +  fprintf(stderr,"%s",(s=simple_free_buf())); +  free(s); +  indent++; +  +  a=low_match_types2(a,b,flags); +  +  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;       switch(EXTRACT_UCHAR(a))    {    case T_AND:    a++;    ret=low_match_types(a,b,flags);    if(!ret) return 0;
pike.git/src/pike_types.c:1261:    case T_NOT:    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 && EXTRACT_UCHAR(b)!=T_VOID)    {    int m=EXTRACT_UCHAR(a+1)-'0'; +  struct pike_string *tmp;    type_stack_mark(); -  low_or_pike_types(a_markers[m] ? a_markers[m]->str : 0,b); +  push_unfinished_type_with_markers(b, b_markers); +  tmp=pop_unfinished_type(); +  +  type_stack_mark(); +  medium_or_pike_types(a_markers[m], tmp);    if(a_markers[m]) free_string(a_markers[m]); -  +  free_string(tmp);    a_markers[m]=pop_unfinished_type(); -  +  + #ifdef PIKE_TYPE_DEBUG +  { +  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())); +  free(s);    } -  + #endif + #ifdef PIKE_DEBUG +  if(a_markers[m]->str[0] == m+'0') +  fatal("Cyclic type!\n"); + #endif +  }    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]) -  +  { + #ifdef PIKE_DEBUG +  if(a_markers[m]->str[0] == EXTRACT_UCHAR(a)) +  fatal("Cyclic type!\n"); +  if(EXTRACT_UCHAR(a_markers[m]->str) == T_OR && +  a_markers[m]->str[1] == EXTRACT_UCHAR(a)) +  fatal("Cyclic type!\n"); + #endif    return low_match_types(a_markers[m]->str, b, flags); -  +  }    else    return low_match_types(mixed_type_string->str, b, flags);    }    }       switch(EXTRACT_UCHAR(b))    {    case T_AND:    b++;    ret=low_match_types(a,b,flags);
pike.git/src/pike_types.c:1311:    case T_NOT:    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 && EXTRACT_UCHAR(a)!=T_VOID)    {    int m=EXTRACT_UCHAR(b+1)-'0'; +  struct pike_string *tmp;    type_stack_mark(); -  low_or_pike_types(b_markers[m] ? b_markers[m]->str : 0,a); +  push_unfinished_type_with_markers(a, a_markers); +  tmp=pop_unfinished_type(); +  +  type_stack_mark(); +  medium_or_pike_types(b_markers[m], tmp);    if(b_markers[m]) free_string(b_markers[m]); -  +  free_string(tmp);    b_markers[m]=pop_unfinished_type(); -  + #ifdef PIKE_TYPE_DEBUG +  { +  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())); +  free(s);    } -  + #endif + #ifdef PIKE_DEBUG +  if(b_markers[m]->str[0] == m+'0') +  fatal("Cyclic type!\n"); + #endif +  }    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]) -  +  { + #ifdef PIKE_DEBUG +  if(b_markers[m]->str[0] == EXTRACT_UCHAR(b)) +  fatal("Cyclic type!\n"); + #endif    return low_match_types(a, b_markers[m]->str, flags); -  +  }    else    return low_match_types(a, mixed_type_string->str, flags);    }    }       /* 'mixed' matches anything */ -  if(EXTRACT_UCHAR(b) == T_MIXED && !(flags & B_EXACT)) return a; -  if(EXTRACT_UCHAR(a) == T_ZERO && !(flags & A_EXACT) && -  EXTRACT_UCHAR(b) != T_VOID) return a; -  if(EXTRACT_UCHAR(a) == T_MIXED && !(flags & A_EXACT)) return a; -  if(EXTRACT_UCHAR(b) == T_ZERO && !(flags & B_EXACT) && -  EXTRACT_UCHAR(a) != T_VOID) return a; +     -  +  if((EXTRACT_UCHAR(a) == T_ZERO && !(flags & A_EXACT) && +  EXTRACT_UCHAR(b) != T_VOID) || +  (EXTRACT_UCHAR(a) == T_MIXED && !(flags & A_EXACT))) +  { + #if 1 +  switch(EXTRACT_UCHAR(b)) +  { +  /* These types can contain sub-types */ +  case T_ARRAY: +  low_match_types(array_type_string->str,b , flags); +  break; +  case T_MAPPING: +  low_match_types(mapping_type_string->str,b, flags); +  break; +  case T_FUNCTION: +  low_match_types(function_type_string->str,b, flags); +  break; +  case T_MULTISET: +  low_match_types(multiset_type_string->str,b, flags); +  break; +  } + #endif +  return a; +  }    -  +  if((EXTRACT_UCHAR(b) == T_MIXED && !(flags & B_EXACT)) || +  (EXTRACT_UCHAR(b) == T_ZERO && !(flags & B_EXACT) && +  EXTRACT_UCHAR(a) != T_VOID)) +  { + #if 1 +  switch(EXTRACT_UCHAR(a)) +  { +  /* These types can contain sub-types */ +  case T_ARRAY: +  low_match_types(a , array_type_string->str, flags); +  break; +  case T_MAPPING: +  low_match_types(a , mapping_type_string->str, flags); +  break; +  case T_FUNCTION: +  low_match_types(a , function_type_string->str, flags); +  break; +  case T_MULTISET: +  low_match_types(a , multiset_type_string->str, flags); +  break; +  } + #endif +  return a; +  } +  +     /* Special cases (tm) */    switch(EXTRACT_TWOT(a,b))    {    case TWOT(T_PROGRAM, T_FUNCTION):    case TWOT(T_FUNCTION, T_PROGRAM):    return a;    case TWOT(T_OBJECT, T_FUNCTION):    {    struct pike_string *s;    if((s=low_object_lfun_type(a, LFUN_CALL)))
pike.git/src/pike_types.c:1536:    return low_pike_types_le(a,b);       case T_NOT:    return !low_pike_types_le(a+1,b);       case T_ASSIGN:    ret=low_pike_types_le(a+2,b);    if(ret && EXTRACT_UCHAR(b)!=T_VOID)    {    int m=EXTRACT_UCHAR(a+1)-'0'; +  struct pike_string *tmp;    type_stack_mark(); -  low_or_pike_types(a_markers[m] ? a_markers[m]->str : 0,b); +  push_unfinished_type_with_markers(b, b_markers); +  tmp=pop_unfinished_type(); +  +  type_stack_mark(); +  medium_or_pike_types(a_markers[m], tmp);    if(a_markers[m]) free_string(a_markers[m]); -  +  free_string(tmp);    a_markers[m]=pop_unfinished_type(); -  + #ifdef PIKE_TYPE_DEBUG +  { +  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())); +  free(s);    } -  + #endif +  }    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_pike_types_le(a_markers[m]->str, b);    else    return low_pike_types_le(mixed_type_string->str, b);
pike.git/src/pike_types.c:1580:    return low_pike_types_le(a,b);       case T_NOT:    return !low_pike_types_le(a,b+1);       case T_ASSIGN:    ret=low_pike_types_le(a,b+2);    if(ret && EXTRACT_UCHAR(a)!=T_VOID)    {    int m=EXTRACT_UCHAR(b+1)-'0'; +  struct pike_string *tmp;    type_stack_mark(); -  low_or_pike_types(b_markers[m] ? b_markers[m]->str : 0,a); +  push_unfinished_type_with_markers(a, a_markers); +  tmp=pop_unfinished_type(); +  +  type_stack_mark(); +  medium_or_pike_types(b_markers[m], tmp);    if(b_markers[m]) free_string(b_markers[m]); -  +  free_string(tmp);    b_markers[m]=pop_unfinished_type(); -  + #ifdef PIKE_TYPE_DEBUG +  { +  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())); +  free(s);    } -  + #endif +  }    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_pike_types_le(a, b_markers[m]->str);    else    return low_pike_types_le(a, mixed_type_string->str);
pike.git/src/pike_types.c:1985:    case T_STRING: /* always int */    case T_MULTISET: /* always int */    reference_shared_string(int_type_string);    return int_type_string;       case T_MAPPING:    t+=type_length(t);    return make_shared_binary_string(t, type_length(t));       case T_ARRAY: -  if(n && low_match_types(string_type_string->str,CDR(n)->type->str,0)) +  if(n && +  (CDR(n)->token == F_CONSTANT ? +  CDR(n)->u.sval.type == T_STRING : +  low_match_types(string_type_string->str,CDR(n)->type->str,0)))    {    struct pike_string *a=low_index_type(t,n);    if(!a)    return make_shared_binary_string(t, type_length(t));       type_stack_mark();    push_finished_type(a);    free_string(a);    push_type(T_ARRAY);    if(low_match_types(int_type_string->str,CDR(n)->type->str,0))