summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--context.cc12
-rw-r--r--control.cc32
-rw-r--r--csgops.cc12
-rw-r--r--mainwin.cc5
-rw-r--r--module.cc39
-rw-r--r--openscad.h17
-rw-r--r--parser.y28
-rw-r--r--primitives.cc10
-rw-r--r--transform.cc13
9 files changed, 97 insertions, 71 deletions
diff --git a/context.cc b/context.cc
index a7b537d..7e6174d 100644
--- a/context.cc
+++ b/context.cc
@@ -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;
}
diff --git a/control.cc b/control.cc
index 8c073da..cea17b9 100644
--- a/control.cc
+++ b/control.cc
@@ -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);
}
diff --git a/csgops.cc b/csgops.cc
index 6d625f7..12c6875 100644
--- a/csgops.cc
+++ b/csgops.cc
@@ -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);
}
diff --git a/mainwin.cc b/mainwin.cc
index 79012c7..45cc289 100644
--- a/mainwin.cc
+++ b/mainwin.cc
@@ -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;
diff --git a/module.cc b/module.cc
index 70ce97f..d090ac7 100644
--- a/module.cc
+++ b/module.cc
@@ -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++;
}
diff --git a/openscad.h b/openscad.h
index 081a7a0..2de5d42 100644
--- a/openscad.h
+++ b/openscad.h
@@ -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;
diff --git a/parser.y b/parser.y
index 8006c6a..50cef6e 100644
--- a/parser.y
+++ b/parser.y
@@ -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);
}
contact: Jan Huwald // Impressum