diff options
author | Marius Kintel <marius@kintel.net> | 2013-04-19 21:52:01 (GMT) |
---|---|---|
committer | Marius Kintel <marius@kintel.net> | 2013-04-26 21:45:03 (GMT) |
commit | 9a297ecee57549a4eb3919bde4f7b41a548724de (patch) | |
tree | b1f523e93f528559e9ada2d38d76be7a0362f9d4 /src/module.cc | |
parent | b4568a09df8be0f212ba1c4fd1660459900e3cf0 (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.cc | 128 |
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; |