diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/localscope.cc | 8 | ||||
-rw-r--r-- | src/modcontext.cc | 47 | ||||
-rw-r--r-- | src/modcontext.h | 3 | ||||
-rw-r--r-- | src/parser.y | 6 |
4 files changed, 59 insertions, 5 deletions
diff --git a/src/localscope.cc b/src/localscope.cc index eecff91..dd40563 100644 --- a/src/localscope.cc +++ b/src/localscope.cc @@ -55,9 +55,11 @@ std::vector<AbstractNode*> LocalScope::instantiateChildren(const Context *evalct // c->functions_p = &this->functions; // c->modules_p = &this->modules; - BOOST_FOREACH (const Assignment &ass, this->assignments) { - c->set_variable(ass.first, ass.second->evaluate(c)); - } + // Uncommenting the following would allow assignments in local scopes, + // but would cause duplicate evaluation of module scopes + // BOOST_FOREACH (const Assignment &ass, this->assignments) { + // c->set_variable(ass.first, ass.second->evaluate(c)); + // } } std::vector<AbstractNode*> childnodes; diff --git a/src/modcontext.cc b/src/modcontext.cc index 8799af9..5b48009 100644 --- a/src/modcontext.cc +++ b/src/modcontext.cc @@ -17,6 +17,51 @@ ModuleContext::~ModuleContext() { } +// Experimental code. See issue #399 +#if 0 +void ModuleContext::evaluateAssignments(const AssignmentList &assignments) +{ + // First, assign all simple variables + std::list<std::string> undefined_vars; + BOOST_FOREACH(const Assignment &ass, assignments) { + Value tmpval = ass.second->evaluate(this); + if (tmpval.isUndefined()) undefined_vars.push_back(ass.first); + else this->set_variable(ass.first, tmpval); + } + + // Variables which couldn't be evaluated in the first pass is attempted again, + // to allow for initialization out of order + + boost::unordered_map<std::string, Expression *> tmpass; + BOOST_FOREACH (const Assignment &ass, assignments) { + tmpass[ass.first] = ass.second; + } + + bool changed = true; + while (changed) { + changed = false; + std::list<std::string>::iterator iter = undefined_vars.begin(); + while (iter != undefined_vars.end()) { + std::list<std::string>::iterator curr = iter++; + boost::unordered_map<std::string, Expression *>::iterator found = tmpass.find(*curr); + if (found != tmpass.end()) { + const Expression *expr = found->second; + Value tmpval = expr->evaluate(this); + // FIXME: it's not enough to check for undefined; + // we need to check for any undefined variable in the subexpression + // For now, ignore this and revisit the validity and order of variable + // assignments later + if (!tmpval.isUndefined()) { + changed = true; + this->set_variable(*curr, tmpval); + undefined_vars.erase(curr); + } + } + } + } +} +#endif + void ModuleContext::initializeModule(const class Module &module) { this->setVariables(module.definition_arguments, evalctx); @@ -26,6 +71,8 @@ void ModuleContext::initializeModule(const class Module &module) BOOST_FOREACH(const Assignment &ass, module.scope.assignments) { this->set_variable(ass.first, ass.second->evaluate(this)); } +// Experimental code. See issue #399 +// evaluateAssignments(module.scope.assignments); } /*! diff --git a/src/modcontext.h b/src/modcontext.h index 0b3e48c..3a05a0c 100644 --- a/src/modcontext.h +++ b/src/modcontext.h @@ -36,6 +36,9 @@ public: #ifdef DEBUG virtual void dump(const class AbstractModule *mod, const ModuleInstantiation *inst); #endif +private: +// Experimental code. See issue #399 +// void evaluateAssignments(const AssignmentList &assignments); }; class FileContext : public ModuleContext diff --git a/src/parser.y b/src/parser.y index 0977efa..5b3d019 100644 --- a/src/parser.y +++ b/src/parser.y @@ -136,15 +136,17 @@ statement inner_input ; assignment: TOK_ID '=' expr ';' { + bool found = false; for (AssignmentList::iterator iter = scope_stack.top()->assignments.begin(); iter != scope_stack.top()->assignments.end(); iter++) { if (iter->first == $1) { - scope_stack.top()->assignments.erase(iter); + iter->second = $3; + found = true; break; } } - scope_stack.top()->assignments.push_back(Assignment($1, $3)); + if (!found) scope_stack.top()->assignments.push_back(Assignment($1, $3)); } ; statement: |