mirror of
https://github.com/QIDITECH/QIDIStudio.git
synced 2026-02-07 04:11:50 +03:00
update libslic3r
This commit is contained in:
@@ -199,7 +199,7 @@ namespace client
|
||||
explicit expr(double d, const Iterator &it_begin, const Iterator &it_end) : type(TYPE_DOUBLE), it_range(it_begin, it_end) { data.d = d; }
|
||||
explicit expr(const char *s) : type(TYPE_STRING) { data.s = new std::string(s); }
|
||||
explicit expr(const std::string &s) : type(TYPE_STRING) { data.s = new std::string(s); }
|
||||
explicit expr(const std::string &s, const Iterator &it_begin, const Iterator &it_end) :
|
||||
explicit expr(const std::string &s, const Iterator &it_begin, const Iterator &it_end) :
|
||||
type(TYPE_STRING), it_range(it_begin, it_end) { data.s = new std::string(s); }
|
||||
expr(const expr &rhs) : type(rhs.type), it_range(rhs.it_range)
|
||||
{ if (rhs.type == TYPE_STRING) data.s = new std::string(*rhs.data.s); else data.set(rhs.data); }
|
||||
@@ -209,7 +209,7 @@ namespace client
|
||||
{ data.set(rhs.data); rhs.type = TYPE_EMPTY; }
|
||||
~expr() { this->reset(); }
|
||||
|
||||
expr &operator=(const expr &rhs)
|
||||
expr &operator=(const expr &rhs)
|
||||
{
|
||||
//QDS: avoid memory leak when call operator= directly before call reset()
|
||||
if (this->type == TYPE_STRING && this->data.s) {
|
||||
@@ -219,15 +219,15 @@ namespace client
|
||||
|
||||
this->type = rhs.type;
|
||||
this->it_range = rhs.it_range;
|
||||
if (rhs.type == TYPE_STRING)
|
||||
if (rhs.type == TYPE_STRING)
|
||||
this->data.s = new std::string(*rhs.data.s);
|
||||
else
|
||||
this->data.set(rhs.data);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
expr &operator=(expr &&rhs)
|
||||
{
|
||||
expr &operator=(expr &&rhs)
|
||||
{
|
||||
type = rhs.type;
|
||||
this->it_range = rhs.it_range;
|
||||
data.set(rhs.data);
|
||||
@@ -235,7 +235,7 @@ namespace client
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset()
|
||||
void reset()
|
||||
{
|
||||
//QDS
|
||||
if (this->type == TYPE_STRING && this->data.s) {
|
||||
@@ -261,14 +261,14 @@ namespace client
|
||||
const std::string& s() const { return *data.s; }
|
||||
void set_s(const std::string &s) { this->reset(); this->data.s = new std::string(s); this->type = TYPE_STRING; }
|
||||
void set_s(std::string &&s) { this->reset(); this->data.s = new std::string(std::move(s)); this->type = TYPE_STRING; }
|
||||
|
||||
std::string to_string() const
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
std::string out;
|
||||
switch (type) {
|
||||
case TYPE_BOOL: out = data.b ? "true" : "false"; break;
|
||||
case TYPE_INT: out = std::to_string(data.i); break;
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_DOUBLE:
|
||||
#if 0
|
||||
// The default converter produces trailing zeros after the decimal point.
|
||||
out = std::to_string(data.d);
|
||||
@@ -317,12 +317,12 @@ namespace client
|
||||
boost::iterator_range<Iterator> it_range;
|
||||
|
||||
expr unary_minus(const Iterator start_pos) const
|
||||
{
|
||||
{
|
||||
switch (this->type) {
|
||||
case TYPE_INT :
|
||||
return expr<Iterator>(- this->i(), start_pos, this->it_range.end());
|
||||
case TYPE_DOUBLE:
|
||||
return expr<Iterator>(- this->d(), start_pos, this->it_range.end());
|
||||
return expr<Iterator>(- this->d(), start_pos, this->it_range.end());
|
||||
default:
|
||||
this->throw_exception("Cannot apply unary minus operator.");
|
||||
}
|
||||
@@ -332,12 +332,12 @@ namespace client
|
||||
}
|
||||
|
||||
expr unary_integer(const Iterator start_pos) const
|
||||
{
|
||||
{
|
||||
switch (this->type) {
|
||||
case TYPE_INT:
|
||||
return expr<Iterator>(this->i(), start_pos, this->it_range.end());
|
||||
case TYPE_DOUBLE:
|
||||
return expr<Iterator>(static_cast<int>(this->d()), start_pos, this->it_range.end());
|
||||
return expr<Iterator>(static_cast<int>(this->d()), start_pos, this->it_range.end());
|
||||
default:
|
||||
this->throw_exception("Cannot convert to integer.");
|
||||
}
|
||||
@@ -347,7 +347,7 @@ namespace client
|
||||
}
|
||||
|
||||
expr round(const Iterator start_pos) const
|
||||
{
|
||||
{
|
||||
switch (this->type) {
|
||||
case TYPE_INT:
|
||||
return expr<Iterator>(this->i(), start_pos, this->it_range.end());
|
||||
@@ -361,8 +361,38 @@ namespace client
|
||||
return expr();
|
||||
}
|
||||
|
||||
expr floor(const Iterator start_pos)const
|
||||
{
|
||||
switch (this->type) {
|
||||
case TYPE_INT:
|
||||
return expr<Iterator>(this->i(), start_pos, this->it_range.end());
|
||||
case TYPE_DOUBLE:
|
||||
return expr<Iterator>(static_cast<int>(std::floor(this->d())), start_pos, this->it_range.end());
|
||||
default:
|
||||
this->throw_exception("Cannot floor a non-numeric value.");
|
||||
}
|
||||
assert(false);
|
||||
// Suppress compiler warnings.
|
||||
return expr();
|
||||
}
|
||||
|
||||
expr ceil(const Iterator start_pos)const
|
||||
{
|
||||
switch (this->type) {
|
||||
case TYPE_INT:
|
||||
return expr<Iterator>(this->i(), start_pos, this->it_range.end());
|
||||
case TYPE_DOUBLE:
|
||||
return expr<Iterator>(static_cast<int>(std::ceil(this->d())), start_pos, this->it_range.end());
|
||||
default:
|
||||
this->throw_exception("Cannot ceil a non-numeric value.");
|
||||
}
|
||||
assert(false);
|
||||
// Suppress compiler warnings.
|
||||
return expr();
|
||||
}
|
||||
|
||||
expr unary_not(const Iterator start_pos) const
|
||||
{
|
||||
{
|
||||
switch (this->type) {
|
||||
case TYPE_BOOL:
|
||||
return expr<Iterator>(! this->b(), start_pos, this->it_range.end());
|
||||
@@ -375,7 +405,7 @@ namespace client
|
||||
}
|
||||
|
||||
expr &operator+=(const expr &rhs)
|
||||
{
|
||||
{
|
||||
if (this->type == TYPE_STRING) {
|
||||
// Convert the right hand side to string and append.
|
||||
*this->data.s += rhs.to_string();
|
||||
@@ -399,7 +429,7 @@ namespace client
|
||||
}
|
||||
|
||||
expr &operator-=(const expr &rhs)
|
||||
{
|
||||
{
|
||||
const char *err_msg = "Cannot subtract non-numeric types.";
|
||||
this->throw_if_not_numeric(err_msg);
|
||||
rhs.throw_if_not_numeric(err_msg);
|
||||
@@ -414,7 +444,7 @@ namespace client
|
||||
}
|
||||
|
||||
expr &operator*=(const expr &rhs)
|
||||
{
|
||||
{
|
||||
const char *err_msg = "Cannot multiply with non-numeric type.";
|
||||
this->throw_if_not_numeric(err_msg);
|
||||
rhs.throw_if_not_numeric(err_msg);
|
||||
@@ -488,16 +518,16 @@ namespace client
|
||||
// Both types are numeric.
|
||||
switch (op) {
|
||||
case '=':
|
||||
value = (lhs.type == TYPE_DOUBLE || rhs.type == TYPE_DOUBLE) ?
|
||||
value = (lhs.type == TYPE_DOUBLE || rhs.type == TYPE_DOUBLE) ?
|
||||
(std::abs(lhs.as_d() - rhs.as_d()) < 1e-8) : (lhs.i() == rhs.i());
|
||||
break;
|
||||
case '<':
|
||||
value = (lhs.type == TYPE_DOUBLE || rhs.type == TYPE_DOUBLE) ?
|
||||
value = (lhs.type == TYPE_DOUBLE || rhs.type == TYPE_DOUBLE) ?
|
||||
(lhs.as_d() < rhs.as_d()) : (lhs.i() < rhs.i());
|
||||
break;
|
||||
case '>':
|
||||
default:
|
||||
value = (lhs.type == TYPE_DOUBLE || rhs.type == TYPE_DOUBLE) ?
|
||||
value = (lhs.type == TYPE_DOUBLE || rhs.type == TYPE_DOUBLE) ?
|
||||
(lhs.as_d() > rhs.as_d()) : (lhs.i() > rhs.i());
|
||||
break;
|
||||
}
|
||||
@@ -509,7 +539,7 @@ namespace client
|
||||
value = lhs.b() == rhs.b();
|
||||
} else if (lhs.type == TYPE_STRING || rhs.type == TYPE_STRING) {
|
||||
// One type is string, the other could be converted to string.
|
||||
value = (op == '=') ? (lhs.to_string() == rhs.to_string()) :
|
||||
value = (op == '=') ? (lhs.to_string() == rhs.to_string()) :
|
||||
(op == '<') ? (lhs.to_string() < rhs.to_string()) : (lhs.to_string() > rhs.to_string());
|
||||
} else {
|
||||
boost::throw_exception(qi::expectation_failure<Iterator>(
|
||||
@@ -529,7 +559,7 @@ namespace client
|
||||
static void throw_if_not_numeric(const expr ¶m)
|
||||
{
|
||||
const char *err_msg = "Not a numeric type.";
|
||||
param.throw_if_not_numeric(err_msg);
|
||||
param.throw_if_not_numeric(err_msg);
|
||||
}
|
||||
|
||||
enum Function2ParamsType {
|
||||
@@ -538,7 +568,7 @@ namespace client
|
||||
};
|
||||
// Store the result into param1.
|
||||
static void function_2params(expr ¶m1, expr ¶m2, Function2ParamsType fun)
|
||||
{
|
||||
{
|
||||
throw_if_not_numeric(param1);
|
||||
throw_if_not_numeric(param2);
|
||||
if (param1.type == TYPE_DOUBLE || param2.type == TYPE_DOUBLE) {
|
||||
@@ -567,7 +597,7 @@ namespace client
|
||||
|
||||
// Store the result into param1.
|
||||
static void random(expr ¶m1, expr ¶m2, std::mt19937 &rng)
|
||||
{
|
||||
{
|
||||
throw_if_not_numeric(param1);
|
||||
throw_if_not_numeric(param2);
|
||||
if (param1.type == TYPE_DOUBLE || param2.type == TYPE_DOUBLE) {
|
||||
@@ -583,7 +613,7 @@ namespace client
|
||||
// param3 is optional
|
||||
template<bool leading_zeros>
|
||||
static void digits(expr ¶m1, expr ¶m2, expr ¶m3)
|
||||
{
|
||||
{
|
||||
throw_if_not_numeric(param1);
|
||||
if (param2.type != TYPE_INT)
|
||||
param2.throw_exception("digits: second parameter must be integer");
|
||||
@@ -663,13 +693,13 @@ namespace client
|
||||
}
|
||||
}
|
||||
|
||||
void throw_exception(const char *message) const
|
||||
void throw_exception(const char *message) const
|
||||
{
|
||||
boost::throw_exception(qi::expectation_failure<Iterator>(
|
||||
this->it_range.begin(), this->it_range.end(), spirit::info(std::string("*") + message)));
|
||||
}
|
||||
|
||||
void throw_if_not_numeric(const char *message) const
|
||||
void throw_if_not_numeric(const char *message) const
|
||||
{
|
||||
if (this->type != TYPE_INT && this->type != TYPE_DOUBLE)
|
||||
this->throw_exception(message);
|
||||
@@ -706,6 +736,14 @@ namespace client
|
||||
// Table to translate symbol tag to a human readable error message.
|
||||
static std::map<std::string, std::string> tag_to_error_message;
|
||||
|
||||
size_t get_extruder_id() const {
|
||||
const ConfigOptionInts * filament_map_opt = external_config->option<ConfigOptionInts>("filament_map");
|
||||
if (filament_map_opt && current_extruder_id < filament_map_opt->values.size()) {
|
||||
return filament_map_opt->values[current_extruder_id];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void evaluate_full_macro(const MyContext *ctx, bool &result) { result = ! ctx->just_boolean_expression; }
|
||||
|
||||
const ConfigOption* optptr(const t_config_option_key &opt_key) const override
|
||||
@@ -724,7 +762,7 @@ namespace client
|
||||
|
||||
template <typename Iterator>
|
||||
static void legacy_variable_expansion(
|
||||
const MyContext *ctx,
|
||||
const MyContext *ctx,
|
||||
boost::iterator_range<Iterator> &opt_key,
|
||||
std::string &output)
|
||||
{
|
||||
@@ -760,7 +798,7 @@ namespace client
|
||||
|
||||
template <typename Iterator>
|
||||
static void legacy_variable_expansion2(
|
||||
const MyContext *ctx,
|
||||
const MyContext *ctx,
|
||||
boost::iterator_range<Iterator> &opt_key,
|
||||
boost::iterator_range<Iterator> &opt_vector_index,
|
||||
std::string &output)
|
||||
@@ -808,58 +846,110 @@ namespace client
|
||||
OptWithPos<Iterator> &opt,
|
||||
expr<Iterator> &output)
|
||||
{
|
||||
if (opt.opt->is_vector())
|
||||
ctx->throw_exception("Referencing a vector variable when scalar is expected", opt.it_range);
|
||||
switch (opt.opt->type()) {
|
||||
case coFloat: output.set_d(opt.opt->getFloat()); break;
|
||||
case coInt: output.set_i(opt.opt->getInt()); break;
|
||||
case coString: output.set_s(static_cast<const ConfigOptionString*>(opt.opt)->value); break;
|
||||
case coPercent: output.set_d(opt.opt->getFloat()); break;
|
||||
case coPoint: output.set_s(opt.opt->serialize()); break;
|
||||
case coBool: output.set_b(opt.opt->getBool()); break;
|
||||
case coFloatOrPercent:
|
||||
{
|
||||
std::string opt_key(opt.it_range.begin(), opt.it_range.end());
|
||||
if (boost::ends_with(opt_key, "line_width")) {
|
||||
// Extrusion width supports defaults and a complex graph of dependencies.
|
||||
output.set_d(Flow::extrusion_width(opt_key, *ctx, static_cast<unsigned int>(ctx->current_extruder_id)));
|
||||
} else if (! static_cast<const ConfigOptionFloatOrPercent*>(opt.opt)->percent) {
|
||||
// Not a percent, just return the value.
|
||||
output.set_d(opt.opt->getFloat());
|
||||
} else {
|
||||
// Resolve dependencies using the "ratio_over" link to a parent value.
|
||||
const ConfigOptionDef *opt_def = print_config_def.get(opt_key);
|
||||
assert(opt_def != nullptr);
|
||||
double v = opt.opt->getFloat() * 0.01; // percent to ratio
|
||||
for (;;) {
|
||||
const ConfigOption *opt_parent = opt_def->ratio_over.empty() ? nullptr : ctx->resolve_symbol(opt_def->ratio_over);
|
||||
if (opt_parent == nullptr)
|
||||
ctx->throw_exception("FloatOrPercent variable failed to resolve the \"ratio_over\" dependencies", opt.it_range);
|
||||
if (boost::ends_with(opt_def->ratio_over, "line_width")) {
|
||||
// Extrusion width supports defaults and a complex graph of dependencies.
|
||||
assert(opt_parent->type() == coFloatOrPercent);
|
||||
v *= Flow::extrusion_width(opt_def->ratio_over, static_cast<const ConfigOptionFloatOrPercent*>(opt_parent), *ctx, static_cast<unsigned int>(ctx->current_extruder_id));
|
||||
break;
|
||||
}
|
||||
if (opt_parent->type() == coFloat || opt_parent->type() == coFloatOrPercent) {
|
||||
v *= opt_parent->getFloat();
|
||||
if (opt_parent->type() == coFloat || ! static_cast<const ConfigOptionFloatOrPercent*>(opt_parent)->percent)
|
||||
break;
|
||||
v *= 0.01; // percent to ratio
|
||||
}
|
||||
// Continue one level up in the "ratio_over" hierarchy.
|
||||
opt_def = print_config_def.get(opt_def->ratio_over);
|
||||
assert(opt_def != nullptr);
|
||||
}
|
||||
output.set_d(v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//QDS: Add enum. Otherwise enum can not be judged in placeholder
|
||||
case coEnum: output.set_s(opt.opt->serialize()); break;
|
||||
default:
|
||||
ctx->throw_exception("Unknown scalar variable type", opt.it_range);
|
||||
if (opt.opt->is_vector()) {
|
||||
switch (opt.opt->type()) {
|
||||
case coFloats: {
|
||||
const ConfigOptionFloatsNullable* opt_floats = static_cast<const ConfigOptionFloatsNullable *>(opt.opt);
|
||||
if (opt_floats->size() == 1) { // old version
|
||||
output.set_d(static_cast<const ConfigOptionFloatsNullable *>(opt.opt)->get_at(0));
|
||||
}
|
||||
else {
|
||||
output.set_d(static_cast<const ConfigOptionFloatsNullable *>(opt.opt)->get_at(ctx->get_extruder_id()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case coFloatsOrPercents: {
|
||||
const ConfigOptionFloatsOrPercentsNullable * opt_floats = static_cast<const ConfigOptionFloatsOrPercentsNullable *>(opt.opt);
|
||||
size_t index = 0; // old version only one value
|
||||
if (opt_floats->size() > 1) {
|
||||
index = ctx->get_extruder_id();
|
||||
}
|
||||
std::string opt_key(opt.it_range.begin(), opt.it_range.end());
|
||||
if (!opt_floats->get_at(index).percent) {
|
||||
// Not a percent, just return the value.
|
||||
output.set_d(opt_floats->get_at(index).value);
|
||||
} else {
|
||||
|
||||
FloatOrPercent opt_value = opt_floats->get_at(index);
|
||||
double v = opt_value.value;
|
||||
if (opt_value.percent) {
|
||||
// Resolve dependencies using the "ratio_over" link to a parent value.
|
||||
const ConfigOptionDef *opt_def = print_config_def.get(opt_key);
|
||||
assert(opt_def != nullptr);
|
||||
assert(opt_def->type == coFloatsOrPercents);
|
||||
v *= 0.01;
|
||||
while (true) {
|
||||
const ConfigOption *opt_parent = opt_def->ratio_over.empty() ? nullptr : ctx->resolve_symbol(opt_def->ratio_over);
|
||||
if (opt_parent == nullptr) {
|
||||
ctx->throw_exception("FloatOrPercentNullable variable failed to resolve the \"ratio_over\" dependencies", opt.it_range);
|
||||
}
|
||||
if (opt_parent->type() == coFloat || opt_parent->type() == coFloatOrPercent) {
|
||||
v *= opt_parent->getFloat();
|
||||
if (opt_parent->type() == coFloat || !static_cast<const ConfigOptionFloatOrPercent *>(opt_parent)->percent) break;
|
||||
v *= 0.01; // percent to ratio
|
||||
}
|
||||
}
|
||||
}
|
||||
output.set_d(v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: ctx->throw_exception("Unknown scalar variable type", opt.it_range);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (opt.opt->type()) {
|
||||
case coFloat: output.set_d(opt.opt->getFloat()); break;
|
||||
case coInt: output.set_i(opt.opt->getInt()); break;
|
||||
case coString: output.set_s(static_cast<const ConfigOptionString*>(opt.opt)->value); break;
|
||||
case coPercent: output.set_d(opt.opt->getFloat()); break;
|
||||
case coPoint: output.set_s(opt.opt->serialize()); break;
|
||||
case coBool: output.set_b(opt.opt->getBool()); break;
|
||||
case coFloatOrPercent:
|
||||
{
|
||||
std::string opt_key(opt.it_range.begin(), opt.it_range.end());
|
||||
if (boost::ends_with(opt_key, "line_width")) {
|
||||
// Extrusion width supports defaults and a complex graph of dependencies.
|
||||
output.set_d(Flow::extrusion_width(opt_key, *ctx, static_cast<unsigned int>(ctx->current_extruder_id)));
|
||||
} else if (! static_cast<const ConfigOptionFloatOrPercent*>(opt.opt)->percent) {
|
||||
// Not a percent, just return the value.
|
||||
output.set_d(opt.opt->getFloat());
|
||||
} else {
|
||||
// Resolve dependencies using the "ratio_over" link to a parent value.
|
||||
const ConfigOptionDef *opt_def = print_config_def.get(opt_key);
|
||||
assert(opt_def != nullptr);
|
||||
double v = opt.opt->getFloat() * 0.01; // percent to ratio
|
||||
for (;;) {
|
||||
const ConfigOption *opt_parent = opt_def->ratio_over.empty() ? nullptr : ctx->resolve_symbol(opt_def->ratio_over);
|
||||
if (opt_parent == nullptr)
|
||||
ctx->throw_exception("FloatOrPercent variable failed to resolve the \"ratio_over\" dependencies", opt.it_range);
|
||||
if (boost::ends_with(opt_def->ratio_over, "line_width")) {
|
||||
// Extrusion width supports defaults and a complex graph of dependencies.
|
||||
assert(opt_parent->type() == coFloatOrPercent);
|
||||
v *= Flow::extrusion_width(opt_def->ratio_over, static_cast<const ConfigOptionFloatOrPercent*>(opt_parent), *ctx, static_cast<unsigned int>(ctx->current_extruder_id));
|
||||
break;
|
||||
}
|
||||
if (opt_parent->type() == coFloat || opt_parent->type() == coFloatOrPercent) {
|
||||
v *= opt_parent->getFloat();
|
||||
if (opt_parent->type() == coFloat || ! static_cast<const ConfigOptionFloatOrPercent*>(opt_parent)->percent)
|
||||
break;
|
||||
v *= 0.01; // percent to ratio
|
||||
}
|
||||
// Continue one level up in the "ratio_over" hierarchy.
|
||||
opt_def = print_config_def.get(opt_def->ratio_over);
|
||||
assert(opt_def != nullptr);
|
||||
}
|
||||
output.set_d(v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
//QDS: Add enum. Otherwise enum can not be judged in placeholder
|
||||
case coEnum: output.set_s(opt.opt->serialize()); break;
|
||||
default:
|
||||
ctx->throw_exception("Unknown scalar variable type", opt.it_range);
|
||||
}
|
||||
}
|
||||
|
||||
output.it_range = opt.it_range;
|
||||
}
|
||||
|
||||
@@ -897,7 +987,7 @@ namespace client
|
||||
template <typename Iterator>
|
||||
static void evaluate_index(expr<Iterator> &expr_index, int &output)
|
||||
{
|
||||
if (expr_index.type != expr<Iterator>::TYPE_INT)
|
||||
if (expr_index.type != expr<Iterator>::TYPE_INT)
|
||||
expr_index.throw_exception("Non-integer index is not allowed to address a vector variable.");
|
||||
output = expr_index.i();
|
||||
}
|
||||
@@ -911,6 +1001,13 @@ namespace client
|
||||
expr<Iterator>::random(param1, param2, ctx->context_data->rng);
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
static void filament_change(const MyContext* ctx, expr<Iterator>& param)
|
||||
{
|
||||
MyContext *context = const_cast<MyContext *>(ctx);
|
||||
context->current_extruder_id = param.as_i();
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static void throw_exception(const std::string &msg, const boost::iterator_range<Iterator> &it_range)
|
||||
{
|
||||
@@ -1012,18 +1109,18 @@ namespace client
|
||||
// This parser is to be used inside a raw[] directive to accept a single valid UTF-8 character.
|
||||
// If an invalid UTF-8 sequence is encountered, a qi::expectation_failure is thrown.
|
||||
struct utf8_char_skipper_parser : qi::primitive_parser<utf8_char_skipper_parser>
|
||||
{
|
||||
// Define the attribute type exposed by this parser component
|
||||
{
|
||||
// Define the attribute type exposed by this parser component
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
// This function is called during the actual parsing process
|
||||
// This function is called during the actual parsing process
|
||||
template <typename Iterator, typename Context , typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last, Context& context, Skipper const& skipper, Attribute& attr) const
|
||||
{
|
||||
{
|
||||
// The skipper shall always be empty, any white space will be accepted.
|
||||
// skip_over(first, last, skipper);
|
||||
if (first == last)
|
||||
@@ -1067,7 +1164,7 @@ namespace client
|
||||
// This function is called during error handling to create a human readable string for the error context.
|
||||
template <typename Context>
|
||||
spirit::info what(Context&) const
|
||||
{
|
||||
{
|
||||
return spirit::info("unicode_char");
|
||||
}
|
||||
};
|
||||
@@ -1148,11 +1245,11 @@ namespace client
|
||||
// An if expression enclosed in {} (the outmost {} are already parsed by the caller).
|
||||
if_else_output =
|
||||
eps[_b=true] >
|
||||
bool_expr_eval(_r1)[_a=_1] > '}' >
|
||||
bool_expr_eval(_r1)[_a=_1] > '}' >
|
||||
text_block(_r1)[px::bind(&expr<Iterator>::set_if, _a, _b, _1, _val)] > '{' >
|
||||
*(kw["elsif"] > bool_expr_eval(_r1)[_a=_1] > '}' >
|
||||
*(kw["elsif"] > bool_expr_eval(_r1)[_a=_1] > '}' >
|
||||
text_block(_r1)[px::bind(&expr<Iterator>::set_if, _a, _b, _1, _val)] > '{') >
|
||||
-(kw["else"] > lit('}') >
|
||||
-(kw["else"] > lit('}') >
|
||||
text_block(_r1)[px::bind(&expr<Iterator>::set_if, _b, _b, _1, _val)] > '{') >
|
||||
kw["endif"];
|
||||
if_else_output.name("if_else_output");
|
||||
@@ -1170,7 +1267,7 @@ namespace client
|
||||
legacy_variable_expansion =
|
||||
(identifier >> &lit(']'))
|
||||
[ px::bind(&MyContext::legacy_variable_expansion<Iterator>, _r1, _1, _val) ]
|
||||
| (identifier > lit('[') > identifier > ']')
|
||||
| (identifier > lit('[') > identifier > ']')
|
||||
[ px::bind(&MyContext::legacy_variable_expansion2<Iterator>, _r1, _1, _2, _val) ]
|
||||
;
|
||||
legacy_variable_expansion.name("legacy_variable_expansion");
|
||||
@@ -1185,12 +1282,12 @@ namespace client
|
||||
>> -('?' > conditional_expression(_r1) > ':' > conditional_expression(_r1)) [px::bind(&expr<Iterator>::ternary_op, _val, _1, _2)];
|
||||
conditional_expression.name("conditional_expression");
|
||||
|
||||
logical_or_expression =
|
||||
logical_or_expression =
|
||||
logical_and_expression(_r1) [_val = _1]
|
||||
>> *( ((kw["or"] | "||") > logical_and_expression(_r1) ) [px::bind(&expr<Iterator>::logical_or, _val, _1)] );
|
||||
logical_or_expression.name("logical_or_expression");
|
||||
|
||||
logical_and_expression =
|
||||
logical_and_expression =
|
||||
equality_expression(_r1) [_val = _1]
|
||||
>> *( ((kw["and"] | "&&") > equality_expression(_r1) ) [px::bind(&expr<Iterator>::logical_and, _val, _1)] );
|
||||
logical_and_expression.name("logical_and_expression");
|
||||
@@ -1210,7 +1307,7 @@ namespace client
|
||||
bool_expr_eval = conditional_expression(_r1) [ px::bind(&expr<Iterator>::evaluate_boolean, _1, _val) ];
|
||||
bool_expr_eval.name("bool_expr_eval");
|
||||
|
||||
relational_expression =
|
||||
relational_expression =
|
||||
additive_expression(_r1) [_val = _1]
|
||||
>> *( ("<=" > additive_expression(_r1) ) [px::bind(&expr<Iterator>::leq, _val, _1)]
|
||||
| (">=" > additive_expression(_r1) ) [px::bind(&expr<Iterator>::geq, _val, _1)]
|
||||
@@ -1255,33 +1352,40 @@ namespace client
|
||||
{ out = value.unary_integer(out.it_range.begin()); }
|
||||
static void round(expr<Iterator> &value, expr<Iterator> &out)
|
||||
{ out = value.round(out.it_range.begin()); }
|
||||
static void floor(expr<Iterator> &value, expr<Iterator> &out)
|
||||
{ out = value.floor(out.it_range.begin()); }
|
||||
static void ceil(expr<Iterator> &value, expr<Iterator> &out)
|
||||
{ out = value.ceil(out.it_range.begin());}
|
||||
// For indicating "no optional parameter".
|
||||
static void noexpr(expr<Iterator> &out) { out.reset(); }
|
||||
};
|
||||
unary_expression = iter_pos[px::bind(&FactorActions::set_start_pos, _1, _val)] >> (
|
||||
scalar_variable_reference(_r1) [ _val = _1 ]
|
||||
| (lit('(') > conditional_expression(_r1) > ')' > iter_pos) [ px::bind(&FactorActions::expr_, _1, _2, _val) ]
|
||||
| (lit('-') > unary_expression(_r1) ) [ px::bind(&FactorActions::minus_, _1, _val) ]
|
||||
| (lit('+') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::expr_, _1, _2, _val) ]
|
||||
| ((kw["not"] | '!') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::not_, _1, _val) ]
|
||||
| (kw["min"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
||||
[ px::bind(&expr<Iterator>::min, _val, _2) ]
|
||||
| (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
||||
[ px::bind(&expr<Iterator>::max, _val, _2) ]
|
||||
| (kw["random"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
||||
[ px::bind(&MyContext::random<Iterator>, _r1, _val, _2) ]
|
||||
| (kw["digits"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > optional_parameter(_r1))
|
||||
[ px::bind(&expr<Iterator>::template digits<false>, _val, _2, _3) ]
|
||||
| (kw["zdigits"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > optional_parameter(_r1))
|
||||
[ px::bind(&expr<Iterator>::template digits<true>, _val, _2, _3) ]
|
||||
| (kw["int"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::to_int, _1, _val) ]
|
||||
| (kw["round"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::round, _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) ]
|
||||
| raw[lexeme['"' > *((utf8char - char_('\\') - char_('"')) | ('\\' > char_)) > '"']]
|
||||
[ px::bind(&FactorActions::string_, _1, _val) ]
|
||||
);
|
||||
scalar_variable_reference(_r1) [ _val = _1 ]
|
||||
| (lit('(') > conditional_expression(_r1) > ')' > iter_pos) [ px::bind(&FactorActions::expr_, _1, _2, _val) ]
|
||||
| (lit('-') > unary_expression(_r1) ) [ px::bind(&FactorActions::minus_, _1, _val) ]
|
||||
| (lit('+') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::expr_, _1, _2, _val) ]
|
||||
| ((kw["not"] | '!') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::not_, _1, _val) ]
|
||||
| (kw["min"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
||||
[ px::bind(&expr<Iterator>::min, _val, _2) ]
|
||||
| (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
||||
[ px::bind(&expr<Iterator>::max, _val, _2) ]
|
||||
| (kw["random"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
||||
[ px::bind(&MyContext::random<Iterator>, _r1, _val, _2) ]
|
||||
| (kw["filament_change"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&MyContext::filament_change<Iterator>, _r1, _1) ]
|
||||
| (kw["digits"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > optional_parameter(_r1))
|
||||
[ px::bind(&expr<Iterator>::template digits<false>, _val, _2, _3) ]
|
||||
| (kw["zdigits"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > optional_parameter(_r1))
|
||||
[ px::bind(&expr<Iterator>::template digits<true>, _val, _2, _3) ]
|
||||
| (kw["int"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::to_int, _1, _val) ]
|
||||
| (kw["round"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::round, _1, _val) ]
|
||||
| (kw["ceil"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::ceil, _1, _val) ]
|
||||
| (kw["floor"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::floor, _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) ]
|
||||
| raw[lexeme['"' > *((utf8char - char_('\\') - char_('"')) | ('\\' > char_)) > '"']]
|
||||
[ px::bind(&FactorActions::string_, _1, _val) ]
|
||||
);
|
||||
unary_expression.name("unary_expression");
|
||||
|
||||
optional_parameter = iter_pos[px::bind(&FactorActions::set_start_pos, _1, _val)] >> (
|
||||
@@ -1290,10 +1394,10 @@ namespace client
|
||||
);
|
||||
optional_parameter.name("optional_parameter");
|
||||
|
||||
scalar_variable_reference =
|
||||
scalar_variable_reference =
|
||||
variable_reference(_r1)[_a=_1] >>
|
||||
(
|
||||
('[' > additive_expression(_r1)[px::bind(&MyContext::evaluate_index<Iterator>, _1, _b)] > ']' >
|
||||
('[' > additive_expression(_r1)[px::bind(&MyContext::evaluate_index<Iterator>, _1, _b)] > ']' >
|
||||
iter_pos[px::bind(&MyContext::vector_variable_reference<Iterator>, _r1, _a, _b, _1, _val)])
|
||||
| eps[px::bind(&MyContext::scalar_variable_reference<Iterator>, _r1, _a, _val)]
|
||||
);
|
||||
@@ -1320,7 +1424,10 @@ namespace client
|
||||
("min")
|
||||
("max")
|
||||
("random")
|
||||
("filament_change")
|
||||
("round")
|
||||
("floor")
|
||||
("ceil")
|
||||
("not")
|
||||
("or")
|
||||
("true");
|
||||
|
||||
Reference in New Issue
Block a user