From 329ad97a842ce6f1436fd202c854c6b41f8d6422 Mon Sep 17 00:00:00 2001 From: Matthias Urlichs Date: Wed, 4 Dec 2019 09:31:21 +0100 Subject: [PATCH] Add int() and % (modulo) --- src/libslic3r/PlaceholderParser.cpp | 35 +++++++++++++++++++++++++++++ t/custom_gcode.t | 3 +++ 2 files changed, 38 insertions(+) diff --git a/src/libslic3r/PlaceholderParser.cpp b/src/libslic3r/PlaceholderParser.cpp index 0cfd97415..c92be2845 100644 --- a/src/libslic3r/PlaceholderParser.cpp +++ b/src/libslic3r/PlaceholderParser.cpp @@ -332,6 +332,21 @@ namespace client return expr(); } + expr unary_integer(const Iterator start_pos) const + { + switch (this->type) { + case TYPE_INT : + return expr(this->i(), start_pos, this->it_range.end()); + case TYPE_DOUBLE: + return expr((int)(this->d()), start_pos, this->it_range.end()); + default: + this->throw_exception("Cannot convert to integer."); + } + assert(false); + // Suppress compiler warnings. + return expr(); + } + expr unary_not(const Iterator start_pos) const { switch (this->type) { @@ -415,6 +430,22 @@ namespace client return *this; } + expr &operator%=(const expr &rhs) + { + this->throw_if_not_numeric("Cannot divide a non-numeric type."); + rhs.throw_if_not_numeric("Cannot divide with a non-numeric type."); + if ((this->type == TYPE_INT) ? (rhs.i() == 0) : (rhs.d() == 0.)) + rhs.throw_exception("Division by zero"); + if (this->type == TYPE_DOUBLE || rhs.type == TYPE_DOUBLE) { + double d = std::fmod(this->as_d(), rhs.as_d()); + this->data.d = d; + this->type = TYPE_DOUBLE; + } else + this->data.i %= rhs.i(); + this->it_range = boost::iterator_range(this->it_range.begin(), rhs.it_range.end()); + return *this; + } + static void to_string2(expr &self, std::string &out) { out = self.to_string(); @@ -1087,6 +1118,7 @@ namespace client unary_expression(_r1) [_val = _1] >> *( (lit('*') > unary_expression(_r1) ) [_val *= _1] | (lit('/') > unary_expression(_r1) ) [_val /= _1] + | (lit('%') > unary_expression(_r1) ) [_val %= _1] ); multiplicative_expression.name("multiplicative_expression"); @@ -1107,6 +1139,8 @@ namespace client { out = value.unary_minus(out.it_range.begin()); } static void not_(expr &value, expr &out) { out = value.unary_not(out.it_range.begin()); } + static void to_int(expr &value, expr &out) + { out = value.unary_integer(out.it_range.begin()); } }; unary_expression = iter_pos[px::bind(&FactorActions::set_start_pos, _1, _val)] >> ( scalar_variable_reference(_r1) [ _val = _1 ] @@ -1118,6 +1152,7 @@ namespace client [ px::bind(&expr::min, _val, _2) ] | (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')') [ px::bind(&expr::max, _val, _2) ] + | (kw["int"] > '(' > unary_expression(_r1) ) [ px::bind(&FactorActions::to_int, _1, _val) ] | (strict_double > iter_pos) [ px::bind(&FactorActions::double_, _1, _2, _val) ] | (int_ > iter_pos) [ px::bind(&FactorActions::int_, _1, _2, _val) ] | (kw[bool_] > iter_pos) [ px::bind(&FactorActions::bool_, _1, _2, _val) ] diff --git a/t/custom_gcode.t b/t/custom_gcode.t index 4c1c1b108..5ffd9b7f4 100644 --- a/t/custom_gcode.t +++ b/t/custom_gcode.t @@ -67,6 +67,8 @@ use Slic3r::Test; is $parser->process('{2*3/6}'), '1', 'math: 2*3/6'; is $parser->process('{2*3/12}'), '0', 'math: 2*3/12'; ok abs($parser->process('{2.*3/12}') - 0.5) < 1e-7, 'math: 2.*3/12'; + is $parser->process('{10%2.5}') '0', 'math: 10 % 2.5'; + is $parser->process('{11/2.5-1}') '1', 'math: 11 % 2.5'; is $parser->process('{2*(3-12)}'), '-18', 'math: 2*(3-12)'; is $parser->process('{2*foo*(3-12)}'), '0', 'math: 2*foo*(3-12)'; is $parser->process('{2*bar*(3-12)}'), '-36', 'math: 2*bar*(3-12)'; @@ -75,6 +77,7 @@ use Slic3r::Test; is $parser->process('{max(12, 14)}'), '14', 'math: max(12, 14)'; is $parser->process('{min(13.4, -1238.1)}'), '-1238.1', 'math: min(13.4, -1238.1)'; is $parser->process('{max(13.4, -1238.1)}'), '13.4', 'math: max(13.4, -1238.1)'; + is $parser->process('{int(13.4)}'), '13', 'math: int(13.4)'; # Test the boolean expression parser. is $parser->evaluate_boolean_expression('12 == 12'), 1, 'boolean expression parser: 12 == 12';