summaryrefslogtreecommitdiff
path: root/src/module.cc
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2013-04-19 21:52:01 (GMT)
committerMarius Kintel <marius@kintel.net>2013-04-26 21:45:03 (GMT)
commit9a297ecee57549a4eb3919bde4f7b41a548724de (patch)
treeb1f523e93f528559e9ada2d38d76be7a0362f9d4 /src/module.cc
parentb4568a09df8be0f212ba1c4fd1660459900e3cf0 (diff)
Refactoring: Split out FileModule from Module, Added LocalScope renamed some confusing 'evaluate' methods to 'instantiate', added FileContext (not yet used)
Diffstat (limited to 'src/module.cc')
-rw-r--r--src/module.cc128
1 files changed, 73 insertions, 55 deletions
diff --git a/src/module.cc b/src/module.cc
index 3b1ec0a..a9e3cbf 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -40,15 +40,59 @@ namespace fs = boost::filesystem;
#include <sstream>
#include <sys/stat.h>
+LocalScope::LocalScope()
+{
+}
+
+LocalScope::~LocalScope()
+{
+ BOOST_FOREACH(ModuleInstantiation *v, children) delete v;
+ BOOST_FOREACH (const Assignment &v, assignments) delete v.second;
+ BOOST_FOREACH (FunctionContainer::value_type &f, functions) delete f.second;
+ BOOST_FOREACH (AbstractModuleContainer::value_type &m, modules) delete m.second;
+}
+
+std::string LocalScope::dump(const std::string &indent) const
+{
+ std::stringstream dump;
+ BOOST_FOREACH(const FunctionContainer::value_type &f, this->functions) {
+ dump << f.second->dump(indent, f.first);
+ }
+ BOOST_FOREACH(const AbstractModuleContainer::value_type &m, this->modules) {
+ dump << m.second->dump(indent, m.first);
+ }
+ BOOST_FOREACH(const Assignment &ass, this->assignments) {
+ dump << indent << ass.first << " = " << *ass.second << ";\n";
+ }
+ BOOST_FOREACH(const ModuleInstantiation *inst, this->children) {
+ dump << inst->dump(indent);
+ }
+ return dump.str();
+}
+
+std::vector<AbstractNode*> LocalScope::instantiateChildren(const Context *evalctx) const
+{
+ Context c(evalctx); // FIXME: Is this correct, or should we use the parent?
+ BOOST_FOREACH (const Assignment &ass, this->assignments) {
+ c.set_variable(ass.first, ass.second->evaluate(&c));
+ }
+ std::vector<AbstractNode*> childnodes;
+ BOOST_FOREACH (ModuleInstantiation *modinst, this->children) {
+ AbstractNode *node = modinst->evaluate(&c);
+ if (node) childnodes.push_back(node);
+ }
+ return childnodes;
+}
+
AbstractModule::~AbstractModule()
{
}
-AbstractNode *AbstractModule::evaluate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
+AbstractNode *AbstractModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
{
AbstractNode *node = new AbstractNode(inst);
- node->children = inst->evaluateChildren(evalctx);
+ node->children = inst->instantiateChildren(evalctx);
return node;
}
@@ -63,12 +107,10 @@ std::string AbstractModule::dump(const std::string &indent, const std::string &n
ModuleInstantiation::~ModuleInstantiation()
{
BOOST_FOREACH(const Assignment &arg, this->arguments) delete arg.second;
- BOOST_FOREACH(ModuleInstantiation *v, children) delete v;
}
IfElseModuleInstantiation::~IfElseModuleInstantiation()
{
- BOOST_FOREACH (ModuleInstantiation *v, else_children) delete v;
}
/*!
@@ -95,76 +137,63 @@ std::string ModuleInstantiation::dump(const std::string &indent) const
if (!arg.first.empty()) dump << arg.first << " = ";
dump << *arg.second;
}
- if (children.size() == 0) {
+ if (scope.numElements() == 0) {
dump << ");\n";
- } else if (children.size() == 1) {
+ } else if (scope.numElements() == 1) {
dump << ")\n";
- dump << children[0]->dump(indent + "\t");
+ dump << scope.dump(indent + "\t");
} else {
dump << ") {\n";
- for (size_t i = 0; i < children.size(); i++) {
- dump << children[i]->dump(indent + "\t");
- }
+ scope.dump(indent + "\t");
dump << indent << "}\n";
}
return dump.str();
}
-AbstractNode *ModuleInstantiation::evaluate_instance(const Context *ctx) const
+AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const
{
- EvalContext c(ctx, this->arguments, &this->children);
+ EvalContext c(ctx, this->arguments, &this->scope);
#if 0 && DEBUG
PRINT("New eval ctx:");
c.dump(NULL, this);
#endif
- AbstractNode *node = ctx->evaluate_module(*this, &c); // Passes c as evalctx
+ AbstractNode *node = ctx->instantiate_module(*this, &c); // Passes c as evalctx
return node;
}
-std::vector<AbstractNode*> ModuleInstantiation::evaluateChildren(const Context *evalctx) const
+std::vector<AbstractNode*> ModuleInstantiation::instantiateChildren(const Context *evalctx) const
{
- std::vector<AbstractNode*> childnodes;
- BOOST_FOREACH (ModuleInstantiation *modinst, this->children) {
- AbstractNode *node = modinst->evaluate_instance(evalctx);
- if (node) childnodes.push_back(node);
- }
- return childnodes;
+ return this->scope.instantiateChildren(evalctx);
}
-std::vector<AbstractNode*> IfElseModuleInstantiation::evaluateElseChildren(const Context *evalctx) const
+std::vector<AbstractNode*> IfElseModuleInstantiation::instantiateElseChildren(const Context *evalctx) const
{
- std::vector<AbstractNode*> childnodes;
- BOOST_FOREACH (ModuleInstantiation *modinst, this->else_children) {
- AbstractNode *node = modinst->evaluate_instance(evalctx);
- if (node != NULL) childnodes.push_back(node);
- }
- return childnodes;
+ return this->else_scope.instantiateChildren(evalctx);
}
Module::~Module()
{
- BOOST_FOREACH (const Assignment &v, assignments) delete v.second;
- BOOST_FOREACH (FunctionContainer::value_type &f, functions) delete f.second;
- BOOST_FOREACH (AbstractModuleContainer::value_type &m, modules) delete m.second;
- BOOST_FOREACH (ModuleInstantiation *v, children) delete v;
}
-AbstractNode *Module::evaluate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
+void Module::addChild(ModuleInstantiation *ch)
+{
+ this->scope.children.push_back(ch);
+}
+
+AbstractNode *Module::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
{
ModuleContext c(this, ctx, evalctx);
// FIXME: Set document path to the path of the module
- c.set_variable("$children", Value(double(inst->children.size())));
+ c.set_variable("$children", Value(double(inst->scope.children.size())));
#if 0 && DEBUG
c.dump(this, inst);
#endif
+ // FIXME: this->scope.instantiateChildren(&c) and ModuleContext c() causes set_variable to be called twice, causing duplicate warning output in e.g. echotest_search-tests
AbstractNode *node = new AbstractNode(inst);
- for (size_t i = 0; i < children.size(); i++) {
- AbstractNode *n = children[i]->evaluate_instance(&c);
- if (n != NULL)
- node->children.push_back(n);
- }
+ std::vector<AbstractNode *> instantiatednodes = this->scope.instantiateChildren(&c);
+ node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
return node;
}
@@ -184,25 +213,14 @@ std::string Module::dump(const std::string &indent, const std::string &name) con
dump << ") {\n";
tab = "\t";
}
- BOOST_FOREACH(const FunctionContainer::value_type &f, functions) {
- dump << f.second->dump(indent + tab, f.first);
- }
- BOOST_FOREACH(const AbstractModuleContainer::value_type &m, modules) {
- dump << m.second->dump(indent + tab, m.first);
- }
- BOOST_FOREACH(const Assignment &ass, assignments) {
- dump << indent << tab << ass.first << " = " << *ass.second << ";\n";
- }
- for (size_t i = 0; i < children.size(); i++) {
- dump << children[i]->dump(indent + tab);
- }
+ dump << scope.dump(indent + tab);
if (!name.empty()) {
dump << indent << "}\n";
}
return dump.str();
}
-void Module::registerInclude(const std::string &filename)
+void FileModule::registerInclude(const std::string &filename)
{
struct stat st;
memset(&st, 0, sizeof(struct stat));
@@ -214,17 +232,17 @@ void Module::registerInclude(const std::string &filename)
Check if any dependencies have been modified and recompile them.
Returns true if anything was recompiled.
*/
-bool Module::handleDependencies()
+bool FileModule::handleDependencies()
{
if (this->is_handling_dependencies) return false;
this->is_handling_dependencies = true;
bool changed = false;
// Iterating manually since we want to modify the container while iterating
- Module::ModuleContainer::iterator iter = this->usedlibs.begin();
+ FileModule::ModuleContainer::iterator iter = this->usedlibs.begin();
while (iter != this->usedlibs.end()) {
- Module::ModuleContainer::iterator curr = iter++;
- Module *oldmodule = curr->second;
+ FileModule::ModuleContainer::iterator curr = iter++;
+ FileModule *oldmodule = curr->second;
curr->second = ModuleCache::instance()->evaluate(curr->first);
if (curr->second != oldmodule) {
changed = true;
contact: Jan Huwald // Impressum