diff options
author | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-07-01 09:48:25 (GMT) |
---|---|---|
committer | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-07-01 09:48:25 (GMT) |
commit | 82fad98cb63d6e27e7c156d4c5e4c9a9847abfd1 (patch) | |
tree | d70ff76ec4f5138706df5cb11fd034e60d927f4d | |
parent | 27ecd0b1d0bf0114b465beeb4db482f0f1f87c52 (diff) |
Clifford Wolf:
Yet another redesign of the evaluation path
git-svn-id: http://svn.clifford.at/openscad/trunk@44 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r-- | context.cc | 12 | ||||
-rw-r--r-- | control.cc | 32 | ||||
-rw-r--r-- | csgops.cc | 12 | ||||
-rw-r--r-- | mainwin.cc | 5 | ||||
-rw-r--r-- | module.cc | 39 | ||||
-rw-r--r-- | openscad.h | 17 | ||||
-rw-r--r-- | parser.y | 28 | ||||
-rw-r--r-- | primitives.cc | 10 | ||||
-rw-r--r-- | transform.cc | 13 |
9 files changed, 97 insertions, 71 deletions
@@ -87,15 +87,13 @@ Value Context::evaluate_function(QString name, const QVector<QString> &argnames, return Value(); } -AbstractNode *Context::evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const +AbstractNode *Context::evaluate_module(const ModuleInstanciation *inst) const { - if (arg_context == NULL) - arg_context = this; - if (modules_p && modules_p->contains(name)) - return modules_p->value(name)->evaluate(this, argnames, argvalues, arg_children, arg_context); + if (modules_p && modules_p->contains(inst->modname)) + return modules_p->value(inst->modname)->evaluate(this, inst); if (parent) - return parent->evaluate_module(name, argnames, argvalues, arg_children, arg_context); - PRINTA("WARNING: Ignoring unkown module '%1'.", name); + return parent->evaluate_module(inst); + PRINTA("WARNING: Ignoring unkown module '%1'.", inst->modname); return NULL; } @@ -34,7 +34,7 @@ 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; + virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstanciation *inst) const; }; void for_eval(AbstractNode *node, int l, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) @@ -77,31 +77,31 @@ void for_eval(AbstractNode *node, int l, const QVector<QString> &call_argnames, } } -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 *ControlModule::evaluate(const Context*, const ModuleInstanciation *inst) const { - AbstractNode *node = new AbstractNode(); + AbstractNode *node = new AbstractNode(inst); if (type == ECHO) { QString msg = QString("ECHO: "); - for (int i = 0; i < call_argnames.size(); i++) { + for (int i = 0; i < inst->argnames.size(); i++) { if (i > 0) msg += QString(", "); - if (!call_argnames[i].isEmpty()) - msg += call_argnames[i] + QString(" = "); - msg += call_argvalues[i].dump(); + if (!inst->argnames[i].isEmpty()) + msg += inst->argnames[i] + QString(" = "); + msg += inst->argvalues[i].dump(); } PRINT(msg); } if (type == ASSIGN) { - 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]); + Context c(inst->ctx); + for (int i = 0; i < inst->argnames.size(); i++) { + if (!inst->argnames[i].isEmpty()) + c.set_variable(inst->argnames[i], inst->argvalues[i]); } - foreach (ModuleInstanciation *v, arg_children) { + foreach (ModuleInstanciation *v, inst->children) { AbstractNode *n = v->evaluate(&c); if (n != NULL) node->children.append(n); @@ -110,14 +110,14 @@ AbstractNode *ControlModule::evaluate(const Context*, const QVector<QString> &ca if (type == FOR) { - for_eval(node, 0, call_argnames, call_argvalues, arg_children, arg_context); + for_eval(node, 0, inst->argnames, inst->argvalues, inst->children, inst->ctx); } if (type == IF) { - if (call_argvalues.size() > 0 && call_argvalues[0].type == Value::BOOL && call_argvalues[0].b) - foreach (ModuleInstanciation *v, arg_children) { - AbstractNode *n = v->evaluate(arg_context); + if (inst->argvalues.size() > 0 && inst->argvalues[0].type == Value::BOOL && inst->argvalues[0].b) + foreach (ModuleInstanciation *v, inst->children) { + AbstractNode *n = v->evaluate(inst->ctx); if (n != NULL) node->children.append(n); } @@ -33,14 +33,14 @@ 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<ModuleInstanciation*> arg_children, const Context *arg_context) const; + virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstanciation *inst) const; }; class CsgNode : public AbstractNode { public: csg_type_e type; - CsgNode(csg_type_e type) : type(type) { } + CsgNode(const ModuleInstanciation *mi, csg_type_e type) : AbstractNode(mi), type(type) { } #ifdef ENABLE_CGAL virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; #endif @@ -48,11 +48,11 @@ public: virtual QString dump(QString indent) const; }; -AbstractNode *CsgModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const +AbstractNode *CsgModule::evaluate(const Context*, const ModuleInstanciation *inst) const { - CsgNode *node = new CsgNode(type); - foreach (ModuleInstanciation *v, arg_children) { - AbstractNode *n = v->evaluate(arg_context); + CsgNode *node = new CsgNode(inst, type); + foreach (ModuleInstanciation *v, inst->children) { + AbstractNode *n = v->evaluate(inst->ctx); if (n != NULL) node->children.append(n); } @@ -238,7 +238,10 @@ void MainWindow::compile() QApplication::processEvents(); AbstractNode::idx_counter = 1; - root_node = root_module->evaluate(&root_ctx, QVector<QString>(), QVector<Value>(), QVector<ModuleInstanciation*>(), NULL); + { + ModuleInstanciation root_inst; + root_node = root_module->evaluate(&root_ctx, &root_inst); + } if (!root_node) goto fail; @@ -26,12 +26,12 @@ AbstractModule::~AbstractModule() { } -AbstractNode *AbstractModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<ModuleInstanciation*> arg_children, const Context *arg_context) const +AbstractNode *AbstractModule::evaluate(const Context*, const ModuleInstanciation *inst) const { - AbstractNode *node = new AbstractNode(); + AbstractNode *node = new AbstractNode(inst); - foreach (ModuleInstanciation *v, arg_children) { - AbstractNode *n = v->evaluate(arg_context); + foreach (ModuleInstanciation *v, inst->children) { + AbstractNode *n = v->evaluate(inst->ctx); if (n) node->children.append(n); } @@ -82,11 +82,21 @@ QString ModuleInstanciation::dump(QString indent) const AbstractNode *ModuleInstanciation::evaluate(const Context *ctx) const { - QVector<Value> argvalues; - foreach (Expression *v, argexpr) { - argvalues.append(v->evaluate(ctx)); + AbstractNode *node = NULL; + if (this->ctx) { + PRINTA("WARNING: Ignoring recursive module instanciation of '%1'.", modname); + } else { + ModuleInstanciation *that = (ModuleInstanciation*)this; + that->argvalues.clear(); + foreach (Expression *v, that->argexpr) { + that->argvalues.append(v->evaluate(ctx)); + } + that->ctx = ctx; + node = ctx->evaluate_module(this); + that->ctx = NULL; + that->argvalues.clear(); } - return ctx->evaluate_module(modname, argnames, argvalues, children); + return node; } Module::~Module() @@ -101,10 +111,10 @@ Module::~Module() delete v; } -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 +AbstractNode *Module::evaluate(const Context *ctx, const ModuleInstanciation *inst) const { Context c(ctx); - c.args(argnames, argexpr, call_argnames, call_argvalues); + c.args(argnames, argexpr, inst->argnames, inst->argvalues); c.functions_p = &functions; c.modules_p = &modules; @@ -113,15 +123,15 @@ AbstractNode *Module::evaluate(const Context *ctx, const QVector<QString> &call_ c.set_variable(assignments_var[i], assignments_expr[i]->evaluate(&c)); } - AbstractNode *node = new AbstractNode(); + AbstractNode *node = new AbstractNode(inst); for (int i = 0; i < children.size(); i++) { AbstractNode *n = children[i]->evaluate(&c); if (n != NULL) node->children.append(n); } - foreach(ModuleInstanciation *v, arg_children) { - AbstractNode *n = v->evaluate(arg_context); + foreach(ModuleInstanciation *v, inst->children) { + AbstractNode *n = v->evaluate(inst->ctx); if (n != NULL) node->children.append(n); } @@ -191,8 +201,9 @@ void destroy_builtin_modules() int AbstractNode::idx_counter; -AbstractNode::AbstractNode() +AbstractNode::AbstractNode(const ModuleInstanciation *mi) { + modinst = mi; idx = idx_counter++; } @@ -209,7 +209,7 @@ class AbstractModule { public: virtual ~AbstractModule(); - 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 AbstractNode *evaluate(const Context *ctx, const ModuleInstanciation *inst) const; virtual QString dump(QString indent, QString name) const; }; @@ -220,9 +220,14 @@ public: QString modname; QVector<QString> argnames; QVector<Expression*> argexpr; + QVector<Value> argvalues; QVector<ModuleInstanciation*> children; - ModuleInstanciation() { } + bool tag_root; + bool tag_highlight; + const Context *ctx; + + ModuleInstanciation() : tag_root(false), tag_highlight(false), ctx(NULL) { } ~ModuleInstanciation(); QString dump(QString indent) const; @@ -246,7 +251,7 @@ public: Module() { } virtual ~Module(); - 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 AbstractNode *evaluate(const Context *ctx, const ModuleInstanciation *inst) const; virtual QString dump(QString indent, QString name) const; }; @@ -279,7 +284,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<ModuleInstanciation*> arg_children, const Context *arg_context = NULL) const; + AbstractNode *evaluate_module(const ModuleInstanciation *inst) const; }; // The CGAL template magic slows down the compilation process by a factor of 5. @@ -390,6 +395,7 @@ class AbstractNode { public: QVector<AbstractNode*> children; + const ModuleInstanciation *modinst; int progress_mark; void progress_prepare(); @@ -398,7 +404,7 @@ public: int idx; static int idx_counter; - AbstractNode(); + AbstractNode(const ModuleInstanciation *mi); virtual ~AbstractNode(); #ifdef ENABLE_CGAL virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; @@ -414,6 +420,7 @@ public: RENDER_CGAL, RENDER_OPENCSG }; + AbstractPolyNode(const ModuleInstanciation *mi) : AbstractNode(mi) { }; virtual PolySet *render_polyset(render_mode_e mode) const; #ifdef ENABLE_CGAL virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; @@ -68,13 +68,15 @@ public: %token LE GE EQ NE AND OR -%left '+' '-' +%left '[' ']' +%left '!' '+' '-' %left '*' '/' '%' %left '.' %left '<' LE GE '>' %left EQ NE %left AND %left OR +%right '?' ':' %type <expr> expr %type <value> vector_const @@ -165,17 +167,20 @@ single_module_instantciation: free($1); delete $3; } | - TOK_ID ':' TOK_ID '(' arguments_call ')' { - $$ = new ModuleInstanciation(); + TOK_ID ':' single_module_instantciation { + $$ = $3; $$->label = QString($1); - $$->modname = QString($3); - $$->argnames = $5->argnames; - $$->argexpr = $5->argexpr; free($1); - free($3); - delete $5; - } ; - + } | + '!' single_module_instantciation { + $$ = $2; + $$->tag_root = true; + } | + '#' single_module_instantciation { + $$ = $2; + $$->tag_highlight = true; + }; + expr: TOK_TRUE { $$ = new Expression(); @@ -365,10 +370,11 @@ expr: } ; vector_const: - TOK_NUMBER { + TOK_NUMBER TOK_NUMBER { $$ = new Value(); $$->type = Value::VECTOR; $$->vec.append(new Value($1)); + $$->vec.append(new Value($2)); } | vector_const TOK_NUMBER { $$ = $1; diff --git a/primitives.cc b/primitives.cc index 6954e87..4494b03 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<ModuleInstanciation*> arg_children, const Context *arg_context) const; + virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstanciation *inst) const; }; class PrimitiveNode : public AbstractPolyNode @@ -43,14 +43,14 @@ public: double x, y, z, h, r1, r2; double fn, fs, fa; primitive_type_e type; - PrimitiveNode(primitive_type_e type) : type(type) { } + PrimitiveNode(const ModuleInstanciation *mi, primitive_type_e type) : AbstractPolyNode(mi), type(type) { } virtual PolySet *render_polyset(render_mode_e mode) const; virtual QString dump(QString indent) const; }; -AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<ModuleInstanciation*>, const Context*) const +AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const ModuleInstanciation *inst) const { - PrimitiveNode *node = new PrimitiveNode(type); + PrimitiveNode *node = new PrimitiveNode(inst, type); node->center = false; node->x = node->y = node->z = node->h = node->r1 = node->r2 = 1; @@ -69,7 +69,7 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const QVector<QStrin } Context c(ctx); - c.args(argnames, argexpr, call_argnames, call_argvalues); + c.args(argnames, argexpr, inst->argnames, inst->argvalues); node->fn = c.lookup_variable("$fn").num; node->fs = c.lookup_variable("$fs").num; diff --git a/transform.cc b/transform.cc index 6c73993..687a570 100644 --- a/transform.cc +++ b/transform.cc @@ -34,13 +34,14 @@ 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<ModuleInstanciation*> arg_children, const Context *arg_context) const; + virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstanciation *inst) const; }; class TransformNode : public AbstractNode { public: double m[16]; + TransformNode(const ModuleInstanciation *mi) : AbstractNode(mi) { } #ifdef ENABLE_CGAL virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; #endif @@ -48,9 +49,9 @@ 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<ModuleInstanciation*> arg_children, const Context *arg_context) const +AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanciation *inst) const { - TransformNode *node = new TransformNode(); + TransformNode *node = new TransformNode(inst); for (int i = 0; i < 16; i++) { node->m[i] = i % 5 == 0 ? 1.0 : 0.0; @@ -73,7 +74,7 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector<QStrin } Context c(ctx); - c.args(argnames, argexpr, call_argnames, call_argvalues); + c.args(argnames, argexpr, inst->argnames, inst->argvalues); if (type == SCALE) { @@ -132,8 +133,8 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const QVector<QStrin } } - foreach (ModuleInstanciation *v, arg_children) { - AbstractNode *n = v->evaluate(arg_context); + foreach (ModuleInstanciation *v, inst->children) { + AbstractNode *n = v->evaluate(inst->ctx); if (n != NULL) node->children.append(n); } |