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.170 2001/03/28 00:48:48 grubba Exp $"); + RCSID("$Id: pike_types.c,v 1.171 2001/03/28 14:56: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:188: Inside #if defined(USE_PIKE_TYPE)
   * MAPPING index type value type    * OR type type    * AND type type    * ARRAY type -    * MULTISET type -    * NOT type -    * '0'-'9' - -    * FLOAT - -    * STRING - -    * TYPE - - -  * PROGRAM - - +  * PROGRAM type -    * MIXED - -    * VOID - -    * ZERO - -    * UNKNOWN - -    * INT min (int) max (int)    * OBJECT implements/is object id(int)    *    * Note that the cdr of a FUNCTION is a valid FUNCTION for the rest of    * the arguments.    *
pike.git/src/pike_types.c:303:    case T_AND:    case PIKE_T_RING:    /* Free car & cdr */    free_type(car);    free_type(cdr);    break;       case T_ARRAY:    case T_MULTISET:    case T_NOT: +  case T_TYPE: +  case T_PROGRAM:    /* Free car */    free_type(car);    break;       case T_SCOPE:    case T_ASSIGN:    /* Free cdr */    free_type(cdr);    break;   
pike.git/src/pike_types.c:473:    *Pike_compiler->type_stackp = mk_type(type,    *(Pike_compiler->type_stackp+1),    *Pike_compiler->type_stackp,    PT_COPY_BOTH);    break;       case T_ARRAY:    case T_MULTISET:    case T_NOT:    case T_TYPE: +  case T_PROGRAM:    /* Make a new type of the top type, and put it in car. */    *Pike_compiler->type_stackp = mk_type(type,    *Pike_compiler->type_stackp, NULL,    PT_COPY_CAR);    break;       case T_SCOPE:    case T_ASSIGN:    case T_INT:    case T_OBJECT:    case PIKE_T_NAME:    default:    /* Should not occurr. */    fatal("Unsupported argument to push_type().\n");    break;       case T_FLOAT:    case T_STRING: -  case T_PROGRAM: +     case T_MIXED:    case T_VOID:    case T_ZERO:    case PIKE_T_UNKNOWN:    /* Leaf type. */    *(++Pike_compiler->type_stackp) = mk_type(type, NULL, NULL, 0);    break;       case '0':    case '1':
pike.git/src/pike_types.c:542:    case T_AND:    case PIKE_T_RING:    /* Both car & cdr. */    push_finished_type(top->cdr);    push_finished_type(top->car);    break;    case T_ARRAY:    case T_MULTISET:    case T_NOT:    case T_TYPE: +  case T_PROGRAM:    /* car */    push_finished_type(top->car);    break;    case T_SCOPE:    case T_ASSIGN:    /* cdr */    push_finished_type(top->cdr);    break;    case T_INT:    case T_OBJECT:    case T_FLOAT:    case T_STRING: -  case T_PROGRAM: +     case T_MIXED:    case T_VOID:    case T_ZERO:    case PIKE_T_UNKNOWN:    case '0':    case '1':    case '2':    case '3':    case '4':    case '5':
pike.git/src/pike_types.c:834:    push_object_type(is, id);    }    else    push_object_type(0, 0);    break;    }    goto bad_type;          case 'p': -  if(!strcmp(buf,"program")) { push_type(T_PROGRAM); break; } +  if(!strcmp(buf,"program")) { +  push_object_type(0, 0); +  push_type(T_PROGRAM); +  break; +  }    goto bad_type;          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;
pike.git/src/pike_types.c:1164: Inside #if defined(PIKE_DEBUG)
   fprintf(stderr, "(%ld..%ld)",(long)min,(long)max);    break;    }    case T_FLOAT: fprintf(stderr, "float"); break;    case T_STRING: fprintf(stderr, "string"); break;    case T_TYPE:    fprintf(stderr, "type(");    simple_describe_type(s->car);    fprintf(stderr, ")");    break; -  case T_PROGRAM: fprintf(stderr, "program"); break; +  case T_PROGRAM: +  fprintf(stderr, "program("); +  simple_describe_type(s->car); +  fprintf(stderr, ")"); +  break;    case T_OBJECT:    fprintf(stderr, "object(%s %ld)",    s->car?"is":"implements",    (long)(ptrdiff_t)s->cdr);    break;    case T_FUNCTION:    case T_MANY:    fprintf(stderr, "function(");    while(s->type == T_FUNCTION) {    simple_describe_type(s->car);
pike.git/src/pike_types.c:1301:       if(min!=MIN_INT32 || max!=MAX_INT32)    {    char buffer[100];    sprintf(buffer,"(%ld..%ld)",(long)min,(long)max);    my_strcat(buffer);    }    break;    }    case T_FLOAT: my_strcat("float"); break; -  case T_PROGRAM: my_strcat("program"); break; +  case T_PROGRAM: +  my_strcat("program("); +  my_describe_type(t->car); +  my_strcat(")"); +  break;    case T_OBJECT:    if (t->cdr)    {    char buffer[100];    sprintf(buffer,"object(%s %ld)",    t->car?"is":"implements",    (long)(ptrdiff_t)t->cdr);    my_strcat(buffer);    }else{    my_strcat("object");
pike.git/src/pike_types.c:1704:    int is_complex = 0;    while(t1->type == T_OR)    {    is_complex |= lower_and_pike_types(t1->car, t2);    t1 = t1->cdr;    }    switch(t1->type) {    case T_ZERO:    case T_VOID:    break; -  case T_PROGRAM: +     case T_STRING:    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:1735:    push_type(T_OR);    } else {    is_complex = 1;    }    }    type = type->cdr;    }    switch(type->type) {    case T_VOID:    case T_ZERO: -  case T_PROGRAM: +     case T_STRING:    case T_FLOAT:    case T_INT:    /* Simple type. Already handled. */    break;    default:    push_finished_type(type);    if (is_complex) {    push_type(T_OR);    }
pike.git/src/pike_types.c:1812:    push_scope_type((ptrdiff_t)t1->car);    }    }    else if (t2->type == T_SCOPE)    {    low_and_pike_types(t1, t2->cdr);    push_scope_type((ptrdiff_t)t2->car);    }    else if((t1->type == t2->type) &&    ((t1->type == T_STRING) || -  (t1->type == T_FLOAT) || -  (t1->type == T_PROGRAM))) +  (t1->type == T_FLOAT)))    {    push_finished_type(t1);    }    else if(low_pike_types_le(t1, t2, 0, 0))    {    push_finished_type(t1);    }    else if(low_pike_types_le(t2, t1, 0, 0))    {    push_finished_type(t2);
pike.git/src/pike_types.c:2196:    return a;    }       /* Special cases (tm) */    switch(TWOT(a->type, b->type))    {    case TWOT(T_PROGRAM, T_FUNCTION):    case TWOT(T_FUNCTION, T_PROGRAM):    case TWOT(T_PROGRAM, T_MANY):    case TWOT(T_MANY, T_PROGRAM): +  /* FIXME: Should look at the sub-type of the program +  * to determine the prototype to use. +  */    return a;       case TWOT(T_OBJECT, T_FUNCTION):    case TWOT(T_OBJECT, T_MANY):    {    struct pike_type *s;    if((s = low_object_lfun_type(a, LFUN_CALL)))    return low_match_types(s, b, flags);    if (flags & B_EXACT) {    /* A function isn't an object */
pike.git/src/pike_types.c:2374:    INT32 amax = (ptrdiff_t)a->cdr;       INT32 bmin = (ptrdiff_t)b->car;    INT32 bmax = (ptrdiff_t)b->cdr;       if(amin > bmax || bmin > amax) return 0;    break;    }       +  case T_PROGRAM:    case T_TYPE:    case T_MULTISET:    case T_ARRAY:    if(!low_match_types(a->car, b->car,    flags & ~(A_EXACT|B_EXACT))) return 0;       case T_FLOAT:    case T_STRING: -  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:2730:    }       /* Special cases (tm) */    switch(TWOT(a->type, b->type))    {    case TWOT(T_PROGRAM, T_FUNCTION):    case TWOT(T_FUNCTION, T_PROGRAM):    case TWOT(T_PROGRAM, T_MANY):    case TWOT(T_MANY, T_PROGRAM):    /* FIXME: Not really... Should check the return value. */ +  /* FIXME: Should also look at the subtype of the program. */    return 1;       case TWOT(T_OBJECT, T_FUNCTION):    case TWOT(T_OBJECT, T_MANY):    {    if((a = low_object_lfun_type(a, LFUN_CALL))) {    goto recurse;    }    return 1;    }
pike.git/src/pike_types.c:2910:       INT32 bmin = (ptrdiff_t)b->car;    INT32 bmax = (ptrdiff_t)b->cdr;       if(amin < bmin || amax > bmax) return 0;    break;    }          case T_TYPE: +  case T_PROGRAM:    case T_MULTISET:    case T_ARRAY:    a = a->car;    b = b->car;    array_cnt = 0;    goto recurse;       case T_FLOAT:    case T_STRING: -  case T_PROGRAM: +     case T_ZERO:    case T_VOID:    case T_MIXED:    break;       default:    fatal("Error in type string.\n");    }    return 1;   }
pike.git/src/pike_types.c:3040:    while(a->type == T_FUNCTION) {    a = a->cdr;    }    /* FALL_THROUGH */    case T_MANY:    a = a->cdr;    push_finished_type_with_markers(a, a_markers );    return 1;       case T_PROGRAM: -  push_object_type(0, 0); +  push_finished_type(a->car);    return 1;       default:    push_type(T_MIXED);    return 1;    }    }    return 0;   }   
pike.git/src/pike_types.c:3630:    INT32 ret,tmp=max_correct_args;    check_type(type->type);    clear_markers();    type = check_call(function_type_string, type, 0);    if(type) free_type(type);    ret=max_correct_args;    max_correct_args=tmp;    return tmp;   }    + /* NOTE: type loses a reference. */ + struct pike_type *new_check_call(node *fun, int *argno, +  struct pike_type *type, node *args) + { +  struct pike_type *tmp_type = NULL;    -  +  while (args && (args->token == F_ARG_LIST)) { +  type = new_check_call(fun, argno, type, CAR(args)); +  args = CDR(args); +  } +  if (!args) { +  return type; +  } +  +  switch(type->type) { +  case T_NOT: +  break; +  +  case T_FUNCTION: +  if (!pike_types_le(args->type, type->car)) { +  if (!match_types(args->type, type->car)) { +  /* Bad arg */ +  } else { +  /* Not strict arg */ +  } +  } +  copy_type(tmp_type, type->cdr); +  free_type(type); +  type = tmp_type; +  (*argno)++; +  break; +  +  case T_MANY: +  if (!pike_types_le(args->type, type->car)) { +  if (!match_types(args->type, type->car)) { +  /* Bad arg */ +  } else { +  /* Not strict arg */ +  } +  } +  (*argno)++; +  break; +  } +  +  return type; + } +    struct pike_type *zzap_function_return(struct pike_type *a, INT32 id)   {    switch(a->type)    {    case T_OR:    {    struct pike_type *ar, *br, *ret=0;    ar = zzap_function_return(a->car, id);    br = zzap_function_return(a->cdr, id);    if(ar && br) ret = or_pike_types(ar, br, 0);
pike.git/src/pike_types.c:3798:    */    push_int_type(s->u.integer, s->u.integer);    return pop_unfinished_type();    }else{    copy_type(ret, zero_type_string);    return ret;    }       case T_PROGRAM:    { +  /* FIXME: An alternative would be to push program(object(1,p->id)). */    struct pike_type *a;    struct pike_string *tmp;    int id;       if(s->u.program->identifiers)    {    id=FIND_LFUN(s->u.program,LFUN_CREATE);    if(id>=0)    {    a = ID_FROM_INT(s->u.program, id)->type;
pike.git/src/pike_types.c:4022:    case T_OR:    case T_AND:    /* Order independant */    /* FIXME: */    return mk_type(type, low_make_pike_type(type_string+1, cont),    low_make_pike_type(*cont, cont), PT_COPY_BOTH);    case T_ARRAY:    case T_MULTISET:    case T_TYPE:    case T_NOT: +  case T_PROGRAM:    /* Single type */    return mk_type(type, low_make_pike_type(type_string+1, cont), NULL,    PT_COPY_CAR);    case '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':    /* Marker type */    *cont = type_string+1;    return mk_type(type, NULL, NULL, PT_SET_MARKER);       case T_FLOAT:    case T_STRING: -  case T_PROGRAM: +     case T_MIXED:    case T_VOID:    case T_ZERO:    case PIKE_T_UNKNOWN:    /* Leaf type */    *cont = type_string+1;    return mk_type(type, NULL, NULL, 0);       case T_INT:    *cont = type_string + 9; /* 2*sizeof(INT32) + 1 */
pike.git/src/pike_types.c:4120:    /* FIXME: Should probably look at both branches. */    type = type->cdr;    goto again;       case T_ARRAY:    case T_MULTISET:    type = type->car;    goto again;       case T_PROGRAM: +  case T_TYPE:    case T_INT:    case T_FLOAT:    case T_STRING:    case T_VOID:    return 1;    default:    fatal("pike_type_allow_premature_toss: Unknown type code (%d)\n",    ((unsigned char *)type)[-1]);    /* NOT_REACHED */    return 0;
pike.git/src/pike_types.c:4141:   }      static void low_type_to_string(struct pike_type *t)   {    recurse:    switch(t->type) {    case T_ARRAY:    case T_MULTISET:    case T_TYPE:    case T_NOT: +  case T_PROGRAM:    my_putchar(t->type);    /* FALL_THROUGH */    case PIKE_T_NAME:    t = t->car;    goto recurse;       case PIKE_T_RING:    case T_TUPLE:    case T_MAPPING:    case T_OR:
pike.git/src/pike_types.c:4167:    case '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9': -  case T_PROGRAM: +     case T_STRING:    case T_FLOAT:    case T_ZERO:    case T_VOID:    case T_MIXED:    my_putchar(t->type);    break;       case T_OBJECT:    {
pike.git/src/pike_types.c:4319:    case T_MAPPING:    case PIKE_T_RING:    case T_OR:    case T_AND:    t+=type_length(t);       case T_ARRAY:    case T_MULTISET:    case T_TYPE:    case T_NOT: +  case T_PROGRAM:    goto one_more_type;       case '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':    case T_FLOAT:    case T_STRING: -  case T_PROGRAM: +     case T_MIXED:    case T_VOID:    case T_ZERO:    case PIKE_T_UNKNOWN:    break;       case T_INT:    t+=sizeof(INT32)*2;    break;   
pike.git/src/pike_types.c:4673:    ++*s;    push_object_type(is, id);    }    else    push_object_type(0, 0);    break;    }    goto bad_type;       case 'p': -  if(!strcmp(buf,"program")) { push_type(T_PROGRAM); break; } +  if(!strcmp(buf,"program")) { +  push_object_type(0, 0); +  push_type(T_PROGRAM); +  break; +  }    goto bad_type;          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;
pike.git/src/pike_types.c:5037:    {    char buffer[100];    sprintf(buffer,"(%ld..%ld)",(long)min,(long)max);    my_strcat(buffer);    }    t+=sizeof(INT32)*2;       break;    }    case T_FLOAT: my_strcat("float"); break; -  case T_PROGRAM: my_strcat("program"); break; +  case T_PROGRAM: +  my_strcat("program("); +  t = low_describe_type(t); +  my_strcat(")"); +  break;    case T_OBJECT:    if(extract_type_int(t+1))    {    char buffer[100];    sprintf(buffer,"object(%s %ld)",*t?"is":"implements",    (long)extract_type_int(t+1));    my_strcat(buffer);    }else{    my_strcat("object");    }
pike.git/src/pike_types.c:5461:    while(EXTRACT_UCHAR(t1)==T_OR)    {    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_FLOAT:    case T_INT:    even_lower_and_pike_types(t1, t2);    break;    default:    return 1;    }    return is_complex;   }
pike.git/src/pike_types.c:5493:    push_type(T_OR);    } else {    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_FLOAT:    case T_INT:    /* Simple type. Already handled. */    break;    default:    push_unfinished_type(type);    if (is_complex) {    push_type(T_OR);    }
pike.git/src/pike_types.c:5572:    }    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_FLOAT && EXTRACT_UCHAR(t2)==T_FLOAT) || -  (EXTRACT_UCHAR(t1)==T_PROGRAM && EXTRACT_UCHAR(t2)==T_PROGRAM)) +  (EXTRACT_UCHAR(t1)==T_FLOAT && EXTRACT_UCHAR(t2)==T_FLOAT))    {    push_unfinished_type(t1);    }    else if(low_pike_types_le(t1, t2, 0, 0))    {    push_unfinished_type(t1);    }    else if(low_pike_types_le(t2, t1, 0, 0))    {    push_unfinished_type(t2);
pike.git/src/pike_types.c:5955:    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): +  /* FIXME: Should look at the program subtype. */    return a;       case TWOT(T_OBJECT, T_FUNCTION):    {    struct pike_type *s;    if((s=low_object_lfun_type(a, LFUN_CALL)))    return low_match_types(s->str,b,flags);    if (flags & B_EXACT) {    /* A function isn't an object */    return 0;
pike.git/src/pike_types.c:6119:    INT32 bmax=extract_type_int(b+1+sizeof(INT32));       if(amin > bmax || bmin > amax) return 0;    break;    }          case T_TYPE:    case T_MULTISET:    case T_ARRAY: +  case T_PROGRAM:    if(!low_match_types(++a,++b,flags & ~(A_EXACT|B_EXACT))) return 0;       case T_FLOAT:    case T_STRING: -  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:6457:    return 0;    }    }       /* Special cases (tm) */    switch(EXTRACT_TWOT(a,b))    {    case TWOT(T_PROGRAM, T_FUNCTION):    case TWOT(T_FUNCTION, T_PROGRAM):    /* FIXME: Not really... Should check the return value. */ +  /* FIXME: Should look at the program subtype. */    return 1;       case TWOT(T_OBJECT, T_FUNCTION):    {    struct pike_type *s;    if((s=low_object_lfun_type(a, LFUN_CALL)))    return low_pike_types_le(s->str, b, array_cnt, flags);    return 1;    }   
pike.git/src/pike_types.c:6637:    INT32 bmax=extract_type_int(b+1+sizeof(INT32));       if(amin < bmin || amax > bmax) return 0;    break;    }          case T_TYPE:    case T_MULTISET:    case T_ARRAY: +  case T_PROGRAM:    if(!low_pike_types_le(++a, ++b, 0, flags)) return 0;       case T_FLOAT:    case T_STRING: -  case T_PROGRAM: +     case T_ZERO:    case T_VOID:    case T_MIXED:    break;       default:    fatal("Error in type string.\n");    }    return 1;   }
pike.git/src/pike_types.c:6758:    {    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;       case T_PROGRAM: -  push_type_int(0); -  push_type(0); -  push_type(T_OBJECT); +  push_unfinished_type(a+1);    return 1;       default:    push_type(T_MIXED);    return 1;    }    }    return 0;   }   
pike.git/src/pike_types.c:7482:    */    push_int_type(s->u.integer, s->u.integer);    return pop_unfinished_type();    }else{    copy_type(ret, zero_type_string);    }    return ret;       case T_PROGRAM:    { +  /* FIXME: An alternative is to push PROGRAM(OBJECT(1, p->id)) */    struct pike_type *t;    int id;       if(s->u.program->identifiers)    {    id=FIND_LFUN(s->u.program,LFUN_CREATE);    if(id>=0)    {    struct pike_string *tmp;    t = ID_FROM_INT(s->u.program, id)->type;
pike.git/src/pike_types.c:7690:    case T_OR:    case T_MAPPING:    if(!low_pike_type_allow_premature_toss(type)) return 0;    case T_AND:    type+=type_length(type);    case T_ARRAY:    case T_MULTISET:    goto again;       case T_PROGRAM: +  case T_TYPE:    case T_INT:    case T_FLOAT:    case T_STRING:    return 1;    }    /* NOT_REACHED */    return 0;   }      int pike_type_allow_premature_toss(struct pike_type *type)
pike.git/src/pike_types.c:7727:      void init_types(void)   {   #ifdef USE_PIKE_TYPE    /* Initialize hashtable here. */    pike_type_hash = (struct pike_type **)xalloc(sizeof(struct pike_type *) *    PIKE_TYPE_HASH_SIZE);    MEMSET(pike_type_hash, 0, sizeof(struct pike_type *) * PIKE_TYPE_HASH_SIZE);    pike_type_hash_size = PIKE_TYPE_HASH_SIZE;   #endif /* USE_PIKE_TYPE */ +  init_pike_type_blocks();    string_type_string = CONSTTYPE(tString);    int_type_string = CONSTTYPE(tInt);    object_type_string = CONSTTYPE(tObj); -  program_type_string = CONSTTYPE(tPrg); +  program_type_string = CONSTTYPE(tPrg(tObj));    float_type_string = CONSTTYPE(tFloat);    mixed_type_string = CONSTTYPE(tMix);    array_type_string = CONSTTYPE(tArray);    multiset_type_string = CONSTTYPE(tMultiset);    mapping_type_string = CONSTTYPE(tMapping);    function_type_string = CONSTTYPE(tFunction);    type_type_string = CONSTTYPE(tType(tMix));    void_type_string = CONSTTYPE(tVoid);    zero_type_string = CONSTTYPE(tZero);    any_type_string = CONSTTYPE(tOr(tVoid,tMix));