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.308 2007/05/09 15:58:03 grubba Exp $ + || $Id: pike_types.c,v 1.309 2007/06/29 17:06:05 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:41:   #define NO_MAX_ARGS 4   #define NO_SHORTCUTS 8      /*    * Flags used by pike_types_le()    */   #define LE_WEAK_OBJECTS 1 /* Perform weaker checking of objects. */   #define LE_A_B_SWAPPED 2 /* Argument A and B have been swapped.    * Relevant for markers.    */ + #define LE_A_GROUPED 0/*4*/ /* Argument A has been grouped. +  * Perform weaker checking for OR-nodes. */ + #define LE_B_GROUPED 0/*8*/ /* Argument B has been grouped. +  * Perform weaker checking for OR-nodes. */ + #define LE_A_B_GROUPED 0/*12*/ /* Both the above two flags. */      /*    * Flags used by low_get_first_arg_type()    */   #define FILTER_KEEP_VOID 1 /* Keep void during the filtering. */      /*    * Flags used as flag_method to mk_type()    */   #define PT_COPY_CAR 1
pike.git/src/pike_types.c:3752:    {    case T_AND:    /* OK if either of the parts is a subset. */    /* FIXME: What if b also contains an AND? */    ret = low_pike_types_le(a->car, b, array_cnt, flags);    if(ret) return ret;    a = a->cdr;    goto recurse;       case T_OR: -  /* OK, if both of the parts are a subset */ +  /* OK, if both of the parts are a subset, +  * unless we are grouped, in which case +  * only one part needs to be a subset. +  */    if (a->car->type == T_VOID) {    /* Special case for T_VOID */    /* FIXME: Should probably be handled as T_ZERO. */ -  +  if (flags & LE_A_GROUPED) return 1;    a = a->cdr;    goto recurse;    } else {    ret = low_pike_types_le(a->car, b, array_cnt, flags); -  if (!ret) return 0; +  if (!ret == !(flags & LE_A_GROUPED)) return ret;    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_RING:    a = a->car;    goto recurse;       case PIKE_T_SCOPE: -  +  flags |= LE_A_GROUPED; +  /* FALL_THROUGH */    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;    array_cnt = -array_cnt; -  flags ^= LE_A_B_SWAPPED; +  flags ^= LE_A_B_SWAPPED|LE_A_B_GROUPED;    goto recurse;    }    /* Some common cases. */    switch(a->car->type) {    case T_NOT:    a = a->car->car;    goto recurse;    case T_MIXED:    a = zero_type_string;    goto recurse;    case T_ZERO:    case T_VOID:    a = mixed_type_string;    goto recurse;    }    if (low_pike_types_le(a->car, b, array_cnt, flags)) {    return 0;    }    /* FIXME: This is wrong... */ -  return !low_pike_types_le(b, a->car, -array_cnt, flags ^ LE_A_B_SWAPPED); +  return !low_pike_types_le(b, a->car, -array_cnt, +  flags ^ (LE_A_B_SWAPPED|LE_A_B_GROUPED));       case T_ASSIGN:    ret = low_pike_types_le(a->cdr, b, array_cnt, flags);    if(ret && (b->type != T_VOID))    {    int m = CAR_TO_INT(a);    struct pike_type *tmp;    int i;       type_stack_mark();
pike.git/src/pike_types.c:3887:    switch(b->type)    {    case T_AND:    /* OK, if a is a subset of both parts. */    ret = low_pike_types_le(a, b->car, array_cnt, flags);    if(!ret) return 0;    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; +  /* OK if a is a subset of either of the parts, +  * unless we are grouped, in which case both +  * parts need to be a subset. +  */ +  ret = low_pike_types_le(a, b->car, array_cnt, flags); +  if (!ret != !(flags & LE_B_GROUPED)) return ret;    b = b->cdr;    goto recurse;       case PIKE_T_RING:    b = b->car;    goto recurse;       case PIKE_T_SCOPE: -  +  flags |= LE_B_GROUPED; +  /* FALL_THROUGH */    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:3921:    goto recurse;    case T_ZERO:    case T_VOID:    b = mixed_type_string;    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 ^ LE_A_B_SWAPPED); +  return !low_pike_types_le(b->car, a, -array_cnt, +  flags ^ (LE_A_B_SWAPPED|LE_A_B_GROUPED));       case T_ASSIGN:    ret = low_pike_types_le(a, b->cdr, array_cnt, flags);    if(ret && (a->type != T_VOID))    {    int m = CAR_TO_INT(b);    struct pike_type *tmp;    int i;       type_stack_mark();
pike.git/src/pike_types.c:4135:    a = a->cdr;    }       b_tmp = b->car;    if (b->type == T_FUNCTION)    {    b = b->cdr;    }       if (a_tmp->type != T_VOID) { -  if (!low_pike_types_le(b_tmp, a_tmp, 0, flags ^ LE_A_B_SWAPPED)) { +  if (!low_pike_types_le(b_tmp, a_tmp, 0, +  flags ^ (LE_A_B_SWAPPED|LE_A_B_GROUPED))) {    return 0;    }    }    }    /* FALL_THROUGH */    case TWOT(T_MANY, T_MANY):    /* check the 'many' type */    if ((a->car->type != T_VOID) && (b->car->type != T_VOID)) { -  if (!low_pike_types_le(b->car, a->car, 0, flags ^ LE_A_B_SWAPPED)) { +  if (!low_pike_types_le(b->car, a->car, 0, +  flags ^ (LE_A_B_SWAPPED|LE_A_B_GROUPED))) {    return 0;    }    }       a = a->cdr;    b = b->cdr;       /* check the returntype */    /* FIXME: Check array_cnt */    if ((b->type != T_VOID) && (a->type != T_VOID)) {
pike.git/src/pike_types.c:5271:    struct pike_type *tmp3 = NULL;       if (soft_type == orig_type) {    copy_pike_type(res, soft_type);    return res;    }       loop:    switch(soft_type->type) {    case T_OR: -  res = or_pike_types(tmp = soft_cast(soft_type->car, orig_type, flags), -  tmp2 = soft_cast(soft_type->cdr, orig_type, flags), 1); +  tmp = soft_cast(soft_type->car, orig_type, flags); +  if (tmp == orig_type) return tmp; +  tmp2 = soft_cast(soft_type->cdr, orig_type, flags); +  if (tmp2 == orig_type) { +  res = tmp2; +  tmp2 = NULL; +  } else { +  res = or_pike_types(tmp, tmp2, 1); +  }    break;    case T_AND: -  +  /* FIXME: Make stricter analogous to OR above. */    res = and_pike_types(tmp = soft_cast(soft_type->car, orig_type, flags),    tmp2 = soft_cast(soft_type->cdr, orig_type, flags));    break;    case T_SCOPE:    case T_ASSIGN:    case PIKE_T_NAME:    soft_type = soft_type->cdr;    goto loop;    /* FIXME: TUPLE, RING */    case PIKE_T_ATTRIBUTE:
pike.git/src/pike_types.c:5314:    copy_pike_type(res, soft_type);    } else {    copy_pike_type(res, orig_type);    }    break;    }    if (!res) {    loop2:    switch(orig_type->type) {    case T_OR: -  res = or_pike_types(tmp = soft_cast(soft_type, orig_type->car, flags), -  tmp2 = soft_cast(soft_type, orig_type->cdr, flags), -  1); +  tmp = soft_cast(soft_type, orig_type->car, flags); +  if (tmp == soft_type) return tmp; +  tmp2 = soft_cast(soft_type, orig_type->cdr, flags); +  if (tmp2 == soft_type) { +  res = tmp2; +  tmp2 = NULL; +  } else { +  res = or_pike_types(tmp, tmp2, 1); +  }    break;    case T_AND: -  +  /* FIXME: Make stricter analogous to OR above. */    res = and_pike_types(tmp = soft_cast(soft_type, orig_type->car, flags),    tmp2 = soft_cast(soft_type, orig_type->cdr, flags));    break;    case T_SCOPE:    case T_ASSIGN:    case PIKE_T_NAME:    orig_type = orig_type->cdr;    goto loop2;    case PIKE_T_ATTRIBUTE:    if ((res = soft_cast(soft_type, orig_type->cdr, flags))) {