diff options
Diffstat (limited to 'src/modcontext.cc')
-rw-r--r-- | src/modcontext.cc | 177 |
1 files changed, 107 insertions, 70 deletions
diff --git a/src/modcontext.cc b/src/modcontext.cc index 7d123b8..44c2002 100644 --- a/src/modcontext.cc +++ b/src/modcontext.cc @@ -7,46 +7,24 @@ #include <boost/foreach.hpp> -ModuleContext::ModuleContext(const class Module *module, const Context *parent, const EvalContext *evalctx) - : Context(parent) +ModuleContext::ModuleContext(const Context *parent, const EvalContext *evalctx) + : Context(parent), functions_p(NULL), modules_p(NULL), evalctx(evalctx) { - if (module) { - setModule(*module, evalctx); - } - else { - this->functions_p = NULL; - this->modules_p = NULL; - this->usedlibs_p = NULL; - } } ModuleContext::~ModuleContext() { } -void ModuleContext::setModule(const Module &module, const EvalContext *evalctx) +void ModuleContext::initializeModule(const class Module &module) { this->setVariables(module.definition_arguments, evalctx); - this->evalctx = evalctx; - // FIXME: Don't access module members directly - this->functions_p = &module.functions; - this->modules_p = &module.modules; - this->usedlibs_p = &module.usedlibs; - BOOST_FOREACH(const std::string &var, module.assignments_var) { - this->set_variable(var, module.assignments.at(var)->evaluate(this)); + this->functions_p = &module.scope.functions; + this->modules_p = &module.scope.modules; + BOOST_FOREACH(const Assignment &ass, module.scope.assignments) { + this->set_variable(ass.first, ass.second->evaluate(this)); } - - if (!module.modulePath().empty()) this->document_path = module.modulePath(); -} - -/*! - Only used to initialize builtins for the top-level root context -*/ -void ModuleContext::registerBuiltin() -{ - this->setModule(Builtins::instance()->getRootModule()); - this->set_constant("PI",Value(M_PI)); } class RecursionGuard @@ -62,61 +40,65 @@ private: const std::string &name; }; -Value ModuleContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const + +/*! + Only used to initialize builtins for the top-level root context +*/ +void ModuleContext::registerBuiltin() { - RecursionGuard g(*this, name); - if (g.recursion_detected()) { - PRINTB("Recursion detected calling function '%s'", name); - return Value(); + const LocalScope &scope = Builtins::instance()->getGlobalScope(); + + // FIXME: Don't access module members directly + this->functions_p = &scope.functions; + this->modules_p = &scope.modules; + BOOST_FOREACH(const Assignment &ass, scope.assignments) { + this->set_variable(ass.first, ass.second->evaluate(this)); } + this->set_constant("PI",Value(M_PI)); +} + +const AbstractFunction *ModuleContext::findLocalFunction(const std::string &name) const +{ if (this->functions_p && this->functions_p->find(name) != this->functions_p->end()) { - return this->functions_p->find(name)->second->evaluate(this, evalctx); - } - - if (this->usedlibs_p) { - BOOST_FOREACH(const ModuleContainer::value_type &m, *this->usedlibs_p) { - if (m.second->functions.find(name) != m.second->functions.end()) { - ModuleContext ctx(m.second, this->parent); - // FIXME: Set document path -#if 0 && DEBUG - PRINTB("New lib Context for %s func:", name); - ctx.dump(NULL, NULL); -#endif - return m.second->functions[name]->evaluate(&ctx, evalctx); - } - } + return this->functions_p->find(name)->second; } - return Context::evaluate_function(name, evalctx); + return NULL; } -AbstractNode *ModuleContext::evaluate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const +const AbstractModule *ModuleContext::findLocalModule(const std::string &name) const { - if (this->modules_p && this->modules_p->find(inst.name()) != this->modules_p->end()) { - AbstractModule *m = this->modules_p->find(inst.name())->second; - std::string replacement = Builtins::instance()->isDeprecated(inst.name()); + if (this->modules_p && this->modules_p->find(name) != this->modules_p->end()) { + AbstractModule *m = this->modules_p->find(name)->second; + std::string replacement = Builtins::instance()->isDeprecated(name); if (!replacement.empty()) { - PRINTB("DEPRECATED: The %s() module will be removed in future releases. Use %s() instead.", inst.name() % replacement); + PRINTB("DEPRECATED: The %s() module will be removed in future releases. Use %s() instead.", name % replacement); } - return m->evaluate(this, &inst, evalctx); + return m; } + return NULL; +} - if (this->usedlibs_p) { - BOOST_FOREACH(const ModuleContainer::value_type &m, *this->usedlibs_p) { - assert(m.second); - if (m.second->modules.find(inst.name()) != m.second->modules.end()) { - ModuleContext ctx(m.second, this->parent); - // FIXME: Set document path -#if 0 && DEBUG - PRINT("New lib Context:"); - ctx.dump(NULL, &inst); -#endif - return m.second->modules[inst.name()]->evaluate(&ctx, &inst, evalctx); - } - } +Value ModuleContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const +{ + RecursionGuard g(*this, name); + if (g.recursion_detected()) { + PRINTB("Recursion detected calling function '%s'", name); + return Value(); } - return Context::evaluate_module(inst, evalctx); + const AbstractFunction *foundf = findLocalFunction(name); + if (foundf) return foundf->evaluate(this, evalctx); + + return Context::evaluate_function(name, evalctx); +} + +AbstractNode *ModuleContext::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const +{ + const AbstractModule *foundm = this->findLocalModule(inst.name()); + if (foundm) return foundm->instantiate(this, &inst, evalctx); + + return Context::instantiate_module(inst, evalctx); } #ifdef DEBUG @@ -150,3 +132,58 @@ void ModuleContext::dump(const AbstractModule *mod, const ModuleInstantiation *i } #endif + +FileContext::FileContext(const class FileModule &module, const Context *parent) + : usedlibs(module.usedlibs), ModuleContext(parent) +{ + if (!module.modulePath().empty()) this->document_path = module.modulePath(); +} + +Value FileContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const +{ + RecursionGuard g(*this, name); + if (g.recursion_detected()) { + PRINTB("Recursion detected calling function '%s'", name); + return Value(); + } + + const AbstractFunction *foundf = findLocalFunction(name); + 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); + // 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 ModuleContext::evaluate_function(name, evalctx); +} + +AbstractNode *FileContext::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const +{ + const AbstractModule *foundm = this->findLocalModule(inst.name()); + 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); + // 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 ModuleContext::instantiate_module(inst, evalctx); +} |