File: FunctionCallExpression.cpp

package info (click to toggle)
freespace2 24.2.0%2Brepack-3
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,740 kB
  • sloc: cpp: 595,005; ansic: 21,741; python: 1,174; sh: 457; makefile: 243; xml: 181
file content (95 lines) | stat: -rw-r--r-- 2,987 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

#include "FunctionCallExpression.h"

#include "actions/expression/TypeDefinition.h"

namespace actions {
namespace expression {
namespace nodes {

FunctionCallExpression::FunctionCallExpression(antlr4::Token* token,
	bool isOperator,
	SCP_string functionName,
	SCP_vector<std::shared_ptr<AbstractExpression>> parameterExpressions)
	: AbstractExpression(token), m_isOperator(isOperator), m_functionName(std::move(functionName)),
	  m_parameterExpressions(std::move(parameterExpressions))
{
}
FunctionCallExpression::~FunctionCallExpression() = default;

Value FunctionCallExpression::execute(const ProgramVariables& variables) const
{
	SCP_vector<Value> parameterValues;
	parameterValues.reserve(m_parameterExpressions.size());

	std::transform(m_parameterExpressions.cbegin(),
		m_parameterExpressions.cend(),
		std::back_inserter(parameterValues),
		[&variables](const std::shared_ptr<AbstractExpression>& expression) { return expression->execute(variables); });

	return m_functionDef->implementation(parameterValues);
}
bool FunctionCallExpression::validate(antlr4::Parser* parser, const ParseContext& context)
{
	bool valid = true;

	for (const auto& paramExpression : m_parameterExpressions) {
		valid &= paramExpression->validate(parser, context);
	}

	if (!valid) {
		// Exit early if there were errors since the values below are meaningless otherwise
		return false;
	}

	Assertion(m_isOperator, "Non-operator functions are not supported yet!");

	SCP_vector<ValueType> parameterTypes;

	std::transform(m_parameterExpressions.cbegin(),
		m_parameterExpressions.cend(),
		std::back_inserter(parameterTypes),
		[](const std::shared_ptr<AbstractExpression>& expression) { return expression->getExpressionType(); });

	const auto functionDef = FunctionManager::instance().findOperator(m_functionName, parameterTypes);

	if (functionDef == nullptr) {
		SCP_stringstream paramListStream;
		if (!parameterTypes.empty()) {
			paramListStream << "<" << TypeDefinition::forValueType(parameterTypes.front()).getName() << ">";

			for (auto iter = parameterTypes.cbegin() + 1; iter != parameterTypes.cend(); ++iter) {
				paramListStream << ", <" << TypeDefinition::forValueType(*iter).getName() << ">";
			}
		}

		parser->notifyErrorListeners(m_token,
			SCP_string("Could not find a definition for the ") + (m_isOperator ? "operator" : "function") + " '" +
				m_functionName + "' with parameters (" + paramListStream.str() + ")",
			nullptr);
		return false;
	}

	m_functionDef = functionDef;
	return true;
}
ValueType FunctionCallExpression::determineReturnType() const
{
	return m_functionDef->returnType;
}
void FunctionCallExpression::validationDone()
{
	AbstractExpression::validationDone();

	// We no longer need this so we can save some memory
	m_functionName.clear();
	m_functionName.shrink_to_fit();

	for (const auto& paramExpression : m_parameterExpressions) {
		paramExpression->validationDone();
	}
}

} // namespace nodes
} // namespace expression
} // namespace actions