summaryrefslogtreecommitdiff
path: root/src/modcontext.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/modcontext.cc')
-rw-r--r--src/modcontext.cc74
1 files changed, 62 insertions, 12 deletions
diff --git a/src/modcontext.cc b/src/modcontext.cc
index 3b957fd..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,17 +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) {
- // m.second is NULL if the library wasn't be compiled (error or file-not-found)
- if (m.second &&
- 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);
}
}
@@ -148,17 +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) {
- // m.second is NULL if the library wasn't be compiled (error or file-not-found)
- if (m.second &&
- 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);
}
}
contact: Jan Huwald // Impressum