pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:4647:    nargs--;    push_reverse_type(T_MANY);       while (nargs--) {    push_reverse_type(T_FUNCTION);    }    return pop_unfinished_type();    }    break;    case PT_BINOP_MINUS: +  /* Subtraction (A - B) +  * +  * The result is the subset of function A where at least one +  * of the arguments or the return type differs from function B. +  * +  * T_FUNCTION(A, X) - T_FUNCTION(B, Y) == +  * T_OR(T_FUNCTION(A - B, X), T_FUNCTION(A, X - Y)) +  * +  * T_FUNCTION(A, X) - T_MANY(T_VOID, Y) == +  * T_OR(T_FUNCTION(A - T_VOID, X), +  * T_MANY(T_VOID, X* - Y)) +  * +  * T_FUNCTION(A, X) - T_MANY(B, Y) == +  * T_OR(T_FUNCTION(A - B, X), T_FUNCTION(A, X - MANY(B, Y))) +  * +  * T_MANY(T_VOID, X) - T_FUNCTION(B, Y) == +  * T_MANY(T_VOID, X) (if B not voidable) +  * T_MANY(T_VOID, X - Y*) (if B voidable) == +  * T_MANY(T_VOID, X) - Y +  * +  * T_MANY(A, X) - T_FUNCTION(B, Y) == +  * T_OR(T_FUNCTION(A - B, T_MANY(A, X)), +  * T_FUNCTION(A, T_MANY(A, X) - Y)) +  * +  * Caveat for the above: Handle the special case where +  * A - B == T_VOID. +  * +  * T_MANY(A, X) - T_MANY(A, Y) == T_MANY(T_VOID, X - Y) +  * +  * T_MANY(T_VOID, X) - T_MANY(B, Y) == T_MANY(T_VOID, X - Y) +  * +  * T_MANY(A, X) - T_MANY(T_VOID, Y) == +  * T_OR(T_FUNCTION(A, T_MANY(A, X)), +  * T_MANY(T_VOID, X - Y)) +  * +  * T_MANY(A, X) - T_MANY(~A, Y) == T_MANY(A, X - Y) +  * +  * T_MANY(A, X) - T_MANY(B, Y) == +  * T_OR(T_MANY(A, X - Y), +  * T_AND(T_MANY(A, X), +  * T_NOT(T_MANY(T_NOT(A - B), T_MIXED)))) +  */    if (avoidable && bvoidable) { -  +  /* FIXME: What if tmp only differs due to remapping? */    if (tmp != a->car) { -  if (!tmp) goto function_fail; +  pop_stack_mark(); +  if (!tmp) { +  push_remap_markers(a->cdr, NULL, remap, remap_flags); +  push_type(T_VOID); +  push_type(T_MANY); +  return pop_unfinished_type(); +  } +  /* FIXME: What about tmp->type == T_VOID? */ +  push_type(T_MIXED); +  push_finished_type(tmp); +  push_type(T_NOT); +  push_type(T_MANY); +  push_type(T_NOT); +  push_remap_markers(a, NULL, remap, remap_flags); +  push_type(T_AND);    free_type(tmp); -  goto complex_function; +  +  tmp = low_type_binop(op, a->cdr, b->cdr, remap, +  PT_FLAG_CMP_VOIDABLE, +  0, remap_flags); +  if (tmp) { +  push_finished_type(tmp); +  push_remap_markers(a->car, NULL, remap, remap_flags); +  push_type(T_MANY); +  push_type(T_OR); +  free_type(tmp);    } -  +  return pop_unfinished_type(); +  }       /* Time to check the return types. */       if (!aret) aret = ai->cdr;    if (!bret) bret = bi->cdr;       /* NB: Ignore the return type if matching against void. */ -  tmp = low_type_binop(op, aret, bret, NULL, +  tmp = low_type_binop(op, aret, bret, remap,    PT_FLAG_CMP_VOIDABLE,    0, remap_flags);       if (remap_flags & PT_FLAG_REMAP_TRACE) {    fprintf(stderr, "ret tmp: ");    simple_describe_type(tmp);    fprintf(stderr, "\n");    }       if (!tmp) goto function_fail;       pop_stack_mark();    push_finished_type(tmp);    push_remap_markers(a->car, NULL, remap, remap_flags);    push_type(T_MANY);       return pop_unfinished_type();    }    if (tmp) { -  +  if (tmp->type != T_VOID) {    push_remap_markers(ai, NULL, remap, remap_flags);    push_finished_type(tmp);    push_type(T_FUNCTION); -  +  } else if (a->type == T_FUNCTION) { +  push_remap_markers(ai, NULL, remap, remap_flags); +  if ((ai->type != T_MANY) || (ai->car != T_VOID)) { +  /* Convert voidable arguments into zero|void +  * if they must be present for later arguments. +  */ +  push_type(T_ZERO); +  push_type(T_VOID); +  push_type(T_OR); +  push_type(T_FUNCTION); +  } +  } else { +  /* a->type == T_MANY */ +  }    free_type(tmp);    } -  tmp = low_type_binop(op, ai, bi, NULL, aflags, bflags, remap_flags); +  tmp = low_type_binop(op, ai, bi, remap, aflags, bflags, remap_flags);    if (tmp) {    push_finished_type(tmp);    push_remap_markers(a->car, NULL, remap, remap_flags);    push_type(T_FUNCTION);    free_type(tmp);    }    nargs = pop_stack_mark();    if (!nargs) {    pop_stack_mark();    return NULL;