EvaluationResult At::evaluate(const EvaluationContext& params) const { const EvaluationResult evaluatedIndex = index->evaluate(params); const EvaluationResult evaluatedInput = input->evaluate(params); if (!evaluatedIndex) { return evaluatedIndex.error(); } if (!evaluatedInput) { return evaluatedInput.error(); } const auto i = evaluatedIndex->get<double>(); const auto inputArray = evaluatedInput->get<std::vector<Value>>(); if (i < 0 || i >= inputArray.size()) { return EvaluationError { "Array index out of bounds: " + stringify(i) + " > " + util::toString(inputArray.size()) + "." }; } if (i != std::floor(i)) { return EvaluationError { "Array index must be an integer, but found " + stringify(i) + " instead." }; } return inputArray[static_cast<std::size_t>(i)]; }
template<> EvaluationResult Match<std::string>::evaluate(const EvaluationContext& params) const { const EvaluationResult inputValue = input->evaluate(params); if (!inputValue) { return inputValue.error(); } if (!inputValue->is<std::string>()) { return otherwise->evaluate(params); } auto it = branches.find(inputValue->get<std::string>()); if (it != branches.end()) { return (*it).second->evaluate(params); } return otherwise->evaluate(params); }
template<> EvaluationResult Match<int64_t>::evaluate(const EvaluationContext& params) const { const EvaluationResult inputValue = input->evaluate(params); if (!inputValue) { return inputValue.error(); } if (!inputValue->is<double>()) { return otherwise->evaluate(params); } const auto numeric = inputValue->get<double>(); int64_t rounded = std::floor(numeric); if (numeric == rounded) { auto it = branches.find(rounded); if (it != branches.end()) { return (*it).second->evaluate(params); } } return otherwise->evaluate(params); }