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() + "."); }
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() + "."); }