pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:5526:       case PT_BINOP_MINUS:    /* Subtraction (A - B)    *    * T_FUNCTION(A, X) - T_FUNCTION(B, Y) ==    *    * B - A == Ø && X - Y == Ø    * ==> Ø # Full overlap    *    * B - A == Ø && X - Y == Z # Argument overlap -  * ==> T_FUNCTION(A, Z) +  * ==> T_FUNCTION(A, Z) # (Recurse)    *    * B - A == B ==> T_FUNCTION(A, X) # No overlap -  +  * # No need to recurse    * -  * B - A == C ==> T_FUNCTION(A, X) & # Partial overlap -  * ~T_FUNCTION(B, Y) +  * B - A == C && X - Y == Z # Partial overlap +  * ==> T_FUNCTION(A - B, X) | # Keep and +  * T_FUNCTION(A, Z) # Recurse    * -  +  * T_FUNCTION(A - B, X) | T_FUNCTION(A, X - Y) +  *    * T_MANY analogous with T_MANY substituted for T_FUNCTION above.    */       /* Check the argument. */       /* NB: The MANY argument is always voidable. */    if (ai->type == T_MANY) avoidable |= PT_FLAG_CMP_VOIDABLE;    if (bi->type == T_MANY) bvoidable |= PT_FLAG_CMP_VOIDABLE;      #if 0
pike.git/src/pike_types.cmod:5554:    simple_describe_type(ai);    fprintf(stderr, " (%d), ", avoidable);    simple_describe_type(bi);    fprintf(stderr, " (%d))\n\n", bvoidable);   #endif       if (!bi->car) {    /* Common case */    tmp = NULL;    } else { -  /* FIXME: Use implicit nullable only for legacy types. */ +  /* FIXME: Use implicit nullable only for legacy types. +  * FIXME: What about PT_FLAG_CMP_VOID_IS_NULL? +  */    tmp = low_type_binop(PT_BINOP_MINUS, bi->car, ai->car, remap,    bvoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE,    avoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    if (tmp) { -  +  /* No or not full overlap. */ +     if ((ai->car == void_type_string) && (tmp != bi->car) &&    (aflags & PT_FLAG_CMP_IGNORE_EXTRA_ARGS)) {    /* End of argument list for a, and it is valid to end the    * argument list here (void matched), and a implicitly    * ignores any further arguments.    */    free_type(tmp);    tmp = NULL;    } else { -  push_finished_type(ai); -  /* FIXME: What if tmp differs due to remapping? */ -  if (tmp != bi->car) { -  /* Some overlap. */ -  push_finished_type(bi); -  push_type(T_NOT); -  push_type(T_AND); +  if (tmp == bi->car) { +  /* Common case, no overlap. */ +  pop_stack_mark(); +  free_type(tmp); +  add_ref(ai); +  return ai;    }    free_type(tmp); -  return pop_unfinished_type(); +  +  tmp = low_type_binop(PT_BINOP_MINUS, ai->car, bi->car, remap, +  avoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE, +  bvoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE, +  remap_flags); +  +  if (tmp == ai->car) { +  /* No overlap. +  * +  * The first overlap test likely failed due +  * to remapping. +  */ +  pop_stack_mark(); +  free_type(tmp); +  add_ref(ai); +  return ai;    } -  +  +  push_finished_type(ai->cdr); +  push_finished_type(tmp); +  push_type(ai->type); +  free_type(tmp); +  tmp = NULL;    }    } -  +  }       /* Advance to the next argument. */    if (ai->type == T_FUNCTION) {    ai = ai->cdr;    }    if (bi->type == T_FUNCTION) {    bi = bi->cdr;    }    if ((ai->type != T_FUNCTION) && (ai->type != T_MANY)) {    if (aret) {    Pike_fatal("Unsupported type operation.\n");    } -  break; +     }    if ((bi->type != T_FUNCTION) && (bi->type != T_MANY)) {    if (bret) {    Pike_fatal("Unsupported type operation.\n");    } -  break; +     }       if (avoidable && bvoidable) {    /* Both a & b are T_MANY. Check the return type. */    if (!aret) aret = ai->cdr;    if (!bret) bret = bi->cdr;       /* NB: Ignore the return type if matching against void. */    tmp = low_type_binop(PT_BINOP_MINUS, aret, bret, remap,    PT_FLAG_CMP_VOIDABLE, 0, remap_flags);       if (tmp) {    /* Not full overlap for the return value. */    push_finished_type(tmp);    push_finished_type(a->car);    push_type(T_MANY);    free_type(tmp); -  return pop_unfinished_type(); +  } else { +  push_type(PIKE_T_UNKNOWN);    } -  pop_stack_mark(); -  return NULL; -  } -  +  } else {    /* Recurse. */    tmp = low_type_binop(PT_BINOP_MINUS, ai, bi, remap,    aflags, bflags, remap_flags);       if (tmp) {    push_finished_type(tmp); -  push_finished_type(ai->car); +  push_finished_type(a->car);    push_type(PIKE_T_FUNCTION);    free_type(tmp); -  return pop_unfinished_type(); +  } else { +  push_type(PIKE_T_UNKNOWN);    } -  pop_stack_mark(); -  return NULL; +  }    -  +  while (peek_stack_mark() > 1) { +  push_type(T_OR); +  } +  return pop_unfinished_type(); +     default:    /* Fall back to complex_function below. */    break;    }       complex_function: -  +  /* Either of ai and/or bi is a complex type. */    -  nargs = peek_stack_mark(); +     if (op != PT_BINOP_AND) { -  nargs = 0; -  ai = a; -  bi = b; +  compiler_discard_type(); +  type_stack_mark(); +  +  push_remap_markers(b, remap, +  remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS); +  push_remap_markers(a, remap, remap_flags); +  +  push_binop(op); +  +  return pop_unfinished_type();    }    -  /* Either of a and/or b is a complex type. */ +  nargs = peek_stack_mark(); +  if ((ai && (ai->type == PIKE_T_TRANSITIVE)) || +  (bi && (bi->type == PIKE_T_TRANSITIVE))) { +  /* Expand ai and/or bi. */ +  tmp = +  low_type_binop(op, ai, bi, remap, aflags, bflags, remap_flags); +  push_finished_type(tmp); +  free_type(tmp); +  } else {    push_remap_markers(bi, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    push_remap_markers(ai, remap, remap_flags);       push_binop(op); -  +  }       while (nargs--) {    push_reverse_type(T_FUNCTION);    }    return pop_unfinished_type();       function_fail:    compiler_discard_type();    return NULL;    }