Branch: Tag:

2020-10-14

2020-10-14 15:18:05 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Compiler [Typechecker]: Fix some more cases in low_type_binop().

It should now handle the same cases as low_intersect_types() and
low_subtract_types().

5031:    if (tmp) {    push_finished_type(a->cdr);    push_finished_type(tmp); -  push_reverse_type(a->type); +  push_type(a->type);    free_type(tmp);    }    if (tmp2) {    push_finished_type(tmp2);    push_finished_type(a->car); -  push_reverse_type(a->type); +  push_type(a->type);    free_type(tmp2);    }    if (peek_stack_mark() == 2) push_type(T_OR);
5062:    push_type(a->type);    return pop_unfinished_type();    -  /* FIXME: AND only from this point on. ======================= */ -  +     case T_OBJECT: -  +  switch(op) { +  case PT_BINOP_AND:    if (!a->cdr) {    add_ref(b);    return b;
5101:    add_ref(b);    return b;    } -  if ((a->car == b->car) && is_compatible(ap, bp)) { -  /* Both car must be 0 due to test above. -  * It is possible to implement a class that +  if ((a->car != b->car) || !is_compatible(ap, bp)) { +  /* It is not possible to implement a class that    * implements both of the classes.    */ -  type_stack_mark(); -  push_finished_type(a); -  push_finished_type(b); -  push_reverse_type(T_AND); -  return pop_unfinished_type(); +  return NULL;    } -  +  } +  case PT_BINOP_MINUS: +  if (!b->cdr) {    return NULL;    } -  +  if (a->cdr) { +  if (a->cdr == b->cdr) { +  return NULL;    } -  +  if (a->car && b->car) { +  /* This is only possible if a->cdr == b->cdr, but that is +  * handled above. +  */ +  add_ref(a); +  return a; +  } +  { +  struct program *ap = id_to_program(CDR_TO_INT(a)); +  struct program *bp = id_to_program(CDR_TO_INT(b));    -  +  if (!b->car && implements(ap, bp)) { +  return NULL; +  } +  if (!is_compatible(ap, bp)) { +  add_ref(a); +  return a; +  } +  } +  } +  break; +  default: +  break; +  } +  +  type_stack_mark(); +  push_finished_type(b); +  push_finished_type(a); +  push_binop(op); +  return pop_unfinished_type(); +  } +     /* Leaf type. */ -  +  if (op & PT_BINOP_AND) {    add_ref(a);    return a;    } -  +  return NULL; + }      /**    * Low-level subtraction (aka And-not) of two types.
5763:    }       type_stack_mark(); -  push_finished_type(a); +     push_finished_type(b);    push_type(T_NOT); -  push_reverse_type(T_AND); +  push_finished_type(a); +  push_type(T_AND);    return pop_unfinished_type();    }