summaryrefslogtreecommitdiff
path: root/src/modcontext.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/modcontext.cc')
-rw-r--r--src/modcontext.cc164
1 files changed, 97 insertions, 67 deletions
diff --git a/src/modcontext.cc b/src/modcontext.cc
index df341f9..44c2002 100644
--- a/src/modcontext.cc
+++ b/src/modcontext.cc
@@ -7,28 +7,18 @@
#include <boost/foreach.hpp>
-ModuleContext::ModuleContext(const class Module *module, const Context *parent, const EvalContext *evalctx)
- : Context(parent), functions_p(NULL), modules_p(NULL), usedlibs_p(NULL)
+ModuleContext::ModuleContext(const Context *parent, const EvalContext *evalctx)
+ : Context(parent), functions_p(NULL), modules_p(NULL), evalctx(evalctx)
{
- if (module) setModule(*module, evalctx);
}
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: Hack - split out file context into separate class?
- const FileModule *fm = dynamic_cast<const FileModule*>(&module);
- if (fm) {
- this->usedlibs_p = &(fm->usedlibs);
- if (!fm->modulePath().empty()) this->document_path = fm->modulePath();
- }
-
// FIXME: Don't access module members directly
this->functions_p = &module.scope.functions;
this->modules_p = &module.scope.modules;
@@ -37,17 +27,6 @@ void ModuleContext::setModule(const Module &module, const EvalContext *evalctx)
}
}
-/*!
- Only used to initialize builtins for the top-level root context
-*/
-void ModuleContext::registerBuiltin()
-{
- // FIXME: built-ins only contains variables, setModule isn't really needed for this
- // FIXME: Where to put set_variable from setModule?
- this->setModule(Builtins::instance()->getRootModule());
- this->set_constant("PI",Value(M_PI));
-}
-
class RecursionGuard
{
public:
@@ -61,60 +40,64 @@ 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);
+ return this->functions_p->find(name)->second;
}
-
- if (this->usedlibs_p) {
- BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, *this->usedlibs_p) {
- if (m.second->scope.functions.find(name) != m.second->scope.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->scope.functions[name]->evaluate(&ctx, evalctx);
- }
- }
- }
- return Context::evaluate_function(name, evalctx);
+ return NULL;
}
-AbstractNode *ModuleContext::instantiate_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->instantiate(this, &inst, evalctx);
+ return m;
}
+ return NULL;
+}
- if (this->usedlibs_p) {
- BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, *this->usedlibs_p) {
- assert(m.second);
- if (m.second->scope.modules.find(inst.name()) != m.second->scope.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->scope.modules[inst.name()]->instantiate(&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();
}
+ 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);
}
@@ -150,10 +133,57 @@ void ModuleContext::dump(const AbstractModule *mod, const ModuleInstantiation *i
}
#endif
-FileContext::FileContext(const class FileModule &module,
- const Context *parent, const EvalContext *evalctx)
- :ModuleContext(&module, parent, evalctx)
+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);
+}
contact: Jan Huwald // Impressum