summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2013-04-19 01:42:33 (GMT)
committerMarius Kintel <marius@kintel.net>2013-04-26 21:42:32 (GMT)
commit64ed1eb9fe00e287d84b18830df86cc0de6b122a (patch)
tree3b5f4a51209b62a14d28abc7c0e01fc5753e162c
parenta96f3f3c67d496279151cd3fff47589b8684c378 (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.cc6
-rw-r--r--src/control.cc28
-rw-r--r--src/dxfdim.cc40
-rw-r--r--src/evalcontext.cc17
-rw-r--r--src/evalcontext.h19
-rw-r--r--src/expr.cc6
-rw-r--r--src/func.cc154
-rw-r--r--src/linearextrude.cc8
-rw-r--r--src/module.cc9
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:");
contact: Jan Huwald // Impressum