diff options
Diffstat (limited to 'src/core/parser/ParserScope.cpp')
-rw-r--r-- | src/core/parser/ParserScope.cpp | 62 |
1 files changed, 55 insertions, 7 deletions
diff --git a/src/core/parser/ParserScope.cpp b/src/core/parser/ParserScope.cpp index df123df..0e2350f 100644 --- a/src/core/parser/ParserScope.cpp +++ b/src/core/parser/ParserScope.cpp @@ -90,11 +90,14 @@ bool DeferredResolution::resolve(Logger &logger) /* Class ParserScope */ -ParserScope::ParserScope(const NodeVector<Node> &nodes) - : ParserScopeBase(nodes), topLevelDepth(nodes.size()) +ParserScope::ParserScope(const NodeVector<Node> &nodes, + const std::vector<ParserFlagDescriptor> &flags) + : ParserScopeBase(nodes), flags(flags), topLevelDepth(nodes.size()) { } +ParserScope::ParserScope() : topLevelDepth(0) {} + bool ParserScope::checkUnwound(Logger &logger) const { if (nodes.size() != topLevelDepth) { @@ -113,7 +116,7 @@ bool ParserScope::checkUnwound(Logger &logger) const return true; } -ParserScope ParserScope::fork() { return ParserScope{nodes}; } +ParserScope ParserScope::fork() { return ParserScope{nodes, flags}; } bool ParserScope::join(const ParserScope &fork, Logger &logger) { @@ -128,11 +131,10 @@ bool ParserScope::join(const ParserScope &fork, Logger &logger) return true; } -ParserScope::ParserScope() : topLevelDepth(0) {} - void ParserScope::push(Handle<Node> node) { - if (nodes.size() == topLevelDepth) { + const size_t currentDepth = nodes.size(); + if (currentDepth == topLevelDepth) { topLevelNodes.push_back(node); } nodes.push_back(node); @@ -140,9 +142,23 @@ void ParserScope::push(Handle<Node> node) void ParserScope::pop() { - if (nodes.size() == topLevelDepth) { + // Make sure pop is not called without an element on the stack + const size_t currentDepth = nodes.size(); + if (currentDepth == topLevelDepth) { throw LoggableException{"No element here to end!"}; } + + // Remove all flags from the stack that were set for higher stack depths. + size_t newLen = 0; + for (ssize_t i = flags.size() - 1; i >= 0; i--) { + if (flags[i].depth < currentDepth) { + newLen = i + 1; + break; + } + } + flags.resize(newLen); + + // Remove the element from the stack nodes.pop_back(); } @@ -152,6 +168,38 @@ Rooted<Node> ParserScope::getRoot() const { return nodes.front(); } Rooted<Node> ParserScope::getLeaf() const { return nodes.back(); } +void ParserScope::setFlag(ParserFlag flag, bool value) +{ + // Fetch the current stack depth + const size_t currentDepth = nodes.size(); + + // Try to change the value of the flag if it was already set on the same + // stack depth + for (auto it = flags.rbegin(); it != flags.rend(); it++) { + if (it->depth == currentDepth) { + if (it->flag == flag) { + it->value = value; + return; + } + } else { + break; + } + } + + // Insert a new element into the flags list + flags.emplace_back(currentDepth, flag, value); +} + +bool ParserScope::getFlag(ParserFlag flag) +{ + for (auto it = flags.crbegin(); it != flags.crend(); it++) { + if (it->flag == flag) { + return it->value; + } + } + return false; +} + bool ParserScope::resolve(const std::vector<std::string> &path, const Rtti &type, Logger &logger, ResolutionImposterCallback imposterCallback, |