#include "ActionExpression.h" #include "ExpressionParser.h" #include "TypeDefinition.h" #include "actions/expression/nodes/AbstractExpression.h" namespace actions { namespace expression { namespace { SCP_string getTypeName(ValueType type) { const auto& typeDef = TypeDefinition::forValueType(type); return typeDef.getName(); } } // namespace ActionExpression ActionExpression::parseFromTable(ValueType expectedReturnType, const ParseContext& context) { SCP_string expressionText; stuff_string(expressionText, F_NAME); ExpressionParser parser(std::move(expressionText)); auto expression = parser.parse(context); if (!expression) { error_display(0, "Failed to parse action expression:\n%s", parser.getErrorText().c_str()); return ActionExpression(); } auto type = expression->getExpressionType(); // Check if the type this evaluates to matches what we expect if (!checkTypeWithImplicitConversion(type, expectedReturnType)) { error_display(0, "Expression evaluates to type <%s> but <%s> was expected!", getTypeName(type).c_str(), getTypeName(expectedReturnType).c_str()); return ActionExpression(); } // Everything is valid return ActionExpression(std::move(expression)); } Value ActionExpression::execute(const ProgramVariables& variables) const { // Do not crash on invalid expressions if (!isValid()) { return Value(); } return m_expression->execute(variables); } bool ActionExpression::isValid() const { return m_expression != nullptr; } } // namespace expression } // namespace actions