pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:4500:    case T_NOT:    /* Rotate the opcode 2 bits.    *    * This converts A to ~A and vice versa.    */    op = ((op << 2) | (op >> 2)) & PT_BINOP_ALL;    return low_type_binop(op, a->car, b,    remap, aflags, bflags, remap_flags);    }    switch(b->type) { +  case T_AND:    case T_OR: -  /* op secondary -  * 0 0000 0 0000 -  * 1 0001 7 0111 -  * 2 0010 1 0001 -  * 3 0011 1, 3, 5, 7 0011 -  * 4 0100 7 0111 -  * 5 0101 7 0111 -  * 6 0110 - -  * 7 0111 7 0111 -  * 8 1000 1 0001 -  * 9 1001 - -  * 10 1010 1 0001 -  * 11 1011 1 0001 -  * 12 1100 1, 3, 5, 7 0011 -  * 13 1101 1 0111 -  * 14 1110 1 0001 -  * 15 1111 15 1111 +  /* op secondary(T_AND) secondary(T_OR) +  * 0 0000 0 0000 0 0000 +  * 1 0001 1 0001 7 0111 +  * 2 0010 7 0111 1 0001 +  * 3 0011 1, 3, 5, 7 0011 1, 3, 5, 7 0011 +  * 4 0100 1 0001 7 0111 +  * 5 0101 1 0001 7 0111 +  * 6 0110 - - +  * 7 0111 1 0001 7 0111 +  * 8 1000 7 0111 1 0001 +  * 9 1001 - - +  * 10 1010 7 0111 1 0001 +  * 11 1011 7 0111 1 0001 +  * 12 1100 1, 3, 5, 7 0011 1, 3, 5, 7 0011 +  * 13 1101 1 0001 7 0111 +  * 14 1110 7 0111 1 0001 +  * 15 1111 15 1111 15 1111 +  * +  * Note that secondary ops 1 and 7 are swapped for T_AND and T_OR.    */    tmp = low_type_binop(op, a, b->car, remap, aflags, bflags, remap_flags);    tmp2 = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);    -  /* NB: XOR and XNOR not supported cf above. -  * This is not a problem in practice, as they -  * are handled earlier. -  */ -  if ("071377-71-113117"[op] == '1') { +  /* FIXME: XOR and XNOR not supported cf above. */ +  if (("017311-17-77317f"[op] == '1') == (b->type == T_AND)) {    /* Secondary operator is AND. */    if (!tmp2) {    free_type(tmp);    return NULL;    }    if (!tmp) {    free_type(tmp2);    return NULL;    }    -  type_stack_mark(); -  push_finished_type(tmp); -  push_finished_type(tmp2); -  push_reverse_type(T_AND); -  } else { -  /* Secondary operator is OR. */ -  if (!tmp2) return tmp; -  if (!tmp) return tmp2; -  -  type_stack_mark(); -  push_finished_type(tmp); -  push_finished_type(tmp2); -  push_reverse_type(T_OR); -  } -  free_type(tmp); -  free_type(tmp2); -  return pop_unfinished_type(); -  -  case T_AND: -  tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags); -  if (!tmp) return NULL; -  tmp2 = low_type_binop(op, a, b->car, remap, aflags, bflags, remap_flags); -  if (!tmp2) { -  free_type(tmp2); -  return NULL; -  } -  -  switch(op) { -  case PT_BINOP_AND: +  if ((b->type == T_AND) && (op == PT_BINOP_AND)) {    /* NB: Attempt to avoid keeping the result from inverted types,    * in order to reduce type expansion.    */    if (b->car->type == T_NOT) {    free_type(tmp);    tmp = remap_markers(b->car, NULL, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    } else if (b->cdr->type == T_NOT) {    free_type(tmp2);    tmp2 = remap_markers(b->cdr, NULL, remap,    remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);    } -  break; -  default: -  /* Make the C-compiler happy. */ -  break; +     }       type_stack_mark();    push_finished_type(tmp);    push_finished_type(tmp2);    push_reverse_type(T_AND); -  +  } else { +  /* Secondary operator is OR. */ +  if (!tmp2) return tmp; +  if (!tmp) return tmp2; +  +  type_stack_mark(); +  push_finished_type(tmp); +  push_finished_type(tmp2); +  push_reverse_type(T_OR); +  }    free_type(tmp);    free_type(tmp2);    return pop_unfinished_type(); -  +     case T_NOT:    /* Swap the bits of the opcode pairwise.    *    * This converts B to ~B and vice versa.    */    op = (((op & PT_BINOP_B) << 1) | ((op >> 1) & PT_BINOP_B)) & PT_BINOP_ALL;    return low_type_binop(op, a, b->car,    remap, aflags, bflags, remap_flags);    }