summaryrefslogtreecommitdiff
path: root/src/core/parser/Scope.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/parser/Scope.cpp')
-rw-r--r--src/core/parser/Scope.cpp188
1 files changed, 0 insertions, 188 deletions
diff --git a/src/core/parser/Scope.cpp b/src/core/parser/Scope.cpp
deleted file mode 100644
index 01292df..0000000
--- a/src/core/parser/Scope.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- Ousía
- Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <core/common/Utils.hpp>
-
-#include "Scope.hpp"
-
-namespace ousia {
-namespace parser {
-
-/* Class GuardedScope */
-
-GuardedScope::GuardedScope(Scope *scope, Handle<Node> node) : scope(scope)
-{
- scope->push(node);
-}
-
-GuardedScope::~GuardedScope()
-{
- if (scope) {
- scope->pop();
- }
-}
-
-GuardedScope::GuardedScope(GuardedScope &&s)
-{
- scope = s.scope;
- s.scope = nullptr;
-}
-
-/* Class ScopeBase */
-
-Rooted<Node> ScopeBase::resolve(const std::vector<std::string> &path,
- const Rtti &type, Logger &logger)
-{
- // Go up the stack and try to resolve the
- for (auto it = nodes.rbegin(); it != nodes.rend(); it++) {
- std::vector<ResolutionResult> res = (*it)->resolve(path, type);
-
- // Abort if the object could not be resolved
- if (res.empty()) {
- continue;
- }
-
- // Log an error if the object is not unique
- if (res.size() > 1) {
- logger.error(std::string("The reference \"") +
- Utils::join(path, ".") + ("\" is ambigous!"));
- logger.note("Referenced objects are:");
- for (const ResolutionResult &r : res) {
- logger.note(Utils::join(r.path(), "."));
- }
- }
- return res[0].node;
- }
- return nullptr;
-}
-
-/* Class DeferredResolution */
-
-DeferredResolution::DeferredResolution(const NodeVector<Node> &nodes,
- const std::vector<std::string> &path,
- const Rtti &type,
- ResolutionResultCallback resultCallback,
- const SourceLocation &location)
- : scope(nodes),
- resultCallback(resultCallback),
- path(path),
- type(type),
- location(location)
-{
-}
-
-bool DeferredResolution::resolve(Logger &logger)
-{
- Rooted<Node> res = scope.resolve(path, type, logger);
- if (res != nullptr) {
- try {
- resultCallback(res, logger);
- }
- catch (LoggableException ex) {
- logger.log(ex);
- }
- return true;
- }
- return false;
-}
-
-/* Class Scope */
-
-void Scope::push(Handle<Node> node) { nodes.push_back(node); }
-
-void Scope::pop() { nodes.pop_back(); }
-
-GuardedScope Scope::descend(Handle<Node> node)
-{
- return GuardedScope{this, node};
-}
-
-Rooted<Node> Scope::getRoot() const { return nodes.front(); }
-
-Rooted<Node> Scope::getLeaf() { return nodes.back(); }
-
-bool Scope::resolve(const std::vector<std::string> &path, const Rtti &type,
- Logger &logger, ResolutionImposterCallback imposterCallback,
- ResolutionResultCallback resultCallback,
- const SourceLocation &location)
-{
- if (!resolve(path, type, logger, resultCallback, location)) {
- resultCallback(imposterCallback(), logger);
- return false;
- }
- return true;
-}
-
-bool Scope::resolve(const std::vector<std::string> &path, const Rtti &type,
- Logger &logger, ResolutionResultCallback resultCallback,
- const SourceLocation &location)
-{
- Rooted<Node> res = ScopeBase::resolve(path, type, logger);
- if (res != nullptr) {
- try {
- resultCallback(res, logger);
- }
- catch (LoggableException ex) {
- logger.log(ex, location);
- }
- return true;
- }
- deferred.emplace_back(nodes, path, type, resultCallback, location);
- return false;
-}
-
-bool Scope::performDeferredResolution(Logger &logger)
-{
- // Repeat the resolution process as long as something has changed in the
- // last iteration (resolving a node may cause other nodes to be resolvable).
- while (true) {
- // Iterate over all deferred resolution processes,
- bool hasChange = false;
- for (auto it = deferred.begin(); it != deferred.end();) {
- if (it->resolve(logger)) {
- it = deferred.erase(it);
- hasChange = true;
- } else {
- it++;
- }
- }
-
- // Abort if nothing has changed in the last iteration
- if (!hasChange) {
- break;
- }
- }
-
- // We were successful if there are no more deferred resolutions
- if (deferred.empty()) {
- return true;
- }
-
- // Output error messages for all elements for which resolution did not
- // succeed.
- for (const auto &failed : deferred) {
- logger.error(std::string("Could not resolve ") + failed.type.name + std::string(" \"") +
- Utils::join(failed.path, ".") +
- std::string("\""),
- failed.location);
- }
- deferred.clear();
- return false;
-}
-}
-}