From ed687599bf1ca36869dc64dab2b9969f1d96b4c1 Mon Sep 17 00:00:00 2001 From: clifford Date: Mon, 29 Jun 2009 20:30:43 +0000 Subject: Clifford Wolf: Restructured AST evaluation for control statements git-svn-id: http://svn.clifford.at/openscad/trunk@37 b57f626f-c46c-0410-a088-ec61d464b74c diff --git a/context.cc b/context.cc index fe36a61..3a257c6 100644 --- a/context.cc +++ b/context.cc @@ -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 &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 &argnames, const QVector &argvalues, const QVector child_nodes) const +AbstractNode *Context::evaluate_module(QString name, const QVector &argnames, const QVector &argvalues, const QVector 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 + * + * 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 &call_argnames, const QVector &call_argvalues, const QVector arg_children, const Context *arg_context) const; +}; + +AbstractNode *ControlModule::evaluate(const Context*, const QVector &call_argnames, const QVector &call_argvalues, const QVector 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); +} + diff --git a/csgops.cc b/csgops.cc index e1aa246..6d625f7 100644 --- a/csgops.cc +++ b/csgops.cc @@ -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 &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector 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&, const QVector&, const QVector child_nodes) const +AbstractNode *CsgModule::evaluate(const Context*, const QVector&, const QVector&, const QVector 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); diff --git a/mainwin.cc b/mainwin.cc index be51724..d180d9f 100644 --- a/mainwin.cc +++ b/mainwin.cc @@ -218,7 +218,7 @@ void MainWindow::compile() QApplication::processEvents(); AbstractNode::idx_counter = 1; - root_node = root_module->evaluate(&root_ctx, QVector(), QVector(), QVector()); + root_node = root_module->evaluate(&root_ctx, QVector(), QVector(), QVector(), NULL); if (!root_node) goto fail; diff --git a/module.cc b/module.cc index 489e3a4..70ce97f 100644 --- a/module.cc +++ b/module.cc @@ -26,14 +26,16 @@ AbstractModule::~AbstractModule() { } -AbstractNode *AbstractModule::evaluate(const Context*, const QVector&, const QVector&, const QVector child_nodes) const +AbstractNode *AbstractModule::evaluate(const Context*, const QVector&, const QVector&, const QVector 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 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 &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const +AbstractNode *Module::evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector 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 &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() diff --git a/openscad.h b/openscad.h index c139d6e..0a8fa5c 100644 --- a/openscad.h +++ b/openscad.h @@ -192,7 +192,7 @@ class AbstractModule { public: virtual ~AbstractModule(); - virtual AbstractNode *evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector 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 &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector arg_children, const Context *arg_context) const; virtual QString dump(QString indent, QString name) const; }; @@ -237,9 +237,10 @@ extern QHash 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 &argnames, const QVector &argvalues) const; - AbstractNode *evaluate_module(QString name, const QVector &argnames, const QVector &argvalues, const QVector child_nodes) const; + AbstractNode *evaluate_module(QString name, const QVector &argnames, const QVector &argvalues, const QVector 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 &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector 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 &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const +AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector, const Context*) const { PrimitiveNode *node = new PrimitiveNode(type); @@ -123,13 +123,10 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector 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 &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const +AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector arg_children, const Context *arg_context) const { TransformNode *node = new TransformNode(); @@ -140,8 +140,11 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const QVectorchildren.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); -- cgit v0.10.1