fix evaluation not resolving correctly due to being unfinished

This commit is contained in:
Jan 2021-02-19 17:02:49 +01:00
parent 7c51c26255
commit 524e188db1
3 changed files with 81 additions and 6 deletions

View File

@ -300,7 +300,7 @@ std::unique_ptr<IEvaluation> CommandsCommonMatchers::ProcessEvaluation(CommandsP
if (currentType == state->GetInUse()) if (currentType == state->GetInUse())
currentType = nullptr; currentType = nullptr;
std::list<std::unique_ptr<IEvaluation>> operands; std::vector<std::unique_ptr<IEvaluation>> operands;
std::list<std::pair<unsigned, const OperationType*>> operators; std::list<std::pair<unsigned, const OperationType*>> operators;
while (true) while (true)
@ -333,13 +333,28 @@ std::unique_ptr<IEvaluation> CommandsCommonMatchers::ProcessEvaluation(CommandsP
operators.sort([](const std::pair<unsigned, const OperationType*>& p1, const std::pair<unsigned, const OperationType*>& p2) operators.sort([](const std::pair<unsigned, const OperationType*>& p1, const std::pair<unsigned, const OperationType*>& p2)
{ {
return p1.second->m_precedence > p2.second->m_precedence; if(p1.second->m_precedence != p2.second->m_precedence)
return p1.second->m_precedence > p2.second->m_precedence;
return p1.first > p2.first;
}); });
while (!operators.empty()) while (!operators.empty())
{ {
const auto [operatorIndex, operatorType] = operators.back();
auto operation = std::make_unique<Operation>(operatorType, std::move(operands[operatorIndex]), std::move(operands[operatorIndex + 1]));
operands.erase(operands.begin() + operatorIndex);
operands[operatorIndex] = std::move(operation);
operators.pop_back(); operators.pop_back();
for(auto& [opIndex, _] : operators)
{
if (opIndex > operatorIndex)
opIndex--;
}
} }
return nullptr; return std::move(operands.front());
} }

View File

@ -1,5 +1,7 @@
#include "SequenceArraySize.h" #include "SequenceArraySize.h"
#include "Domain/Definition/ArrayDeclarationModifier.h"
#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h" #include "Parsing/Commands/Matcher/CommandsMatcherFactory.h"
#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h" #include "Parsing/Commands/Matcher/CommandsCommonMatchers.h"
@ -20,4 +22,31 @@ SequenceArraySize::SequenceArraySize()
void SequenceArraySize::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const void SequenceArraySize::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
{ {
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE);
StructureInformation* structure;
std::vector<MemberInformation*> memberChain;
if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), structure, memberChain))
throw ParsingException(typeNameToken.GetPos(), "Unknown type");
if (memberChain.empty())
throw ParsingException(typeNameToken.GetPos(), "Must specify type with member");
const auto& memberDeclarationModifiers = memberChain.back()->m_member->m_type_declaration->m_declaration_modifiers;
ArrayDeclarationModifier* arrayModifier = nullptr;
for (const auto& modifier : memberDeclarationModifiers)
{
if (modifier->GetType() == DeclarationModifierType::ARRAY)
{
arrayModifier = dynamic_cast<ArrayDeclarationModifier*>(modifier.get());
break;
}
}
if (arrayModifier == nullptr)
throw ParsingException(typeNameToken.GetPos(), "Specified member is not an array");
auto evaluation = CommandsCommonMatchers::ProcessEvaluation(state, result, structure);
arrayModifier->m_dynamic_size_evaluation = std::move(evaluation);
} }

View File

@ -1,5 +1,6 @@
#include "SequenceCondition.h" #include "SequenceCondition.h"
#include "Domain/Evaluation/OperandStatic.h"
#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h" #include "Parsing/Commands/Matcher/CommandsMatcherFactory.h"
#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h" #include "Parsing/Commands/Matcher/CommandsCommonMatchers.h"
@ -24,4 +25,34 @@ SequenceCondition::SequenceCondition()
void SequenceCondition::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const void SequenceCondition::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
{ {
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE);
StructureInformation* type;
std::vector<MemberInformation*> memberChain;
if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), type, memberChain))
throw ParsingException(typeNameToken.GetPos(), "Unknown type");
if (memberChain.empty())
throw ParsingException(typeNameToken.GetPos(), "Conditions can only be set on members and not for types");
std::unique_ptr<IEvaluation> conditionEvaluation;
switch(result.NextTag())
{
case TAG_ALWAYS:
conditionEvaluation = std::make_unique<OperandStatic>(1);
break;
case TAG_NEVER:
conditionEvaluation = std::make_unique<OperandStatic>(0);
break;
case TAG_EVALUATION:
conditionEvaluation = CommandsCommonMatchers::ProcessEvaluation(state, result, type);
break;
default:
throw ParsingException(TokenPos(), "Unknown evaluation type @ Condition");
}
memberChain.back()->m_condition = std::move(conditionEvaluation);
} }