2013-04-09 08:28:16 +04:00
|
|
|
#include "modcontext.h"
|
|
|
|
#include "module.h"
|
|
|
|
#include "expression.h"
|
|
|
|
#include "function.h"
|
|
|
|
#include "printutils.h"
|
|
|
|
#include "builtin.h"
|
|
|
|
|
|
|
|
#include <boost/foreach.hpp>
|
|
|
|
|
2013-04-24 17:17:25 +04:00
|
|
|
ModuleContext::ModuleContext(const Context *parent, const EvalContext *evalctx)
|
|
|
|
: Context(parent), functions_p(NULL), modules_p(NULL), evalctx(evalctx)
|
2013-04-09 08:28:16 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ModuleContext::~ModuleContext()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-04-24 17:17:25 +04:00
|
|
|
void ModuleContext::initializeModule(const class Module &module)
|
2013-04-09 08:28:16 +04:00
|
|
|
{
|
2013-04-19 02:34:14 +04:00
|
|
|
this->setVariables(module.definition_arguments, evalctx);
|
2013-04-09 08:28:16 +04:00
|
|
|
// FIXME: Don't access module members directly
|
2013-04-20 01:52:01 +04:00
|
|
|
this->functions_p = &module.scope.functions;
|
|
|
|
this->modules_p = &module.scope.modules;
|
|
|
|
BOOST_FOREACH(const Assignment &ass, module.scope.assignments) {
|
2013-04-19 21:56:27 +04:00
|
|
|
this->set_variable(ass.first, ass.second->evaluate(this));
|
2013-04-09 08:28:16 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-24 17:17:25 +04:00
|
|
|
/*!
|
|
|
|
Only used to initialize builtins for the top-level root context
|
|
|
|
*/
|
|
|
|
void ModuleContext::registerBuiltin()
|
2013-04-09 08:28:16 +04:00
|
|
|
{
|
2013-04-24 17:17:25 +04:00
|
|
|
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));
|
2013-04-16 04:58:15 +04:00
|
|
|
}
|
|
|
|
|
2013-04-24 17:17:25 +04:00
|
|
|
this->set_constant("PI",Value(M_PI));
|
|
|
|
}
|
|
|
|
|
|
|
|
const AbstractFunction *ModuleContext::findLocalFunction(const std::string &name) const
|
|
|
|
{
|
2013-04-09 08:28:16 +04:00
|
|
|
if (this->functions_p && this->functions_p->find(name) != this->functions_p->end()) {
|
2013-04-24 17:17:25 +04:00
|
|
|
return this->functions_p->find(name)->second;
|
2013-04-09 08:28:16 +04:00
|
|
|
}
|
2013-04-24 17:17:25 +04:00
|
|
|
return NULL;
|
2013-04-09 08:28:16 +04:00
|
|
|
}
|
|
|
|
|
2013-04-24 17:17:25 +04:00
|
|
|
const AbstractModule *ModuleContext::findLocalModule(const std::string &name) const
|
2013-04-09 08:28:16 +04:00
|
|
|
{
|
2013-04-24 17:17:25 +04:00
|
|
|
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);
|
2013-04-09 08:28:16 +04:00
|
|
|
if (!replacement.empty()) {
|
2013-04-24 17:17:25 +04:00
|
|
|
PRINTB("DEPRECATED: The %s() module will be removed in future releases. Use %s() instead.", name % replacement);
|
2013-04-09 08:28:16 +04:00
|
|
|
}
|
2013-04-24 17:17:25 +04:00
|
|
|
return m;
|
2013-04-09 08:28:16 +04:00
|
|
|
}
|
2013-04-24 17:17:25 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
2013-04-09 08:28:16 +04:00
|
|
|
|
2013-04-24 17:17:25 +04:00
|
|
|
Value ModuleContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
2013-04-20 01:52:01 +04:00
|
|
|
return Context::instantiate_module(inst, evalctx);
|
2013-04-09 08:28:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
void ModuleContext::dump(const AbstractModule *mod, const ModuleInstantiation *inst)
|
|
|
|
{
|
|
|
|
if (inst)
|
|
|
|
PRINTB("ModuleContext %p (%p) for %s inst (%p) ", this % this->parent % inst->name() % inst);
|
|
|
|
else
|
|
|
|
PRINTB("ModuleContext: %p (%p)", this % this->parent);
|
|
|
|
PRINTB(" document path: %s", this->document_path);
|
|
|
|
if (mod) {
|
|
|
|
const Module *m = dynamic_cast<const Module*>(mod);
|
|
|
|
if (m) {
|
|
|
|
PRINT(" module args:");
|
2013-04-19 02:34:14 +04:00
|
|
|
BOOST_FOREACH(const Assignment &arg, m->definition_arguments) {
|
|
|
|
PRINTB(" %s = %s", arg.first % variables[arg.first]);
|
2013-04-09 08:28:16 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
typedef std::pair<std::string, Value> ValueMapType;
|
|
|
|
PRINT(" vars:");
|
|
|
|
BOOST_FOREACH(const ValueMapType &v, constants) {
|
|
|
|
PRINTB(" %s = %s", v.first % v.second);
|
|
|
|
}
|
|
|
|
BOOST_FOREACH(const ValueMapType &v, variables) {
|
|
|
|
PRINTB(" %s = %s", v.first % v.second);
|
|
|
|
}
|
|
|
|
BOOST_FOREACH(const ValueMapType &v, config_variables) {
|
|
|
|
PRINTB(" %s = %s", v.first % v.second);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
2013-04-20 01:52:01 +04:00
|
|
|
|
2013-04-24 17:17:25 +04:00
|
|
|
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
|
2013-04-20 01:52:01 +04:00
|
|
|
{
|
2013-04-24 17:17:25 +04:00
|
|
|
const AbstractFunction *foundf = findLocalFunction(name);
|
|
|
|
if (foundf) return foundf->evaluate(this, evalctx);
|
2013-04-20 01:52:01 +04:00
|
|
|
|
2013-04-24 17:17:25 +04:00
|
|
|
BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) {
|
2013-05-27 05:55:00 +04:00
|
|
|
// 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()) {
|
2013-04-24 17:17:25 +04:00
|
|
|
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);
|
2013-04-20 01:52:01 +04:00
|
|
|
}
|
|
|
|
|
2013-04-24 17:17:25 +04:00
|
|
|
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) {
|
2013-05-27 05:55:00 +04:00
|
|
|
// 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()) {
|
2013-04-24 17:17:25 +04:00
|
|
|
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);
|
|
|
|
}
|