C++ Mathematical Expression Library (ExprTk) http://www.partow.net/programming/exprtk/index.html

This commit is contained in:
Arash Partow 2015-03-29 23:43:29 +11:00
parent 53b2977902
commit a92190fd2d
3 changed files with 223 additions and 70 deletions

View File

@ -3657,12 +3657,12 @@ namespace exprtk
inline type_store& back() inline type_store& back()
{ {
return parameter_list_[size() - 1]; return parameter_list_.back();
} }
inline const type_store& back() const inline const type_store& back() const
{ {
return parameter_list_[size() - 1]; return parameter_list_.back();
} }
private: private:
@ -13465,7 +13465,7 @@ namespace exprtk
inline virtual T operator()(const std::vector<T>&) inline virtual T operator()(const std::vector<T>&)
{ {
exprtk_debug(("ivararg_function::operator() - Operator has not been overriden.\n")); exprtk_debug(("ivararg_function::operator() - Operator has not been overridden.\n"));
return std::numeric_limits<T>::quiet_NaN(); return std::numeric_limits<T>::quiet_NaN();
} }
@ -13493,28 +13493,28 @@ namespace exprtk
// f(i_0,i_1,....,i_N) --> Number // f(i_0,i_1,....,i_N) --> Number
inline virtual T operator()(parameter_list_t) inline virtual T operator()(parameter_list_t)
{ {
exprtk_debug(("igeneric_function::operator() - Operator has not been overriden. [1]\n")); exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [1]\n"));
return std::numeric_limits<T>::quiet_NaN(); return std::numeric_limits<T>::quiet_NaN();
} }
// f(i_0,i_1,....,i_N) --> String // f(i_0,i_1,....,i_N) --> String
inline virtual T operator()(std::string&, parameter_list_t) inline virtual T operator()(std::string&, parameter_list_t)
{ {
exprtk_debug(("igeneric_function::operator() - Operator has not been overriden. [2]\n")); exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [2]\n"));
return std::numeric_limits<T>::quiet_NaN(); return std::numeric_limits<T>::quiet_NaN();
} }
// f(psi,i_0,i_1,....,i_N) --> Number // f(psi,i_0,i_1,....,i_N) --> Number
inline virtual T operator()(const std::size_t&, parameter_list_t) inline virtual T operator()(const std::size_t&, parameter_list_t)
{ {
exprtk_debug(("igeneric_function::operator() - Operator has not been overriden. [3]\n")); exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [3]\n"));
return std::numeric_limits<T>::quiet_NaN(); return std::numeric_limits<T>::quiet_NaN();
} }
// f(psi,i_0,i_1,....,i_N) --> String // f(psi,i_0,i_1,....,i_N) --> String
inline virtual T operator()(const std::size_t&, std::string&, parameter_list_t) inline virtual T operator()(const std::size_t&, std::string&, parameter_list_t)
{ {
exprtk_debug(("igeneric_function::operator() - Operator has not been overriden. [4]\n")); exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [4]\n"));
return std::numeric_limits<T>::quiet_NaN(); return std::numeric_limits<T>::quiet_NaN();
} }
@ -15050,19 +15050,25 @@ namespace exprtk
} }
} }
inline void register_local_data(void* data, const std::size_t& size = 0, const bool vectype = false) inline void register_local_data(void* data, const std::size_t& size = 0, const std::size_t data_mode = 0)
{ {
if (data) if (data)
{ {
if (expression_holder_) if (expression_holder_)
{ {
typename expression_holder::data_type dt = expression_holder::e_data;
switch(data_mode)
{
case 0 : dt = expression_holder::e_data; break;
case 1 : dt = expression_holder::e_vecdata; break;
case 2 : dt = expression_holder::e_string; break;
}
expression_holder_-> expression_holder_->
local_data_list.push_back( local_data_list.push_back(
typename expression<T>::expression_holder:: typename expression<T>::expression_holder::
data_pack(reinterpret_cast<void*>(data), data_pack(reinterpret_cast<void*>(data),dt,size));
vectype ? expression_holder::e_vecdata :
expression_holder::e_data,
size));
} }
} }
} }
@ -15364,9 +15370,10 @@ namespace exprtk
e_string e_string
}; };
typedef variable_node_t* variable_node_ptr;
typedef details::vector_holder<T> vector_holder_t; typedef details::vector_holder<T> vector_holder_t;
typedef variable_node_t* variable_node_ptr;
typedef vector_holder_t* vector_holder_ptr; typedef vector_holder_t* vector_holder_ptr;
typedef stringvar_node_t* stringvar_node_ptr;
scope_element() scope_element()
: name("???"), : name("???"),
@ -15379,7 +15386,8 @@ namespace exprtk
active(false), active(false),
data (0), data (0),
var_node(0), var_node(0),
vec_node(0) vec_node(0),
str_node(0)
{} {}
bool operator < (const scope_element& se) const bool operator < (const scope_element& se) const
@ -15411,6 +15419,7 @@ namespace exprtk
void* data; void* data;
variable_node_ptr var_node; variable_node_ptr var_node;
vector_holder_ptr vec_node; vector_holder_ptr vec_node;
stringvar_node_ptr str_node;
}; };
class scope_element_manager class scope_element_manager
@ -15538,12 +15547,16 @@ namespace exprtk
delete element_[i].vec_node; delete element_[i].vec_node;
} }
T* data = (T*)(element_[i].data);
switch (element_[i].type) switch (element_[i].type)
{ {
case scope_element::e_variable : delete data; break; case scope_element::e_variable : delete (T*)(element_[i].data);
case scope_element::e_vector : delete [] data; break; break;
case scope_element::e_vector : delete [] (T*)(element_[i].data);
break;
case scope_element::e_string : delete (std::string*)(element_[i].data);
default : break; default : break;
} }
} }
@ -20024,6 +20037,72 @@ namespace exprtk
return result; return result;
} }
inline expression_node_ptr parse_define_string_statement(const std::string& str_name, expression_node_ptr initialisation_expression)
{
stringvar_node_t* str_node = reinterpret_cast<stringvar_node_t*>(0);
scope_element& se = sem_.get_element(str_name);
if (se.name == str_name)
{
if (se.active)
{
set_error(
make_error(parser_error::e_syntax,
current_token_,
"ERR132 - Illegal redefinition of local variable: '" + str_name + "'"));
free_node(node_allocator_,initialisation_expression);
return error_node();
}
else if ((scope_element::e_string == se.type))
{
str_node = se.str_node;
se.active = true;
se.depth = scope_depth_;
se.ref_count++;
}
}
if (0 == str_node)
{
scope_element nse;
nse.name = str_name;
nse.active = true;
nse.ref_count = 1;
nse.type = scope_element::e_string;
nse.depth = scope_depth_;
nse.data = new std::string;
nse.str_node = new stringvar_node_t(*(std::string*)(nse.data));
if (!sem_.add_element(nse))
{
set_error(
make_error(parser_error::e_syntax,
current_token_,
"ERR133 - Failed to add new local string variable '" + str_name + "' to SEM"));
free_node(node_allocator_,initialisation_expression);
return error_node();
}
str_node = nse.str_node;
exprtk_debug(("parse_define_string_statement() - INFO - Added new local string variable: %s\n",nse.name.c_str()));
}
lodge_symbol(str_name,e_st_local_string);
expression_node_ptr branch[2] = {0};
branch[0] = str_node;
branch[1] = initialisation_expression;
return expression_generator_(details::e_assign,branch);
}
inline bool local_variable_is_shadowed(const std::string& symbol) inline bool local_variable_is_shadowed(const std::string& symbol)
{ {
const scope_element& se = sem_.get_element(symbol); const scope_element& se = sem_.get_element(symbol);
@ -20037,7 +20116,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR132 - Illegal variable definition")); "ERR134 - Illegal variable definition"));
return error_node(); return error_node();
} }
@ -20057,7 +20136,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR133 - Expected a symbol for variable definition")); "ERR135 - Expected a symbol for variable definition"));
return error_node(); return error_node();
} }
@ -20066,7 +20145,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR134 - Illegal redefinition of reserved keyword: '" + var_name + "'")); "ERR136 - Illegal redefinition of reserved keyword: '" + var_name + "'"));
return error_node(); return error_node();
} }
@ -20075,7 +20154,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR135 - Illegal redefinition of variable '" + var_name + "'")); "ERR137 - Illegal redefinition of variable '" + var_name + "'"));
return error_node(); return error_node();
} }
@ -20084,7 +20163,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR136 - Illegal redefinition of local variable: '" + var_name + "'")); "ERR138 - Illegal redefinition of local variable: '" + var_name + "'"));
return error_node(); return error_node();
} }
@ -20103,7 +20182,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR137 - Failed to parse initialisation expression")); "ERR139 - Failed to parse initialisation expression"));
return error_node(); return error_node();
} }
@ -20120,7 +20199,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR138 - Expected ';' after variable definition")); "ERR140 - Expected ';' after variable definition"));
free_node(node_allocator_,initialisation_expression); free_node(node_allocator_,initialisation_expression);
@ -20128,6 +20207,14 @@ namespace exprtk
} }
} }
if (
(0 != initialisation_expression) &&
details::is_generally_string_node(initialisation_expression)
)
{
return parse_define_string_statement(var_name,initialisation_expression);
}
variable_node_t* var_node = reinterpret_cast<variable_node_t*>(0); variable_node_t* var_node = reinterpret_cast<variable_node_t*>(0);
scope_element& se = sem_.get_element(var_name); scope_element& se = sem_.get_element(var_name);
@ -20139,7 +20226,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR139 - Illegal redefinition of local variable: '" + var_name + "'")); "ERR141 - Illegal redefinition of local variable: '" + var_name + "'"));
free_node(node_allocator_,initialisation_expression); free_node(node_allocator_,initialisation_expression);
@ -20170,7 +20257,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR140 - Failed to add new local variable '" + var_name + "' to SEM")); "ERR142 - Failed to add new local variable '" + var_name + "' to SEM"));
free_node(node_allocator_,initialisation_expression); free_node(node_allocator_,initialisation_expression);
@ -20202,7 +20289,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR141 - Expected a '{}' for uninitialised var definition")); "ERR143 - Expected a '{}' for uninitialised var definition"));
return error_node(); return error_node();
} }
@ -20211,7 +20298,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR142 - Expected ';' after uninitialised variable definition")); "ERR144 - Expected ';' after uninitialised variable definition"));
return error_node(); return error_node();
} }
@ -20227,7 +20314,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR143 - Illegal redefinition of local variable: '" + var_name + "'")); "ERR145 - Illegal redefinition of local variable: '" + var_name + "'"));
return error_node(); return error_node();
} }
@ -20256,7 +20343,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR144 - Failed to add new local variable '" + var_name + "' to SEM")); "ERR146 - Failed to add new local variable '" + var_name + "' to SEM"));
return error_node(); return error_node();
} }
@ -20283,7 +20370,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR145 - Expected '(' at start of swap statement")); "ERR147 - Expected '(' at start of swap statement"));
return error_node(); return error_node();
} }
@ -20301,7 +20388,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR146 - Expected a symbol for variable or vector element definition")); "ERR148 - Expected a symbol for variable or vector element definition"));
return error_node(); return error_node();
} }
@ -20312,7 +20399,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR147 - First parameter to swap is an invalid vector element: '" + var0_name + "'")); "ERR149 - First parameter to swap is an invalid vector element: '" + var0_name + "'"));
return error_node(); return error_node();
} }
@ -20344,7 +20431,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR148 - First parameter to swap is an invalid variable: '" + var0_name + "'")); "ERR150 - First parameter to swap is an invalid variable: '" + var0_name + "'"));
return error_node(); return error_node();
} }
@ -20357,7 +20444,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token(), current_token(),
"ERR149 - Expected ',' between parameters to swap")); "ERR151 - Expected ',' between parameters to swap"));
if (variable0_generated) if (variable0_generated)
{ {
@ -20374,7 +20461,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR150 - Expected a symbol for variable or vector element definition")); "ERR152 - Expected a symbol for variable or vector element definition"));
if (variable0_generated) if (variable0_generated)
{ {
@ -20390,7 +20477,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR151 - Second parameter to swap is an invalid vector element: '" + var1_name + "'")); "ERR153 - Second parameter to swap is an invalid vector element: '" + var1_name + "'"));
if (variable0_generated) if (variable0_generated)
{ {
@ -20427,7 +20514,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR152 - Second parameter to swap is an invalid variable: '" + var1_name + "'")); "ERR154 - Second parameter to swap is an invalid variable: '" + var1_name + "'"));
if (variable0_generated) if (variable0_generated)
{ {
@ -20445,7 +20532,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR153 - Expected ')' at end of swap statement")); "ERR155 - Expected ')' at end of swap statement"));
if (variable0_generated) if (variable0_generated)
{ {
@ -20500,7 +20587,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR154 - Invalid sequence of variable '"+ symbol + "' and bracket")); "ERR156 - Invalid sequence of variable '"+ symbol + "' and bracket"));
return false; return false;
} }
@ -20545,7 +20632,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR155 - Invalid sequence of brackets")); "ERR157 - Invalid sequence of brackets"));
return false; return false;
} }
@ -20583,7 +20670,7 @@ namespace exprtk
return variable; return variable;
} }
// Are we dealing with a locally defined variable or vector? // Are we dealing with a locally defined variable, vector or string?
if (!sem_.empty()) if (!sem_.empty())
{ {
scope_element& se = sem_.get_active_element(symbol); scope_element& se = sem_.get_active_element(symbol);
@ -20606,6 +20693,15 @@ namespace exprtk
{ {
return parse_vector(); return parse_vector();
} }
else if (scope_element::e_string == se.type)
{
se.active = true;
lodge_symbol(symbol,e_st_local_string);
next_token();
return se.str_node;
}
} }
} }
@ -20635,7 +20731,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR156 - Failed to generate node for function: '" + symbol + "'")); "ERR158 - Failed to generate node for function: '" + symbol + "'"));
return error_node(); return error_node();
} }
@ -20660,7 +20756,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR157 - Failed to generate node for vararg function: '" + symbol + "'")); "ERR159 - Failed to generate node for vararg function: '" + symbol + "'"));
return error_node(); return error_node();
} }
@ -20685,7 +20781,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR158 - Failed to generate node for generic function: '" + symbol + "'")); "ERR160 - Failed to generate node for generic function: '" + symbol + "'"));
return error_node(); return error_node();
} }
@ -20710,7 +20806,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR159 - Failed to generate node for string function: '" + symbol + "'")); "ERR161 - Failed to generate node for string function: '" + symbol + "'"));
return error_node(); return error_node();
} }
@ -20731,7 +20827,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR160 - Invalid use of reserved symbol '" + symbol + "'")); "ERR162 - Invalid use of reserved symbol '" + symbol + "'"));
return error_node(); return error_node();
} }
@ -20788,7 +20884,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_symtab, make_error(parser_error::e_symtab,
current_token_, current_token_,
"ERR161 - Failed to create variable: '" + symbol + "'")); "ERR163 - Failed to create variable: '" + symbol + "'"));
return error_node(); return error_node();
} }
@ -20798,7 +20894,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR162 - Undefined symbol: '" + symbol + "'")); "ERR164 - Undefined symbol: '" + symbol + "'"));
return error_node(); return error_node();
} }
@ -20895,7 +20991,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_symtab, make_error(parser_error::e_symtab,
current_token_, current_token_,
"ERR163 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token_.value)); "ERR165 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token_.value));
return error_node(); return error_node();
} }
@ -20920,7 +21016,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_numeric, make_error(parser_error::e_numeric,
current_token_, current_token_,
"ERR164 - Failed to convert '" + current_token_.value + "' to a number")); "ERR166 - Failed to convert '" + current_token_.value + "' to a number"));
return error_node(); return error_node();
} }
@ -20946,7 +21042,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR165 - Expected ')' instead of: '" + current_token_.value + "'")); "ERR167 - Expected ')' instead of: '" + current_token_.value + "'"));
free_node(node_allocator_,branch); free_node(node_allocator_,branch);
@ -20970,7 +21066,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR166 - Expected ']' instead of: '" + current_token_.value + "'")); "ERR168 - Expected ']' instead of: '" + current_token_.value + "'"));
free_node(node_allocator_,branch); free_node(node_allocator_,branch);
@ -20994,7 +21090,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR167 - Expected '}' instead of: '" + current_token_.value + "'")); "ERR169 - Expected '}' instead of: '" + current_token_.value + "'"));
free_node(node_allocator_,branch); free_node(node_allocator_,branch);
@ -21033,7 +21129,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR168 - Premature end of expression[1]")); "ERR170 - Premature end of expression[1]"));
return error_node(); return error_node();
} }
@ -21042,7 +21138,7 @@ namespace exprtk
set_error( set_error(
make_error(parser_error::e_syntax, make_error(parser_error::e_syntax,
current_token_, current_token_,
"ERR169 - Premature end of expression[2]")); "ERR171 - Premature end of expression[2]"));
return error_node(); return error_node();
} }
@ -29223,24 +29319,37 @@ namespace exprtk
if (se.data) if (se.data)
{ {
e.register_local_data(se.data,1); e.register_local_data(se.data,1,0);
} }
} }
else if (scope_element::e_vector == se.type) else if (scope_element::e_vector == se.type)
{ {
if (se.vec_node) if (se.vec_node)
{ {
e.register_local_var (se.vec_node); e.register_local_var(se.vec_node);
} }
if (se.data) if (se.data)
{ {
e.register_local_data(se.data,se.size,true); e.register_local_data(se.data,se.size,1);
}
}
else if (scope_element::e_string == se.type)
{
if (se.str_node)
{
e.register_local_var(se.str_node);
}
if (se.data)
{
e.register_local_data(se.data,se.size,2);
} }
} }
se.var_node = 0; se.var_node = 0;
se.vec_node = 0; se.vec_node = 0;
se.str_node = 0;
se.data = 0; se.data = 0;
se.ref_count = 0; se.ref_count = 0;
se.active = false; se.active = false;

View File

@ -3741,6 +3741,17 @@ inline bool run_test10()
"var x:= 2; var y := 3; (abs(x + 0)/-abs(y - 0)) == -(2/3) ", "var x:= 2; var y := 3; (abs(x + 0)/-abs(y - 0)) == -(2/3) ",
"var x := 1; var y := 2; swap(x,y); (x == 2) and (y == 1)", "var x := 1; var y := 2; swap(x,y); (x == 2) and (y == 1)",
"var x := 1; var y := 2; x <=> y ; (x == 2) and (y == 1)", "var x := 1; var y := 2; x <=> y ; (x == 2) and (y == 1)",
"var x := 'abc'; x == 'abc' ",
"var x := 'abc'; var y := '123'; x != y ",
"var x := 'abc'; var y := x + '123'; y == 'abc123' ",
"var x := 'abc'; var y := '123' + x; y == '123abc' ",
"~{var x := '123'; x[]} + ~{var x := '1234'; x[]} == 7",
"~{var x := '123'; x[]} + ~{~{var x := '1234'; x[]}} == 7",
"~{~{var x := '123'; x[]}} + ~{var x := '1234'; x[]} == 7",
"~{var x := '123'; x[]} + ~{var x := 4} == 7",
"~{var x := 3} + ~{var x := '1234'; x[]} == 7",
"~{var x := '123'; x[]} + ~{~{var x := 4}} == 7",
"~{~{var x := 3}} + ~{var x := '1234'; x[]} == 7",
"var v[2] := {1,2}; swap(v[0],v[1]); (v[0] == 2) and (v[1] == 1)", "var v[2] := {1,2}; swap(v[0],v[1]); (v[0] == 2) and (v[1] == 1)",
"var v[2] := {1,2}; v[0] <=> v[1] ; (v[0] == 2) and (v[1] == 1)", "var v[2] := {1,2}; v[0] <=> v[1] ; (v[0] == 2) and (v[1] == 1)",
"var x := 1; var y := 2; ~(swap(x,y),(x == 2) and (y == 1))", "var x := 1; var y := 2; ~(swap(x,y),(x == 2) and (y == 1))",
@ -3779,6 +3790,8 @@ inline bool run_test10()
"(~{~{ var x[1] := [1] }} + ~{ var x := [1] } + ~{ var x[1] := [2] } + ~{{ var x[1] := [2] }}) == 6", "(~{~{ var x[1] := [1] }} + ~{ var x := [1] } + ~{ var x[1] := [2] } + ~{{ var x[1] := [2] }}) == 6",
"(~{~{ var x[1] := [1] }} + ~{ var x[1] := [1] } + ~{ var x := [2] } + ~{{ var x[1] := [2] }}) == 6", "(~{~{ var x[1] := [1] }} + ~{ var x[1] := [1] } + ~{ var x := [2] } + ~{{ var x[1] := [2] }}) == 6",
"(~{~{ var x[1] := [1] }} + ~{ var x[1] := [1] } + ~{ var x[1] := [2] } + ~{{ var x := [2] }}) == 6", "(~{~{ var x[1] := [1] }} + ~{ var x[1] := [1] } + ~{ var x[1] := [2] } + ~{{ var x := [2] }}) == 6",
"(~{~{~{var x[1] := [1]}}} + ~{~{var x[1] := [2]}} + ~{var x[1] := [3]}) == 6",
"(~{var x[1] := [1]} + ~{~{var x[1] := [2]}} + ~{~{~{var x[1] := [3]}}}) == 6",
"(~{ var x[3] := [1] } + ~{ var x[6] := {6,5,4,3,2,1}}) == 7", "(~{ var x[3] := [1] } + ~{ var x[6] := {6,5,4,3,2,1}}) == 7",
"(~{ var x[6] := {6,5,4,3,2,1} } + ~{ var x := 1 }) == 7", "(~{ var x[6] := {6,5,4,3,2,1} } + ~{ var x := 1 }) == 7",
"(~{ var x := 1 } + ~{ var x[6] := {6,5,4,3,2,1} }) == 7", "(~{ var x := 1 } + ~{ var x[6] := {6,5,4,3,2,1} }) == 7",

View File

@ -948,10 +948,10 @@ correctly optimize such expressions for a given architecture.
[13 - VARIABLE & VECTOR DEFINITION] [13 - VARIABLE , VECTOR & STRING DEFINITION]
ExprTk supports the definition of expression local variables and ExprTk supports the definition of expression local variables, vectors
vectors. The definitions must be unique as shadowing is not allowed and strings. The definitions must be unique as shadowing is not
and object life-times are based on scope. Definitions use the allowed and object life-times are based on scope. Definitions use the
following general form: following general form:
var <name> := <initialiser>; var <name> := <initialiser>;
@ -998,14 +998,45 @@ zero. The following are examples of vector definitions:
var x[0]; var x[0];
(3) Return Value (3) String Definition
Strings are a sequence of 8-bit characters. They can only be defined
with an explicit initialisation value. The following are examples of
string variable definitions:
(a) Initialise to a string
var x := 'abc';
(b) Initialise to a string expression
var x := 'abc' + '123';
(c) Initialise to a string range
var x := 'abc123'[2:4];
(d) Initialise to another string variable
var x := 'abc';
var y := x;
(e) Initialise to another string variable range
var x := 'abc123';
var y := x[2:4];
(f) Initialise to a string expression
var x := 'abc';
var y := x + '123';
(f) Initialise to a string expression range
var x := 'abc';
var y := (x + '123')[1:3];
(4) Return Value
Variable and vector definitions have a return value. In the case of Variable and vector definitions have a return value. In the case of
variable definitions, the value to which the variable is initialised variable definitions, the value to which the variable is initialised
will be returned. Where as for vectors, the value of the first element will be returned. Where as for vectors, the value of the first element
(eg: v[0]) will be returned. (eg: v[0]) will be returned.
(4) Variable/Vector Assignment (5) Variable/Vector Assignment
The value of a variable can be assigned to a vector and a vector or a The value of a variable can be assigned to a vector and a vector or a
vector expression can be assigned to a variable. vector expression can be assigned to a variable.