diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-30 14:42:06 +0100 |
---|---|---|
committer | Andreas Stöckel <andreas@somweyr.de> | 2015-01-30 14:42:06 +0100 |
commit | 729ea17ed17cf81eb19847216406e40686df679d (patch) | |
tree | 8636b0f3f39887f64047ee19f3d823dfbcf31426 /src/core/parser/ParserScope.cpp | |
parent | 0ba26c258b9c834894de34e7e14a9fdc774988a5 (diff) |
Finished implementing constant importing
Diffstat (limited to 'src/core/parser/ParserScope.cpp')
-rw-r--r-- | src/core/parser/ParserScope.cpp | 135 |
1 files changed, 52 insertions, 83 deletions
diff --git a/src/core/parser/ParserScope.cpp b/src/core/parser/ParserScope.cpp index c7a9f2a..efd07d1 100644 --- a/src/core/parser/ParserScope.cpp +++ b/src/core/parser/ParserScope.cpp @@ -18,6 +18,7 @@ #include <core/common/Exceptions.hpp> #include <core/common/Utils.hpp> +#include <core/common/VariantWriter.hpp> #include <core/model/Typesystem.hpp> #include "ParserScope.hpp" @@ -319,6 +320,44 @@ bool ParserScope::resolveType(const std::string &name, Handle<Node> owner, return resolveType(Utils::split(name, '.'), owner, logger, resultCallback); } +bool ParserScope::resolveValue(Variant &data, Handle<Type> type, + Handle<Node> owner, Logger &logger) +{ + return type->build( + data, logger, + [&](Variant &innerData, + const Type *innerType) mutable -> Type::MagicCallbackResult { + // Try to resolve the node + Rooted<Constant> constant = + ParserScopeBase::resolve(RttiTypes::Constant, + Utils::split(innerData.asMagic(), '.'), + logger).cast<Constant>(); + + // Abort if nothing was found + if (constant == nullptr) { + return Type::MagicCallbackResult::NOT_FOUND; + } + + // Set the data to the value of the constant + innerData = constant->getValue(); + + // Check whether the inner type of the constant is correct + // TODO: Use correct "isa" provided by Type + Rooted<Type> constantType = constant->getType(); + if (innerType != constantType) { + logger.error(std::string("Expected value of type \"") + + innerType->getName() + + std::string("\" but found constant \"") + + constant->getName() + + std::string("\" of type \"") + + constantType->getName() + "\" instead.", + *owner); + return Type::MagicCallbackResult::FOUND_INVALID; + } + return Type::MagicCallbackResult::FOUND_VALID; + }); +} + bool ParserScope::resolveTypeWithValue(const std::vector<std::string> &path, Handle<Node> owner, Variant &value, Logger &logger, @@ -326,90 +365,20 @@ bool ParserScope::resolveTypeWithValue(const std::vector<std::string> &path, { // Fork the parser scope -- constants need to be resolved in the same // context as this resolve call - std::shared_ptr<ParserScope> scope = std::make_shared<ParserScope>(fork()); - - return resolveType( - path, owner, logger, - [=](Handle<Node> resolved, Handle<Node> owner, Logger &logger) mutable { - // Abort if the lookup failed - if (resolved == nullptr) { - resultCallback(resolved, owner, logger); - return; - } - - // Fetch the type reference and the manager reference - Rooted<Type> type = resolved.cast<Type>(); - Manager *mgr = &type->getManager(); - - // The type has been resolved, try to resolve magic values as - // constants and postpone calling the callback function until - // all magic values have been resolved - std::shared_ptr<bool> isAsync = std::make_shared<bool>(false); - std::shared_ptr<int> magicCount = std::make_shared<int>(0); - type->build(value, logger, [=](Variant &magicValue, bool isValid, - ManagedUid innerTypeUid) mutable { - // Fetch the inner type - Rooted<Type> innerType = - dynamic_cast<Type *>(mgr->getManaged(innerTypeUid)); - if (innerType == nullptr) { - return; - } - - // Fetch a pointer at the variant - Variant *magicValuePtr = &magicValue; - - // Increment the number of encountered magic values - (*magicCount)++; - - // Try to resolve the value as constant - std::string constantName = magicValue.asMagic(); - scope->resolve<Constant>(constantName, owner, logger, - [=](Handle<Node> resolved, - Handle<Node> owner, - Logger &logger) mutable { - if (resolved != nullptr) { - // Make sure the constant is of the correct inner type - Rooted<Constant> constant = resolved.cast<Constant>(); - Rooted<Type> constantType = constant->getType(); - if (constantType != innerType) { - logger.error( - std::string("Expected value of type \"") + - innerType->getName() + - std::string("\" but found constant \"") + - constant->getName() + - std::string(" of type \"") + - constantType->getName() + "\" instead.", - *owner); - } else if (!isValid) { - logger.error("Identifier \"" + constantName + - "\" is not a valid " + - innerType->getName(), - *owner); - } - - // Nevertheless, no matter what happened, set the value - // of the original magic variant to the given constant - *magicValuePtr = constant->getValue(); - } - - // Decrement the number of magic values, call the callback - // function if all magic values have been resolved - (*magicCount)--; - if ((*magicCount) == 0 && (*isAsync)) { - resultCallback(resolved, owner, logger); - } - }); - }); - - // Now we are asynchronous - (*isAsync) = true; + ParserScope scope = fork(); + Variant *valuePtr = &value; + + return resolveType(path, owner, logger, + [=](Handle<Node> resolved, Handle<Node> owner, + Logger &logger) mutable { + if (resolved != nullptr) { + Rooted<Type> type = resolved.cast<Type>(); + scope.resolveValue(*valuePtr, type, owner, logger); + } - // Directly call the callback function if there were no magic values - // involved - if ((*magicCount) == 0) { - resultCallback(resolved, owner, logger); - } - }); + // Call the result callback with the type + resultCallback(resolved, owner, logger); + }); } bool ParserScope::resolveTypeWithValue(const std::string &name, |