pike.git / src / pike_types.c

version» Context lines:

pike.git/src/pike_types.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: pike_types.c,v 1.307 2007/05/07 12:18:42 grubba Exp $ + || $Id: pike_types.c,v 1.308 2007/05/09 15:58:03 grubba Exp $   */      #include "global.h"   #include <ctype.h>   #include "svalue.h"   #include "pike_types.h"   #include "stralloc.h"   #include "stuff.h"   #include "array.h"   #include "program.h"
pike.git/src/pike_types.c:523:    t->car = car;    t->cdr = cdr;       t->hash = hash;    t->next = pike_type_hash[index];    pike_type_hash[index] = t;       if (flag_method) {    if (flag_method == PT_IS_MARKER) {    t->flags = PT_FLAG_MARKER_0 << (type-'0'); +  } else if (type == PIKE_T_SCOPE) { +  /* The scope blocks propagation of markers. */ +  t->flags = cdr->flags & ~(PT_FLAG_MARKER|PT_FLAG_ASSIGN);    } else {    if (car && (flag_method & PT_COPY_CAR)) {    t->flags |= car->flags;    }    if (cdr && (flag_method & PT_COPY_CDR)) {    t->flags |= cdr->flags;    }    }    }   
pike.git/src/pike_types.c:1066:    /* The marker has a value. */    struct pike_type *type = dmalloc_touch(struct pike_type *, markers[m]);   #ifdef PIKE_TYPE_DEBUG    if (l_flag > 2) {    fprintf(stderr, "Marker value.\n");    }   #endif    /* FIXME: We probably ought to switch to the other marker set here. */    markers[m] = NULL;    push_finished_type_with_markers(type, markers, 0); +  if (type->flags & (PT_FLAG_MARKER|PT_FLAG_ASSIGN)) { +  push_scope_type(0); +  }    if (markers[m]) free_type(markers[m]);    markers[m] = dmalloc_touch(struct pike_type *, type);    } else {    /* The marker has not been set. */   #ifdef PIKE_TYPE_DEBUG    if (l_flag > 2) {    fprintf(stderr, "No marker value.\n");    }   #endif    }
pike.git/src/pike_types.c:2024:       case T_ASSIGN:    my_putchar('(');    my_putchar('0' + CAR_TO_INT(t));    my_putchar('=');    my_describe_type(t->cdr);    my_putchar(')');    break;       case T_SCOPE: -  my_putchar('{'); -  my_putchar(CAR_TO_INT(t)); +  my_strcat("scope("); +  my_putchar('0' + CAR_TO_INT(t));    my_putchar(',');    my_describe_type(t->cdr); -  my_putchar('}'); +  my_putchar(')');    break;       case T_TUPLE:    my_putchar('[');    my_describe_type(t->car);    my_putchar(',');    my_describe_type(t->cdr);    my_putchar(']');    break;   
pike.git/src/pike_types.c:2567: Inside #if 0
   struct pike_type *top = NULL;   #if 0    fprintf(stderr, " lower_or_pike_types(");    simple_describe_type(t1);    fprintf(stderr, ", ");    simple_describe_type(t2);    fprintf(stderr, ")\n");   #endif    if (t1 == t2) {    t = t1; +  } else if (!t1) { +  t = t2; +  ret = 1; +  } else if (!t2) { +  t = t1; +  ret = -1;    } else if (zero_implied && (t1->type == T_ZERO)) {    t = t2;    } else if (zero_implied && (t2->type == T_ZERO)) {    t = t1; -  } else if (t1->type < t2->type) { +  } else if ((t1->type ^ '0') < (t2->type ^ '0')) { +  /* Note: Adjusted order to get markers first. */    t = t1;    ret = -1; -  } else if (t1->type > t2->type) { +  } else if ((t1->type ^ '0') > (t2->type ^ '0')) { +  /* Note: Adjusted order to get markers first. */    t = t2;    ret = 1;    } else {   #ifdef PIKE_DEBUG    if (t1->type != t2->type) {    Pike_fatal("Lost track of types t1->type: %d, t2->type: %d\n",    t1->type, t2->type);    }   #endif /* PIKE_DEBUG */    switch(t1->type) {
pike.git/src/pike_types.c:2596:    if (CAR_TO_INT(t1) < CAR_TO_INT(t2)) {    t = t1;    ret = -1;    } else {    t = t2;    ret = 1;    }    break;    case T_STRING:    { -  switch(lower_or_pike_types(t1->car, t2->car, 1, 0)) { -  case 0: break; -  case 1: -  push_finished_type(t1->car); -  push_type(T_OR); -  break; -  case -1: -  push_finished_type(t2->car); -  push_type(T_OR); -  break; -  } +  low_or_pike_types(t1->car, t2->car, 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.c:2661:    t = t1;    ret = -1;    break;    } else if (t1->car->type > t2->car->type) {    t = t2;    ret = 1;    break;    }    /* FALL_THOUGH */    default: + #if 0 +  if (pike_types_le(t1, t2)) { +  t = t2; +  } else if (pike_types_le(t2, t1)) {    t = t1; -  +  } else + #endif /* 0 */ +  if (t1 < t2) { +  t = t1;    ret = -1; -  +  } else { +  t = t2; +  ret = 1; +  }    break;    }    }    if (!elem_on_stack) {    push_finished_type(t);    } else if ((top = peek_type_stack())->type != t->type) {    if (zero_implied && (top->type == T_ZERO)) {    Pike_compiler->type_stackp--;    free_type(top);    push_finished_type(t);    } else if (zero_implied && (t->type == T_ZERO)) {    /* The zero is implied. */    } else {    push_finished_type(t);    } -  +  } else if (t == top) { +  /* No need to do anything. */    } else {    switch(t->type) {    case T_FLOAT:    case T_MIXED:    case T_VOID:    case T_ZERO:    /* There can only be one. */    break;    case T_INT:    {
pike.git/src/pike_types.c:2722:    min1 = MINIMUM(min1, min2);    max1 = MAXIMUM(max1, max2);       push_int_type(min1, max1);    }    }    break;    case T_STRING:    {    Pike_compiler->type_stackp--; -  switch(lower_or_pike_types(t->car, top->car, 1, 0)) { -  case 0: break; -  case 1: -  push_finished_type(t->car); -  push_type(T_OR); -  break; -  case -1: -  push_finished_type(top->car); -  push_type(T_OR); -  break; -  } +  low_or_pike_types(t->car, top->car, 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:    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_SCOPE: -  Pike_compiler->type_stackp--; -  low_or_pike_types(t->cdr, top->cdr, zero_implied); -  if (CAR_TO_INT(t) > CAR_TO_INT(top)) -  push_scope_type(CAR_TO_INT(t)); -  else -  push_scope_type(CAR_TO_INT(top)); -  free_type(top); -  break; +     case T_MAPPING:    if (t->car == top->car) {    Pike_compiler->type_stackp--;    push_finished_type(t->car);    low_or_pike_types(t->cdr, top->cdr, zero_implied);    push_reverse_type(T_MAPPING);    free_type(top);    break;    } else if (t->cdr == top->cdr) {    Pike_compiler->type_stackp--;    push_finished_type(t->cdr);    low_or_pike_types(t->car, top->car, zero_implied);    push_type(T_MAPPING);    free_type(top);    break;    }    /* FALL_THROUGH */    default: -  +  if (t < top) { +  Pike_compiler->type_stackp--;    push_finished_type(t); -  +  push_finished_type(top); +  free_type(top); +  } else { +  push_finished_type(t); +  }    break;    }    }    return ret;   }      static void low_or_pike_types(struct pike_type *t1,    struct pike_type *t2,    int zero_implied)   {
pike.git/src/pike_types.c:2819:    {    push_finished_type(t1);    }    else if (t1->type == T_ZERO && zero_implied)    {    push_finished_type(t2);    }    else if (t1 == t2) {    push_finished_type(t1);    } -  else if (t1->type == T_OR) { +  else if ((t1->type == T_OR) || (t2->type == T_OR)) {    int on_stack = 0;    type_stack_mark();    while (t1 || t2) { -  if (!t1) { -  if (t2->type == T_OR) { -  push_finished_type(t2->car); -  t2 = t2->cdr; -  } else { -  push_finished_type(t2); -  t2 = NULL; -  } -  } else if (!t2) { -  if (t1->type == T_OR) { -  push_finished_type(t1->car); -  t1 = t1->cdr; -  } else { -  push_finished_type(t1); -  t1 = NULL; -  } -  } else { +     struct pike_type *a = t1;    struct pike_type *b = t2;    struct pike_type *n1 = NULL;    struct pike_type *n2 = NULL;    int val; -  if (t1->type == T_OR) { +  if (t1 && t1->type == T_OR) {    a = t1->car;    n1 = t1->cdr;    } -  if (t2->type == T_OR) { +  if (t2 && t2->type == T_OR) {    b = t2->car;    n2 = t2->cdr;    }   #ifdef PIKE_DEBUG -  if ((a->type == T_OR) || (b->type == T_OR)) { +  if (a && b && ((a->type == T_OR) || (b->type == T_OR))) {    fprintf(stderr, " low_or_pike_types(");    simple_describe_type(arg1);    fprintf(stderr, ", ");    simple_describe_type(arg2);    fprintf(stderr, ")\n a:");    simple_describe_type(a);    fprintf(stderr, "\n b:");    simple_describe_type(b);    fprintf(stderr, ")\n");    Pike_fatal("Invalid type to lower_or_pike_types!\n");    }   #endif    val = lower_or_pike_types(a, b, zero_implied, on_stack);    if (val <= 0) t1 = n1;    if (val >= 0) t2 = n2; -  } +     on_stack = 1;    }    on_stack = pop_stack_mark();    while (on_stack > 1) {    push_reverse_joiner_type(T_OR);    on_stack--;    }    } -  else if (t2->type == T_OR) { -  low_or_pike_types(t2, t1, zero_implied); -  } +     else {    int val = lower_or_pike_types(t1, t2, zero_implied, 0);    if (val < 0) {    push_finished_type(t2);    push_reverse_joiner_type(T_OR);    } else if (val > 0) {    push_finished_type(t1);    push_reverse_joiner_type(T_OR);    }    }
pike.git/src/pike_types.c:3254:    {    low_match_types(a->cdr, b, flags);    return ret;    }else{    return low_match_types(a->cdr, b, flags);    }       case PIKE_T_RING:    return low_match_types(a->car, b, flags);    +  case PIKE_T_SCOPE:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    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:
pike.git/src/pike_types.c:3362:    {    low_match_types(a, b->cdr, flags);    return ret;    }else{    return low_match_types(a, b->cdr, flags);    }       case PIKE_T_RING:    return low_match_types(a, b->car, flags);    +  case PIKE_T_SCOPE:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    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:
pike.git/src/pike_types.c:3788:    } else {    a = a->cdr;    goto recurse;    }    }       case PIKE_T_RING:    a = a->car;    goto recurse;    +  case PIKE_T_SCOPE:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    a = a->cdr;    goto recurse;       case T_NOT:    if (b->type == T_NOT) {    struct pike_type *tmp = a->car;    a = b->car;    b = tmp;
pike.git/src/pike_types.c:3909:    /* 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_RING:    b = b->car;    goto recurse;    +  case PIKE_T_SCOPE:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    b = b->cdr;    goto recurse;       case T_NOT:    /* Some common cases. */    switch(b->car->type) {    case T_NOT:    b = b->car->car;
pike.git/src/pike_types.c:4314:      /*    * Check the function parameters.    * Note: The difference between this function, and pike_types_le()    * is the more lenient check for T_OR, and the handling of T_ARRAY.    */   int strict_check_call(struct pike_type *fun_type,    struct pike_type *arg_type)   {    while ((fun_type->type == T_OR) || -  (fun_type->type == T_ARRAY)) { +  (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;    }    }    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
pike.git/src/pike_types.c:4381:    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_RING:    return low_get_return_type(a->car, b);    +  case PIKE_T_SCOPE:    case PIKE_T_NAME:    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;   
pike.git/src/pike_types.c:5678:       loop:    /* Count the number of array levels. */    while(fun_type->type == PIKE_T_ARRAY) {    array_cnt++;    fun_type = fun_type->car;    }       switch(fun_type->type) {    case T_SCOPE: +  /* FIXME: Save and restore the corresponding marker set. */    case T_ASSIGN:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    fun_type = fun_type->cdr;    goto loop;          case T_OR:    res = lower_new_check_call(fun_type->car, arg_type, flags, sval CHECK_CALL_ARGS);    if (!res) {
pike.git/src/pike_types.c:5991:    * and the latter kept.    * In non-strict mode both should be split here.    * Suggestion:    * Introduce a new operator (UNION?) for the former case.    */       loop:    clear_markers();    /* First split the argument type into basic types. */    switch(arg_type->type) { -  case PIKE_T_SCOPE: +     case T_ASSIGN:    case PIKE_T_NAME:    arg_type = arg_type->cdr;    goto loop;       case T_OR:    if (!(tmp = low_new_check_call(fun_type, arg_type->car, flags, sval))) {    if (flags & CALL_STRICT) {    return NULL;    }
pike.git/src/pike_types.c:6635:    my_yyerror("Too many arguments to %S (expected %d arguments).",    fun_name, *argno - 1);    yytype_error(NULL, NULL, args->type, 0);    }    free_type(fun_type);    return NULL;   }      struct pike_type *zzap_function_return(struct pike_type *a, INT32 id)   { +  struct pike_type *ret = NULL;    switch(a->type)    { -  +  case T_SCOPE: +  ret = zzap_function_return(a->cdr, id); +  if (!ret) return NULL; +  type_stack_mark(); +  push_finished_type(ret); +  free_type(ret); +  push_scope_type(CAR_TO_INT(a)); +  return pop_unfinished_type(); +     case T_OR:    { -  struct pike_type *ar, *br, *ret=0; +  struct pike_type *ar, *br;    ar = zzap_function_return(a->car, id);    br = zzap_function_return(a->cdr, id);    if(ar && br) ret = or_pike_types(ar, br, 0);    if(ar) free_type(ar);    if(br) free_type(br);    return ret;    }       case T_FUNCTION:    case T_MANY:
pike.git/src/pike_types.c:7243:    break;    }   }      /* Make a pike-type from a serialized (old-style) type. */   struct pike_type *debug_make_pike_type(const char *serialized_type)   {    unsigned char *dummy;    type_stack_mark();    low_make_pike_type((unsigned char *)serialized_type, &dummy); + #if 1 +  if ((Pike_compiler->type_stackp[0]->flags & +  (PT_FLAG_MARKER|PT_FLAG_ASSIGN)) || +  (Pike_compiler->type_stackp[0]->type == T_OR) || +  (Pike_compiler->type_stackp[0]->type == T_AND)) { +  push_scope_type(0); +  } + #endif /* 1 */    return pop_unfinished_type();   }      int pike_type_allow_premature_toss(struct pike_type *type)   {    again:   #if 0    fprintf(stderr, "pike_type_allow_premature_toss(): Type: %d\n",    type->type);   #endif /* 0 */