diff options
author | Marius Kintel <marius@kintel.net> | 2013-04-19 01:42:33 (GMT) |
---|---|---|
committer | Marius Kintel <marius@kintel.net> | 2013-04-26 21:42:32 (GMT) |
commit | 64ed1eb9fe00e287d84b18830df86cc0de6b122a (patch) | |
tree | 3b5f4a51209b62a14d28abc7c0e01fc5753e162c | |
parent | a96f3f3c67d496279151cd3fff47589b8684c378 (diff) |
Experiment: Lazy evaluation of argument lists in evaluation context. Allows e.g. for loop variables to be dependent on each other
-rw-r--r-- | src/context.cc | 6 | ||||
-rw-r--r-- | src/control.cc | 28 | ||||
-rw-r--r-- | src/dxfdim.cc | 40 | ||||
-rw-r--r-- | src/evalcontext.cc | 17 | ||||
-rw-r--r-- | src/evalcontext.h | 19 | ||||
-rw-r--r-- | src/expr.cc | 6 | ||||
-rw-r--r-- | src/func.cc | 154 | ||||
-rw-r--r-- | src/linearextrude.cc | 8 | ||||
-rw-r--r-- | src/module.cc | 9 |
9 files changed, 151 insertions, 136 deletions
diff --git a/src/context.cc b/src/context.cc index 706407c..ea48dad 100644 --- a/src/context.cc +++ b/src/context.cc @@ -66,9 +66,9 @@ void Context::setVariables(const AssignmentList &args, if (evalctx) { size_t posarg = 0; - for (size_t i=0; i<evalctx->eval_arguments.size(); i++) { - const std::string &name = evalctx->eval_arguments[i].first; - const Value &val = evalctx->eval_arguments[i].second; + for (size_t i=0; i<evalctx->numArgs(); i++) { + const std::string &name = evalctx->getArgName(i); + const Value &val = evalctx->getArgValue(i); if (name.empty()) { if (posarg < args.size()) this->set_variable(args[posarg++].first, val); } else { diff --git a/src/control.cc b/src/control.cc index d47eec0..d45ee02 100644 --- a/src/control.cc +++ b/src/control.cc @@ -52,9 +52,9 @@ public: void for_eval(AbstractNode &node, const ModuleInstantiation &inst, size_t l, const Context *ctx, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() > l) { - const std::string &it_name = evalctx->eval_arguments[l].first; - const Value &it_values = evalctx->eval_arguments[l].second; + if (evalctx->numArgs() > l) { + const std::string &it_name = evalctx->getArgName(l); + const Value &it_values = evalctx->getArgValue(l, ctx); Context c(ctx); if (it_values.type() == Value::RANGE) { Value::RangeType range = it_values.toRange(); @@ -93,9 +93,9 @@ AbstractNode *ControlModule::evaluate(const Context *ctx, const ModuleInstantiat if (type == CHILD) { int n = 0; - if (evalctx->eval_arguments.size() > 0) { + if (evalctx->numArgs() > 0) { double v; - if (evalctx->eval_arguments[0].second.getDouble(v)) { + if (evalctx->getArgValue(0).getDouble(v)) { n = trunc(v); if (n < 0) { PRINTB("WARNING: Negative child index (%d) not allowed", n); @@ -114,14 +114,14 @@ AbstractNode *ControlModule::evaluate(const Context *ctx, const ModuleInstantiat // assert(filectx->evalctx); if (filectx->evalctx) { - if (n < filectx->evalctx->children.size()) { - node = filectx->evalctx->children[n]->evaluate_instance(filectx->evalctx); + if (n < filectx->evalctx->numChildren()) { + node = filectx->evalctx->getChild(n)->evaluate_instance(filectx->evalctx); } else { // How to deal with negative objects in this case? // (e.g. first child of difference is invalid) PRINTB("WARNING: Child index (%d) out of bounds (%d children)", - n % filectx->evalctx->children.size()); + n % filectx->evalctx->numChildren()); } } return node; @@ -142,8 +142,8 @@ AbstractNode *ControlModule::evaluate(const Context *ctx, const ModuleInstantiat msg << "ECHO: "; for (size_t i = 0; i < inst->arguments.size(); i++) { if (i > 0) msg << ", "; - if (!evalctx->eval_arguments[i].first.empty()) msg << evalctx->eval_arguments[i].first << " = "; - msg << evalctx->eval_arguments[i].second; + if (!evalctx->getArgName(i).empty()) msg << evalctx->getArgName(i) << " = "; + msg << evalctx->getArgValue(i); } PRINTB("%s", msg.str()); } @@ -151,9 +151,9 @@ AbstractNode *ControlModule::evaluate(const Context *ctx, const ModuleInstantiat if (type == ASSIGN) { Context c(evalctx); - for (size_t i = 0; i < evalctx->eval_arguments.size(); i++) { - if (!evalctx->eval_arguments[i].first.empty()) - c.set_variable(evalctx->eval_arguments[i].first, evalctx->eval_arguments[i].second); + for (size_t i = 0; i < evalctx->numArgs(); i++) { + if (!evalctx->getArgName(i).empty()) + c.set_variable(evalctx->getArgName(i), evalctx->getArgValue(i)); } std::vector<AbstractNode *> evaluatednodes = inst->evaluateChildren(&c); node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); @@ -167,7 +167,7 @@ AbstractNode *ControlModule::evaluate(const Context *ctx, const ModuleInstantiat if (type == IF) { const IfElseModuleInstantiation *ifelse = dynamic_cast<const IfElseModuleInstantiation*>(inst); - if (evalctx->eval_arguments.size() > 0 && evalctx->eval_arguments[0].second.toBool()) { + if (evalctx->numArgs() > 0 && evalctx->getArgValue(0).toBool()) { std::vector<AbstractNode *> evaluatednodes = ifelse->evaluateChildren(evalctx); node->children.insert(node->children.end(), evaluatednodes.begin(), evaluatednodes.end()); } diff --git a/src/dxfdim.cc b/src/dxfdim.cc index fbc24c4..ecdae80 100644 --- a/src/dxfdim.cc +++ b/src/dxfdim.cc @@ -52,17 +52,17 @@ Value builtin_dxf_dim(const Context *ctx, const EvalContext *evalctx) // FIXME: We don't lookup the file relative to where this function was instantiated // since the path is only available for ModuleInstantiations, not function expressions. // See issue #217 - for (size_t i = 0; i < evalctx->eval_arguments.size(); i++) { - if (evalctx->eval_arguments[i].first == "file") - filename = ctx->getAbsolutePath(evalctx->eval_arguments[i].second.toString()); - if (evalctx->eval_arguments[i].first == "layer") - layername = evalctx->eval_arguments[i].second.toString(); - if (evalctx->eval_arguments[i].first == "origin") - evalctx->eval_arguments[i].second.getVec2(xorigin, yorigin); - if (evalctx->eval_arguments[i].first == "scale") - evalctx->eval_arguments[i].second.getDouble(scale); - if (evalctx->eval_arguments[i].first == "name") - name = evalctx->eval_arguments[i].second.toString(); + for (size_t i = 0; i < evalctx->numArgs(); i++) { + if (evalctx->getArgName(i) == "file") + filename = ctx->getAbsolutePath(evalctx->getArgValue(i).toString()); + if (evalctx->getArgName(i) == "layer") + layername = evalctx->getArgValue(i).toString(); + if (evalctx->getArgName(i) == "origin") + evalctx->getArgValue(i).getVec2(xorigin, yorigin); + if (evalctx->getArgName(i) == "scale") + evalctx->getArgValue(i).getDouble(scale); + if (evalctx->getArgName(i) == "name") + name = evalctx->getArgValue(i).toString(); } std::stringstream keystream; @@ -146,15 +146,15 @@ Value builtin_dxf_cross(const Context *ctx, const EvalContext *evalctx) // FIXME: We don't lookup the file relative to where this function was instantiated // since the path is only available for ModuleInstantiations, not function expressions. // See isse #217 - for (size_t i = 0; i < evalctx->eval_arguments.size(); i++) { - if (evalctx->eval_arguments[i].first == "file") - filename = ctx->getAbsolutePath(evalctx->eval_arguments[i].second.toString()); - if (evalctx->eval_arguments[i].first == "layer") - layername = evalctx->eval_arguments[i].second.toString(); - if (evalctx->eval_arguments[i].first == "origin") - evalctx->eval_arguments[i].second.getVec2(xorigin, yorigin); - if (evalctx->eval_arguments[i].first == "scale") - evalctx->eval_arguments[i].second.getDouble(scale); + for (size_t i = 0; i < evalctx->numArgs(); i++) { + if (evalctx->getArgName(i) == "file") + filename = ctx->getAbsolutePath(evalctx->getArgValue(i).toString()); + if (evalctx->getArgName(i) == "layer") + layername = evalctx->getArgValue(i).toString(); + if (evalctx->getArgName(i) == "origin") + evalctx->getArgValue(i).getVec2(xorigin, yorigin); + if (evalctx->getArgName(i) == "scale") + evalctx->getArgValue(i).getDouble(scale); } std::stringstream keystream; diff --git a/src/evalcontext.cc b/src/evalcontext.cc index b7566e3..25b6716 100644 --- a/src/evalcontext.cc +++ b/src/evalcontext.cc @@ -7,6 +7,19 @@ #include <boost/foreach.hpp> +const std::string &EvalContext::getArgName(size_t i) const +{ + assert(i < this->eval_arguments.size()); + return this->eval_arguments[i].first; +} + +Value EvalContext::getArgValue(size_t i, const Context *ctx) const +{ + assert(i < this->eval_arguments.size()); + const Assignment &arg = this->eval_arguments[i]; + return arg.second ? arg.second->evaluate(ctx ? ctx : this) : Value(); +} + #ifdef DEBUG void EvalContext::dump(const AbstractModule *mod, const ModuleInstantiation *inst) { @@ -20,9 +33,9 @@ void EvalContext::dump(const AbstractModule *mod, const ModuleInstantiation *ins for (int i=0;i<this->eval_arguments.size();i++) { PRINTB(" %s = %s", this->eval_arguments[i].first % this->eval_arguments[i].second); } - if (this->children.size() > 0) { + if (this->children && this->children->size() > 0) { PRINT(" children:"); - BOOST_FOREACH(const ModuleInstantiation *ch, this->children) { + BOOST_FOREACH(const ModuleInstantiation *ch, *this->children) { PRINTB(" %s", ch->name()); } } diff --git a/src/evalcontext.h b/src/evalcontext.h index 3d7d222..26a4a68 100644 --- a/src/evalcontext.h +++ b/src/evalcontext.h @@ -10,15 +10,28 @@ class EvalContext : public Context { public: - EvalContext(const Context *parent = NULL) : Context(parent) {} + typedef std::vector<class ModuleInstantiation *> InstanceList; + + EvalContext(const Context *parent, + const AssignmentList &args, const InstanceList *const children = NULL) + : Context(parent), eval_arguments(args), children(children) {} virtual ~EvalContext() {} - std::vector<std::pair<std::string, Value> > eval_arguments; - std::vector<class ModuleInstantiation *> children; + size_t numArgs() const { return this->eval_arguments.size(); } + const std::string &getArgName(size_t i) const; + Value getArgValue(size_t i, const Context *ctx = NULL) const; + + size_t numChildren() const { return this->children ? this->children->size() : 0; } + ModuleInstantiation *getChild(size_t i) const { return this->children ? (*this->children)[i] : NULL; } #ifdef DEBUG virtual void dump(const class AbstractModule *mod, const ModuleInstantiation *inst); #endif + +private: + const AssignmentList &eval_arguments; + std::vector<std::pair<std::string, Value> > eval_values; + const InstanceList *const children; }; #endif diff --git a/src/expr.cc b/src/expr.cc index 7a8180f..6629bf5 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -127,11 +127,7 @@ Value Expression::evaluate(const Context *context) const return Value(); } if (this->type == "F") { - EvalContext c(context); - for (size_t i=0; i < this->call_arguments.size(); i++) { - c.eval_arguments.push_back(std::make_pair(this->call_arguments[i].first, - this->call_arguments[i].second->evaluate(context))); - } + EvalContext c(context, this->call_arguments); // Value::VectorType argvalues; // std::transform(this->children.begin(), this->children.end(), // std::back_inserter(argvalues), diff --git a/src/func.cc b/src/func.cc index 88bf3c8..4377a90 100644 --- a/src/func.cc +++ b/src/func.cc @@ -129,35 +129,35 @@ static inline double rad2deg(double x) Value builtin_abs(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(fabs(evalctx->eval_arguments[0].second.toDouble())); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(fabs(evalctx->getArgValue(0).toDouble())); return Value(); } Value builtin_sign(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value((evalctx->eval_arguments[0].second.toDouble()<0) ? -1.0 : ((evalctx->eval_arguments[0].second.toDouble()>0) ? 1.0 : 0.0)); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value((evalctx->getArgValue(0).toDouble()<0) ? -1.0 : ((evalctx->getArgValue(0).toDouble()>0) ? 1.0 : 0.0)); return Value(); } Value builtin_rands(const Context *, const EvalContext *evalctx) { bool deterministic = false; - if (evalctx->eval_arguments.size() == 3 && - evalctx->eval_arguments[0].second.type() == Value::NUMBER && - evalctx->eval_arguments[1].second.type() == Value::NUMBER && - evalctx->eval_arguments[2].second.type() == Value::NUMBER) + if (evalctx->numArgs() == 3 && + evalctx->getArgValue(0).type() == Value::NUMBER && + evalctx->getArgValue(1).type() == Value::NUMBER && + evalctx->getArgValue(2).type() == Value::NUMBER) { deterministic = false; } - else if (evalctx->eval_arguments.size() == 4 && - evalctx->eval_arguments[0].second.type() == Value::NUMBER && - evalctx->eval_arguments[1].second.type() == Value::NUMBER && - evalctx->eval_arguments[2].second.type() == Value::NUMBER && - evalctx->eval_arguments[3].second.type() == Value::NUMBER) + else if (evalctx->numArgs() == 4 && + evalctx->getArgValue(0).type() == Value::NUMBER && + evalctx->getArgValue(1).type() == Value::NUMBER && + evalctx->getArgValue(2).type() == Value::NUMBER && + evalctx->getArgValue(3).type() == Value::NUMBER) { - deterministic_rng.seed( (unsigned int) evalctx->eval_arguments[3].second.toDouble() ); + deterministic_rng.seed( (unsigned int) evalctx->getArgValue(3).toDouble() ); deterministic = true; } else @@ -165,11 +165,11 @@ Value builtin_rands(const Context *, const EvalContext *evalctx) return Value(); } - double min = std::min( evalctx->eval_arguments[0].second.toDouble(), evalctx->eval_arguments[1].second.toDouble() ); - double max = std::max( evalctx->eval_arguments[0].second.toDouble(), evalctx->eval_arguments[1].second.toDouble() ); + double min = std::min( evalctx->getArgValue(0).toDouble(), evalctx->getArgValue(1).toDouble() ); + double max = std::max( evalctx->getArgValue(0).toDouble(), evalctx->getArgValue(1).toDouble() ); boost::uniform_real<> distributor( min, max ); Value::VectorType vec; - for (int i=0; i<evalctx->eval_arguments[2].second.toDouble(); i++) { + for (int i=0; i<evalctx->getArgValue(2).toDouble(); i++) { if ( deterministic ) { vec.push_back( Value( distributor( deterministic_rng ) ) ); } else { @@ -183,11 +183,11 @@ Value builtin_rands(const Context *, const EvalContext *evalctx) Value builtin_min(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() >= 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) { - double val = evalctx->eval_arguments[0].second.toDouble(); - for (size_t i = 1; i < evalctx->eval_arguments.size(); i++) - if (evalctx->eval_arguments[1].second.type() == Value::NUMBER) - val = fmin(val, evalctx->eval_arguments[i].second.toDouble()); + if (evalctx->numArgs() >= 1 && evalctx->getArgValue(0).type() == Value::NUMBER) { + double val = evalctx->getArgValue(0).toDouble(); + for (size_t i = 1; i < evalctx->numArgs(); i++) + if (evalctx->getArgValue(1).type() == Value::NUMBER) + val = fmin(val, evalctx->getArgValue(i).toDouble()); return Value(val); } return Value(); @@ -195,11 +195,11 @@ Value builtin_min(const Context *, const EvalContext *evalctx) Value builtin_max(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() >= 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) { - double val = evalctx->eval_arguments[0].second.toDouble(); - for (size_t i = 1; i < evalctx->eval_arguments.size(); i++) - if (evalctx->eval_arguments[1].second.type() == Value::NUMBER) - val = fmax(val, evalctx->eval_arguments[i].second.toDouble()); + if (evalctx->numArgs() >= 1 && evalctx->getArgValue(0).type() == Value::NUMBER) { + double val = evalctx->getArgValue(0).toDouble(); + for (size_t i = 1; i < evalctx->numArgs(); i++) + if (evalctx->getArgValue(1).type() == Value::NUMBER) + val = fmax(val, evalctx->getArgValue(i).toDouble()); return Value(val); } return Value(); @@ -207,117 +207,117 @@ Value builtin_max(const Context *, const EvalContext *evalctx) Value builtin_sin(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(sin(deg2rad(evalctx->eval_arguments[0].second.toDouble()))); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(sin(deg2rad(evalctx->getArgValue(0).toDouble()))); return Value(); } Value builtin_cos(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(cos(deg2rad(evalctx->eval_arguments[0].second.toDouble()))); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(cos(deg2rad(evalctx->getArgValue(0).toDouble()))); return Value(); } Value builtin_asin(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(rad2deg(asin(evalctx->eval_arguments[0].second.toDouble()))); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(rad2deg(asin(evalctx->getArgValue(0).toDouble()))); return Value(); } Value builtin_acos(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(rad2deg(acos(evalctx->eval_arguments[0].second.toDouble()))); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(rad2deg(acos(evalctx->getArgValue(0).toDouble()))); return Value(); } Value builtin_tan(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(tan(deg2rad(evalctx->eval_arguments[0].second.toDouble()))); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(tan(deg2rad(evalctx->getArgValue(0).toDouble()))); return Value(); } Value builtin_atan(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(rad2deg(atan(evalctx->eval_arguments[0].second.toDouble()))); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(rad2deg(atan(evalctx->getArgValue(0).toDouble()))); return Value(); } Value builtin_atan2(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 2 && evalctx->eval_arguments[0].second.type() == Value::NUMBER && evalctx->eval_arguments[1].second.type() == Value::NUMBER) - return Value(rad2deg(atan2(evalctx->eval_arguments[0].second.toDouble(), evalctx->eval_arguments[1].second.toDouble()))); + if (evalctx->numArgs() == 2 && evalctx->getArgValue(0).type() == Value::NUMBER && evalctx->getArgValue(1).type() == Value::NUMBER) + return Value(rad2deg(atan2(evalctx->getArgValue(0).toDouble(), evalctx->getArgValue(1).toDouble()))); return Value(); } Value builtin_pow(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 2 && evalctx->eval_arguments[0].second.type() == Value::NUMBER && evalctx->eval_arguments[1].second.type() == Value::NUMBER) - return Value(pow(evalctx->eval_arguments[0].second.toDouble(), evalctx->eval_arguments[1].second.toDouble())); + if (evalctx->numArgs() == 2 && evalctx->getArgValue(0).type() == Value::NUMBER && evalctx->getArgValue(1).type() == Value::NUMBER) + return Value(pow(evalctx->getArgValue(0).toDouble(), evalctx->getArgValue(1).toDouble())); return Value(); } Value builtin_round(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(round(evalctx->eval_arguments[0].second.toDouble())); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(round(evalctx->getArgValue(0).toDouble())); return Value(); } Value builtin_ceil(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(ceil(evalctx->eval_arguments[0].second.toDouble())); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(ceil(evalctx->getArgValue(0).toDouble())); return Value(); } Value builtin_floor(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(floor(evalctx->eval_arguments[0].second.toDouble())); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(floor(evalctx->getArgValue(0).toDouble())); return Value(); } Value builtin_sqrt(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(sqrt(evalctx->eval_arguments[0].second.toDouble())); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(sqrt(evalctx->getArgValue(0).toDouble())); return Value(); } Value builtin_exp(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(exp(evalctx->eval_arguments[0].second.toDouble())); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(exp(evalctx->getArgValue(0).toDouble())); return Value(); } Value builtin_length(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1) { - if (evalctx->eval_arguments[0].second.type() == Value::VECTOR) return Value(int(evalctx->eval_arguments[0].second.toVector().size())); - if (evalctx->eval_arguments[0].second.type() == Value::STRING) return Value(int(evalctx->eval_arguments[0].second.toString().size())); + if (evalctx->numArgs() == 1) { + if (evalctx->getArgValue(0).type() == Value::VECTOR) return Value(int(evalctx->getArgValue(0).toVector().size())); + if (evalctx->getArgValue(0).type() == Value::STRING) return Value(int(evalctx->getArgValue(0).toString().size())); } return Value(); } Value builtin_log(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 2 && evalctx->eval_arguments[0].second.type() == Value::NUMBER && evalctx->eval_arguments[1].second.type() == Value::NUMBER) - return Value(log(evalctx->eval_arguments[1].second.toDouble()) / log(evalctx->eval_arguments[0].second.toDouble())); - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(log(evalctx->eval_arguments[0].second.toDouble()) / log(10.0)); + if (evalctx->numArgs() == 2 && evalctx->getArgValue(0).type() == Value::NUMBER && evalctx->getArgValue(1).type() == Value::NUMBER) + return Value(log(evalctx->getArgValue(1).toDouble()) / log(evalctx->getArgValue(0).toDouble())); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(log(evalctx->getArgValue(0).toDouble()) / log(10.0)); return Value(); } Value builtin_ln(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() == 1 && evalctx->eval_arguments[0].second.type() == Value::NUMBER) - return Value(log(evalctx->eval_arguments[0].second.toDouble())); + if (evalctx->numArgs() == 1 && evalctx->getArgValue(0).type() == Value::NUMBER) + return Value(log(evalctx->getArgValue(0).toDouble())); return Value(); } @@ -325,8 +325,8 @@ Value builtin_str(const Context *, const EvalContext *evalctx) { std::stringstream stream; - for (size_t i = 0; i < evalctx->eval_arguments.size(); i++) { - stream << evalctx->eval_arguments[i].second.toString(); + for (size_t i = 0; i < evalctx->numArgs(); i++) { + stream << evalctx->getArgValue(i).toString(); } return Value(stream.str()); } @@ -334,16 +334,16 @@ Value builtin_str(const Context *, const EvalContext *evalctx) Value builtin_lookup(const Context *, const EvalContext *evalctx) { double p, low_p, low_v, high_p, high_v; - if (evalctx->eval_arguments.size() < 2 || // Needs two args - !evalctx->eval_arguments[0].second.getDouble(p) || // First must be a number - evalctx->eval_arguments[1].second.toVector().size() < 2 || // Second must be a vector of vectors - evalctx->eval_arguments[1].second.toVector()[0].toVector().size() < 2) + if (evalctx->numArgs() < 2 || // Needs two args + !evalctx->getArgValue(0).getDouble(p) || // First must be a number + evalctx->getArgValue(1).toVector().size() < 2 || // Second must be a vector of vectors + evalctx->getArgValue(1).toVector()[0].toVector().size() < 2) return Value(); - if (!evalctx->eval_arguments[1].second.toVector()[0].getVec2(low_p, low_v) || !evalctx->eval_arguments[1].second.toVector()[0].getVec2(high_p, high_v)) + if (!evalctx->getArgValue(1).toVector()[0].getVec2(low_p, low_v) || !evalctx->getArgValue(1).toVector()[0].getVec2(high_p, high_v)) return Value(); - for (size_t i = 1; i < evalctx->eval_arguments[1].second.toVector().size(); i++) { + for (size_t i = 1; i < evalctx->getArgValue(1).toVector().size(); i++) { double this_p, this_v; - if (evalctx->eval_arguments[1].second.toVector()[i].getVec2(this_p, this_v)) { + if (evalctx->getArgValue(1).toVector()[i].getVec2(this_p, this_v)) { if (this_p <= p && (this_p > low_p || low_p > p)) { low_p = this_p; low_v = this_v; @@ -406,12 +406,12 @@ Value builtin_lookup(const Context *, const EvalContext *evalctx) */ Value builtin_search(const Context *, const EvalContext *evalctx) { - if (evalctx->eval_arguments.size() < 2) return Value(); + if (evalctx->numArgs() < 2) return Value(); - const Value &findThis = evalctx->eval_arguments[0].second; - const Value &searchTable = evalctx->eval_arguments[1].second; - unsigned int num_returns_per_match = (evalctx->eval_arguments.size() > 2) ? evalctx->eval_arguments[2].second.toDouble() : 1; - unsigned int index_col_num = (evalctx->eval_arguments.size() > 3) ? evalctx->eval_arguments[3].second.toDouble() : 0; + const Value &findThis = evalctx->getArgValue(0); + const Value &searchTable = evalctx->getArgValue(1); + unsigned int num_returns_per_match = (evalctx->numArgs() > 2) ? evalctx->getArgValue(2).toDouble() : 1; + unsigned int index_col_num = (evalctx->numArgs() > 3) ? evalctx->getArgValue(3).toDouble() : 0; Value::VectorType returnvec; @@ -512,7 +512,7 @@ Value builtin_version(const Context *, const EvalContext *evalctx) Value builtin_version_num(const Context *ctx, const EvalContext *evalctx) { - Value val = (evalctx->eval_arguments.size() == 0) ? builtin_version(ctx, evalctx) : evalctx->eval_arguments[0].second; + Value val = (evalctx->numArgs() == 0) ? builtin_version(ctx, evalctx) : evalctx->getArgValue(0); double y, m, d = 0; if (!val.getVec3(y, m, d)) { if (!val.getVec2(y, m)) { diff --git a/src/linearextrude.cc b/src/linearextrude.cc index f4c1112..a3337e8 100644 --- a/src/linearextrude.cc +++ b/src/linearextrude.cc @@ -80,10 +80,10 @@ AbstractNode *LinearExtrudeModule::evaluate(const Context *ctx, const ModuleInst // if height not given, and first argument is a number, // then assume it should be the height. if (c.lookup_variable("height").isUndefined() && - evalctx->eval_arguments.size() > 0 && - evalctx->eval_arguments[0].first == "" && - evalctx->eval_arguments[0].second.type() == Value::NUMBER) { - height = Value(evalctx->eval_arguments[0].second); + evalctx->numArgs() > 0 && + evalctx->getArgName(0) == "" && + evalctx->getArgValue(0).type() == Value::NUMBER) { + height = evalctx->getArgValue(0); } node->layername = layer.isUndefined() ? "" : layer.toString(); diff --git a/src/module.cc b/src/module.cc index 7d83975..3f6dd22 100644 --- a/src/module.cc +++ b/src/module.cc @@ -112,14 +112,7 @@ std::string ModuleInstantiation::dump(const std::string &indent) const AbstractNode *ModuleInstantiation::evaluate_instance(const Context *ctx) const { - EvalContext c(ctx); - BOOST_FOREACH(const Assignment &arg, this->arguments) { - c.eval_arguments.push_back(std::make_pair(arg.first, - arg.second ? - arg.second->evaluate(ctx) : - Value())); - } - c.children = this->children; + EvalContext c(ctx, this->arguments, &this->children); #if 0 && DEBUG PRINT("New eval ctx:"); |