#ifndef YERBACON_SEMANTICANALYSIS_HPP #define YERBACON_SEMANTICANALYSIS_HPP #include "parsing/ParseComponents.hpp" #include "Tasking.hpp" using namespace StandardComponents; struct SemanticAnalyser final: public Tasking { typedef Yerbacon::Exception SemanticException; static void error(const string_view& text, unsigned long line = 0) { throw SemanticException(text, line); } const auto& analyseTree(const ParseTree& tree) { const auto& task_map = getTaskMapInstance(); for (unsigned int i = 0; i < tree.size(); ++i) { try { task_map.at(tree[i]->getId())(tree, i); } catch (const out_of_range&) {} } return tree; } private: unordered_task_map getTaskMapInstance() final { // TODO Include line in error messages using namespace StandardComponents; return { make_nonlocal_task(Reference, if (index > 0 and any_of(parsedTree.cbegin(), parsedTree.cbegin() + index + 1, [&parseComponent](const component_ptr& pointer){ try { return dynamic_cast&>(*pointer).name == parseComponent.name; } catch (const bad_cast&) { return false; } })) { error(parseComponent.name + " has already been defined previously"); } ), share_task(Reference, Function), share_task(Reference, Class), share_task(Reference, Define), }; }; }; #endif //YERBACON_SEMANTICANALYSIS_HPP