44 lines
1.6 KiB
C++
44 lines
1.6 KiB
C++
#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<NamedIdentifier<true>&>(*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<true>),
|
|
};
|
|
};
|
|
};
|
|
|
|
#endif //YERBACON_SEMANTICANALYSIS_HPP
|