summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/context.cc137
-rw-r--r--src/context.h48
-rw-r--r--src/dxfdim.cc4
-rw-r--r--src/dxflinextrude.cc2
-rw-r--r--src/dxfrotextrude.cc2
-rw-r--r--src/func.cc4
-rw-r--r--src/import.cc4
-rw-r--r--src/mainwin.cc4
-rw-r--r--src/module.cc4
-rw-r--r--src/surface.cc2
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) {
contact: Jan Huwald // Impressum