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.160 2001/03/05 18:53:40 grubba Exp $"); + RCSID("$Id: pike_types.c,v 1.161 2001/03/05 21:32:52 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:250:    case T_NOT:    /* Free car */    t = car;    goto loop;       case T_SCOPE:    case T_ASSIGN:    /* Free cdr */    t = cdr;    goto loop; +  +  case PIKE_T_NAME: +  free_string((struct pike_string *)car); +  t = cdr; +  goto loop;    }    }   }      /* Flags used as flag_method: */   #define PT_COPY_CAR 1   #define PT_COPY_CDR 2   #define PT_COPY_BOTH 3   #define PT_SET_MARKER 4   
pike.git/src/pike_types.c:275:    unsigned INT32 hash = DO_NOT_WARN((unsigned INT32)    ((ptrdiff_t)type*0x10204081)^    (0x8003*(ptrdiff_t)car)^    ~(0x10001*(ptrdiff_t)cdr));    unsigned INT32 index = hash % pike_type_hash_size;    struct pike_type *t;       for(t = pike_type_hash[index]; t; t = t->next) {    if ((t->hash == hash) && (t->type == type) &&    (t->car == car) && (t->cdr == cdr)) { +  switch(type) { +  case T_FUNCTION: +  case T_MANY: +  case T_TUPLE: +  case T_MAPPING: +  case T_OR: +  case T_AND: +  /* Free car & cdr */ +  free_type(car); +  free_type(cdr); +  break; +  +  case T_ARRAY: +  case T_MULTISET: +  case T_NOT: +  /* Free car */ +  free_type(car); +  break; +  +  case T_SCOPE: +  case T_ASSIGN: +  /* Free cdr */ +  free_type(cdr); +  break; +  +  case PIKE_T_NAME: +  free_string((struct pike_string *)car); +  free_type(cdr); +  break; +  } +  /* FIXME: Free car & cdr as appropriate. */    add_ref(t);    return t;    }    }       t = alloc_pike_type();       t->refs = 1;    t->type = type;    t->flags = 0;
pike.git/src/pike_types.c:380:      void push_assign_type(int marker)   {    *Pike_compiler->type_stackp = mk_type(T_ASSIGN,    (void *)(ptrdiff_t)marker,    *Pike_compiler->type_stackp,    PT_COPY_CDR);    TYPE_STACK_DEBUG("push_assign_type");   }    + void push_type_name(struct pike_string *name) + { +  /* fprintf(stderr, "push_type_name(\"%s\")\n", name->str); */ +  add_ref(name); +  *Pike_compiler->type_stackp = mk_type(PIKE_T_NAME, +  (void *)name, +  *Pike_compiler->type_stackp, +  PT_COPY_CDR); +  TYPE_STACK_DEBUG("push_type_name"); + } +    void push_finished_type(struct pike_type *t)   {    copy_type(*(++Pike_compiler->type_stackp), t);       TYPE_STACK_DEBUG("push_finished_type");   }      void push_type(unsigned INT16 type)   {    /* fprintf(stderr, "push_type(%d)\n", type); */
pike.git/src/pike_types.c:419:    /* 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("");    break;       case T_FLOAT:    case T_STRING:    case T_TYPE:    case T_PROGRAM:    case T_MIXED:
pike.git/src/pike_types.c:506:    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':    /* Leaf */    break; +  case PIKE_T_NAME: +  /* Pop the name and recurse. */ +  push_finished_type(top->cdr); +  pop_type_stack(); +  break;    default:    Pike_error("pop_type_stack(): Unhandled node type: %d\n", top->type);    }    free_type(top);       TYPE_STACK_DEBUG("pop_type_stack");   }      void push_reverse_type(unsigned INT16 type)   {
pike.git/src/pike_types.c:576:    return;    }    if (type->type == T_ASSIGN) {    /* Strip assign */   #if 0    fprintf(stderr, "Assign to marker %d.\n", ((ptrdiff_t)type->car)-'0');   #endif /* 0 */    type = type->cdr;    goto recurse;    } +  if (type->type == PIKE_T_NAME) { +  /* Strip the name, since it won't be correct anymore. */ +  type = type->cdr; +  goto recurse; +  }    /* FIXME: T_SCOPE */    if (type->cdr) {    push_finished_type_with_markers(type->cdr, markers);    }    /* In all other cases type->car will be a valid node. */    push_finished_type_with_markers(type->car, markers);    /* push_type has sufficient magic to recreate the type. */    push_type(type->type);    TYPE_STACK_DEBUG("push_finished_type_with_markers");   }
pike.git/src/pike_types.c:1025: Inside #if defined(PIKE_DEBUG)
     void simple_describe_type(struct pike_type *s)   {    if (s) {    switch(s->type) {    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    printf("%d", s->type-'0');    break;    +  case PIKE_T_NAME: +  printf("{ %s = ", ((struct pike_string *)s->car)->str); +  simple_describe_type(s->cdr); +  printf(" }"); +  break; +     case T_SCOPE:    printf("scope(%ld, ", (long)(ptrdiff_t)s->car);    simple_describe_type(s->cdr);    printf(")");    break;    case T_TUPLE:    printf("tuple(");    simple_describe_type(s->car);    printf(", ");    simple_describe_type(s->cdr);
pike.git/src/pike_types.c:1144:    {    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    my_putchar(t->type);    break;       case T_ASSIGN:    my_putchar('(');    my_putchar((ptrdiff_t)t->car);    my_putchar('='); -  low_describe_type(t->cdr); +  my_describe_type(t->cdr);    my_putchar(')');    break;       case T_SCOPE:    my_putchar('{');    my_putchar((ptrdiff_t)t->car);    my_putchar(','); -  low_describe_type(t->cdr); +  my_describe_type(t->cdr);    my_putchar('}');    break;       case T_TUPLE:    my_putchar('['); -  low_describe_type(t->car); +  my_describe_type(t->car);    my_putchar(','); -  low_describe_type(t->cdr); +  my_describe_type(t->cdr);    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 PIKE_T_UNKNOWN: my_strcat("unknown"); break;    case T_INT:    {    INT32 min=(ptrdiff_t)t->car;
pike.git/src/pike_types.c:1200:    (long)(ptrdiff_t)t->cdr);    my_strcat(buffer);    }else{    my_strcat("object");    }    break;       case T_STRING: my_strcat("string"); break;    case T_TYPE: my_strcat("type"); break;    +  case PIKE_T_NAME: +  if (!((struct pike_string *)t->car)->size_shift) { +  my_strcat("{ "); +  my_binary_strcat(((struct pike_string *)t->car)->str, +  ((struct pike_string *)t->car)->len); +  my_strcat(" = "); +  my_describe_type(t->cdr); +  my_strcat(" }"); +  } else { +  my_describe_type(t->cdr); +  } +  break; +     case T_FUNCTION:    case T_MANY:    {    int s;    my_strcat("function");    if(t->type == T_MANY &&    t->cdr->type == T_OR &&    ((t->cdr->car->type == T_MIXED && t->cdr->cdr->type == T_VOID) ||    (t->cdr->cdr->type == T_MIXED && t->cdr->car->type == T_VOID)) &&    (t->car->type == T_ZERO ||
pike.git/src/pike_types.c:1224:    /* function == function(zero...:mixed|void) or    * function(zero|void...:mixed|void)    */    /* done */    } else {    my_strcat("(");    s=0;    while(t->type != T_MANY)    {    if(s++) my_strcat(", "); -  low_describe_type(t->car); +  my_describe_type(t->car);    t = t->cdr;    }    if(t->car->type != T_VOID)    {    if(s++) my_strcat(", "); -  low_describe_type(t->car); +  my_describe_type(t->car);    my_strcat(" ...");    }    my_strcat(" : "); -  low_describe_type(t->cdr); +  my_describe_type(t->cdr);    my_strcat(")");    }    break;    }       case T_ARRAY:    my_strcat("array");    if(t->car->type != T_MIXED) {    my_strcat("("); -  low_describe_type(t->car); +  my_describe_type(t->car);    my_strcat(")");    }    break;       case T_MULTISET:    my_strcat("multiset");    if(t->car->type != T_MIXED) {    my_strcat("("); -  low_describe_type(t->car); +  my_describe_type(t->car);    my_strcat(")");    }    break;       case T_NOT:    my_strcat("!");    if (t->car->type > T_NOT) {    my_strcat("("); -  low_describe_type(t->car); +  my_describe_type(t->car);    my_strcat(")");    } else { -  low_describe_type(t->car); +  my_describe_type(t->car);    }    break;       case T_OR:    if (t->car->type > T_OR) {    my_strcat("("); -  low_describe_type(t->car); +  my_describe_type(t->car);    my_strcat(")");    } else { -  low_describe_type(t->car); +  my_describe_type(t->car);    }    my_strcat(" | ");    if (t->cdr->type > T_OR) {    my_strcat("("); -  low_describe_type(t->cdr); +  my_describe_type(t->cdr);    my_strcat(")");    } else { -  low_describe_type(t->cdr); +  my_describe_type(t->cdr);    }    break;       case T_AND:    if (t->car->type > T_AND) {    my_strcat("("); -  low_describe_type(t->car); +  my_describe_type(t->car);    my_strcat(")");    } else { -  low_describe_type(t->car); +  my_describe_type(t->car);    }    my_strcat(" & ");    if (t->cdr->type > T_AND) {    my_strcat("("); -  low_describe_type(t->cdr); +  my_describe_type(t->cdr);    my_strcat(")");    } else { -  low_describe_type(t->cdr); +  my_describe_type(t->cdr);    }    break;       case T_MAPPING:    my_strcat("mapping");    if(t->car->type != T_MIXED || t->cdr->type != T_MIXED) {    my_strcat("("); -  low_describe_type(t->car); +  my_describe_type(t->car);    my_strcat(":"); -  low_describe_type(t->cdr); +  my_describe_type(t->cdr);    my_strcat(")");    }    break;    default:    {    char buf[20];    my_strcat("unknown code(");    sprintf(buf, "%d", t->type);    my_strcat(buf);    my_strcat(")");
pike.git/src/pike_types.c:1371:    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: +  case PIKE_T_NAME:    return compile_type_to_runtime_type(t->cdr);       case T_MANY:    return T_FUNCTION;       case T_ARRAY:    case T_MAPPING:    case T_MULTISET:       case T_OBJECT:
pike.git/src/pike_types.c:1831:    ret = low_match_types(a->car, b, flags);    if(ret && !(flags & NO_SHORTCUTS)) return ret;    if(ret)    {    low_match_types(a->cdr, b, flags);    return ret;    }else{    return low_match_types(a->cdr, b, flags);    }    +  case PIKE_T_NAME: +  return low_match_types(a->cdr, b, flags); +     case T_NOT:    if(low_match_types(a->car, b, (flags ^ B_EXACT ) | NO_MAX_ARGS))    return 0;    return a;       case T_ASSIGN:    ret = low_match_types(a->cdr, b, flags);    if(ret && (b->type != T_VOID))    {    int m = ((ptrdiff_t)a->car)-'0';
pike.git/src/pike_types.c:1912:    ret = low_match_types(a, b->car, flags);    if(ret && !(flags & NO_SHORTCUTS)) return ret;    if(ret)    {    low_match_types(a, b->cdr, flags);    return ret;    }else{    return low_match_types(a, b->cdr, flags);    }    +  case PIKE_T_NAME: +  return low_match_types(a, b->cdr, flags); +     case T_NOT:    if(low_match_types(a, b->car, (flags ^ A_EXACT ) | NO_MAX_ARGS))    return 0;    return a;       case T_ASSIGN:    ret = low_match_types(a, b->cdr, flags);    if(ret && (a->type != T_VOID))    {    int m = ((ptrdiff_t)b->car)-'0';
pike.git/src/pike_types.c:2336:    if (a->cdr->type == T_VOID) {    /* Special case for T_VOID */    /* FIXME: Should probably be handled as T_ZERO. */    return 1;    } else {    a = a->cdr;    goto recurse;    }    }    +  case PIKE_T_NAME: +  a = a->cdr; +  goto recurse; +     case T_NOT:    if (b->type == T_NOT) {    struct pike_type *tmp = a->car;    a = b->car;    b = tmp;    array_cnt = -array_cnt;    goto recurse;    }    if (a->car->type == T_NOT) {    a = a->car->car;
pike.git/src/pike_types.c:2419:    b = b->cdr;    goto recurse;       case T_OR:    /* OK if a is a subset of either of the parts. */    ret=low_pike_types_le(a, b->car, array_cnt, flags);    if (ret) return ret;    b = b->cdr;    goto recurse;    +  case PIKE_T_NAME: +  b = b->cdr; +  goto recurse; +     case T_NOT:    if (b->car->type == T_NOT) {    b = b->car->car;    goto recurse;    }    if (low_pike_types_le(a, b->car, array_cnt, flags)) {    return 0;    }    /* FIXME: This is wrong... */    return !low_pike_types_le(b->car, a, -array_cnt, flags);
pike.git/src/pike_types.c:2824:    return 1;    }       case T_AND:    type_stack_mark();    tmp = low_get_return_type(a->car, b);    type_stack_pop_to_mark();    if(!tmp) return 0;    return low_get_return_type(a->cdr, b);    +  case PIKE_T_NAME: +  return low_get_return_type(a->cdr, b); +     case T_ARRAY:    tmp = low_get_return_type(a->car, b);    if(!tmp) return 0;    push_type(T_ARRAY);    return 1;    }       a = low_match_types(a, b, NO_SHORTCUTS);    if(a)    {
pike.git/src/pike_types.c:2905:    struct program *p;       switch(low_check_indexing(t, index_type, n))    {    case 0: return 0;    case -1:    add_ref(zero_type_string);    return zero_type_string;    }    +  while(t->type == PIKE_T_NAME) { +  t = t->cdr; +  } +  while(index_type->type == PIKE_T_NAME) { +  index_type = index_type->cdr; +  } +     switch(t->type)    {    case T_OBJECT:    {    p = id_to_program((ptrdiff_t)t->cdr);       comefrom_int_index:    if(p && n)    {    INT32 i;
pike.git/src/pike_types.c:3175:    low_or_pike_types(a,b,1);    free_type(a);    free_type(b);    return pop_unfinished_type();    }       case T_AND:    /* FIXME: Shouldn't this look at both branches? */    return low_key_type(t->cdr, n);    +  case PIKE_T_NAME: +  return low_key_type(t->cdr, n); +     case T_ARRAY:    case T_STRING: /* always int */    add_ref(int_type_string);    return int_type_string;       case T_MAPPING:    case T_MULTISET:    copy_type(t, t->car);    return t;    }
pike.git/src/pike_types.c:3217:    return low_check_indexing(type->car, index_type, n) ||    low_check_indexing(type->cdr, index_type, n);       case T_AND:    return low_check_indexing(type->car, index_type, n) &&    low_check_indexing(type->cdr, index_type, n);       case T_NOT:    return low_check_indexing(type->car, index_type, n) != 1;    +  case PIKE_T_NAME: +  return low_check_indexing(type->cdr, index_type, n); +     case T_ARRAY:    if(low_match_types(string_type_string, index_type, 0) &&    low_check_indexing(type->car, index_type, n))    return 1;       case T_STRING:    return !!low_match_types(int_type_string, index_type, 0);       case T_OBJECT:    {
pike.git/src/pike_types.c:3295:    return num>num2?num:num2;       case T_AND:    num = low_count_arguments(q->car);    num2 = low_count_arguments(q->cdr);    if(num<0 && num2>0) return num2;    if(num2<0 && num>0) return num;    if(num2<0 && num<0) return ~num<~num2?num:num2;    return num<num2?num:num2;    +  case PIKE_T_NAME: +  return low_count_arguments(q->cdr); +     default: return 0x7fffffff;       case T_FUNCTION:    while(q->type == T_FUNCTION)    {    num++;    q = q->cdr;    }    /* FALL_THROUGH */    case T_MANY:
pike.git/src/pike_types.c:3336:       switch(q->type)    {    case T_OR:    case T_AND:    return MAXIMUM(low_count_arguments(q->car),    low_count_arguments(q->cdr));       default: return 0;    +  case PIKE_T_NAME: +  return low_minimum_arguments(q->cdr); +     case T_FUNCTION:    num = 0;    while(q->type == T_FUNCTION)    {    if(low_match_types(void_type_string, q->car, B_EXACT))    return num;       num++;    q = q->cdr;    }
pike.git/src/pike_types.c:3463:    push_reverse_type(T_MANY);    while(nargs-- > 0) {    push_reverse_type(T_FUNCTION);    }    return pop_unfinished_type();    }       case T_ARRAY:    return zzap_function_return(a->car, id);    +  case PIKE_T_NAME: +  return zzap_function_return(a->cdr, id); +     case T_MIXED:    /* I wonder when this occurrs, but apparently it does... */    /* FIXME: */    type_stack_mark();    push_object_type(1, id);    push_type(T_VOID);    push_type(T_MIXED);    push_type(T_OR);    push_type(T_MANY);    return pop_unfinished_type();
pike.git/src/pike_types.c:3692:    return type_may_overload(type->cdr, lfun);       case T_FUNCTION:    case T_MANY:    case T_ARRAY:    /* might want to check for `() */       default:    return 0;    +  case PIKE_T_NAME: +  return type_may_overload(type->cdr, lfun); +     case T_OR:    return type_may_overload(type->car, lfun) ||    type_may_overload(type->cdr, lfun);       case T_AND:    return type_may_overload(type->car, lfun) &&    type_may_overload(type->cdr, lfun);       case T_NOT:    return !type_may_overload(type->car, lfun);
pike.git/src/pike_types.c:3867:    {    case T_NOT:    return !pike_type_allow_premature_toss(type->car);       case T_OBJECT:    case T_MIXED:    case T_FUNCTION:    case T_MANY:    return 0;    +  case PIKE_T_NAME:    case T_SCOPE:    case T_ASSIGN:    type = type->cdr;    goto again;       case T_OR:    case T_MAPPING:    if(!pike_type_allow_premature_toss(type->car)) return 0;    type = type->cdr;    goto again;
pike.git/src/pike_types.c:7362:    free_type(type_type_string);    free_type(mixed_type_string);    free_type(void_type_string);    free_type(zero_type_string);    free_type(any_type_string);    free_type(weak_type_string);   #ifdef USE_PIKE_TYPE    /* Free the hashtable here. */    if (pike_type_hash) {    free(pike_type_hash); -  pike_type_hash = NULL; +  /* Don't do this, it messes up stuff... */ +  /* pike_type_hash = NULL; */    } -  pike_type_hash_size = 0; +  /* Don't do this, it messes up stuff... */ +  /* pike_type_hash_size = 0; */   #endif /* USE_PIKE_TYPE */   }