File: VariableReferenceExpression.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 (69 lines) | stat: -rw-r--r-- 2,059 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

#include "VariableReferenceExpression.h"

namespace actions {
namespace expression {
namespace nodes {

VariableReferenceExpression::VariableReferenceExpression(SCP_vector<SCP_string> references,
	SCP_vector<antlr4::Token*> referenceTokens)
	: AbstractExpression(referenceTokens.back()), m_references(std::move(references)),
	  m_referenceTokens(std::move(referenceTokens))
{
}
VariableReferenceExpression::~VariableReferenceExpression() = default;

Value VariableReferenceExpression::execute(const ProgramVariables& variables) const
{
	return variables.getValue(m_fullVariablePath);
}
bool VariableReferenceExpression::validate(antlr4::Parser* parser, const ParseContext& context)
{
	// Start out in the global scope
	auto currentScope = &context.variables;
	SCP_string currentScopeName("<global>");

	for (size_t i = 0; i < m_references.size() - 1; ++i) {
		const auto nextScope = currentScope->getScope(m_references[i]);

		if (nextScope == nullptr) {
			parser->notifyErrorListeners(m_referenceTokens[i],
				"Could not find scope " + m_references[i] + " in scope " + currentScopeName + ".",
				nullptr);
			return false;
		}

		currentScope = nextScope;
		currentScopeName = m_references[i];
	}

	auto variableType = currentScope->getMemberType(m_references.back());

	if (variableType == ValueType::Invalid) {
		parser->notifyErrorListeners(m_referenceTokens.back(),
			"Could not find variable " + m_references.back() + " in scope " + currentScopeName + ".",
			nullptr);
		return false;
	}

	// Cache this so we don't duplicate all this code in determineReturnType()
	m_variableType = variableType;
	m_fullVariablePath = ProgramVariables::getMemberName(m_references);
	return true;
}
ValueType VariableReferenceExpression::determineReturnType() const
{
	return m_variableType;
}
void VariableReferenceExpression::validationDone()
{
	AbstractExpression::validationDone();

	// Clear these since they are not necessary anymore
	m_references.clear();
	m_referenceTokens.clear();
}

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