Exemple #1
0
static inline Int
a_cmp(Term t1, Term t2)
{
  ArithError = FALSE;
  if (IsVarTerm(t1)) {
    ArithError = TRUE;
    Yap_Error(INSTANTIATION_ERROR, t1, "=:=/2");
    return FALSE;
  }
  if (IsVarTerm(t2)) {
    ArithError = TRUE;
    Yap_Error(INSTANTIATION_ERROR, t2, "=:=/2");
    return FALSE;
  }
  if (IsFloatTerm(t1) && IsFloatTerm(t2)) {
    return flt_cmp(FloatOfTerm(t1)-FloatOfTerm(t2));
  }
  if (IsIntegerTerm(t1) && IsIntegerTerm(t2)) {
    return int_cmp(IntegerOfTerm(t1)-IntegerOfTerm(t2));
  }
  t1 = Yap_Eval(t1);
  if (!t1) {
    return FALSE;
  }
  if (IsIntegerTerm(t1)) {
    Int i1 = IntegerOfTerm(t1);
    t2 = Yap_Eval(t2);

    if (IsIntegerTerm(t2)) {
      Int i2 = IntegerOfTerm(t2);
      return int_cmp(i1-i2);
    } else if (IsFloatTerm(t2)) {
      Float f2 = FloatOfTerm(t2);
#if HAVE_ISNAN
      if (isnan(f2)) {
	Yap_Error_TYPE = EVALUATION_ERROR_UNDEFINED;
	Yap_Error_Term = t2;
	Yap_ErrorMessage = "trying to evaluate nan";
	ArithError = TRUE;
      }
#endif      
      return flt_cmp(i1-f2);
#ifdef USE_GMP
    } else if (IsBigIntTerm(t2)) {
      return Yap_gmp_cmp_int_big(i1,t2);
#endif
    } else {
      return FALSE;
    }
  } else if (IsFloatTerm(t1)) {
    Float f1 = FloatOfTerm(t1);
#if HAVE_ISNAN
    if (isnan(f1)) {
      Yap_Error_TYPE = EVALUATION_ERROR_UNDEFINED;
      Yap_Error_Term = t1;
      Yap_ErrorMessage = "trying to evaluate nan";
      ArithError = TRUE;
    }
#endif      
    t2 = Yap_Eval(t2);
#if HAVE_ISNAN
      if (isnan(f1))
	return -1;
#endif      

    if (IsIntegerTerm(t2)) {
      Int i2 = IntegerOfTerm(t2);
      return flt_cmp(f1-i2);
    } else if (IsFloatTerm(t2)) {
      Float f2 = FloatOfTerm(t2);
#if HAVE_ISNAN
      if (isnan(f2)) {
	Yap_Error_TYPE = EVALUATION_ERROR_UNDEFINED;
	Yap_Error_Term = t2;
	Yap_ErrorMessage = "trying to evaluate nan";
	ArithError = TRUE;
      }
#endif      
      return flt_cmp(f1-f2);
#ifdef USE_GMP
    } else if (IsBigIntTerm(t2)) {
      return Yap_gmp_cmp_float_big(f1,t2);
#endif
    } else {
      return FALSE;
    }
#ifdef USE_GMP
  } else if (IsBigIntTerm(t1)) {
    {
      t2 = Yap_Eval(t2);

      if (IsIntegerTerm(t2)) {
	return Yap_gmp_cmp_big_int(t1, IntegerOfTerm(t2));
      } else if (IsFloatTerm(t2)) {
	Float f2 = FloatOfTerm(t2);
#if HAVE_ISNAN
	if (isnan(f2)) {
	  Yap_Error_TYPE = EVALUATION_ERROR_UNDEFINED;
	  Yap_Error_Term = t2;
	  Yap_ErrorMessage = "trying to evaluate nan";
	  ArithError = TRUE;
	}
#endif      
	return Yap_gmp_cmp_big_float(t1, f2);
      } else if (IsBigIntTerm(t2)) {
	return Yap_gmp_cmp_big_big(t1, t2);
      } else {
	return FALSE;
      }
    }
#endif
  } else {
    return FALSE;
  }
}
Exemple #2
0
static Int a_cmp(Term t1, Term t2 USES_REGS) {
  if (IsVarTerm(t1)) {
    Yap_ArithError(INSTANTIATION_ERROR, t1,
                   "while doing arithmetic comparison");
  }
  if (IsVarTerm(t2)) {
    Yap_ArithError(INSTANTIATION_ERROR,  t2,
                   "while doing arithmetic comparison");
  }
  if (IsFloatTerm(t1) && IsFloatTerm(t2)) {
    return flt_cmp(FloatOfTerm(t1) - FloatOfTerm(t2));
  }
  if (IsIntegerTerm(t1) && IsIntegerTerm(t2)) {
    return int_cmp(IntegerOfTerm(t1) - IntegerOfTerm(t2));
  }
  t1 = Yap_Eval(t1);
  if (!t1) {
    return FALSE;
  }
  if (IsIntegerTerm(t1)) {
    Int i1 = IntegerOfTerm(t1);
    t2 = Yap_Eval(t2);

    if (IsIntegerTerm(t2)) {
      Int i2 = IntegerOfTerm(t2);
      return int_cmp(i1 - i2);
    } else if (IsFloatTerm(t2)) {
      Float f2 = FloatOfTerm(t2);
#if HAVE_ISNAN
      if (isnan(f2)) {
        Yap_ArithError(EVALUATION_ERROR_UNDEFINED, t2,
                       "trying to evaluate nan");
      }
#endif
      return flt_cmp(i1 - f2);
#ifdef USE_GMP
    } else if (IsBigIntTerm(t2)) {
      return Yap_gmp_cmp_int_big(i1, t2);
#endif
    } else {
      return FALSE;
    }
  } else if (IsFloatTerm(t1)) {
    Float f1 = FloatOfTerm(t1);
#if HAVE_ISNAN
    if (isnan(f1)) {
      Yap_ArithError(EVALUATION_ERROR_UNDEFINED, t1,
                     "trying to evaluate nan");
    }
#endif
    t2 = Yap_Eval(t2);
#if HAVE_ISNAN
    if (isnan(f1))
      return -1;
#endif

    if (IsIntegerTerm(t2)) {
      Int i2 = IntegerOfTerm(t2);
      return flt_cmp(f1 - i2);
    } else if (IsFloatTerm(t2)) {
      Float f2 = FloatOfTerm(t2);
#if HAVE_ISNAN
      if (isnan(f2)) {
        Yap_ArithError(EVALUATION_ERROR_UNDEFINED, t2,
                       "trying to evaluate nan");
      }
#endif
      return flt_cmp(f1 - f2);
#ifdef USE_GMP
    } else if (IsBigIntTerm(t2)) {
      return Yap_gmp_cmp_float_big(f1, t2);
#endif
    } else {
      return FALSE;
    }
#ifdef USE_GMP
  } else if (IsBigIntTerm(t1)) {
    {
      t2 = Yap_Eval(t2);

      if (IsIntegerTerm(t2)) {
        return Yap_gmp_cmp_big_int(t1, IntegerOfTerm(t2));
      } else if (IsFloatTerm(t2)) {
        Float f2 = FloatOfTerm(t2);
#if HAVE_ISNAN
        if (isnan(f2)) {
          Yap_ArithError(EVALUATION_ERROR_UNDEFINED, t2,
                         "trying to evaluate nan");
        }
#endif
        return Yap_gmp_cmp_big_float(t1, f2);
      } else if (IsBigIntTerm(t2)) {
        return Yap_gmp_cmp_big_big(t1, t2);
      } else {
        return FALSE;
      }
    }
#endif
  } else {
    return FALSE;
  }
}
Exemple #3
0
/*
 * NAME:	optimize->binconst()
 * DESCRIPTION:	optimize a binary operator constant expression
 */
static Uint opt_binconst(node **m)
{
    node *n;
    xfloat f1, f2;
    bool flag;

    n = *m;
    if (n->l.left->type != n->r.right->type) {
	if (n->type == N_EQ) {
	    node_toint(n, (Int) FALSE);
	} else if (n->type == N_NE) {
	    node_toint(n, (Int) TRUE);
	} else {
	    return 2;	/* runtime error expected */
	}
	return 1;
    }

    switch (n->l.left->type) {
    case N_INT:
	switch (n->type) {
	case N_ADD_INT:
	    n->l.left->l.number += n->r.right->l.number;
	    break;

	case N_AND_INT:
	    n->l.left->l.number &= n->r.right->l.number;
	    break;

	case N_DIV_INT:
	    if (n->r.right->l.number == 0) {
		return 2;	/* runtime error: division by 0 */
	    }
	    n->l.left->l.number /= n->r.right->l.number;
	    break;

	case N_EQ_INT:
	    n->l.left->l.number = (n->l.left->l.number == n->r.right->l.number);
	    break;

	case N_GE_INT:
	    n->l.left->l.number = (n->l.left->l.number >= n->r.right->l.number);
	    break;

	case N_GT_INT:
	    n->l.left->l.number = (n->l.left->l.number > n->r.right->l.number);
	    break;

	case N_LE_INT:
	    n->l.left->l.number = (n->l.left->l.number <= n->r.right->l.number);
	    break;

	case N_LSHIFT_INT:
	    n->l.left->l.number <<= n->r.right->l.number;
	    break;

	case N_LT_INT:
	    n->l.left->l.number = (n->l.left->l.number < n->r.right->l.number);
	    break;

	case N_MOD_INT:
	    if (n->r.right->l.number == 0) {
		return 2;	/* runtime error: % 0 */
	    }
	    n->l.left->l.number %= n->r.right->l.number;
	    break;

	case N_MULT_INT:
	    n->l.left->l.number *= n->r.right->l.number;
	    break;

	case N_NE_INT:
	    n->l.left->l.number = (n->l.left->l.number != n->r.right->l.number);
	    break;

	case N_OR_INT:
	    n->l.left->l.number |= n->r.right->l.number;
	    break;

	case N_RSHIFT_INT:
	    n->l.left->l.number >>= n->r.right->l.number;
	    break;

	case N_SUB_INT:
	    n->l.left->l.number -= n->r.right->l.number;
	    break;

	case N_XOR_INT:
	    n->l.left->l.number ^= n->r.right->l.number;
	    break;

	default:
	    return 2;	/* runtime error expected */
	}

	*m = n->l.left;
	(*m)->line = n->line;
	return 1;

    case N_FLOAT:
	NFLT_GET(n->l.left, f1);
	NFLT_GET(n->r.right, f2);

	switch (n->type) {
	case N_ADD:
	    flt_add(&f1, &f2);
	    break;

	case N_DIV:
	    if (NFLT_ISZERO(n->r.right)) {
		return 2;	/* runtime error: division by 0.0 */
	    }
	    flt_div(&f1, &f2);
	    break;

	case N_EQ:
	    node_toint(n->l.left, (Int) (flt_cmp(&f1, &f2) == 0));
	    break;

	case N_GE:
	    node_toint(n->l.left, (Int) (flt_cmp(&f1, &f2) >= 0));
	    break;

	case N_GT:
	    node_toint(n->l.left, (Int) (flt_cmp(&f1, &f2) > 0));
	    break;

	case N_LE:
	    node_toint(n->l.left, (Int) (flt_cmp(&f1, &f2) <= 0));
	    break;

	case N_LT:
	    node_toint(n->l.left, (Int) (flt_cmp(&f1, &f2) < 0));
	    break;

	case N_MULT:
	    flt_mult(&f1, &f2);
	    break;

	case N_NE:
	    node_toint(n->l.left, (Int) (flt_cmp(&f1, &f2) != 0));
	    break;

	case N_SUB:
	    flt_sub(&f1, &f2);
	    break;

	default:
	    return 2;	/* runtime error expected */
	}

	NFLT_PUT(n->l.left, f1);
	*m = n->l.left;
	(*m)->line = n->line;
	return 1;

    case N_STR:
	switch (n->type) {
	case N_ADD:
	    node_tostr(n, str_add(n->l.left->l.string, n->r.right->l.string));
	    return 1;

	case N_EQ:
	    flag = (str_cmp(n->l.left->l.string, n->r.right->l.string) == 0);
	    break;

	case N_GE:
	    flag = (str_cmp(n->l.left->l.string, n->r.right->l.string) >= 0);
	    break;

	case N_GT:
	    flag = (str_cmp(n->l.left->l.string, n->r.right->l.string) > 0);
	    break;

	case N_LE:
	    flag = (str_cmp(n->l.left->l.string, n->r.right->l.string) <= 0);
	    break;

	case N_LT:
	    flag = (str_cmp(n->l.left->l.string, n->r.right->l.string) < 0);
	    break;

	case N_NE:
	    flag = (str_cmp(n->l.left->l.string, n->r.right->l.string) != 0);
	    break;

	default:
	    return 2;	/* runtime error expected */
	}

	node_toint(n, (Int) flag);
	return 1;

    case N_NIL:
	switch (n->type) {
	case N_EQ:
	    flag = TRUE;
	    break;

	case N_NE:
	    flag = FALSE;
	    break;

	default:
	    return 2;	/* runtime error expected */
	}

	node_toint(n, (Int) flag);
	return 1;
    }

    return 2;
}