diff options
author | Marius Kintel <marius@kintel.net> | 2011-09-03 16:51:29 (GMT) |
---|---|---|
committer | Marius Kintel <marius@kintel.net> | 2011-09-03 16:51:29 (GMT) |
commit | f58c0a3eb5ce9f252e98f41ddc34dcb70a68052b (patch) | |
tree | a2f3fb5b102e494feadc7c4e6e1cbf843f0699e3 /src | |
parent | 16b74df94104525436342e7a128573a2a63d3494 (diff) |
Some cleanup of the Context class
Diffstat (limited to 'src')
-rw-r--r-- | src/context.cc | 137 | ||||
-rw-r--r-- | src/context.h | 48 | ||||
-rw-r--r-- | src/dxfdim.cc | 4 | ||||
-rw-r--r-- | src/dxflinextrude.cc | 2 | ||||
-rw-r--r-- | src/dxfrotextrude.cc | 2 | ||||
-rw-r--r-- | src/func.cc | 4 | ||||
-rw-r--r-- | src/import.cc | 4 | ||||
-rw-r--r-- | src/mainwin.cc | 4 | ||||
-rw-r--r-- | src/module.cc | 4 | ||||
-rw-r--r-- | src/surface.cc | 2 |
10 files changed, 113 insertions, 98 deletions
diff --git a/src/context.cc b/src/context.cc index 7a0e3cd..9722428 100644 --- a/src/context.cc +++ b/src/context.cc @@ -33,15 +33,30 @@ #include <QDir> #include <boost/foreach.hpp> -Context::Context(const Context *parent) +std::vector<const Context*> Context::ctx_stack; + +/*! + Initializes this context. Optionally initializes a context for an external library +*/ +Context::Context(const Context *parent, const Module *library) + : parent(parent), inst_p(NULL) { - this->parent = parent; - functions_p = NULL; - modules_p = NULL; - usedlibs_p = NULL; - inst_p = NULL; - if (parent) document_path = parent->document_path; ctx_stack.push_back(this); + if (parent) document_path = parent->document_path; + if (library) { + this->functions_p = &library->functions; + this->modules_p = &library->modules; + this->usedlibs_p = &library->usedlibs; + for (size_t j = 0; j < library->assignments_var.size(); j++) { + this->set_variable(library->assignments_var[j], + library->assignments_expr[j]->evaluate(this)); + } + } + else { + functions_p = NULL; + modules_p = NULL; + usedlibs_p = NULL; + } } Context::~Context() @@ -49,11 +64,17 @@ Context::~Context() ctx_stack.pop_back(); } -void Context::args(const std::vector<std::string> &argnames, const std::vector<Expression*> &argexpr, - const std::vector<std::string> &call_argnames, const std::vector<Value> &call_argvalues) +/*! + Initialize context from argument lists (function call/module instantiation) + */ +void Context::args(const std::vector<std::string> &argnames, + const std::vector<Expression*> &argexpr, + const std::vector<std::string> &call_argnames, + const std::vector<Value> &call_argvalues) { for (size_t i=0; i<argnames.size(); i++) { - set_variable(argnames[i], i < argexpr.size() && argexpr[i] ? argexpr[i]->evaluate(this->parent) : Value()); + set_variable(argnames[i], i < argexpr.size() && argexpr[i] ? + argexpr[i]->evaluate(this->parent) : Value()); } size_t posarg = 0; @@ -67,14 +88,20 @@ void Context::args(const std::vector<std::string> &argnames, const std::vector<E } } -std::vector<const Context*> Context::ctx_stack; - -void Context::set_variable(const std::string &name, Value value) +void Context::set_variable(const std::string &name, const Value &value) { if (name[0] == '$') - config_variables[name] = value; + this->config_variables[name] = value; + else + this->variables[name] = value; +} + +void Context::set_constant(const std::string &name, const Value &value) +{ + if (this->constants.find(name) != this->constants.end()) + PRINTF("WARNING: Attempt to modify constant '%s'.",name.c_str()); else - variables[name] = value; + this->constants[name] = value; } Value Context::lookup_variable(const std::string &name, bool silent) const @@ -87,79 +114,58 @@ Value Context::lookup_variable(const std::string &name, bool silent) const } return Value(); } - if (!parent && constants.find(name) != constants.end()) - return constants.find(name)->second; - if (variables.find(name) != variables.end()) - return variables.find(name)->second; - if (parent) - return parent->lookup_variable(name, silent); + if (!this->parent && this->constants.find(name) != this->constants.end()) + return this->constants.find(name)->second; + if (this->variables.find(name) != this->variables.end()) + return this->variables.find(name)->second; + if (this->parent) + return this->parent->lookup_variable(name, silent); if (!silent) PRINTF("WARNING: Ignoring unknown variable '%s'.", name.c_str()); return Value(); } -void Context::set_constant(const std::string &name, Value value) +Value Context::evaluate_function(const std::string &name, + const std::vector<std::string> &argnames, + const std::vector<Value> &argvalues) const { - if (constants.count(name)) - PRINTF("WARNING: Attempt to modify constant '%s'.",name.c_str()); - else - constants[name] = value; -} - -Value Context::evaluate_function(const std::string &name, const std::vector<std::string> &argnames, const std::vector<Value> &argvalues) const -{ - if (functions_p && functions_p->find(name) != functions_p->end()) - return functions_p->find(name)->second->evaluate(this, argnames, argvalues); - if (usedlibs_p) { - BOOST_FOREACH(const ModuleContainer::value_type &m, *usedlibs_p) { - if (m.second->functions.count(name)) { - Module *lib = m.second; - Context ctx(parent); - ctx.functions_p = &lib->functions; - ctx.modules_p = &lib->modules; - ctx.usedlibs_p = &lib->usedlibs; - for (size_t j = 0; j < lib->assignments_var.size(); j++) { - ctx.set_variable(lib->assignments_var[j], lib->assignments_expr[j]->evaluate(&ctx)); - } + if (this->functions_p && this->functions_p->find(name) != this->functions_p->end()) + return this->functions_p->find(name)->second->evaluate(this, argnames, argvalues); + if (this->usedlibs_p) { + BOOST_FOREACH(const ModuleContainer::value_type &m, *this->usedlibs_p) { + if (m.second->functions.find(name) != m.second->functions.end()) { + Context ctx(this->parent, m.second); return m.second->functions[name]->evaluate(&ctx, argnames, argvalues); } } } - if (parent) - return parent->evaluate_function(name, argnames, argvalues); - PRINTF("WARNING: Ignoring unkown function '%s'.", name.c_str()); + if (this->parent) + return this->parent->evaluate_function(name, argnames, argvalues); + PRINTF("WARNING: Ignoring unknown function '%s'.", name.c_str()); return Value(); } -AbstractNode *Context::evaluate_module(const ModuleInstantiation *inst) const +AbstractNode *Context::evaluate_module(const ModuleInstantiation &inst) const { - if (modules_p && modules_p->find(inst->modname) != modules_p->end()) - return modules_p->find(inst->modname)->second->evaluate(this, inst); - if (usedlibs_p) { - BOOST_FOREACH(const ModuleContainer::value_type &m, *usedlibs_p) { - if (m.second->modules.count(inst->modname)) { - Module *lib = m.second; - Context ctx(parent); - ctx.functions_p = &lib->functions; - ctx.modules_p = &lib->modules; - ctx.usedlibs_p = &lib->usedlibs; - for (size_t j = 0; j < lib->assignments_var.size(); j++) { - ctx.set_variable(lib->assignments_var[j], lib->assignments_expr[j]->evaluate(&ctx)); - } - return m.second->modules[inst->modname]->evaluate(&ctx, inst); + if (this->modules_p && this->modules_p->find(inst.modname) != this->modules_p->end()) + return this->modules_p->find(inst.modname)->second->evaluate(this, &inst); + if (this->usedlibs_p) { + BOOST_FOREACH(const ModuleContainer::value_type &m, *this->usedlibs_p) { + if (m.second->modules.find(inst.modname) != m.second->modules.end()) { + Context ctx(this->parent, m.second); + return m.second->modules[inst.modname]->evaluate(&ctx, &inst); } } } - if (parent) - return parent->evaluate_module(inst); - PRINTF("WARNING: Ignoring unkown module '%s'.", inst->modname.c_str()); + if (this->parent) return this->parent->evaluate_module(inst); + PRINTF("WARNING: Ignoring unknown module '%s'.", inst.modname.c_str()); return NULL; } /*! Returns the absolute path to the given filename, unless it's empty. */ -std::string Context::get_absolute_path(const std::string &filename) const +std::string Context::getAbsolutePath(const std::string &filename) const { if (!filename.empty()) { return QFileInfo(QDir(QString::fromStdString(this->document_path)), @@ -169,4 +175,3 @@ std::string Context::get_absolute_path(const std::string &filename) const return filename; } } - diff --git a/src/context.h b/src/context.h index 99726a9..f085e01 100644 --- a/src/context.h +++ b/src/context.h @@ -11,34 +11,42 @@ using boost::unordered_map; class Context { public: + Context(const Context *parent = NULL, const class Module *library = NULL); + ~Context(); + + void args(const std::vector<std::string> &argnames, + const std::vector<class Expression*> &argexpr, + const std::vector<std::string> &call_argnames, + const std::vector<Value> &call_argvalues); + + void set_variable(const std::string &name, const Value &value); + void set_constant(const std::string &name, const Value &value); + + Value lookup_variable(const std::string &name, bool silent = false) const; + Value evaluate_function(const std::string &name, + const std::vector<std::string> &argnames, + const std::vector<Value> &argvalues) const; + class AbstractNode *evaluate_module(const class ModuleInstantiation &inst) const; + + void setDocumentPath(const std::string &path) { this->document_path = path; } + std::string getAbsolutePath(const std::string &filename) const; + +public: const Context *parent; - typedef unordered_map<std::string, Value> ValueMap; - ValueMap constants; - ValueMap variables; - ValueMap config_variables; const unordered_map<std::string, class AbstractFunction*> *functions_p; const unordered_map<std::string, class AbstractModule*> *modules_p; typedef unordered_map<std::string, class Module*> ModuleContainer; const ModuleContainer *usedlibs_p; - const class ModuleInstantiation *inst_p; - std::string document_path; + const ModuleInstantiation *inst_p; static std::vector<const Context*> ctx_stack; - Context(const Context *parent = NULL); - ~Context(); - - void args(const std::vector<std::string> &argnames, const std::vector<class Expression*> &argexpr, const std::vector<std::string> &call_argnames, const std::vector<Value> &call_argvalues); - - void set_variable(const std::string &name, Value value); - Value lookup_variable(const std::string &name, bool silent = false) const; - - void set_constant(const std::string &name, Value value); - - std::string get_absolute_path(const std::string &filename) const; - - Value evaluate_function(const std::string &name, const std::vector<std::string> &argnames, const std::vector<Value> &argvalues) const; - class AbstractNode *evaluate_module(const ModuleInstantiation *inst) const; +private: + typedef unordered_map<std::string, Value> ValueMap; + ValueMap constants; + ValueMap variables; + ValueMap config_variables; + std::string document_path; }; #endif diff --git a/src/dxfdim.cc b/src/dxfdim.cc index 88e007c..636ea6c 100644 --- a/src/dxfdim.cc +++ b/src/dxfdim.cc @@ -51,7 +51,7 @@ Value builtin_dxf_dim(const Context *ctx, const std::vector<std::string> &argnam for (size_t i = 0; i < argnames.size() && i < args.size(); i++) { if (argnames[i] == "file") - filename = ctx->get_absolute_path(args[i].text); + filename = ctx->getAbsolutePath(args[i].text); if (argnames[i] == "layer") layername = args[i].text; if (argnames[i] == "origin") @@ -135,7 +135,7 @@ Value builtin_dxf_cross(const Context *ctx, const std::vector<std::string> &argn for (size_t i = 0; i < argnames.size() && i < args.size(); i++) { if (argnames[i] == "file") - filename = ctx->get_absolute_path(args[i].text); + filename = ctx->getAbsolutePath(args[i].text); if (argnames[i] == "layer") layername = args[i].text; if (argnames[i] == "origin") diff --git a/src/dxflinextrude.cc b/src/dxflinextrude.cc index 283c7f4..94792ef 100644 --- a/src/dxflinextrude.cc +++ b/src/dxflinextrude.cc @@ -77,7 +77,7 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI Value slices = c.lookup_variable("slices", true); if (!file.text.empty()) - node->filename = c.get_absolute_path(file.text); + node->filename = c.getAbsolutePath(file.text); node->layername = layer.text; node->height = height.num; diff --git a/src/dxfrotextrude.cc b/src/dxfrotextrude.cc index b333fbf..44a70a5 100644 --- a/src/dxfrotextrude.cc +++ b/src/dxfrotextrude.cc @@ -71,7 +71,7 @@ AbstractNode *DxfRotateExtrudeModule::evaluate(const Context *ctx, const ModuleI Value scale = c.lookup_variable("scale", true); if (!file.text.empty()) - node->filename = c.get_absolute_path(file.text); + node->filename = c.getAbsolutePath(file.text); node->layername = layer.text; node->convexity = (int)convexity.num; diff --git a/src/func.cc b/src/func.cc index 31c8ad2..52f04dd 100644 --- a/src/func.cc +++ b/src/func.cc @@ -58,7 +58,9 @@ Function::~Function() delete expr; } -Value Function::evaluate(const Context *ctx, const std::vector<std::string> &call_argnames, const std::vector<Value> &call_argvalues) const +Value Function::evaluate(const Context *ctx, + const std::vector<std::string> &call_argnames, + const std::vector<Value> &call_argvalues) const { Context c(ctx); c.args(argnames, argexpr, call_argnames, call_argvalues); diff --git a/src/import.cc b/src/import.cc index b26d05d..0f107f7 100644 --- a/src/import.cc +++ b/src/import.cc @@ -82,8 +82,8 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati node->fa = c.lookup_variable("$fa").num; Value v = c.lookup_variable("file"); - node->filename = c.get_absolute_path(v.text); -// node->filename = c.get_absolute_path(c.lookup_variable("file").text); + node->filename = c.getAbsolutePath(v.text); +// node->filename = c.getAbsolutePath(c.lookup_variable("file").text); node->layername = c.lookup_variable("layer", true).text; node->convexity = c.lookup_variable("convexity", true).num; diff --git a/src/mainwin.cc b/src/mainwin.cc index 6408418..4b5ba89 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -495,7 +495,7 @@ MainWindow::setFileName(const QString &filename) { if (filename.isEmpty()) { this->fileName.clear(); - this->root_ctx.document_path = currentdir.toStdString(); + this->root_ctx.setDocumentPath(currentdir.toStdString()); setWindowTitle("OpenSCAD - New Document[*]"); } else { @@ -518,7 +518,7 @@ MainWindow::setFileName(const QString &filename) this->fileName = fileinfo.fileName(); } - this->root_ctx.document_path = fileinfo.dir().absolutePath().toStdString(); + this->root_ctx.setDocumentPath(fileinfo.dir().absolutePath().toStdString()); QDir::setCurrent(fileinfo.dir().absolutePath()); } diff --git a/src/module.cc b/src/module.cc index 49a5f1b..2852c4e 100644 --- a/src/module.cc +++ b/src/module.cc @@ -102,7 +102,7 @@ AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const { AbstractNode *node = NULL; if (this->ctx) { - PRINTF("WARNING: Ignoring recursive module instanciation of '%s'.", modname.c_str()); + PRINTF("WARNING: Ignoring recursive module instantiation of '%s'.", modname.c_str()); } else { ModuleInstantiation *that = (ModuleInstantiation*)this; that->argvalues.clear(); @@ -110,7 +110,7 @@ AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const that->argvalues.push_back(v->evaluate(ctx)); } that->ctx = ctx; - node = ctx->evaluate_module(this); + node = ctx->evaluate_module(*this); that->ctx = NULL; that->argvalues.clear(); } diff --git a/src/surface.cc b/src/surface.cc index d9a0c6e..b7dfa0f 100644 --- a/src/surface.cc +++ b/src/surface.cc @@ -78,7 +78,7 @@ AbstractNode *SurfaceModule::evaluate(const Context *ctx, const ModuleInstantiat Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); - node->filename = c.get_absolute_path(c.lookup_variable("file").text); + node->filename = c.getAbsolutePath(c.lookup_variable("file").text); Value center = c.lookup_variable("center", true); if (center.type == Value::BOOL) { |