diff options
Diffstat (limited to 'src/modcontext.cc')
-rw-r--r-- | src/modcontext.cc | 71 |
1 files changed, 62 insertions, 9 deletions
diff --git a/src/modcontext.cc b/src/modcontext.cc index 3879811..5b48009 100644 --- a/src/modcontext.cc +++ b/src/modcontext.cc @@ -4,6 +4,7 @@ #include "function.h" #include "printutils.h" #include "builtin.h" +#include "ModuleCache.h" #include <boost/foreach.hpp> @@ -16,6 +17,51 @@ ModuleContext::~ModuleContext() { } +// Experimental code. See issue #399 +#if 0 +void ModuleContext::evaluateAssignments(const AssignmentList &assignments) +{ + // First, assign all simple variables + std::list<std::string> undefined_vars; + BOOST_FOREACH(const Assignment &ass, assignments) { + Value tmpval = ass.second->evaluate(this); + if (tmpval.isUndefined()) undefined_vars.push_back(ass.first); + else this->set_variable(ass.first, tmpval); + } + + // Variables which couldn't be evaluated in the first pass is attempted again, + // to allow for initialization out of order + + boost::unordered_map<std::string, Expression *> tmpass; + BOOST_FOREACH (const Assignment &ass, assignments) { + tmpass[ass.first] = ass.second; + } + + bool changed = true; + while (changed) { + changed = false; + std::list<std::string>::iterator iter = undefined_vars.begin(); + while (iter != undefined_vars.end()) { + std::list<std::string>::iterator curr = iter++; + boost::unordered_map<std::string, Expression *>::iterator found = tmpass.find(*curr); + if (found != tmpass.end()) { + const Expression *expr = found->second; + Value tmpval = expr->evaluate(this); + // FIXME: it's not enough to check for undefined; + // we need to check for any undefined variable in the subexpression + // For now, ignore this and revisit the validity and order of variable + // assignments later + if (!tmpval.isUndefined()) { + changed = true; + this->set_variable(*curr, tmpval); + undefined_vars.erase(curr); + } + } + } + } +} +#endif + void ModuleContext::initializeModule(const class Module &module) { this->setVariables(module.definition_arguments, evalctx); @@ -25,6 +71,8 @@ void ModuleContext::initializeModule(const class Module &module) BOOST_FOREACH(const Assignment &ass, module.scope.assignments) { this->set_variable(ass.first, ass.second->evaluate(this)); } +// Experimental code. See issue #399 +// evaluateAssignments(module.scope.assignments); } /*! @@ -125,15 +173,18 @@ Value FileContext::evaluate_function(const std::string &name, const EvalContext if (foundf) return foundf->evaluate(this, evalctx); BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) { - if (m.second->scope.functions.find(name) != m.second->scope.functions.end()) { - FileContext ctx(*m.second, this->parent); - ctx.initializeModule(*m.second); + // usedmod is NULL if the library wasn't be compiled (error or file-not-found) + FileModule *usedmod = ModuleCache::instance()->lookup(m); + if (usedmod && + usedmod->scope.functions.find(name) != usedmod->scope.functions.end()) { + FileContext ctx(*usedmod, this->parent); + ctx.initializeModule(*usedmod); // FIXME: Set document path #if 0 && DEBUG PRINTB("New lib Context for %s func:", name); ctx.dump(NULL, NULL); #endif - return m.second->scope.functions[name]->evaluate(&ctx, evalctx); + return usedmod->scope.functions[name]->evaluate(&ctx, evalctx); } } @@ -146,16 +197,18 @@ AbstractNode *FileContext::instantiate_module(const ModuleInstantiation &inst, c if (foundm) return foundm->instantiate(this, &inst, evalctx); BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) { - assert(m.second); - if (m.second->scope.modules.find(inst.name()) != m.second->scope.modules.end()) { - FileContext ctx(*m.second, this->parent); - ctx.initializeModule(*m.second); + FileModule *usedmod = ModuleCache::instance()->lookup(m); + // usedmod is NULL if the library wasn't be compiled (error or file-not-found) + if (usedmod && + usedmod->scope.modules.find(inst.name()) != usedmod->scope.modules.end()) { + FileContext ctx(*usedmod, this->parent); + ctx.initializeModule(*usedmod); // FIXME: Set document path #if 0 && DEBUG PRINT("New file Context:"); ctx.dump(NULL, &inst); #endif - return m.second->scope.modules[inst.name()]->instantiate(&ctx, &inst, evalctx); + return usedmod->scope.modules[inst.name()]->instantiate(&ctx, &inst, evalctx); } } |