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.85 1999/12/07 09:40:59 hubbe Exp $"); + RCSID("$Id: pike_types.c,v 1.86 1999/12/10 23:45:02 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"
pike.git/src/pike_types.c:130:    char *q=t;   one_more_type:    switch(EXTRACT_UCHAR(t++))    {    default:    fatal("error in type string %d.\n",EXTRACT_UCHAR(t-1));    /*NOTREACHED*/       break;    +  case T_SCOPE:    case T_ASSIGN:    t++;    goto one_more_type;       case T_FUNCTION:    while(EXTRACT_UCHAR(t)!=T_MANY) t+=type_length(t); /* skip arguments */    t++;    -  +  case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    t+=type_length(t);       case T_ARRAY:    case T_MULTISET:    case T_NOT:    goto one_more_type;   
pike.git/src/pike_types.c:160:    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':    case T_FLOAT:    case T_STRING: +  case T_TYPE:    case T_PROGRAM:    case T_MIXED:    case T_VOID:    case T_ZERO:    case T_UNKNOWN:    break;       case T_INT:    t+=sizeof(INT32)*2;    break;
pike.git/src/pike_types.c:366:    {    if(len>=sizeof(buf)) error("Buffer overflow in parse_type\n");    buf[len] = s[0][len];    }    buf[len]=0;    *s += len;       switch(buf[0])    {    case 'z': -  if(!strcmp(buf,"zero")) { push_type(T_MIXED); break; } +  if(!strcmp(buf,"zero")) { push_type(T_ZERO); break; }    goto bad_type;       case 'i':    if(!strcmp(buf,"int"))    {    while(ISSPACE(**s)) ++*s;    if(**s=='(')    {    INT32 min,max;    ++*s;
pike.git/src/pike_types.c:489:          case 's':    if(!strcmp(buf,"string")) { push_type(T_STRING); break; }    goto bad_type;       case 'v':    if(!strcmp(buf,"void")) { push_type(T_VOID); break; }    goto bad_type;    +  case 't': +  if (!strcmp(buf,"tuple")) +  { +  while(ISSPACE(**s)) ++*s; +  if(**s == '(') +  { +  type_stack_mark(); +  ++*s; +  type_stack_mark(); +  internal_parse_type(_s); +  type_stack_reverse(); +  if(**s != ',') error("Expecting ','.\n"); +  ++*s; +  type_stack_mark(); +  internal_parse_type(_s); +  type_stack_reverse(); +  if(**s != ')') error("Expecting ')'.\n"); +  ++*s; +  type_stack_reverse(); +  }else{ +  push_type(T_MIXED); +  push_type(T_MIXED); +  } +  push_type(T_TUPLE); +  break; +  } +  if(!strcmp(buf,"type")) { push_type(T_TYPE); break; } +  goto bad_type; +     case 'm':    if(!strcmp(buf,"mixed")) { push_type(T_MIXED); break; }    if(!strcmp(buf,"mapping"))    {    while(ISSPACE(**s)) ++*s;    if(**s == '(')    {    type_stack_mark();    ++*s;    type_stack_mark();
pike.git/src/pike_types.c:707: Inside #if defined(PIKE_DEBUG)
   for(e=0;e<len;e++)    {    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_SCOPE: printf("scope"); break; +  case T_TUPLE: printf("tuple"); break;    case T_ASSIGN: printf("="); break;    case T_INT:    {    INT32 min=extract_type_int(a+e+1);    INT32 max=extract_type_int(a+e+1+sizeof(INT32));    printf("int");    if(min!=MIN_INT32 || max!=MAX_INT32)    printf("(%ld..%ld)",(long)min,(long)max);    e+=sizeof(INT32)*2;    break;    }    case T_FLOAT: printf("float"); break;    case T_STRING: printf("string"); break; -  +  case T_TYPE: printf("type"); break;    case T_PROGRAM: printf("program"); break;    case T_OBJECT:    printf("object(%s %ld)",    EXTRACT_UCHAR(a+e+1)?"clone of":"inherits",    (long)extract_type_int(a+e+2));    e+=sizeof(INT32)+1;    break;    case T_FUNCTION: printf("function"); break;    case T_ARRAY: printf("array"); break;    case T_MAPPING: printf("mapping"); break;
pike.git/src/pike_types.c:770:    break;       case T_ASSIGN:    my_putchar('(');    my_putchar(EXTRACT_UCHAR(t++));    my_putchar('=');    t=low_describe_type(t);    my_putchar(')');    break;    +  case T_SCOPE: +  my_putchar('{'); +  my_putchar(EXTRACT_UCHAR(t++)); +  my_putchar(','); +  t = low_describe_type(t); +  my_putchar('}'); +  break; +  +  case T_TUPLE: +  my_putchar('['); +  t = low_describe_type(t); +  my_putchar(','); +  t = low_describe_type(t); +  my_putchar(']'); +  break; +     case T_VOID: my_strcat("void"); break;    case T_ZERO: my_strcat("zero"); break;    case T_MIXED: my_strcat("mixed"); break;    case T_UNKNOWN: my_strcat("unknown"); break;    case T_INT:    {    INT32 min=extract_type_int(t);    INT32 max=extract_type_int(t+sizeof(INT32));    my_strcat("int");   
pike.git/src/pike_types.c:806:    sprintf(buffer,"object(%s %ld)",*t?"is":"implements",(long)extract_type_int(t+1));    my_strcat(buffer);    }else{    my_strcat("object");    }       t+=sizeof(INT32)+1;    /* Prog id */    break;    case T_STRING: my_strcat("string"); break; +  case T_TYPE: my_strcat("type"); break;       case T_FUNCTION:    {    int s;    my_strcat("function");    if(EXTRACT_UCHAR(t) == T_MANY &&    (EXTRACT_UCHAR(t+1) == T_MIXED &&    EXTRACT_UCHAR(t+2) == T_OR &&    ((EXTRACT_UCHAR(t+3) == T_MIXED && EXTRACT_UCHAR(t+4) == T_VOID) ||    (EXTRACT_UCHAR(t+4) == T_MIXED && EXTRACT_UCHAR(t+3) == T_VOID)))
pike.git/src/pike_types.c:937:   {    TYPE_T tmp;    switch(EXTRACT_UCHAR(t))    {    case T_OR:    t++;    tmp=low_compile_type_to_runtime_type(t);    if(tmp == low_compile_type_to_runtime_type(t+type_length(t)))    return tmp;    +  case T_TUPLE: +  /* FIXME: Shouldn't occur/should be converted to array? */ +  /* FALL_THROUGH */    default:    return T_MIXED;       case T_ZERO:    return T_INT;    -  +  case T_SCOPE: +  return low_compile_type_to_runtime_type(t+2); +     case T_ARRAY:    case T_MAPPING:    case T_MULTISET:       case T_OBJECT:    case T_PROGRAM:    case T_FUNCTION:       case T_STRING: -  +  case T_TYPE:    case T_INT:    case T_FLOAT:    return EXTRACT_UCHAR(t);    }   }      TYPE_T compile_type_to_runtime_type(struct pike_string *s)   {    return low_compile_type_to_runtime_type(s->str);   }
pike.git/src/pike_types.c:1037:    i1=extract_type_int(t1+1+sizeof(INT32));    i2=extract_type_int(t2+1+sizeof(INT32));    push_type_int(MAXIMUM(i1,i2));       i1=extract_type_int(t1+1);    i2=extract_type_int(t2+1);    push_type_int(MINIMUM(i1,i2));       push_type(T_INT);    } +  else if (EXTRACT_UCHAR(t1) == T_SCOPE) +  { +  if (EXTRACT_UCHAR(t2) == T_SCOPE) { +  low_or_pike_types(t1+2, t2+2, zero_implied); +  if (EXTRACT_UCHAR(t1+1) > EXTRACT_UCHAR(t2+1)) +  push_type(EXTRACT_UCHAR(t1+1));    else -  +  push_type(EXTRACT_UCHAR(t2+1)); +  } else { +  low_or_pike_types(t1+2, t2, zero_implied); +  push_type(EXTRACT_UCHAR(t1+1)); +  } +  push_type(T_SCOPE); +  } +  else if (EXTRACT_UCHAR(t2) == T_SCOPE)    { -  +  low_or_pike_types(t1, t2+2, zero_implied); +  push_type(EXTRACT_UCHAR(t2+1)); +  push_type(T_SCOPE); +  } +  else +  {    push_unfinished_type(t1);    very_low_or_pike_types(t2,t1);    }   }      static void medium_or_pike_types(struct pike_string *a,    struct pike_string *b,    int zero_implied)   {    low_or_pike_types( a ? a->str : 0 , b ? b->str : 0 , zero_implied);   }      struct pike_string *or_pike_types(struct pike_string *a,    struct pike_string *b,    int zero_implied)   {    type_stack_mark(); -  medium_or_pike_types(a,b,zero_implied); +  medium_or_pike_types(a,b,1 /*zero_implied*/);    return pop_unfinished_type();   }      static void very_low_and_pike_types(char *to_push, char *not_push)   {    while(EXTRACT_UCHAR(to_push)==T_AND)    {    to_push++;    very_low_and_pike_types(to_push, not_push);    to_push+=type_length(to_push);
pike.git/src/pike_types.c:1123:    t1++;    is_complex |= lower_and_pike_types(t1, t2);    t1 += type_length(t1);    }    switch(EXTRACT_UCHAR(t1)) {    case T_ZERO:    case T_VOID:    break;    case T_PROGRAM:    case T_STRING: +  case T_TYPE:    case T_FLOAT:    case T_INT:    even_lower_and_pike_types(t1, t2);    break;    default:    return 1;    }    return is_complex;   }   
pike.git/src/pike_types.c:1155:    is_complex = 1;    }    }    type += type_length(type);    }    switch(EXTRACT_UCHAR(type)) {    case T_VOID:    case T_ZERO:    case T_PROGRAM:    case T_STRING: +  case T_TYPE:    case T_FLOAT:    case T_INT:    /* Simple type. Already handled. */    break;    default:    push_unfinished_type(type);    if (is_complex) {    push_type(T_OR);    }    return 1;
pike.git/src/pike_types.c:1211:    if (upper_bound >= lower_bound) {    push_type_int(upper_bound);    push_type_int(lower_bound);    push_type(T_INT);    } else {    /* No overlap! */    /* FIXME: Warn? */    push_type(T_VOID);    }    } +  else if (EXTRACT_UCHAR(t1) == T_SCOPE) +  { +  if (EXTRACT_UCHAR(t2) == T_SCOPE) { +  low_and_pike_types(t1+2, t2+2); +  if (EXTRACT_UCHAR(t1+1) > EXTRACT_UCHAR(t2+1)) +  push_type(EXTRACT_UCHAR(t1+1)); +  else +  push_type(EXTRACT_UCHAR(t2+1)); +  } else { +  low_and_pike_types(t1+2, t2); +  push_type(EXTRACT_UCHAR(t1+1)); +  } +  push_type(T_SCOPE); +  } +  else if (EXTRACT_UCHAR(t2) == T_SCOPE) +  { +  low_and_pike_types(t1, t2+2); +  push_type(EXTRACT_UCHAR(t2+1)); +  push_type(T_SCOPE); +  }    else if((EXTRACT_UCHAR(t1)==T_STRING && EXTRACT_UCHAR(t2)==T_STRING) || -  +  (EXTRACT_UCHAR(t1)==T_TYPE && EXTRACT_UCHAR(t2)==T_TYPE) ||    (EXTRACT_UCHAR(t1)==T_FLOAT && EXTRACT_UCHAR(t2)==T_FLOAT) ||    (EXTRACT_UCHAR(t1)==T_PROGRAM && EXTRACT_UCHAR(t2)==T_PROGRAM))    {    push_unfinished_type(t1);    }    else if(low_pike_types_le(t1, t2))    {    push_unfinished_type(t1);    }    else if(low_pike_types_le(t2, t1))
pike.git/src/pike_types.c:1551: Inside #if 1
   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;    }    +  /* Convert zero to int(0..0). */ +  if (EXTRACT_UCHAR(a) == T_ZERO) +  a = tInt0; +  if (EXTRACT_UCHAR(b) == T_ZERO) +  b = tInt0;       /* 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))) -  return low_match_types(s->str,b,flags); +  return low_match_types(s->str,b,flags & ~(A_EXACT|B_EXACT));    return a;    }       case TWOT(T_FUNCTION, T_OBJECT):    {    struct pike_string *s;    if((s=low_object_lfun_type(b, LFUN_CALL))) -  return low_match_types(a,s->str,flags); +  return low_match_types(a,s->str,flags & ~(A_EXACT|B_EXACT));    return a;    }    }       if(EXTRACT_UCHAR(a) != EXTRACT_UCHAR(b)) return 0;       ret=a;    switch(EXTRACT_UCHAR(a))    {    case T_FUNCTION:
pike.git/src/pike_types.c:1603:    }       if(EXTRACT_UCHAR(b)==T_MANY)    {    b_tmp=b+1;    }else{    b_tmp=b;    b+=type_length(b);    }    -  if(!low_match_types(a_tmp, b_tmp, flags | NO_MAX_ARGS)) return 0; +  if(!low_match_types(a_tmp, b_tmp, +  (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT))) +  return 0;    if(++correct_args > max_correct_args)    if(!(flags & NO_MAX_ARGS))    max_correct_args=correct_args;    }    /* check the 'many' type */    a++;    b++;    if(EXTRACT_UCHAR(b)==T_VOID || EXTRACT_UCHAR(a)==T_VOID)    {    a+=type_length(a);    b+=type_length(b);    }else{ -  if(!low_match_types(a,b,flags | NO_MAX_ARGS)) return 0; +  if(!low_match_types(a,b, (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT))) +  return 0;    }    if(!(flags & NO_MAX_ARGS))    max_correct_args=0x7fffffff;    /* check the returntype */    if ((EXTRACT_UCHAR(b) == T_VOID) && (EXTRACT_UCHAR(a) != T_VOID)) {    /* Promote b to a function returning zero. */ -  if (!low_match_types(a, tZero, flags)) return 0; +  if (!low_match_types(a, tZero, flags & ~(A_EXACT|B_EXACT))) return 0;    } else if ((EXTRACT_UCHAR(a) == T_VOID) && (EXTRACT_UCHAR(b) != T_VOID)) {    /* Promote a to a function returning zero. */ -  if(!low_match_types(tZero,b,flags)) return 0; -  } else if(!low_match_types(a,b,flags)) return 0; +  if(!low_match_types(tZero,b,flags & ~(A_EXACT|B_EXACT))) return 0; +  } else if(!low_match_types(a,b,flags & ~(A_EXACT|B_EXACT))) return 0;    break;       case T_MAPPING: -  if(!low_match_types(++a,++b,flags)) return 0; -  if(!low_match_types(a+type_length(a),b+type_length(b),flags)) return 0; +  if(!low_match_types(++a,++b,flags & ~(A_EXACT|B_EXACT))) return 0; +  if(!low_match_types(a+type_length(a),b+type_length(b), +  flags & ~(A_EXACT|B_EXACT))) return 0;    break;       case T_OBJECT:   #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));
pike.git/src/pike_types.c:1697:    INT32 bmin=extract_type_int(b+1);    INT32 bmax=extract_type_int(b+1+sizeof(INT32));       if(amin > bmax || bmin > amax) return 0;    break;    }          case T_MULTISET:    case T_ARRAY: -  if(!low_match_types(++a,++b,flags)) return 0; +  if(!low_match_types(++a,++b,flags & ~(A_EXACT|B_EXACT))) return 0;       case T_FLOAT:    case T_STRING: -  +  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;
pike.git/src/pike_types.c:2101:    /* It's not an error to index a multiset with a nonexistant key. */    if(!low_pike_types_le(++a,++b) &&    !low_pike_types_le(b, a)) return 0;    break;       case T_ARRAY:    if(!low_pike_types_le(++a,++b)) return 0;       case T_FLOAT:    case T_STRING: +  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;
pike.git/src/pike_types.c:2168:    a++;    tmp=low_get_return_type(a,b);    if(!tmp) return 0;    push_type(T_ARRAY);    return 1;    }       a=low_match_types(a,b,NO_SHORTCUTS);    if(a)    { + #if 0 +  if ((lex.pragmas & ID_STRICT_TYPES) && +  !low_pike_types_le(a, b)) { +  yywarning("Type mismatch"); +  } + #endif /* 0 */    switch(EXTRACT_UCHAR(a))    {    case T_FUNCTION:    a++;    while(EXTRACT_UCHAR(a)!=T_MANY) a+=type_length(a);    a++;    a+=type_length(a);    push_unfinished_type_with_markers(a, a_markers );    return 1;   
pike.git/src/pike_types.c:2223:   #define low_index_type debug_low_index_type   #endif      /* FIXME, add the index */   static struct pike_string *debug_low_index_type(char *t,    char *index_type,    node *n)   {    struct pike_string *tmp;    struct program *p; +     switch(low_check_indexing(t, index_type, n))    {    case 0: return 0;    case -1:    reference_shared_string(zero_type_string);    return zero_type_string;    }       switch(EXTRACT_UCHAR(t++))    {
pike.git/src/pike_types.c:2298:    }   #endif    }    }    }    }    default:    reference_shared_string(mixed_type_string);    return mixed_type_string;    +  case T_MIXED: +  if (lex.pragmas & ID_STRICT_TYPES) { +  yywarning("Indexing mixed."); +  } +  reference_shared_string(mixed_type_string); +  return mixed_type_string; +     case T_INT:   #ifdef AUTO_BIGNUM    /* Don't force Gmp.mpz to be loaded here since this function    * is called long before the master object is compiled...    * /Hubbe    */    p=get_auto_bignum_program_or_zero();    goto comefrom_int_index;   #endif    case T_ZERO: -  +  case T_TYPE:    case T_VOID:    case T_FLOAT:    return 0;       case T_OR:    {    struct pike_string *a,*b;    a=low_index_type(t,index_type,n);    t+=type_length(t);    b=low_index_type(t,index_type,n);
pike.git/src/pike_types.c:2417:    }    reference_shared_string(string_type_string);    return string_type_string;    }    default:    reference_shared_string(mixed_type_string);    return mixed_type_string;       case T_VOID:    case T_ZERO: +  case T_TYPE:    case T_FLOAT:    case T_INT:    return 0;       case T_OR:    {    struct pike_string *a,*b;    a=low_key_type(t,n);    t+=type_length(t);    b=low_key_type(t,n);
pike.git/src/pike_types.c:2828:    case T_ARRAY: return "array";    case T_FLOAT: return "float";    case T_FUNCTION: return "function";    case T_INT: return "int";    case T_LVALUE: return "lvalue";    case T_MAPPING: return "mapping";    case T_MULTISET: return "multiset";    case T_OBJECT: return "object";    case T_PROGRAM: return "program";    case T_STRING: return "string"; +  case T_TYPE: return "type";    case T_ZERO: return "zero";    case T_VOID: return "void";    default: return "unknown";    }   }      void cleanup_pike_types(void)   {    free_string(string_type_string);    free_string(int_type_string);