pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:224:    * ASSIGN variable (int) type    * NAME name (string) type    * ATTRIBUTE name (string) type Added in 7.7.    * FUNCTION type FUNCTION|MANY    * MANY many type return type    * RING type type Reserved.    * TUPLE type type Reserved.    * MAPPING index type value type    * OR type (not OR) type    * AND type type -  * ARRAY type - +  * ARRAY - type    * MULTISET type -    * NOT type -    * '0'-'9' - -    * FLOAT - - -  * STRING ZERO, INT or OR - Range added in 7.7 +  * STRING - ZERO, INT or OR Range added in 7.7    * TYPE type -    * 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
pike.git/src/pike_types.cmod:321:    /* Free car & cdr */    free_type(car);    t = (struct pike_type *) cdr;    debug_free_type_preamble (t);    goto loop;       case PIKE_T_AUTO:    if (!car)    break;    /* FALLTHRU */ -  case T_ARRAY: +     case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM: -  case T_STRING: +     /* Free car */    t = (struct pike_type *) car;    debug_free_type_preamble (t);    goto loop;       case T_SCOPE:    case T_ASSIGN: -  +  case T_ARRAY: +  case T_STRING:    /* Free cdr */    t = (struct pike_type *) cdr;    debug_free_type_preamble (t);    goto loop;       case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME:    free_string((struct pike_string *)car);    t = (struct pike_type *) cdr;    debug_free_type_preamble (t);
pike.git/src/pike_types.cmod:489:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    case PIKE_T_RING:    /* Free car & cdr */    free_type((struct pike_type *)debug_malloc_pass(car));    free_type((struct pike_type *)debug_malloc_pass(cdr));    break;    -  case T_ARRAY: +     case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM: -  case T_STRING: +     /* Free car */    free_type((struct pike_type *)debug_malloc_pass(car));    break;    case PIKE_T_AUTO:    if( car )    free_type((struct pike_type *)debug_malloc_pass(car));    break;       case T_SCOPE:    case T_ASSIGN: -  +  case T_ARRAY: +  case T_STRING:    /* Free cdr */    free_type((struct pike_type *)debug_malloc_pass(cdr));    break;       case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME:    free_string((struct pike_string *)debug_malloc_pass(car));    free_type((struct pike_type *)debug_malloc_pass(cdr));    break;   #ifdef PIKE_DEBUG
pike.git/src/pike_types.cmod:593:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    case PIKE_T_RING:    debug_malloc_pass(car);    debug_malloc_pass(cdr);    break;    -  case T_ARRAY: +     case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM: -  case T_STRING: +     case PIKE_T_AUTO:    debug_malloc_pass(car);    break;       case T_ASSIGN:    t->flags |= PT_FLAG_ASSIGN_0 << PTR_TO_INT(car);    /* FALLTHRU */    case T_SCOPE: -  +  case T_ARRAY: +  case T_STRING:    debug_malloc_pass(cdr);    break;       case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME:    debug_malloc_pass(car);    debug_malloc_pass(cdr);    break;       case '0':
pike.git/src/pike_types.cmod:891:    struct pike_type *t = (*Pike_compiler->type_stackp);    while ((t->type == PIKE_T_NAME) || (t->type == PIKE_T_ATTRIBUTE)) {    t = t->cdr;    }    if (t->type != T_OBJECT) {    /* Not a program type, convert it to a type type. */    type = T_TYPE;    }    }    /* FALLTHRU */ -  case T_ARRAY: +     case T_MULTISET:    case T_NOT:    case T_TYPE: -  case T_STRING: +     case PIKE_T_AUTO:    /* 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_ARRAY: +  case T_STRING: +  /* Make a new type of the top type, and put it in cdr. */ +  *Pike_compiler->type_stackp = mk_type(type, +  NULL, *Pike_compiler->type_stackp, +  PT_COPY_CDR); +  break; +     case T_SCOPE:    case T_ASSIGN:    case T_INT:    case T_OBJECT:    case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME:    default:    /* Should not occur. */    Pike_fatal("Unsupported argument to push_type(): %d\n", type);    break;
pike.git/src/pike_types.cmod:975:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    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: -  case T_STRING: +     case PIKE_T_AUTO:    /* car */    push_finished_type(top->car);    break;    case T_SCOPE:    case T_ASSIGN: -  +  case T_ARRAY: +  case T_STRING:    /* cdr */    push_finished_type(top->cdr);    break;    case T_INT:    case T_OBJECT:    case T_FLOAT:    case T_MIXED:    case T_VOID:    case T_ZERO:    case PIKE_T_UNKNOWN:
pike.git/src/pike_types.cmod:1253:    free_type(pop_unfinished_type());    free_type(pop_unfinished_type());    push_finished_type(zero_type_string);    } else {    pop_stack_mark();    pop_stack_mark();    push_type(T_AND);    }    }    } else { +  /* Make sure to filter invalid nodes from the marker in case +  * it is a string type. +  */ +  if (type->type == PIKE_T_STRING) cdr_set |= PT_FLAG_INT_ONLY;    if (type->cdr) {    /* In all other cases type->cdr will be a valid node if is not NULL. */    push_finished_type_with_markers(type->cdr, markers, cdr_set);    } -  /* Make sure to filter invalid nodes from the marker in case -  * it is a string type. -  */ -  if (type->type == PIKE_T_STRING) car_set |= PT_FLAG_INT_ONLY; -  /* In all other cases type->car will be a valid node. */ +  if (type->car) { +  /* In all other cases type->car will be a valid node if it is not NULL. */    push_finished_type_with_markers(type->car, markers, car_set); -  +  }    /* push_type has sufficient magic to recreate the type. */    push_type(type->type);    }    done:    TYPE_STACK_DEBUG("push_finished_type_with_markers");   }      static void push_type_field(TYPE_FIELD field)   {    field &= (BIT_BASIC|BIT_COMPLEX);
pike.git/src/pike_types.cmod:2038:    fprintf(stderr, "(%ld..%ld)",(long)min,(long)max);    }    }    break;    }    case T_FLOAT: fprintf(stderr, "float"); break;    case T_STRING:    {    INT32 min;    INT32 max; -  s = s->car; +  s = s->cdr;    fprintf(stderr, "string");    if (s != int_type_string) {    fprintf(stderr, "(");    while (s->type == T_OR) {    struct pike_type *char_type = s->car;    while(char_type->type == T_ASSIGN) {    char_type = char_type->cdr;    }       if (char_type->type == T_ZERO) {
pike.git/src/pike_types.cmod:2162:    if (s->car->type != T_VOID) {    simple_describe_type(s->car);    fprintf(stderr, "...");    }    fprintf(stderr, ":");    simple_describe_type(s->cdr);    fprintf(stderr, ")");    break;    case T_ARRAY:    fprintf(stderr, "array("); -  simple_describe_type(s->car); +  simple_describe_type(s->cdr);    fprintf(stderr, ")");    break;    case T_MAPPING:    fprintf(stderr, "mapping(");    simple_describe_type(s->car);    fprintf(stderr, ":");    simple_describe_type(s->cdr);    fprintf(stderr, ")");    break;    case T_MULTISET:
pike.git/src/pike_types.cmod:2314:    }    }else{    string_builder_strcat(s, "object");    }    break;       case T_STRING:    {    INT32 min;    INT32 max; -  t = t->car; +  t = t->cdr;    if (t->type == T_ZERO) {    string_builder_strcat(s, "string(zero)");    } else if (t != int_type_string) {    string_builder_strcat(s, "string(");    while (t->type == T_OR) {    struct pike_type *char_type = t->car;    while(char_type->type == T_ASSIGN) {    char_type = char_type->cdr;    }    if (char_type->type != T_INT) {
pike.git/src/pike_types.cmod:2449:    if(arg++) string_builder_strcat(s, ", ");    low_describe_type(s, t->car);    string_builder_strcat(s, " ...");    }    string_builder_sprintf(s, " : %T)", t->cdr);    }    break;    }       case T_ARRAY: -  if(t->car->type != T_MIXED) { -  string_builder_sprintf(s, "array(%T)", t->car); +  if(t->cdr->type != T_MIXED) { +  string_builder_sprintf(s, "array(%T)", t->cdr);    } else {    string_builder_strcat(s, "array");    }    break;       case T_MULTISET:    if(t->car->type != T_MIXED) {    string_builder_sprintf(s, "multiset(%T)", t->car);    } else {    string_builder_strcat(s, "multiset");
pike.git/src/pike_types.cmod:2723:    if (CAR_TO_INT(t1) < CAR_TO_INT(t2)) {    t = t1;    ret = -1;    } else {    t = t2;    ret = 1;    }    break;    case T_STRING:    { -  low_or_pike_types(t1->car, t2->car, 1); +  low_or_pike_types(t1->cdr, t2->cdr, 1);    push_type(T_STRING);    return 0;    }    break;    case T_OBJECT:    if (!CDR_TO_INT(t1)) {    t = t1;    } else if (!CDR_TO_INT(t2)) {    t = t2;    } else if (CDR_TO_INT(t1) < CDR_TO_INT(t2)) {
pike.git/src/pike_types.cmod:2766:    }    if (t1->cdr->type > t2->cdr->type) {    t = t2;    ret = 1;    break;    }    t = t1;    ret = -1;    break;    case T_ARRAY: +  if (t1->cdr->type < t2->cdr->type) { +  t = t1; +  ret = -1; +  break; +  } else if (t1->cdr->type > t2->cdr->type) { +  t = t2; +  ret = 1; +  break; +  } +  if (t1 < t2) { +  t = t1; +  ret = -1; +  } else { +  t = t2; +  ret = 1; +  } +  break;    case T_MULTISET:    if (t1->car->type < t2->car->type) {    t = t1;    ret = -1;    break;    } else if (t1->car->type > t2->car->type) {    t = t2;    ret = 1;    break;    }
pike.git/src/pike_types.cmod:2881:    min1 = MINIMUM(min1, min2);    max1 = MAXIMUM(max1, max2);       push_int_type(min1, max1);    }    }    break;    case T_STRING:    {    Pike_compiler->type_stackp--; -  low_or_pike_types(t->car, top->car, 1); +  low_or_pike_types(t->cdr, top->cdr, 1);    push_type(T_STRING);    free_type(top);    }    break;    case T_OBJECT:    if (CDR_TO_INT(top)) {    push_finished_type(t);    }    break;    case T_ARRAY: -  +  Pike_compiler->type_stackp--; +  low_or_pike_types(t->cdr, top->cdr, zero_implied); +  push_type(t->type); +  free_type(top); +  break;    case T_MULTISET:    Pike_compiler->type_stackp--;    low_or_pike_types(t->car, top->car, zero_implied);    push_type(t->type);    free_type(top);    break;    case T_MAPPING:    if (t->car == top->car) {    Pike_compiler->type_stackp--;    push_finished_type(t->car);
pike.git/src/pike_types.cmod:3068:    i1 = CAR_TO_INT(t1);    i2 = CAR_TO_INT(t2);    lower_bound = MAXIMUM(i1,i2);       if (upper_bound >= lower_bound) {    push_int_type(lower_bound, upper_bound);    push_type(T_OR);    }    } else if (t1->type == T_STRING) {    push_type(T_ZERO); -  even_lower_and_pike_types(t1->car, t2->car); +  even_lower_and_pike_types(t1->cdr, t2->cdr);    push_type(T_STRING);    push_type(T_OR);    } else {    push_finished_type(t1);    push_type(T_OR);    }    }   }      static int lower_and_pike_types(struct pike_type *t1, struct pike_type *t2)
pike.git/src/pike_types.cmod:3197:    low_and_pike_types(t1->cdr, t2);    push_scope_type(CAR_TO_INT(t1));    }    }    else if (t2->type == T_SCOPE)    {    low_and_pike_types(t1, t2->cdr);    push_scope_type(CAR_TO_INT(t2));    }    else if ((t1->type == T_STRING) && (t2->type == T_STRING)) { -  low_and_pike_types(t1->car, t2->car); +  low_and_pike_types(t1->cdr, t2->cdr);    push_type(T_STRING);    }    else if((t1->type == T_FLOAT) && (t2->type == T_FLOAT))    {    push_finished_type(t1);    }    else if(low_pike_types_le(t1, t2, 0, 0))    {    push_finished_type(t1);    }
pike.git/src/pike_types.cmod:3799:    INT32 amin = CAR_TO_INT(a);    INT32 amax = CDR_TO_INT(a);       INT32 bmin = CAR_TO_INT(b);    INT32 bmax = CDR_TO_INT(b);       if(amin > bmax || bmin > amax) return 0;    break;    }    +  case T_ARRAY: +  case T_STRING: +  if(!low_match_types(a->cdr, b->cdr, +  flags & ~(A_EXACT|B_EXACT))) return 0; +  break;       case T_PROGRAM:    case T_TYPE:    case T_MULTISET: -  case T_ARRAY: -  case T_STRING: +     if(!low_match_types(a->car, b->car,    flags & ~(A_EXACT|B_EXACT))) return 0; -  +  break;       case T_FLOAT:    case T_ZERO:    case T_VOID:    case T_MIXED:    break;   #ifdef PIKE_DEBUG    default:    Pike_fatal("Error in type string.\n");   #endif
pike.git/src/pike_types.cmod:4266:    } else {    b = mixed_type_string;    }    }    goto recurse;    }    }       if ((array_cnt < 0) && (b->type == T_ARRAY)) {    while (b->type == T_ARRAY) { -  b = b->car; +  b = b->cdr;    if (!++array_cnt) break;    }    goto recurse;    } else if ((array_cnt > 0) && (a->type == T_ARRAY)) {    while (a->type == T_ARRAY) { -  a = a->car; +  a = a->cdr;    if (!--array_cnt) break;    }    goto recurse;    }       /* NOTE: void only matches void. */    if (a->type == T_VOID) {    /* void <= any_type */    if (array_cnt >= 0) {    /* !array(void) */
pike.git/src/pike_types.cmod:4401:    if((b=low_object_lfun_type(b, LFUN_CALL))) {    goto recurse;    }    return 1;    }       case TWOT(T_FUNCTION, T_ARRAY):    case TWOT(T_MANY, T_ARRAY):    {    while (b->type == T_ARRAY) { -  b = b->car; +  b = b->cdr;    array_cnt++;    }    goto recurse;    }       case TWOT(T_ARRAY, T_FUNCTION):    case TWOT(T_ARRAY, T_MANY):    {    while (a->type == T_ARRAY) { -  a = a->car; +  a = a->cdr;    array_cnt--;    }    goto recurse;    }       case TWOT(T_FUNCTION, T_FUNCTION):    case TWOT(T_FUNCTION, T_MANY):    case TWOT(T_MANY, T_FUNCTION):    /*    * function(A...:B) <= function(C...:D) iff C <= A && B <= D
pike.git/src/pike_types.cmod:4607:    if (bmax == -1) bmax = 0;       if(amin < bmin || amax > bmax) return 0;    break;    }          case T_TYPE:    case T_PROGRAM:    case T_MULTISET: -  case T_ARRAY: -  case T_STRING: +     if (flags & LE_TYPE_SVALUE) return 1;    a = a->car;    b = b->car;    array_cnt = 0;    goto recurse;    -  +  case T_ARRAY: +  case T_STRING: +  if (flags & LE_TYPE_SVALUE) return 1; +  a = a->cdr; +  b = b->cdr; +  array_cnt = 0; +  goto recurse; +     case T_FLOAT:    case T_ZERO:    case T_VOID:    case T_MIXED:    break;      #ifdef PIKE_DEBUG    default:    Pike_fatal("Error in type string.\n");   #endif
pike.git/src/pike_types.cmod:4647:    while ((fun_type->type == T_OR) ||    (fun_type->type == T_ARRAY) ||    (fun_type->type == PIKE_T_SCOPE)) {    if (fun_type->type == T_OR) {    int res = strict_check_call(fun_type->car, arg_type);    if (res) return res;    fun_type = fun_type->cdr;    } else if (fun_type->type == PIKE_T_SCOPE) {    fun_type = fun_type->cdr;    } else { -  fun_type = fun_type->car; +  fun_type = fun_type->cdr;    }    }    return low_pike_types_le(fun_type, arg_type, 0, 0);   }      /*    * Check validity of soft-cast.    * Note: This uses a weaker check of function arguments, since    * people get confused otherwise.    */
pike.git/src/pike_types.cmod:4722:    return low_get_return_type(a->cdr, b);       case PIKE_T_ATTRIBUTE:    if (low_get_return_type(a->cdr, b)) {    push_type_attribute((struct pike_string *)a->car);    return 1;    }    return 0;       case T_ARRAY: -  tmp = low_get_return_type(a->car, b); +  tmp = low_get_return_type(a->cdr, b);    if(!tmp) return 0;    push_type(T_ARRAY);    return 1;    }       a = low_match_types(a, b, NO_SHORTCUTS);    if(a)    {   #if 0    if ((c->lex.pragmas & ID_STRICT_TYPES) &&
pike.git/src/pike_types.cmod:4926:    free_type(b);    return pop_unfinished_type();    }       case T_AND:    /* FIXME: Shouldn't both branches be looked at? */    return low_index_type(t->cdr, index_type, n);       case T_STRING: /* always int */    { -  if (t->car->type == T_ZERO) { +  if (t->cdr->type == T_ZERO) {    yywarning("Indexing the empty string.");    } -  add_ref(t->car); -  return t->car; +  add_ref(t->cdr); +  return t->cdr;    }       case T_MULTISET: /* always int(0..1) */    type_stack_mark();    push_int_type(0, 1);    return pop_unfinished_type();       case T_MAPPING:    add_ref(t = t->cdr);    return t;       case T_ARRAY:    {    struct pike_type *a;       if(low_pike_types_le(string0_type_string, index_type, 0, 0) && -  (a = low_index_type(t->car, string0_type_string, n))) { +  (a = low_index_type(t->cdr, string0_type_string, n))) {    /* Possible to index the array with a string. */    type_stack_mark();    push_finished_type(a);    free_type(a);    push_type(T_ARRAY);       if (low_match_types(int_type_string, index_type, 0)) {    /* Also possible to index the array with an int. */ -  push_finished_type(t->car); +  push_finished_type(t->cdr);    push_type(T_OR);    }    return pop_unfinished_type();    }    if (low_match_types(int_type_string, index_type, 0)) {    /* Possible to index the array with an int. */ -  add_ref(t->car); -  return t->car; +  add_ref(t->cdr); +  return t->cdr;    }    /* Bad index type. */    return 0;    }    }   }      struct pike_type *index_type(struct pike_type *type,    struct pike_type *index_type,    node *n)
pike.git/src/pike_types.cmod:5216:    free_type(sub_t);    res = new;    } else {    res = sub_t;    }    }    }    if (arr_t->type != T_ARRAY)    return res;    -  copy_pike_type(sub_t, arr_t->car); +  copy_pike_type(sub_t, arr_t->cdr);       if (res) {    struct pike_type *new = or_pike_types(res, sub_t, 1);    free_type(res);    free_type(sub_t);    return new;    }    return sub_t;   }   
pike.git/src/pike_types.cmod:5393:    }    return 0;       case PIKE_T_NAME:    case T_ASSIGN:    case T_SCOPE:    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)) +  low_check_indexing(type->cdr, index_type, n))    return 1;    /* FALLTHRU */    case T_STRING:    return !!low_match_types(int_type_string, index_type, 0);       case T_OBJECT:    {    struct program *p = id_to_program(CDR_TO_INT(type));    if(p)    {
pike.git/src/pike_types.cmod:5653:    add_ref(fun->car);    return fun->car;       case T_MIXED:    add_ref(fun);    return fun;       case T_ARRAY:    if (arg_no < 0) {    type_stack_mark(); -  push_finished_type(fun = get_argument_type(fun->car, arg_no)); +  push_finished_type(fun = get_argument_type(fun->cdr, arg_no));    push_type(T_ARRAY);    free_type(fun);    return pop_unfinished_type();    }    return get_argument_type(fun->car, arg_no);       case PIKE_T_ATTRIBUTE:    type_stack_mark();    push_finished_type(tmp = get_argument_type(fun->cdr, arg_no));    push_type_attribute((struct pike_string *)(fun->car));
pike.git/src/pike_types.cmod:5878:    soft_type = function_type_string;    }    /* FALLTHRU */    case T_FUNCTION:    case T_MANY:    {    int array_cnt = 0;    int loop_cnt = 0;    while(orig_type->type == T_ARRAY) {    array_cnt++; -  orig_type = orig_type->car; +  orig_type = orig_type->cdr;    }    if (orig_type->type == T_PROGRAM) {    copy_pike_type(tmp, orig_type->car); /* Return type */    if ((tmp2 = low_object_lfun_type(tmp, LFUN_CREATE))) {    orig_type = tmp2;    tmp2 = NULL;    } else {    /* FIXME: Multiple cases. */    tmp2 = soft_type;    while(tmp2->type == T_FUNCTION) tmp2 = tmp2->cdr;
pike.git/src/pike_types.cmod:5998:    push_finished_type(zero_type_string);    }    if ((tmp2 = soft_cast(soft_type->cdr, orig_type->cdr, flags))) {    push_finished_type(tmp2);    } else {    push_finished_type(zero_type_string);    }    push_reverse_type(T_MAPPING);    res = pop_unfinished_type();    break; -  case T_ARRAY: +     case T_MULTISET:    case T_TYPE:    type_stack_mark();    if ((tmp = soft_cast(soft_type->car, orig_type->car, flags))) {    push_finished_type(tmp);    } else if (flags & SOFT_WEAKER) {    push_finished_type(mixed_type_string);    } else {    push_finished_type(zero_type_string);    }    push_type(soft_type->type);    res = pop_unfinished_type();    break;    case T_FLOAT:    copy_pike_type(res, soft_type);    break; -  +  case T_ARRAY: +  type_stack_mark(); +  if ((tmp = soft_cast(soft_type->cdr, orig_type->cdr, flags))) { +  push_finished_type(tmp); +  } else if (flags & SOFT_WEAKER) { +  push_finished_type(mixed_type_string); +  } else { +  push_finished_type(zero_type_string); +  } +  push_type(T_ARRAY); +  res = pop_unfinished_type(); +  break;    case T_STRING: -  res = soft_cast(soft_type->car, orig_type->car, flags); +  res = soft_cast(soft_type->cdr, orig_type->cdr, flags);    if (!res) return NULL;    type_stack_mark();    push_finished_type(res);    free_type(res);    push_type(T_STRING);    res = pop_unfinished_type();    break;    case T_INT:    {    INT32 min, max;
pike.git/src/pike_types.cmod:6193:    res = is_compatible( o->prog, mark );    else    res = implements( o->prog, mark );    }    }    }    break;    case PIKE_T_STRING:    if( TYPEOF( *sval ) == PIKE_T_STRING )    { -  sub = type->car; +  sub = type->cdr;    if (sub->type == T_ZERO)    {    res = (sval->u.string->len == 0);    break;    }    else if( sub->type == PIKE_T_INT )    {    struct pike_string *s = sval->u.string;    INT32 min = CAR_TO_INT( sub ), max = CDR_TO_INT( sub );    INT32 string_min, string_max;
pike.git/src/pike_types.cmod:6321:    fprintf(stderr, ", 0x%08x, ", flags);    debug_describe_svalue(sval);    fprintf(stderr, ")...\n");    }   #endif /* PIKE_DEBUG */       loop:    /* Count the number of array levels. */    while(fun_type->type == PIKE_T_ARRAY) {    array_cnt++; -  fun_type = fun_type->car; +  fun_type = fun_type->cdr;    }       switch(fun_type->type) {    case T_SCOPE:    /* FIXME: Save and restore the corresponding marker set. */    case T_ASSIGN:    case PIKE_T_NAME:    fun_type = fun_type->cdr;    goto loop;   
pike.git/src/pike_types.cmod:6528:    fprintf(stderr, ", ");    simple_describe_type(arg_type);    fprintf(stderr, ", 0x%04x, %p)...\n", flags, sval);    }   #endif /* PIKE_DEBUG */       loop:    /* Count the number of array levels. */    while(fun_type->type == PIKE_T_ARRAY) {    array_cnt++; -  fun_type = fun_type->car; +  fun_type = fun_type->cdr;    }       switch(fun_type->type) {    case T_SCOPE:    /* FIXME: Save and restore the corresponding marker set. */    case T_ASSIGN:    case PIKE_T_NAME:    fun_type = fun_type->cdr;    goto loop;   
pike.git/src/pike_types.cmod:7047:    fprintf(stderr, " Getting return type for ");    simple_describe_type(fun_type);    fprintf(stderr, "... ");    }   #endif /* PIKE_DEBUG */       loop:    /* Count the number of array levels. */    while(fun_type->type == PIKE_T_ARRAY) {    array_cnt++; -  fun_type = fun_type->car; +  fun_type = fun_type->cdr;    }       switch(fun_type->type) {    case PIKE_T_SCOPE:    case T_ASSIGN:    case PIKE_T_NAME:    fun_type = fun_type->cdr;    goto loop;       case PIKE_T_ATTRIBUTE:
pike.git/src/pike_types.cmod:7291:    }    type_stack_mark();    push_finished_type(tmp);    free_type(tmp);    push_type(arg_type->type);    return pop_unfinished_type();    }    /* FALLTHRU */       case T_ARRAY: +  /* Keep void! */ +  tmp = low_get_first_arg_type(arg_type->cdr, flags|FILTER_KEEP_VOID); +  type_stack_mark(); +  push_finished_type(tmp); +  free_type(tmp); +  push_type(arg_type->type); +  return pop_unfinished_type(); +     case T_MULTISET:    /* Keep void! */    tmp = low_get_first_arg_type(arg_type->car, flags|FILTER_KEEP_VOID);    type_stack_mark();    push_finished_type(tmp);    free_type(tmp);    push_type(arg_type->type);    return pop_unfinished_type();       case T_MAPPING:
pike.git/src/pike_types.cmod:7341:    */   struct pike_type *get_first_arg_type(struct pike_type *fun_type,    INT32 flags)   {    struct pike_type *res = NULL;    struct pike_type *tmp;    struct pike_type *tmp2;    loop:    /* Get rid of the array levels. */    while(fun_type->type == PIKE_T_ARRAY) { -  fun_type = fun_type->car; +  fun_type = fun_type->cdr;    }      #ifdef PIKE_DEBUG    if (l_flag > 2) {    fprintf(stderr, "get_first_arg_type(");    simple_describe_type(fun_type);    fprintf(stderr, ", 0x%04x)\n", flags);    }   #endif   
pike.git/src/pike_types.cmod:7829:    push_finished_type(a->car);    push_finished_type(fun_ret);    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, fun_ret); +  return zzap_function_return(a->cdr, fun_ret);       case PIKE_T_NAME:    return zzap_function_return(a->cdr, fun_ret);       case PIKE_T_ATTRIBUTE:    {    struct pike_type *res;    if ((res = zzap_function_return(a->cdr, fun_ret))) {    type_stack_mark();    push_finished_type(res);
pike.git/src/pike_types.cmod:8539:    case T_OBJECT:    case T_MIXED:    case T_FUNCTION:    case T_MANY:    return 0;       case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    case T_SCOPE:    case T_ASSIGN: +  case T_ARRAY:    type = type->cdr;    goto again;       case PIKE_T_RING:    type = type->car;    goto again;       case T_OR:    case T_MAPPING:    if(!pike_type_allow_premature_toss(type->car)) return 0;    type = type->cdr;    goto again;       case T_AND:    /* 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 PIKE_T_ZERO:    case T_VOID:    return 1;    }   }      static void low_type_to_string(struct byte_buffer *buf, struct pike_type *t)   {    recurse:    switch(t->type) { -  case T_ARRAY: +     case T_MULTISET:    case T_TYPE:    case T_PROGRAM:    buffer_add_char(buf, t->type ^ MIN_REF_TYPE);    t = t->car;    goto recurse;    -  +  case T_ARRAY: +  buffer_add_char(buf, t->type ^ MIN_REF_TYPE); +  t = t->cdr; +  goto recurse; +     case T_NOT:    buffer_add_char(buf, t->type);    t = t->car;    goto recurse;       case T_MAPPING:    buffer_add_char(buf, t->type ^ MIN_REF_TYPE);    low_type_to_string(buf, t->car);    t = t->cdr;    goto recurse;
pike.git/src/pike_types.cmod:8641:    i = (INT32)CDR_TO_INT(t);       if( i > 65535 ) i = 0; /* Not constant between recompilations */       buffer_add_be32(buf, i);    }    break;       case T_STRING:    { -  if (t->car == int_type_string) { +  if (t->cdr == int_type_string) {    buffer_add_char(buf, T_STRING ^ MIN_REF_TYPE);    } else {    buffer_add_char(buf, PIKE_T_NSTRING); -  low_type_to_string(buf, t->car); +  low_type_to_string(buf, t->cdr);    }    }    break;       case T_INT:    {    INT32 i;    buffer_add_char(buf, T_INT ^ MIN_REF_TYPE);    i = (INT32)CAR_TO_INT(t);    buffer_add_be32(buf, i);
pike.git/src/pike_types.cmod:8941:    case T_OR:    case T_AND:    case PIKE_T_RING:    res = find_type(t->car, cb);    if (res) return res;    /* FALLTHRU */    case T_SCOPE:    case T_ASSIGN:    case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME: +  case T_ARRAY: +  case T_STRING:    return find_type(t->cdr, cb);    -  case T_ARRAY: +     case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM: -  case T_STRING: +     return find_type(t->car, cb);      #ifdef PIKE_DEBUG    case '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':
pike.git/src/pike_types.cmod:9008:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    case PIKE_T_RING:    visit_type_ref (t->car, REF_TYPE_INTERNAL, extra);    /* FALLTHRU */    case T_SCOPE:    case T_ASSIGN: +  case T_ARRAY: +  case T_STRING:    visit_type_ref (t->cdr, REF_TYPE_INTERNAL, extra);    break; -  case T_ARRAY: +     case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM: -  case T_STRING: +     visit_type_ref (t->car, REF_TYPE_INTERNAL, extra);    break;    case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME:    visit_string_ref ((struct pike_string *) t->car, REF_TYPE_INTERNAL,    extra);    visit_type_ref (t->cdr, REF_TYPE_INTERNAL, extra);    break;   #ifdef PIKE_DEBUG    case '0':
pike.git/src/pike_types.cmod:9067:      void gc_mark_type_as_referenced(struct pike_type *t)   {    if (gc_mark(t, PIKE_T_TYPE)) {    GC_ENTER(t, PIKE_T_TYPE) {    switch(t->type) {    case PIKE_T_SCOPE:    case T_ASSIGN:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE: +  case PIKE_T_ARRAY:    if (t->cdr) gc_mark_type_as_referenced(t->cdr);    break;    case PIKE_T_FUNCTION:    case T_MANY:    case PIKE_T_RING:    case PIKE_T_TUPLE:    case PIKE_T_MAPPING:    case T_OR:    case T_AND:    if (t->cdr) gc_mark_type_as_referenced(t->cdr);    /* FALLTHROUGH */ -  case PIKE_T_ARRAY: +     case PIKE_T_MULTISET:    case T_NOT:    case PIKE_T_TYPE:    case PIKE_T_PROGRAM:    if (t->car) gc_mark_type_as_referenced(t->car);    break;    }    } GC_LEAVE;    }   }
pike.git/src/pike_types.cmod:9174:    break;    case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME:   #ifdef PIKE_DEBUG    /* this is a string and without PIKE_DEBUG    * they are not touched by the GC */    debug_gc_check (t->car, " as car in a type");   #endif    debug_gc_check (t->cdr, " as cdr in a type");    break; -  case T_ARRAY: +     case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM: -  case T_STRING: +     case PIKE_T_AUTO:    debug_gc_check (t->car, " as car in a type");    break;    case T_SCOPE:    case T_ASSIGN: -  +  case T_ARRAY: +  case T_STRING:    debug_gc_check (t->cdr, " as cdr in a type");    break;   #ifdef PIKE_DEBUG    case '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':