Move redefinition checking to SemanticAnalysis.hpp
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
This commit is contained in:
parent
7fb9ca37a7
commit
2c0cec16d6
|
@ -4,7 +4,13 @@
|
|||
#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) {
|
||||
|
@ -15,9 +21,25 @@ struct SemanticAnalyser final: public Tasking {
|
|||
return tree;
|
||||
}
|
||||
private:
|
||||
unordered_task_map getTaskMapInstance() final {
|
||||
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),
|
||||
make_nonlocal_task(Define,
|
||||
const optional previousDefinition = parsedTree.findReferenceByName<Define>(parseComponent.name).value();
|
||||
if (&previousDefinition.value().get() != &parseComponent && (previousDefinition.value().get().final || parseComponent.final))
|
||||
error(parseComponent.name + string(previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared"));
|
||||
)
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define make_task(T, F) make_task_base_R(T, this, F)
|
||||
#define make_task_noR(T, F) make_task_base(,T, this, F)
|
||||
#define make_nonlocal_task(T, F) make_task_base_R(T, , F)
|
||||
#define share_task(T, T2) make_task_noR(T2, this->getTaskMapInstance()[typeid(T)](parsedTree, index);)
|
||||
|
||||
class Tasking {
|
||||
protected:
|
||||
|
|
|
@ -134,13 +134,9 @@ namespace Parser {
|
|||
i += 2;
|
||||
break;
|
||||
} else i -= parametersDistance;
|
||||
|
||||
// TODO Move this to semantic analysis
|
||||
|
||||
bool isFinalDefine = nextAre({TAG, DEFINE});
|
||||
if (isFinalDefine || next.toktype == DEFINE) {
|
||||
const optional previousDefinition = parseTree.template findReferenceByName<Define>(current.toktext);
|
||||
if (previousDefinition.has_value() && (previousDefinition.value().get().final || isFinalDefine))
|
||||
parsingError(current, previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared", true);
|
||||
const unsigned increment = 2 + isFinalDefine;
|
||||
const auto beginning = lexed.begin() + i + increment;
|
||||
const auto end = find_if(beginning, lexed.end(), [¤t](const tok& it){
|
||||
|
@ -184,23 +180,6 @@ namespace Parser {
|
|||
} catch (const NamedIdentifier<true>::identifier_reserved_exception&) {
|
||||
parsingError(current, " is a reserved identifier", true);
|
||||
}
|
||||
// TODO Move this to semantic analysis
|
||||
if (not parseTree.empty()) {
|
||||
const auto& last = parseTree.cend() - 1;
|
||||
const type_info& lastId = last->get()->getId();
|
||||
const auto* last_identifier = dynamic_cast<NamedIdentifier<true>*>(last->get());
|
||||
if (last_identifier != nullptr) {
|
||||
if (lastId != typeid(Define) and
|
||||
any_of(parseTree.cbegin(), last, [&last_identifier](const component_ptr& pointer){
|
||||
try {
|
||||
return dynamic_cast<NamedIdentifier<true>&>(*pointer).name == last_identifier->name;
|
||||
} catch (const bad_cast&) {
|
||||
return false;
|
||||
}
|
||||
}))
|
||||
{ parsingError(current, " has already been defined previously", true); }
|
||||
}
|
||||
}
|
||||
}
|
||||
return parseTree;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue