Exemplo n.º 1
0
Co<Expression> ExpressionGreaterOrEqual::evaluate_helper(Co<Expression> l,
                                                         Co<Expression> r,
                                                         const std::string &source,
                                                         const SourceLocation &location,
                                                         Environment &env) {
  Co<Expression> l_value = l->evaluate(env);
  Co<Expression> r_value = r->evaluate(env);

  // Integers
  ExpressionInteger *l_integer = dynamic_cast<ExpressionInteger *>(l_value.GetPointer());
  ExpressionInteger *r_integer = dynamic_cast<ExpressionInteger *>(r_value.GetPointer());
  if (l_integer && r_integer) {
    return Co<Expression>(new ExpressionBoolean(l_integer->toInteger() >= r_integer->toInteger()));
  }

  // Any mix of numbers
  ExpressionNumber *l_number = dynamic_cast<ExpressionNumber *>(l_value.GetPointer());
  ExpressionNumber *r_number = dynamic_cast<ExpressionNumber *>(r_value.GetPointer());
  if (l_number && r_number) {
    return Co<Expression>(new ExpressionBoolean(l_number->toReal() >= r_number->toReal()));
  }

  // Both are arrays
  ExpressionArrayReference *l_array = dynamic_cast<ExpressionArrayReference *>(l_value.GetPointer());
  ExpressionArrayReference *r_array = dynamic_cast<ExpressionArrayReference *>(r_value.GetPointer());
  if (l_array && r_array) {
    int nitems = l_array->getArray()->getSize();
    if (nitems == r_array->getArray()->getSize()) {
      Co<ExpressionArray> array(new ExpressionArray(nitems));
      for (int i = 0; i < nitems; ++i) {
        array->setElement(i, evaluate_helper((*l_array->getArray())[i], (*r_array->getArray())[i], source, location, env));
      }
      return Co<Expression>(new ExpressionArrayReference(array));
    } else {
      throw MessagedException(location.toAnchor() + ": Operator >= doesn't know how to compare arrays of different sizes.");
    }
  } 

  // Left only is an array
  if (l_array) {
    int nitems = l_array->getArray()->getSize();
    Co<ExpressionArray> array(new ExpressionArray(nitems));
    for (int i = 0; i < nitems; ++i) {
      array->setElement(i, evaluate_helper((*l_array->getArray())[i], r_value, source, location, env));
    }
    return Co<Expression>(new ExpressionArrayReference(array));
  }

  // Right only is an array
  if (r_array) {
    int nitems = r_array->getArray()->getSize();
    Co<ExpressionArray> array(new ExpressionArray(nitems));
    for (int i = 0; i < nitems; ++i) {
      array->setElement(i, evaluate_helper(l_value, (*r_array->getArray())[i], source, location, env));
    }
    return Co<Expression>(new ExpressionArrayReference(array));
  }

  throw MessagedException(location.toAnchor() + ": Operator >= doesn't know how to compare " + l->getSource() + " and " + r->getSource() + ".");
}
Exemplo n.º 2
0
Co<Expression> ExpressionLog::evaluate_helper(Co<Expression> base,
                                              Co<Expression> x,
                                              const std::string &source,
                                              const SourceLocation &location,
                                              Environment &env) {
  Co<Expression> base_value = base->evaluate(env);
  Co<Expression> x_value = x->evaluate(env);

  // Any mix of numbers
  ExpressionNumber *base_number = dynamic_cast<ExpressionNumber *>(base_value.GetPointer());
  ExpressionNumber *x_number = dynamic_cast<ExpressionNumber *>(x_value.GetPointer());
  if (base_number && x_number) {
    if (log(base_number->toReal()) != 0.0f) {
      return Co<Expression>(new ExpressionReal(log(x_number->toReal()) / log(base_number->toReal())));
    } else {
      throw MessagedException(base->getSourceLocation().toAnchor() + ": I don't know how to take a log of base " + base->getSource() + ".");
    }
  }

  // Both are arrays
  ExpressionArrayReference *base_array = dynamic_cast<ExpressionArrayReference *>(base_value.GetPointer());
  ExpressionArrayReference *x_array = dynamic_cast<ExpressionArrayReference *>(x_value.GetPointer());
  if (base_array && x_array) {
    int nitems = base_array->getArray()->getSize();
    if (nitems == x_array->getArray()->getSize()) {
      Co<ExpressionArray> array(new ExpressionArray(nitems));
      for (int i = 0; i < nitems; ++i) {
        array->setElement(i, evaluate_helper((*base_array->getArray())[i], (*x_array->getArray())[i], source, location, env));
      }
      return Co<Expression>(new ExpressionArrayReference(array));
    } else {
      throw MessagedException(location.toAnchor() + ": I don't know how to compute the log of arrays of different sizes.");
    }
  } 

  // Left only is an array
  if (base_array && x_number) {
    int nitems = base_array->getArray()->getSize();
    Co<ExpressionArray> array(new ExpressionArray(nitems, ExpressionUnit::getSingleton()));
    for (int i = 0; i < nitems; ++i) {
      array->setElement(i, evaluate_helper((*base_array->getArray())[i], x_value, source, location, env));
    }
    return Co<Expression>(new ExpressionArrayReference(array));
  }

  // Right only is an array
  if (base_number && x_array) {
    int nitems = x_array->getArray()->getSize();
    Co<ExpressionArray> array(new ExpressionArray(nitems, ExpressionUnit::getSingleton()));
    for (int i = 0; i < nitems; ++i) {
      array->setElement(i, evaluate_helper(base_value, (*x_array->getArray())[i], source, location, env));
    }
    return Co<Expression>(new ExpressionArrayReference(array));
  }

  throw MessagedException(location.toAnchor() + ": I don't know to compute the log of " + x->getSource() + " base " + base->getSource() + ".");
}