Select Git revision
DoWhileProcessor.hpp
DoWhileProcessor.hpp 2.13 KiB
#ifndef DO_WHILE_PROCESSOR_HPP
#define DO_WHILE_PROCESSOR_HPP
#include <language/ast/ASTNode.hpp>
#include <language/node_processor/INodeProcessor.hpp>
#include <language/utils/ASTCheckpointsInfo.hpp>
#include <language/utils/SymbolTable.hpp>
#include <utils/checkpointing/Checkpoint.hpp>
#include <utils/checkpointing/ResumingManager.hpp>
class DoWhileProcessor final : public INodeProcessor
{
private:
ASTNode& m_node;
public:
Type
type() const
{
return Type::do_while_processor;
}
DataVariant
execute(ExecutionPolicy& exec_policy)
{
bool continuation_test = true;
ExecutionPolicy exec_until_jump;
ResumingManager& resuming_manager = ResumingManager::getInstance();
do {
if (resuming_manager.isResuming()) {
const size_t checkpoint_id = resuming_manager.checkpointId();
const ASTCheckpointsInfo& ast_checkpoint_info = ASTCheckpointsInfo::getInstance();
const ASTCheckpoint& ast_checkpoint = ast_checkpoint_info.getASTCheckpoint(checkpoint_id);
const size_t i_child = ast_checkpoint.getASTLocation()[resuming_manager.currentASTLevel()++];
Assert(i_child == 0);
};
m_node.children[0]->execute(exec_until_jump);
if (not exec_until_jump.exec()) {
if (exec_until_jump.jumpType() == ExecutionPolicy::JumpType::break_jump) {
break;
} else if (exec_until_jump.jumpType() == ExecutionPolicy::JumpType::continue_jump) {
exec_until_jump = ExecutionPolicy{}; // getting ready for next loop traversal
}
}
;
continuation_test = static_cast<bool>(std::visit(
[](auto&& value) -> bool {
using T = std::decay_t<decltype(value)>;
if constexpr (std::is_arithmetic_v<T>) {
return value;
} else {
return false; // LCOV_EXCL_LINE (unreachable: only there for compilation purpose)
}
},
m_node.children[1]->execute(exec_policy)));
} while (continuation_test);
m_node.children[0]->m_symbol_table->clearValues();
return {};
}
DoWhileProcessor(ASTNode& node) : m_node{node} {}
};
#endif // DO_WHILE_PROCESSOR_HPP