diff options
-rw-r--r-- | context.cc | 10 | ||||
-rw-r--r-- | control.cc | 75 | ||||
-rw-r--r-- | csgops.cc | 16 | ||||
-rw-r--r-- | mainwin.cc | 2 | ||||
-rw-r--r-- | module.cc | 43 | ||||
-rw-r--r-- | openscad.h | 13 | ||||
-rw-r--r-- | primitives.cc | 9 | ||||
-rw-r--r-- | transform.cc | 13 |
8 files changed, 127 insertions, 54 deletions
@@ -71,6 +71,7 @@ Value Context::lookup_variable(QString name) const return variables[name]; if (parent) return parent->lookup_variable(name); + PRINTA("WARNING: Ignoring unkown variable '%1'.", name); return Value(); } @@ -80,15 +81,18 @@ Value Context::evaluate_function(QString name, const QVector<QString> &argnames, return functions_p->value(name)->evaluate(this, argnames, argvalues); if (parent) return parent->evaluate_function(name, argnames, argvalues); + PRINTA("WARNING: Ignoring unkown function '%1'.", name); return Value(); } -AbstractNode *Context::evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues, const QVector<AbstractNode*> child_nodes) const +AbstractNode *Context::evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const { + if (arg_context == NULL) + arg_context = this; if (modules_p->contains(name)) - return modules_p->value(name)->evaluate(this, argnames, argvalues, child_nodes); + return modules_p->value(name)->evaluate(this, argnames, argvalues, arg_children, arg_context); if (parent) - return parent->evaluate_module(name, argnames, argvalues, child_nodes); + return parent->evaluate_module(name, argnames, argvalues, arg_children, arg_context); PRINTA("WARNING: Ignoring unkown module '%1'.", name); return NULL; } diff --git a/control.cc b/control.cc new file mode 100644 index 0000000..82fa6bf --- /dev/null +++ b/control.cc @@ -0,0 +1,75 @@ +/* + * OpenSCAD (www.openscad.at) + * Copyright (C) 2009 Clifford Wolf <clifford@clifford.at> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define INCLUDE_ABSTRACT_NODE_DETAILS + +#include "openscad.h" + +enum control_type_e { + ASSIGN, + FOR, + IF +}; + +class ControlModule : public AbstractModule +{ +public: + control_type_e type; + ControlModule(control_type_e type) : type(type) { } + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const; +}; + +AbstractNode *ControlModule::evaluate(const Context*, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const +{ + AbstractNode *node = new AbstractNode(); + + if (type == ASSIGN) + { + /* FIXME */ + Context c(arg_context); + for (int i = 0; i < call_argnames.size(); i++) { + if (!call_argnames[i].isEmpty()) + c.set_variable(call_argnames[i], call_argvalues[i]); + } + foreach (ModuleInstanciation *v, arg_children) { + AbstractNode *n = v->evaluate(&c); + if (n != NULL) + node->children.append(n); + } + } + + if (type == FOR) + { + } + + if (type == IF) + { + } + + return node; +} + +void register_builtin_control() +{ + // builtin_modules["assign"] = new ControlModule(ASSIGN); + // builtin_modules["for"] = new ControlModule(FOR); + // builtin_modules["if"] = new ControlModule(IF); +} + @@ -33,7 +33,7 @@ class CsgModule : public AbstractModule public: csg_type_e type; CsgModule(csg_type_e type) : type(type) { } - virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const; }; class CsgNode : public AbstractNode @@ -48,14 +48,14 @@ public: virtual QString dump(QString indent) const; }; -AbstractNode *CsgModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<AbstractNode*> child_nodes) const +AbstractNode *CsgModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const { - if (child_nodes.size() == 1) - return child_nodes[0]; - CsgNode *node = new CsgNode(type); - foreach (AbstractNode *v, child_nodes) - node->children.append(v); + foreach (ModuleInstanciation *v, arg_children) { + AbstractNode *n = v->evaluate(arg_context); + if (n != NULL) + node->children.append(n); + } return node; } @@ -117,7 +117,7 @@ QString CsgNode::dump(QString indent) const return text + indent + "}\n"; } -void register_builtin_csg() +void register_builtin_csgops() { builtin_modules["union"] = new CsgModule(UNION); builtin_modules["difference"] = new CsgModule(DIFFERENCE); @@ -218,7 +218,7 @@ void MainWindow::compile() QApplication::processEvents(); AbstractNode::idx_counter = 1; - root_node = root_module->evaluate(&root_ctx, QVector<QString>(), QVector<Value>(), QVector<AbstractNode*>()); + root_node = root_module->evaluate(&root_ctx, QVector<QString>(), QVector<Value>(), QVector<ModuleInstanciation*>(), NULL); if (!root_node) goto fail; @@ -26,14 +26,16 @@ AbstractModule::~AbstractModule() { } -AbstractNode *AbstractModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<AbstractNode*> child_nodes) const +AbstractNode *AbstractModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const { - if (child_nodes.size() == 1) - return child_nodes[0]; - AbstractNode *node = new AbstractNode(); - foreach (AbstractNode *v, child_nodes) - node->children.append(v); + + foreach (ModuleInstanciation *v, arg_children) { + AbstractNode *n = v->evaluate(arg_context); + if (n) + node->children.append(n); + } + return node; } @@ -84,13 +86,7 @@ AbstractNode *ModuleInstanciation::evaluate(const Context *ctx) const foreach (Expression *v, argexpr) { argvalues.append(v->evaluate(ctx)); } - QVector<AbstractNode*> child_nodes; - foreach (ModuleInstanciation *v, children) { - AbstractNode *n = v->evaluate(ctx); - if (n != NULL) - child_nodes.append(n); - } - return ctx->evaluate_module(modname, argnames, argvalues, child_nodes); + return ctx->evaluate_module(modname, argnames, argvalues, children); } Module::~Module() @@ -105,7 +101,7 @@ Module::~Module() delete v; } -AbstractNode *Module::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const +AbstractNode *Module::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const { Context c(ctx); c.args(argnames, argexpr, call_argnames, call_argvalues); @@ -124,14 +120,10 @@ AbstractNode *Module::evaluate(const Context *ctx, const QVector<QString> &call_ node->children.append(n); } - foreach (AbstractNode *v, child_nodes) - node->children.append(v); - - if (node->children.size() == 1) { - AbstractNode *c = node->children[0]; - node->children.clear(); - delete node; - return c; + foreach(ModuleInstanciation *v, arg_children) { + AbstractNode *n = v->evaluate(arg_context); + if (n != NULL) + node->children.append(n); } return node; @@ -184,9 +176,10 @@ void initialize_builtin_modules() { builtin_modules["group"] = new AbstractModule(); - register_builtin_csg(); - register_builtin_trans(); - register_builtin_primitive(); + register_builtin_csgops(); + register_builtin_transform(); + register_builtin_primitives(); + register_builtin_control(); } void destroy_builtin_modules() @@ -192,7 +192,7 @@ class AbstractModule { public: virtual ~AbstractModule(); - virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const; virtual QString dump(QString indent, QString name) const; }; @@ -229,7 +229,7 @@ public: Module() { } virtual ~Module(); - virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const; virtual QString dump(QString indent, QString name) const; }; @@ -237,9 +237,10 @@ extern QHash<QString, AbstractModule*> builtin_modules; extern void initialize_builtin_modules(); extern void destroy_builtin_modules(); -extern void register_builtin_csg(); -extern void register_builtin_trans(); -extern void register_builtin_primitive(); +extern void register_builtin_csgops(); +extern void register_builtin_transform(); +extern void register_builtin_primitives(); +extern void register_builtin_control(); class Context { @@ -261,7 +262,7 @@ public: Value lookup_variable(QString name) const; Value evaluate_function(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues) const; - AbstractNode *evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues, const QVector<AbstractNode*> child_nodes) const; + AbstractNode *evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context = NULL) const; }; // The CGAL template magic slows down the compilation process by a factor of 5. diff --git a/primitives.cc b/primitives.cc index ac80ac5..59c5938 100644 --- a/primitives.cc +++ b/primitives.cc @@ -33,7 +33,7 @@ class PrimitiveModule : public AbstractModule public: primitive_type_e type; PrimitiveModule(primitive_type_e type) : type(type) { } - virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const; }; class PrimitiveNode : public AbstractPolyNode @@ -48,7 +48,7 @@ public: virtual QString dump(QString indent) const; }; -AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const +AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*>, const Context*) const { PrimitiveNode *node = new PrimitiveNode(type); @@ -123,13 +123,10 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector<QStrin } } - foreach (AbstractNode *v, child_nodes) - delete v; - return node; } -void register_builtin_primitive() +void register_builtin_primitives() { builtin_modules["cube"] = new PrimitiveModule(CUBE); builtin_modules["sphere"] = new PrimitiveModule(SPHERE); diff --git a/transform.cc b/transform.cc index 5951a70..de29aaf 100644 --- a/transform.cc +++ b/transform.cc @@ -34,7 +34,7 @@ class TransformModule : public AbstractModule public: transform_type_e type; TransformModule(transform_type_e type) : type(type) { } - virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const; }; class TransformNode : public AbstractNode @@ -48,7 +48,7 @@ public: virtual QString dump(QString indent) const; }; -AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const +AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const { TransformNode *node = new TransformNode(); @@ -140,8 +140,11 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector<QStrin } } - foreach (AbstractNode *v, child_nodes) - node->children.append(v); + foreach (ModuleInstanciation *v, arg_children) { + AbstractNode *n = v->evaluate(arg_context); + if (n != NULL) + node->children.append(n); + } return node; } @@ -204,7 +207,7 @@ QString TransformNode::dump(QString indent) const return text + indent + "}\n"; } -void register_builtin_trans() +void register_builtin_transform() { builtin_modules["scale"] = new TransformModule(SCALE); builtin_modules["rotate"] = new TransformModule(ROTATE); |