summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/MainWindow.h2
-rw-r--r--src/builtin.cc16
-rw-r--r--src/builtin.h10
-rw-r--r--src/context.h2
-rw-r--r--src/localscope.cc67
-rw-r--r--src/localscope.h2
-rw-r--r--src/mainwin.cc14
-rw-r--r--src/modcontext.cc164
-rw-r--r--src/modcontext.h25
-rw-r--r--src/module.cc67
-rw-r--r--src/module.h5
-rw-r--r--src/openscad.cc16
12 files changed, 235 insertions, 155 deletions
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 7bb008a..378705e 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -29,7 +29,7 @@ public:
QTimer *autoReloadTimer;
std::string autoReloadId;
- ModuleContext root_ctx;
+ ModuleContext top_ctx;
FileModule *root_module; // Result of parsing
ModuleInstantiation root_inst; // Top level instance
AbstractNode *absolute_root_node; // Result of tree evaluation
diff --git a/src/builtin.cc b/src/builtin.cc
index a8b60df..e116f17 100644
--- a/src/builtin.cc
+++ b/src/builtin.cc
@@ -16,12 +16,12 @@ Builtins *Builtins::instance(bool erase)
void Builtins::init(const char *name, class AbstractModule *module)
{
- Builtins::instance()->rootmodule.scope.modules[name] = module;
+ Builtins::instance()->globalscope.modules[name] = module;
}
void Builtins::init(const char *name, class AbstractFunction *function)
{
- Builtins::instance()->rootmodule.scope.functions[name] = function;
+ Builtins::instance()->globalscope.functions[name] = function;
}
extern void register_builtin_functions();
@@ -80,18 +80,18 @@ std::string Builtins::isDeprecated(const std::string &name)
Builtins::Builtins()
{
- this->rootmodule.scope.assignments.push_back(Assignment("$fn", new Expression(Value(0.0))));
- this->rootmodule.scope.assignments.push_back(Assignment("$fs", new Expression(Value(2.0))));
- this->rootmodule.scope.assignments.push_back(Assignment("$fa", new Expression(Value(12.0))));
- this->rootmodule.scope.assignments.push_back(Assignment("$t", new Expression(Value(0.0))));
+ this->globalscope.assignments.push_back(Assignment("$fn", new Expression(Value(0.0))));
+ this->globalscope.assignments.push_back(Assignment("$fs", new Expression(Value(2.0))));
+ this->globalscope.assignments.push_back(Assignment("$fa", new Expression(Value(12.0))));
+ this->globalscope.assignments.push_back(Assignment("$t", new Expression(Value(0.0))));
Value::VectorType zero3;
zero3.push_back(Value(0.0));
zero3.push_back(Value(0.0));
zero3.push_back(Value(0.0));
Value zero3val(zero3);
- this->rootmodule.scope.assignments.push_back(Assignment("$vpt", new Expression(zero3val)));
- this->rootmodule.scope.assignments.push_back(Assignment("$vpr", new Expression(zero3val)));
+ this->globalscope.assignments.push_back(Assignment("$vpt", new Expression(zero3val)));
+ this->globalscope.assignments.push_back(Assignment("$vpr", new Expression(zero3val)));
}
Builtins::~Builtins()
diff --git a/src/builtin.h b/src/builtin.h
index 564c951..9397aa9 100644
--- a/src/builtin.h
+++ b/src/builtin.h
@@ -4,6 +4,7 @@
#include <string>
#include <boost/unordered_map.hpp>
#include "module.h"
+#include "localscope.h"
class Builtins
{
@@ -17,18 +18,13 @@ public:
void initialize();
std::string isDeprecated(const std::string &name);
- const FunctionContainer &functions() { return this->builtinfunctions; }
- const ModuleContainer &modules() { return this->builtinmodules; }
-
- const Module &getRootModule() { return this->rootmodule; }
+ const LocalScope &getGlobalScope() { return this->globalscope; }
private:
Builtins();
~Builtins();
- Module rootmodule;
- FunctionContainer builtinfunctions;
- ModuleContainer builtinmodules;
+ LocalScope globalscope;
boost::unordered_map<std::string, std::string> deprecations;
};
diff --git a/src/context.h b/src/context.h
index 5be1efd..9817df3 100644
--- a/src/context.h
+++ b/src/context.h
@@ -39,7 +39,7 @@ protected:
ValueMap variables;
ValueMap config_variables;
- std::string document_path;
+ std::string document_path; // FIXME: This is a remnant only needed by dxfdim
#ifdef DEBUG
public:
diff --git a/src/localscope.cc b/src/localscope.cc
new file mode 100644
index 0000000..c4001f5
--- /dev/null
+++ b/src/localscope.cc
@@ -0,0 +1,67 @@
+#include "localscope.h"
+#include "modcontext.h"
+#include "module.h"
+#include "typedefs.h"
+#include "expression.h"
+#include "function.h"
+
+#include <boost/foreach.hpp>
+
+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();
+}
+
+// FIXME: Two parameters here is a hack. Rather have separate types of scopes, or check the type of the first parameter. Note const vs. non-const
+std::vector<AbstractNode*> LocalScope::instantiateChildren(const Context *evalctx, FileContext *filectx) const
+{
+ Context *c = filectx;
+
+ if (!c) {
+ c = new Context(evalctx);
+
+ // FIXME: If we make c a ModuleContext, child() doesn't work anymore
+ // 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));
+ }
+ }
+
+ std::vector<AbstractNode*> childnodes;
+ BOOST_FOREACH (ModuleInstantiation *modinst, this->children) {
+ AbstractNode *node = modinst->evaluate(c);
+ if (node) childnodes.push_back(node);
+ }
+
+ if (c != filectx) delete c;
+
+ return childnodes;
+}
+
diff --git a/src/localscope.h b/src/localscope.h
index e631028..87f8430 100644
--- a/src/localscope.h
+++ b/src/localscope.h
@@ -12,7 +12,7 @@ public:
size_t numElements() const { return assignments.size() + children.size(); }
std::string dump(const std::string &indent) const;
- std::vector<class AbstractNode*> instantiateChildren(const class Context *evalctx) const;
+ std::vector<class AbstractNode*> instantiateChildren(const class Context *evalctx, class FileContext *filectx = NULL) const;
AssignmentList assignments;
ModuleInstantiationList children;
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 87ec744..027f72a 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -168,7 +168,7 @@ MainWindow::MainWindow(const QString &filename)
this, SLOT(actionRenderCGALDone(CGAL_Nef_polyhedron *)));
#endif
- root_ctx.registerBuiltin();
+ top_ctx.registerBuiltin();
this->openglbox = NULL;
root_module = NULL;
@@ -506,7 +506,7 @@ MainWindow::setFileName(const QString &filename)
{
if (filename.isEmpty()) {
this->fileName.clear();
- this->root_ctx.setDocumentPath(currentdir);
+ this->top_ctx.setDocumentPath(currentdir);
setWindowTitle("OpenSCAD - New Document[*]");
}
else {
@@ -522,7 +522,7 @@ MainWindow::setFileName(const QString &filename)
this->fileName = fileinfo.fileName();
}
- this->root_ctx.setDocumentPath(fileinfo.dir().absolutePath().toLocal8Bit().constData());
+ this->top_ctx.setDocumentPath(fileinfo.dir().absolutePath().toLocal8Bit().constData());
QDir::setCurrent(fileinfo.dir().absolutePath());
}
@@ -644,7 +644,7 @@ bool MainWindow::compile(bool reload, bool procevents)
AbstractNode::resetIndexCounter();
this->root_inst = ModuleInstantiation("group");
- this->absolute_root_node = this->root_module->instantiate(&this->root_ctx, &this->root_inst, NULL);
+ this->absolute_root_node = this->root_module->instantiate(&top_ctx, &this->root_inst, NULL);
if (this->absolute_root_node) {
// Do we have an explicit root node (! modifier)?
@@ -979,19 +979,19 @@ void MainWindow::pasteViewportRotation()
void MainWindow::updateTemporalVariables()
{
- this->root_ctx.set_variable("$t", Value(this->e_tval->text().toDouble()));
+ this->top_ctx.set_variable("$t", Value(this->e_tval->text().toDouble()));
Value::VectorType vpt;
vpt.push_back(Value(-qglview->cam.object_trans.x()));
vpt.push_back(Value(-qglview->cam.object_trans.y()));
vpt.push_back(Value(-qglview->cam.object_trans.z()));
- this->root_ctx.set_variable("$vpt", Value(vpt));
+ this->top_ctx.set_variable("$vpt", Value(vpt));
Value::VectorType vpr;
vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.x() + 90, 360)));
vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.y(), 360)));
vpr.push_back(Value(fmodf(360 - qglview->cam.object_rot.z(), 360)));
- root_ctx.set_variable("$vpr", Value(vpr));
+ top_ctx.set_variable("$vpr", Value(vpr));
}
bool MainWindow::fileChangedOnDisk()
diff --git a/src/modcontext.cc b/src/modcontext.cc
index df341f9..44c2002 100644
--- a/src/modcontext.cc
+++ b/src/modcontext.cc
@@ -7,28 +7,18 @@
#include <boost/foreach.hpp>
-ModuleContext::ModuleContext(const class Module *module, const Context *parent, const EvalContext *evalctx)
- : Context(parent), functions_p(NULL), modules_p(NULL), usedlibs_p(NULL)
+ModuleContext::ModuleContext(const Context *parent, const EvalContext *evalctx)
+ : Context(parent), functions_p(NULL), modules_p(NULL), evalctx(evalctx)
{
- if (module) setModule(*module, evalctx);
}
ModuleContext::~ModuleContext()
{
}
-void ModuleContext::setModule(const Module &module, const EvalContext *evalctx)
+void ModuleContext::initializeModule(const class Module &module)
{
this->setVariables(module.definition_arguments, evalctx);
- this->evalctx = evalctx;
-
- // FIXME: Hack - split out file context into separate class?
- const FileModule *fm = dynamic_cast<const FileModule*>(&module);
- if (fm) {
- this->usedlibs_p = &(fm->usedlibs);
- if (!fm->modulePath().empty()) this->document_path = fm->modulePath();
- }
-
// FIXME: Don't access module members directly
this->functions_p = &module.scope.functions;
this->modules_p = &module.scope.modules;
@@ -37,17 +27,6 @@ void ModuleContext::setModule(const Module &module, const EvalContext *evalctx)
}
}
-/*!
- Only used to initialize builtins for the top-level root context
-*/
-void ModuleContext::registerBuiltin()
-{
- // FIXME: built-ins only contains variables, setModule isn't really needed for this
- // FIXME: Where to put set_variable from setModule?
- this->setModule(Builtins::instance()->getRootModule());
- this->set_constant("PI",Value(M_PI));
-}
-
class RecursionGuard
{
public:
@@ -61,60 +40,64 @@ private:
const std::string &name;
};
-Value ModuleContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const
+
+/*!
+ Only used to initialize builtins for the top-level root context
+*/
+void ModuleContext::registerBuiltin()
{
- RecursionGuard g(*this, name);
- if (g.recursion_detected()) {
- PRINTB("Recursion detected calling function '%s'", name);
- return Value();
+ const LocalScope &scope = Builtins::instance()->getGlobalScope();
+
+ // FIXME: Don't access module members directly
+ this->functions_p = &scope.functions;
+ this->modules_p = &scope.modules;
+ BOOST_FOREACH(const Assignment &ass, scope.assignments) {
+ this->set_variable(ass.first, ass.second->evaluate(this));
}
+ this->set_constant("PI",Value(M_PI));
+}
+
+const AbstractFunction *ModuleContext::findLocalFunction(const std::string &name) const
+{
if (this->functions_p && this->functions_p->find(name) != this->functions_p->end()) {
- return this->functions_p->find(name)->second->evaluate(this, evalctx);
+ return this->functions_p->find(name)->second;
}
-
- if (this->usedlibs_p) {
- BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, *this->usedlibs_p) {
- if (m.second->scope.functions.find(name) != m.second->scope.functions.end()) {
- ModuleContext ctx(m.second, this->parent);
- // FIXME: Set document path
-#if 0 && DEBUG
- PRINTB("New lib Context for %s func:", name);
- ctx.dump(NULL, NULL);
-#endif
- return m.second->scope.functions[name]->evaluate(&ctx, evalctx);
- }
- }
- }
- return Context::evaluate_function(name, evalctx);
+ return NULL;
}
-AbstractNode *ModuleContext::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const
+const AbstractModule *ModuleContext::findLocalModule(const std::string &name) const
{
- if (this->modules_p && this->modules_p->find(inst.name()) != this->modules_p->end()) {
- AbstractModule *m = this->modules_p->find(inst.name())->second;
- std::string replacement = Builtins::instance()->isDeprecated(inst.name());
+ if (this->modules_p && this->modules_p->find(name) != this->modules_p->end()) {
+ AbstractModule *m = this->modules_p->find(name)->second;
+ std::string replacement = Builtins::instance()->isDeprecated(name);
if (!replacement.empty()) {
- PRINTB("DEPRECATED: The %s() module will be removed in future releases. Use %s() instead.", inst.name() % replacement);
+ PRINTB("DEPRECATED: The %s() module will be removed in future releases. Use %s() instead.", name % replacement);
}
- return m->instantiate(this, &inst, evalctx);
+ return m;
}
+ return NULL;
+}
- if (this->usedlibs_p) {
- BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, *this->usedlibs_p) {
- assert(m.second);
- if (m.second->scope.modules.find(inst.name()) != m.second->scope.modules.end()) {
- ModuleContext ctx(m.second, this->parent);
- // FIXME: Set document path
-#if 0 && DEBUG
- PRINT("New lib Context:");
- ctx.dump(NULL, &inst);
-#endif
- return m.second->scope.modules[inst.name()]->instantiate(&ctx, &inst, evalctx);
- }
- }
+Value ModuleContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const
+{
+ RecursionGuard g(*this, name);
+ if (g.recursion_detected()) {
+ PRINTB("Recursion detected calling function '%s'", name);
+ return Value();
}
+ const AbstractFunction *foundf = findLocalFunction(name);
+ if (foundf) return foundf->evaluate(this, evalctx);
+
+ return Context::evaluate_function(name, evalctx);
+}
+
+AbstractNode *ModuleContext::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const
+{
+ const AbstractModule *foundm = this->findLocalModule(inst.name());
+ if (foundm) return foundm->instantiate(this, &inst, evalctx);
+
return Context::instantiate_module(inst, evalctx);
}
@@ -150,10 +133,57 @@ void ModuleContext::dump(const AbstractModule *mod, const ModuleInstantiation *i
}
#endif
-FileContext::FileContext(const class FileModule &module,
- const Context *parent, const EvalContext *evalctx)
- :ModuleContext(&module, parent, evalctx)
+FileContext::FileContext(const class FileModule &module, const Context *parent)
+ : usedlibs(module.usedlibs), ModuleContext(parent)
+{
+ if (!module.modulePath().empty()) this->document_path = module.modulePath();
+}
+
+Value FileContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const
{
+ RecursionGuard g(*this, name);
+ if (g.recursion_detected()) {
+ PRINTB("Recursion detected calling function '%s'", name);
+ return Value();
+ }
+
+ const AbstractFunction *foundf = findLocalFunction(name);
+ if (foundf) return foundf->evaluate(this, evalctx);
+ BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) {
+ if (m.second->scope.functions.find(name) != m.second->scope.functions.end()) {
+ FileContext ctx(*m.second, this->parent);
+ ctx.initializeModule(*m.second);
+ // FIXME: Set document path
+#if 0 && DEBUG
+ PRINTB("New lib Context for %s func:", name);
+ ctx.dump(NULL, NULL);
+#endif
+ return m.second->scope.functions[name]->evaluate(&ctx, evalctx);
+ }
+ }
+
+ return ModuleContext::evaluate_function(name, evalctx);
}
+AbstractNode *FileContext::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const
+{
+ const AbstractModule *foundm = this->findLocalModule(inst.name());
+ if (foundm) return foundm->instantiate(this, &inst, evalctx);
+
+ BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) {
+ assert(m.second);
+ if (m.second->scope.modules.find(inst.name()) != m.second->scope.modules.end()) {
+ FileContext ctx(*m.second, this->parent);
+ ctx.initializeModule(*m.second);
+ // FIXME: Set document path
+#if 0 && DEBUG
+ PRINT("New file Context:");
+ ctx.dump(NULL, &inst);
+#endif
+ return m.second->scope.modules[inst.name()]->instantiate(&ctx, &inst, evalctx);
+ }
+ }
+
+ return ModuleContext::instantiate_module(inst, evalctx);
+}
diff --git a/src/modcontext.h b/src/modcontext.h
index d9965c5..4479051 100644
--- a/src/modcontext.h
+++ b/src/modcontext.h
@@ -14,18 +14,21 @@
class ModuleContext : public Context
{
public:
- ModuleContext(const class Module *module = NULL, const Context *parent = NULL, const EvalContext *evalctx = NULL);
+ ModuleContext(const Context *parent = NULL, const EvalContext *evalctx = NULL);
virtual ~ModuleContext();
- void setModule(const Module &module, const EvalContext *evalctx = NULL);
+ void initializeModule(const Module &m);
void registerBuiltin();
+ virtual Value evaluate_function(const std::string &name,
+ const EvalContext *evalctx) const;
+ virtual AbstractNode *instantiate_module(const ModuleInstantiation &inst,
+ const EvalContext *evalctx) const;
- virtual Value evaluate_function(const std::string &name, const EvalContext *evalctx) const;
- virtual AbstractNode *instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const;
+ const AbstractModule *findLocalModule(const std::string &name) const;
+ const AbstractFunction *findLocalFunction(const std::string &name) const;
- const boost::unordered_map<std::string, class AbstractFunction*> *functions_p;
- const boost::unordered_map<std::string, class AbstractModule*> *modules_p;
- const FileModule::ModuleContainer *usedlibs_p;
+ const LocalScope::FunctionContainer *functions_p;
+ const LocalScope::AbstractModuleContainer *modules_p;
// FIXME: Points to the eval context for the call to this module. Not sure where it belongs
const class EvalContext *evalctx;
@@ -40,8 +43,14 @@ public:
class FileContext : public ModuleContext
{
public:
- FileContext(const class FileModule &module, const Context *parent = NULL, const EvalContext *evalctx = NULL);
+ FileContext(const class FileModule &module, const Context *parent);
virtual ~FileContext() {}
+ virtual Value evaluate_function(const std::string &name, const EvalContext *evalctx) const;
+ virtual AbstractNode *instantiate_module(const ModuleInstantiation &inst,
+ const EvalContext *evalctx) const;
+
+private:
+ const FileModule::ModuleContainer &usedlibs;
};
#endif
diff --git a/src/module.cc b/src/module.cc
index a9e3cbf..e9a5169 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -40,50 +40,6 @@ 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()
{
}
@@ -183,14 +139,14 @@ void Module::addChild(ModuleInstantiation *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
+ ModuleContext c(ctx, evalctx);
+ c.initializeModule(*this);
c.set_variable("$children", Value(double(inst->scope.children.size())));
+ // FIXME: Set document path to the path of the module
#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);
std::vector<AbstractNode *> instantiatednodes = this->scope.instantiateChildren(&c);
node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
@@ -259,3 +215,20 @@ bool FileModule::handleDependencies()
this->is_handling_dependencies = false;
return changed;
}
+
+AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
+{
+ assert(evalctx == NULL);
+ FileContext c(*this, ctx);
+ c.initializeModule(*this);
+ // FIXME: Set document path to the path of the module
+#if 0 && DEBUG
+ c.dump(this, inst);
+#endif
+
+ AbstractNode *node = new AbstractNode(inst);
+ std::vector<AbstractNode *> instantiatednodes = this->scope.instantiateChildren(ctx, &c);
+ node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end());
+
+ return node;
+}
diff --git a/src/module.h b/src/module.h
index 39d4bba..b7ee23d 100644
--- a/src/module.h
+++ b/src/module.h
@@ -65,7 +65,7 @@ public:
Module() { }
virtual ~Module();
- virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const;
+ virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
virtual std::string dump(const std::string &indent, const std::string &name) const;
void addChild(ModuleInstantiation *ch);
@@ -75,6 +75,8 @@ public:
LocalScope scope;
};
+// FIXME: A FileModule doesn't have definition arguments, so we shouldn't really
+// inherit from a Module
class FileModule : public Module
{
public:
@@ -85,6 +87,7 @@ public:
const std::string &modulePath() const { return this->path; }
void registerInclude(const std::string &filename);
bool handleDependencies();
+ virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
typedef boost::unordered_map<std::string, class FileModule*> ModuleContainer;
ModuleContainer usedlibs;
diff --git a/src/openscad.cc b/src/openscad.cc
index 96dcf4e..6a0d057 100644
--- a/src/openscad.cc
+++ b/src/openscad.cc
@@ -327,6 +327,14 @@ int main(int argc, char **argv)
if (!filename) help(argv[0]);
+ // Top context - this context only holds builtins
+ ModuleContext top_ctx;
+ top_ctx.registerBuiltin();
+ PRINT("Root Context:");
+#if 0 && DEBUG
+ top_ctx.dump(NULL, NULL);
+#endif
+
FileModule *root_module;
ModuleInstantiation root_inst("group");
AbstractNode *root_node;
@@ -348,18 +356,12 @@ int main(int argc, char **argv)
if (!root_module) exit(1);
root_module->handleDependencies();
- ModuleContext root_ctx;
- root_ctx.registerBuiltin();
- PRINT("Root Context:");
-#if 0 && DEBUG
- root_ctx.dump(NULL, NULL);
-#endif
fs::path fpath = boosty::absolute(fs::path(filename));
fs::path fparent = fpath.parent_path();
fs::current_path(fparent);
AbstractNode::resetIndexCounter();
- absolute_root_node = root_module->instantiate(&root_ctx, &root_inst, NULL);
+ absolute_root_node = root_module->instantiate(&top_ctx, &root_inst, NULL);
// Do we have an explicit root node (! modifier)?
if (!(root_node = find_root_tag(absolute_root_node)))
contact: Jan Huwald // Impressum