pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:4550:    * and leave it to the evaluator to join the multiple    * assignments with or. The alternative (and stricter) would    * be to allocate a new marker for each step of the expansion    * and to have explicit or nodes:    * function(assign(m1, mixed), many(assign(m2, mixed), or(m1, m2))).    */    {    int nargs;    struct pike_type *ai = a;    struct pike_type *bi = b; -  int got_empty = 0; -  int got_full = 0; +        type_stack_mark();    type_stack_mark(); /* To keep track of the number of args. */       while(1) {    /* Invariant:    * ai->type and bi->type are either T_FUNCTION or T_MANY.    */    enum pt_cmp_flags avoidable = 0;    enum pt_cmp_flags bvoidable = 0;
pike.git/src/pike_types.cmod:4575:    /* 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;       /* FIXME: Only use implicit nullable for legacy types. */    tmp = low_type_binop(op, ai->car, bi->car, remap,    avoidable | PT_FLAG_CMP_NULLABLE,    bvoidable | PT_FLAG_CMP_NULLABLE,    remap_flags);    +  /* 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 (remap_flags & PT_FLAG_REMAP_TRACE) { -  fprintf(stderr, "got_empty: %d, got_full: %d\n" -  "tmp: ", -  got_empty, got_full); +  fprintf(stderr, "tmp: ");    simple_describe_type(tmp);    fprintf(stderr, "\n");    }       switch(op) {    case PT_BINOP_AND:    if (!tmp) {    if (avoidable && bvoidable) {    /* NB: The VOIDABLE flag only affects comparisons with    * explicit void. If both arguments have implicit void,
pike.git/src/pike_types.cmod:4631:    nargs--;    push_reverse_type(T_MANY);       while (nargs--) {    push_reverse_type(T_FUNCTION);    }    return pop_unfinished_type();    }    break;    case PT_BINOP_MINUS: -  if (!tmp) { -  if (got_full) goto function_next; -  got_empty = 1; -  } else { -  if (tmp == ai) { -  got_full = 1; -  } else { +  if (avoidable && bvoidable) { +  if (tmp != a->car) { +  if (!tmp) goto function_fail;    free_type(tmp);    goto complex_function;    } -  free_type(tmp); -  if (got_empty) goto function_next; -  } +     -  if (avoidable && bvoidable) { +     /* 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,    PT_FLAG_CMP_VOIDABLE,    0, remap_flags);       if (remap_flags & PT_FLAG_REMAP_TRACE) { -  fprintf(stderr, "got_empty: %d, got_full: %d\n" -  "ret tmp: ", -  got_empty, got_full); +  fprintf(stderr, "ret tmp: ");    simple_describe_type(tmp);    fprintf(stderr, "\n");    }    -  if (!tmp) { -  if (got_full) goto function_next; -  got_empty = 1; -  } else { -  if (tmp == aret) { -  got_full = 1; -  } else { +  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) { +  push_remap_markers(ai, NULL, remap, remap_flags); +  push_finished_type(tmp); +  push_type(T_FUNCTION);    free_type(tmp); -  goto function_next; +     } -  +  tmp = low_type_binop(op, ai, bi, NULL, 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); -  if (got_empty) goto function_next; +     } -  -  /* Note: We have pushed two type stack marks earlier, -  * so we need to get rid of them before returning. -  */ -  if (!got_full) { +  nargs = pop_stack_mark(); +  if (!nargs) {    pop_stack_mark(); -  pop_stack_mark(); +     return NULL;    } -  -  pop_stack_mark(); -  push_remap_markers(a, NULL, remap, remap_flags); +  while (nargs-- > 1) push_type(T_OR);    return pop_unfinished_type(); -  } -  break; +     default:    Pike_fatal("Unsupported.\n");    }    -  function_next: -  +     if (avoidable && bvoidable) break; -  -  /* 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; -  } -  } +        complex_function:       nargs = pop_stack_mark();    if (op != PT_BINOP_AND) {    nargs = 0;    ai = a;    bi = b;    }   
pike.git/src/pike_types.cmod:4743:    push_remap_markers(ai, NULL, remap, remap_flags);       push_binop(op);       while (nargs--) {    push_reverse_type(T_FUNCTION);    }    return pop_unfinished_type();       function_fail: -  compiler_discard_type(); +     pop_stack_mark(); -  +  compiler_discard_type();    return NULL;    }       case TWOT(T_VOID, T_ZERO):    if (op & PT_BINOP_AND) {    /* Return zero. */    add_ref(b);    return b;    }    return NULL;