Beispiel #1
0
Cell cellArith(Op o, Cell c1, Cell c2) {
again:
    if (c1.m_type == KindOfInt64) {
        for (;;) {
            if (c2.m_type == KindOfInt64)  return o(c1.m_data.num, c2.m_data.num);
            if (c2.m_type == KindOfDouble) return o(c1.m_data.num, c2.m_data.dbl);
            c2 = numericConvHelper(c2);
            assert(c2.m_type == KindOfInt64 || c2.m_type == KindOfDouble);
        }
    }

    if (c1.m_type == KindOfDouble) {
        for (;;) {
            if (c2.m_type == KindOfDouble) return o(c1.m_data.dbl, c2.m_data.dbl);
            if (c2.m_type == KindOfInt64)  return o(c1.m_data.dbl, c2.m_data.num);
            c2 = numericConvHelper(c2);
            assert(c2.m_type == KindOfInt64 || c2.m_type == KindOfDouble);
        }
    }

    if (c1.m_type == KindOfArray && c2.m_type == KindOfArray) {
        return make_tv<KindOfArray>(o(c1.m_data.parr, c2.m_data.parr));
    }

    c1 = numericConvHelper(c1);
    assert(c1.m_type == KindOfInt64 || c1.m_type == KindOfDouble);
    goto again;
}
Beispiel #2
0
Cell cellArithO(Op o, Check ck, Over ov, Cell c1, Cell c2) {
  if (c1.m_type == KindOfArray && c2.m_type == KindOfArray) {
    return cellArith(o, c1, c2);
  }

  auto ensure_num = [](Cell& c) {
    if (c.m_type != KindOfInt64 && c.m_type != KindOfDouble) {
      cellCopy(numericConvHelper(c), c);
    }
  };

  ensure_num(c1);
  ensure_num(c2);
  auto both_ints = (c1.m_type == KindOfInt64 && c2.m_type == KindOfInt64);
  int64_t a = c1.m_data.num;
  int64_t b = c2.m_data.num;

  return (both_ints && ck(a,b)) ? ov(a,b) : cellArith(o, c1, c2);
}