C++ Mathematical Expression Library (ExprTk)  http://www.partow.net/programming/exprtk/index.html
diff --git a/exprtk.hpp b/exprtk.hpp
index b11c6a9..3d4ada1 100644
--- a/exprtk.hpp
+++ b/exprtk.hpp
@@ -221,7 +221,7 @@
          if (('0' <= h) && (h <= '9'))
             return (h - '0');
          else
-            return (std::toupper(h) - 'A');
+            return static_cast<unsigned char>(std::toupper(h) - 'A');
       }
 
       template <typename Iterator>
@@ -410,6 +410,30 @@
 
       static const std::size_t cntrl_struct_list_size = sizeof(cntrl_struct_list) / sizeof(std::string);
 
+      static const std::string arithmetic_ops_list[] =
+                                  {
+                                    "+", "-", "*", "/", "%",  "^"
+                                  };
+
+      static const std::size_t arithmetic_ops_list_size = sizeof(arithmetic_ops_list) / sizeof(std::string);
+
+      static const std::string assignment_ops_list[] =
+                                  {
+                                    ":=", "+=", "-=",
+                                    "*=", "/=", "%="
+                                  };
+
+      static const std::size_t assignment_ops_list_size = sizeof(assignment_ops_list) / sizeof(std::string);
+
+      static const std::string inequality_ops_list[] =
+                                  {
+                                     "<",  "<=", "==",
+                                     "=",  "!=", "<>",
+                                    ">=",  ">"
+                                  };
+
+      static const std::size_t inequality_ops_list_size = sizeof(inequality_ops_list) / sizeof(std::string);
+
       inline bool is_reserved_word(const std::string& symbol)
       {
          for (std::size_t i = 0; i < reserved_words_size; ++i)
@@ -594,12 +618,12 @@
          {
             if ('*' == (*p_itr))
             {
-               const char target = std::toupper(*(p_itr - 1));
+               const char target = static_cast<char>(std::toupper(*(p_itr - 1)));
 
                if ('*' == target)
                {
                   diff_index = std::distance(str.begin(),s_itr);
-                  diff_value = std::toupper(*p_itr);
+                  diff_value = static_cast<char>(std::toupper(*p_itr));
 
                   return false;
                }
@@ -622,7 +646,7 @@
                     )
             {
                diff_index = std::distance(str.begin(),s_itr);
-               diff_value = std::toupper(*p_itr);
+               diff_value = static_cast<char>(std::toupper(*p_itr));
 
                return false;
             }
@@ -3078,6 +3102,34 @@
                   t.position = t0.position;
                   return true;
                }
+               // '+ -' --> '-'
+               else if ((t0.type == lexer::token::e_add) && (t1.type == lexer::token::e_sub))
+               {
+                  t.type     = lexer::token::e_sub;
+                  t.value    = "-";
+                  t.position = t0.position;
+                  return true;
+               }
+               // '- +' --> '-'
+               else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_add))
+               {
+                  t.type     = lexer::token::e_sub;
+                  t.value    = "-";
+                  t.position = t0.position;
+                  return true;
+               }
+               // '- -' --> '-'
+               else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_sub))
+               {
+                  /*
+                     Note: May need to reconsider this when wanting to implement
+                     pre/postfix decrement operator
+                  */
+                  t.type     = lexer::token::e_add;
+                  t.value    = "+";
+                  t.position = t0.position;
+                  return true;
+               }
                else
                   return false;
             }
@@ -4067,9 +4119,38 @@
          e_sf4ext44 = 2044, e_sf4ext45 = 2045, e_sf4ext46 = 2046, e_sf4ext47 = 2047,
          e_sf4ext48 = 2048, e_sf4ext49 = 2049, e_sf4ext50 = 2050, e_sf4ext51 = 2051,
          e_sf4ext52 = 2052, e_sf4ext53 = 2053, e_sf4ext54 = 2054, e_sf4ext55 = 2055,
-         e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059
+         e_sf4ext56 = 2056, e_sf4ext57 = 2057, e_sf4ext58 = 2058, e_sf4ext59 = 2059,
+         e_sf4ext60 = 2060
       };
 
+      std::string to_str(const operator_type opr)
+      {
+         switch (opr)
+         {
+            case e_add    : return  "+";
+            case e_sub    : return  "-";
+            case e_mul    : return  "*";
+            case e_div    : return  "/";
+            case e_mod    : return  "%";
+            case e_pow    : return  "^";
+            case e_assign : return ":=";
+            case e_addass : return "+=";
+            case e_subass : return "-=";
+            case e_mulass : return "*=";
+            case e_divass : return "/=";
+            case e_modass : return "%=";
+            case e_lt     : return  "<";
+            case e_lte    : return "<=";
+            case e_eq     : return "==";
+            case e_equal  : return  "=";
+            case e_ne     : return "!=";
+            case e_nequal : return "<>";
+            case e_gte    : return ">=";
+            case e_gt     : return  ">";
+            default       : return"N/A";
+         }
+      }
+
       struct base_operation_t
       {
          base_operation_t(const operator_type t, const unsigned int& np)
@@ -4792,6 +4873,9 @@
 
          typedef range_pack<T> range_t;
 
+         virtual ~range_interface()
+         {}
+
          virtual range_t& range_ref() = 0;
 
          virtual const range_t& range_ref() const = 0;
@@ -4804,6 +4888,9 @@
 
          typedef range_data_type<T> range_data_type_t;
 
+         virtual ~string_base_node()
+         {}
+
          virtual std::string str () const = 0;
 
          virtual const char* base() const = 0;
@@ -5976,6 +6063,9 @@
       {
       public:
 
+         virtual ~ivariable()
+         {}
+
          virtual T& ref() = 0;
          virtual const T& ref() const = 0;
       };
@@ -6276,10 +6366,13 @@
       public:
 
          typedef expression_node<T>* expression_ptr;
+         typedef vector_holder<T>    vector_holder_t;
+         typedef vector_holder_t*    vector_holder_ptr;
 
-         vector_elem_node(expression_ptr index, T* vector_base)
+         vector_elem_node(expression_ptr index, vector_holder_ptr vec_holder)
          : index_(index),
-           vector_base_(vector_base),
+           vec_holder_(vec_holder),
+           vector_base_((*vec_holder)[0]),
            index_deletable_(branch_deletable(index_))
          {}
 
@@ -6311,9 +6404,15 @@
             return expression_node<T>::e_vecelem;
          }
 
+         inline vector_holder_t& vec_holder()
+         {
+            return (*vec_holder_);
+         }
+
       private:
 
          expression_ptr index_;
+         vector_holder_ptr vec_holder_;
          T* vector_base_;
          bool index_deletable_;
       };
@@ -6473,7 +6572,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
                {
                   vec0_node_ptr_ = vi->vec();
                }
@@ -6483,7 +6582,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
                {
                   vec1_node_ptr_ = vi->vec();
                }
@@ -6493,6 +6592,7 @@
             {
                vec_size_ = std::min(vec0_node_ptr_->ref().size(),
                                     vec1_node_ptr_->ref().size());
+
                initialised_ = true;
             }
          }
@@ -6648,7 +6748,7 @@
            rp_(rp)
          {}
 
-        ~string_range_node()
+         virtual ~string_range_node()
          {
             rp_.free();
          }
@@ -7979,6 +8079,7 @@
       define_sfop4(ext57,((x - y) + (z - w)),"(t-t)+(t-t)")
       define_sfop4(ext58,((x - y) - (z - w)),"(t-t)-(t-t)")
       define_sfop4(ext59,((x / y) + (z * w)),"(t/t)+(t*t)")
+      define_sfop4(ext60,(((x * y) * z) / w),"((t*t)*t)/t")
 
       #undef define_sfop3
       #undef define_sfop4
@@ -8415,7 +8516,8 @@
          : binary_node<T>(opr,branch0,branch1),
            vec0_node_ptr_(0),
            vec1_node_ptr_(0),
-           vec_size_     (0)
+           vec_size_     (0),
+           initialised_(false)
          {
             if (is_vector_node(binary_node<T>::branch_[0].first))
             {
@@ -8430,7 +8532,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
                {
                   vec1_node_ptr_ = vi->vec();
                }
@@ -8440,6 +8542,8 @@
             {
                vec_size_ = std::min(vec0_node_ptr_->ref().size(),
                                     vec1_node_ptr_->ref().size());
+
+               initialised_ = true;
             }
          }
 
@@ -8447,7 +8551,7 @@
          {
             binary_node<T>::branch_[1].first->value();
 
-            if (vec0_node_ptr_ && vec1_node_ptr_)
+            if (initialised_)
             {
                vector_holder<T>& vec0 = vec0_node_ptr_->ref();
                vector_holder<T>& vec1 = vec1_node_ptr_->ref();
@@ -8488,6 +8592,7 @@
          vector_node<T>* vec0_node_ptr_;
          vector_node<T>* vec1_node_ptr_;
          std::size_t     vec_size_;
+         bool            initialised_;
       };
 
       template <typename T, typename Operation>
@@ -8642,12 +8747,13 @@
          typedef vector_node<T>*     vector_node_ptr;
 
          assignment_vecvec_op_node(const operator_type& opr,
-                                expression_ptr branch0,
-                                expression_ptr branch1)
+                                   expression_ptr branch0,
+                                   expression_ptr branch1)
          : binary_node<T>(opr,branch0,branch1),
            vec0_node_ptr_(0),
            vec1_node_ptr_(0),
-           vec_size_     (0)
+           vec_size_     (0),
+           initialised_(false)
          {
             if (is_vector_node(binary_node<T>::branch_[0].first))
             {
@@ -8662,7 +8768,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
                {
                   vec1_node_ptr_ = vi->vec();
                }
@@ -8672,12 +8778,14 @@
             {
                vec_size_ = std::min(vec0_node_ptr_->ref().size(),
                                     vec1_node_ptr_->ref().size());
+
+               initialised_ = true;
             }
          }
 
          inline T value() const
          {
-            if (vec0_node_ptr_ && vec1_node_ptr_)
+            if (initialised_)
             {
                binary_node<T>::branch_[0].first->value();
                binary_node<T>::branch_[1].first->value();
@@ -8723,6 +8831,7 @@
          vector_node<T>* vec0_node_ptr_;
          vector_node<T>* vec1_node_ptr_;
          std::size_t     vec_size_;
+         bool            initialised_;
       };
 
       template <typename T, typename Operation>
@@ -8740,7 +8849,8 @@
          : binary_node<T>(opr,branch0,branch1),
            vec0_node_ptr_(0),
            vec1_node_ptr_(0),
-           vec_size_     (0)
+           vec_size_     (0),
+           initialised_(false)
          {
 
             if (is_vector_node(binary_node<T>::branch_[0].first))
@@ -8751,7 +8861,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
                {
                   vec0_node_ptr_ = vi->vec();
                }
@@ -8765,7 +8875,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
                {
                   vec1_node_ptr_ = vi->vec();
                }
@@ -8775,12 +8885,14 @@
             {
                vec_size_ = std::min(vec0_node_ptr_->ref().size(),
                                     vec1_node_ptr_->ref().size());
+
+               initialised_ = true;
             }
          }
 
          inline T value() const
          {
-            if (vec0_node_ptr_ && vec1_node_ptr_)
+            if (initialised_)
             {
                binary_node<T>::branch_[0].first->value();
                binary_node<T>::branch_[1].first->value();
@@ -8827,6 +8939,7 @@
          vector_node<T>* vec0_node_ptr_;
          vector_node<T>* vec1_node_ptr_;
          std::size_t     vec_size_;
+         bool            initialised_;
       };
 
       template <typename T, typename Operation>
@@ -8853,7 +8966,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
                {
                   vec_node_ptr_ = vi->vec();
                }
@@ -8938,7 +9051,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
                {
                   vec_node_ptr_ = vi->vec();
                }
@@ -9018,7 +9131,8 @@
            vec_size_     (0),
            data_         (0),
            temp_         (0),
-           temp_vec_node_(0)
+           temp_vec_node_(0),
+           initialised_(false)
          {
             if (is_vector_node(binary_node<T>::branch_[0].first))
             {
@@ -9028,7 +9142,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
                {
                   vec0_node_ptr_ = vi->vec();
                }
@@ -9042,7 +9156,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
                {
                   vec1_node_ptr_ = vi->vec();
                }
@@ -9057,6 +9171,8 @@
                data_          = new T[vec_size_];
                temp_          = new vector_holder<T>(data_,vec_size_);
                temp_vec_node_ = new vector_node<T>  (temp_);
+
+               initialised_ = true;
             }
          }
 
@@ -9069,7 +9185,7 @@
 
          inline T value() const
          {
-            if (vec0_node_ptr_ && vec1_node_ptr_)
+            if (initialised_)
             {
                binary_node<T>::branch_[0].first->value();
                binary_node<T>::branch_[1].first->value();
@@ -9122,6 +9238,7 @@
          T*                data_;
          vector_holder_ptr temp_;
          vector_node_ptr   temp_vec_node_;
+         bool              initialised_;
       };
 
       template <typename T, typename Operation>
@@ -9152,7 +9269,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[0].first)))
                {
                   vec0_node_ptr_ = vi->vec();
                }
@@ -9257,7 +9374,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(binary_node<T>::branch_[1].first)))
                {
                   vec1_node_ptr_ = vi->vec();
                }
@@ -9360,7 +9477,7 @@
             {
                vector_interface<T>* vi = reinterpret_cast<vector_interface<T>*>(0);
 
-               if ((vi = dynamic_cast<vector_interface<T>*>(unary_node<T>::branch_)))
+               if (0 != (vi = dynamic_cast<vector_interface<T>*>(unary_node<T>::branch_)))
                {
                   vec0_node_ptr_ = vi->vec();
                }
@@ -9903,7 +10020,7 @@
            arg_list_(arg_list)
          {}
 
-        ~generic_function_node()
+         virtual ~generic_function_node()
          {
             cleanup_branches::execute(branch_);
          }
@@ -10260,6 +10377,9 @@
       {
       public:
 
+         virtual ~null_igenfunc()
+         {}
+
          typedef type_store<T> generic_type;
          typedef typename generic_type::parameter_list parameter_list_t;
 
@@ -11383,6 +11503,9 @@
       {
       public:
 
+         virtual ~vov_base_node()
+         {}
+
          inline virtual operator_type operation() const
          {
             return details::e_default;
@@ -11398,6 +11521,9 @@
       {
       public:
 
+       virtual ~cov_base_node()
+          {}
+
          inline virtual operator_type operation() const
          {
             return details::e_default;
@@ -11413,6 +11539,9 @@
       {
       public:
 
+         virtual ~voc_base_node()
+         {}
+
          inline virtual operator_type operation() const
          {
             return details::e_default;
@@ -11428,6 +11557,9 @@
       {
       public:
 
+         virtual ~vob_base_node()
+         {}
+
          virtual const T& v() const = 0;
       };
 
@@ -11436,6 +11568,9 @@
       {
       public:
 
+         virtual ~bov_base_node()
+         {}
+
          virtual const T& v() const = 0;
       };
 
@@ -11444,6 +11579,9 @@
       {
       public:
 
+       virtual ~cob_base_node()
+       {}
+
          inline virtual operator_type operation() const
          {
             return details::e_default;
@@ -11461,6 +11599,9 @@
       {
       public:
 
+         virtual ~boc_base_node()
+       {}
+
          inline virtual operator_type operation() const
          {
             return details::e_default;
@@ -11478,6 +11619,9 @@
       {
       public:
 
+         virtual ~uv_base_node()
+         {}
+
          inline virtual operator_type operation() const
          {
             return details::e_default;
@@ -11491,6 +11635,9 @@
       {
       public:
 
+         virtual ~sos_base_node()
+         {}
+
          inline virtual operator_type operation() const
          {
             return details::e_default;
@@ -11502,6 +11649,9 @@
       {
       public:
 
+         virtual ~sosos_base_node()
+         {}
+
          inline virtual operator_type operation() const
          {
             return details::e_default;
@@ -11513,6 +11663,9 @@
       {
       public:
 
+         virtual ~T0oT1oT2_base_node()
+         {}
+
          virtual std::string type_id() const = 0;
       };
 
@@ -11521,6 +11674,9 @@
       {
       public:
 
+         virtual ~T0oT1oT2oT3_base_node()
+         {}
+
          virtual std::string type_id() const = 0;
       };
 
@@ -12274,6 +12430,9 @@
       {
       public:
 
+         virtual ~sf3ext_type_node()
+         {}
+
          virtual T0 t0() const = 0;
 
          virtual T1 t1() const = 0;
@@ -13900,7 +14059,9 @@
 
       function_traits()
       : allow_zero_parameters_(false),
-        has_side_effects_(true)
+        has_side_effects_(true),
+        min_num_args_(0),
+        max_num_args_(std::numeric_limits<std::size_t>::max())
       {}
 
       inline bool& allow_zero_parameters()
@@ -13913,16 +14074,33 @@
          return has_side_effects_;
       }
 
+      std::size_t& min_num_args()
+      {
+         return min_num_args_;
+      }
+
+      std::size_t& max_num_args()
+      {
+         return max_num_args_;
+      }
+
    private:
 
       bool allow_zero_parameters_;
       bool has_side_effects_;
+      std::size_t min_num_args_;
+      std::size_t max_num_args_;
    };
 
    template <typename FunctionType>
    void enable_zero_parameters(FunctionType& func)
    {
       func.allow_zero_parameters() = true;
+
+      if (0 != func.min_num_args())
+      {
+         func.min_num_args() = 0;
+      }
    }
 
    template <typename FunctionType>
@@ -13943,6 +14121,21 @@
       func.has_side_effects() = false;
    }
 
+   template <typename FunctionType>
+   void set_min_num_args(FunctionType& func, const std::size_t& num_args)
+   {
+      func.min_num_args() = num_args;
+
+      if ((0 != func.min_num_args()) && func.allow_zero_parameters())
+         func.allow_zero_parameters() = false;
+   }
+
+   template <typename FunctionType>
+   void set_max_num_args(FunctionType& func, const std::size_t& num_args)
+   {
+      func.max_num_args() = num_args;
+   }
+
    template <typename T>
    class ifunction : public function_traits
    {
@@ -14093,18 +14286,25 @@
    {
    public:
 
+      enum return_type
+      {
+         e_rtrn_scalar = 0,
+         e_rtrn_string = 1
+      };
+
       typedef T type;
       typedef type_store<T> generic_type;
       typedef typename generic_type::parameter_list parameter_list_t;
 
-      igeneric_function(const std::string& param_seq = "")
-      : parameter_sequence(param_seq)
+      igeneric_function(const std::string& param_seq = "", const return_type rtr_type = e_rtrn_scalar)
+      : parameter_sequence(param_seq),
+        rtrn_type(rtr_type)
       {}
 
       virtual ~igeneric_function()
       {}
 
-      // f(i_0,i_1,....,i_N) --> Number
+      // f(i_0,i_1,....,i_N) --> Scalar
       inline virtual T operator()(parameter_list_t)
       {
          exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [1]\n"));
@@ -14118,7 +14318,7 @@
          return std::numeric_limits<T>::quiet_NaN();
       }
 
-      // f(psi,i_0,i_1,....,i_N) --> Number
+      // f(psi,i_0,i_1,....,i_N) --> Scalar
       inline virtual T operator()(const std::size_t&, parameter_list_t)
       {
          exprtk_debug(("igeneric_function::operator() - Operator has not been overridden. [3]\n"));
@@ -14133,6 +14333,7 @@
       }
 
       std::string parameter_sequence;
+      return_type rtrn_type;
    };
 
    template <typename T> class parser;
@@ -14141,8 +14342,56 @@
    template <typename T>
    class symbol_table
    {
+   public:
+
+      typedef T (*ff1_functor)(T);
+      typedef T (*ff2_functor)(T,T);
+      typedef T (*ff3_functor)(T,T,T);
+      typedef T (*ff4_functor)(T,T,T,T);
+      typedef T (*ff5_functor)(T,T,T,T,T);
+
    protected:
 
+      struct freefunc1 : public exprtk::ifunction<T>
+      {
+         freefunc1(ff1_functor ff) : exprtk::ifunction<T>(1), f(ff) {}
+         inline T operator()(const T& v0)
+         { return f(v0); }
+         ff1_functor f;
+      };
+
+      struct freefunc2 : public exprtk::ifunction<T>
+      {
+         freefunc2(ff2_functor ff) : exprtk::ifunction<T>(2), f(ff) {}
+         inline T operator()(const T& v0, const T& v1)
+         { return f(v0,v1); }
+         ff2_functor f;
+      };
+
+      struct freefunc3 : public exprtk::ifunction<T>
+      {
+         freefunc3(ff3_functor ff) : exprtk::ifunction<T>(3), f(ff) {}
+         inline T operator()(const T& v0, const T& v1, const T& v2)
+         { return f(v0,v1,v2); }
+         ff3_functor f;
+      };
+
+      struct freefunc4 : public exprtk::ifunction<T>
+      {
+         freefunc4(ff4_functor ff) : exprtk::ifunction<T>(4), f(ff) {}
+         inline T operator()(const T& v0, const T& v1, const T& v2, const T& v3)
+         { return f(v0,v1,v2,v3); }
+         ff4_functor f;
+      };
+
+      struct freefunc5 : public exprtk::ifunction<T>
+      {
+         freefunc5(ff5_functor ff) : exprtk::ifunction<T>(5), f(ff) {}
+         inline T operator()(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4)
+         { return f(v0,v1,v2,v3,v4); }
+         ff5_functor f;
+      };
+
       template <typename Type, typename RawType>
       struct type_store
       {
@@ -14554,14 +14803,23 @@
                }
             }
 
+           ~st_data()
+            {
+               for (std::size_t i = 0; i < free_function_list_.size(); ++i)
+               {
+                  delete free_function_list_[i];
+               }
+            }
+
             inline bool is_reserved_symbol(const std::string& symbol) const
             {
                return (reserved_symbol_table_.end() != reserved_symbol_table_.find(symbol));
             }
 
-            std::list<T> local_symbol_list_;
-            std::list<std::string> local_stringvar_list_;
-            std::set<std::string> reserved_symbol_table_;
+            std::list<T>               local_symbol_list_;
+            std::list<std::string>     local_stringvar_list_;
+            std::set<std::string>      reserved_symbol_table_;
+            std::vector<ifunction<T>*> free_function_list_;
          };
 
          st_holder()
@@ -14929,14 +15187,7 @@
             return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
       }
 
-      enum func_type
-      {
-         e_ft_unknown   = 0,
-         e_ft_basicfunc = 1,
-         e_ft_strfunc   = 2
-      };
-
-      inline bool add_function(const std::string& function_name, generic_function_t& function, const func_type ft = e_ft_basicfunc)
+      inline bool add_function(const std::string& function_name, generic_function_t& function)
       {
          if (!valid())
             return false;
@@ -14946,14 +15197,94 @@
             return false;
          else if (std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|"))
             return false;
-         else if (e_ft_basicfunc == ft)
+         else if (generic_function_t::e_rtrn_scalar == function.rtrn_type)
             return local_data().generic_function_store.add(function_name,function);
-         else if (e_ft_strfunc == ft)
+         else if (generic_function_t::e_rtrn_string == function.rtrn_type)
             return local_data().string_function_store.add(function_name, function);
          else
             return false;
       }
 
+      inline bool add_function(const std::string& function_name, ff1_functor function)
+      {
+         if (!valid())
+            return false;
+         else if (!valid_symbol(function_name))
+            return false;
+         else if (symbol_exists(function_name))
+            return false;
+
+         exprtk::ifunction<T>* ifunc = new freefunc1(function);
+
+         local_data().free_function_list_.push_back(ifunc);
+
+         return add_function(function_name,(*local_data().free_function_list_.back()));
+      }
+
+      inline bool add_function(const std::string& function_name, ff2_functor function)
+      {
+         if (!valid())
+            return false;
+         else if (!valid_symbol(function_name))
+            return false;
+         else if (symbol_exists(function_name))
+            return false;
+
+         exprtk::ifunction<T>* ifunc = new freefunc2(function);
+
+         local_data().free_function_list_.push_back(ifunc);
+
+         return add_function(function_name,(*local_data().free_function_list_.back()));
+      }
+
+      inline bool add_function(const std::string& function_name, ff3_functor function)
+      {
+         if (!valid())
+            return false;
+         else if (!valid_symbol(function_name))
+            return false;
+         else if (symbol_exists(function_name))
+            return false;
+
+         exprtk::ifunction<T>* ifunc = new freefunc3(function);
+
+         local_data().free_function_list_.push_back(ifunc);
+
+         return add_function(function_name,(*local_data().free_function_list_.back()));
+      }
+
+      inline bool add_function(const std::string& function_name, ff4_functor function)
+      {
+         if (!valid())
+            return false;
+         else if (!valid_symbol(function_name))
+            return false;
+         else if (symbol_exists(function_name))
+            return false;
+
+         exprtk::ifunction<T>* ifunc = new freefunc4(function);
+
+         local_data().free_function_list_.push_back(ifunc);
+
+         return add_function(function_name,(*local_data().free_function_list_.back()));
+      }
+
+      inline bool add_function(const std::string& function_name, ff5_functor function)
+      {
+         if (!valid())
+            return false;
+         else if (!valid_symbol(function_name))
+            return false;
+         else if (symbol_exists(function_name))
+            return false;
+
+         exprtk::ifunction<T>* ifunc = new freefunc5(function);
+
+         local_data().free_function_list_.push_back(ifunc);
+
+         return add_function(function_name,(*local_data().free_function_list_.back()));
+      }
+
       inline bool add_reserved_function(const std::string& function_name, function_t& function)
       {
          if (!valid())
@@ -14978,7 +15309,7 @@
             return local_data().vararg_function_store.add(vararg_function_name,vararg_function);
       }
 
-      inline bool add_reserved_function(const std::string& function_name, generic_function_t& function, const func_type ft = e_ft_basicfunc)
+      inline bool add_reserved_function(const std::string& function_name, generic_function_t& function)
       {
          if (!valid())
             return false;
@@ -14988,9 +15319,9 @@
             return false;
          else if (std::string::npos != function.parameter_sequence.find_first_not_of("STV*?|"))
             return false;
-         else if (e_ft_basicfunc == ft)
+         else if (generic_function_t::e_rtrn_scalar == function.rtrn_type)
             return local_data().generic_function_store.add(function_name,function);
-         else if (e_ft_strfunc == ft)
+         else if (generic_function_t::e_rtrn_string == function.rtrn_type)
             return local_data().string_function_store.add(function_name, function);
          else
             return false;
@@ -15330,7 +15661,7 @@
                for (std::size_t i = 0; i < name_list.size(); ++i)
                {
                   exprtk::igeneric_function<T>& ifunc = *st.get_string_function(name_list[i]);
-                  add_function(name_list[i],ifunc,e_ft_strfunc);
+                  add_function(name_list[i],ifunc);
                }
             }
          }
@@ -16241,9 +16572,11 @@
                case scope_element::e_vecelem : if (se.var_node) delete se.var_node;
                                                break;
 
+               #ifndef exprtk_disable_string_capabilities
                case scope_element::e_string  : if (se.data    ) delete (std::string*) se.data;
                                                if (se.str_node) delete se.str_node;
                                                break;
+               #endif
 
                default                       : return;
             }
@@ -16825,11 +17158,12 @@
          e_st_unknown        = 0,
          e_st_variable       = 1,
          e_st_vector         = 2,
-         e_st_string         = 3,
-         e_st_function       = 4,
-         e_st_local_variable = 5,
-         e_st_local_vector   = 6,
-         e_st_local_string   = 7
+         e_st_vecelem        = 3,
+         e_st_string         = 4,
+         e_st_function       = 5,
+         e_st_local_variable = 6,
+         e_st_local_vector   = 7,
+         e_st_local_string   = 8
       };
 
       class dependent_entity_collector
@@ -17049,6 +17383,28 @@
             e_logic_xor, e_logic_scand, e_logic_scor
          };
 
+         enum settings_arithmetic_opr
+         {
+            e_arith_unknown = 0,
+            e_arith_add, e_arith_sub, e_arith_mul,
+            e_arith_div, e_arith_mod, e_arith_pow
+         };
+
+         enum settings_assignment_opr
+         {
+            e_assign_unknown = 0,
+            e_assign_assign, e_assign_addass, e_assign_subass,
+            e_assign_mulass, e_assign_divass, e_assign_modass
+         };
+
+         enum settings_inequality_opr
+         {
+            e_ineq_unknown = 0,
+            e_ineq_lt,    e_ineq_lte, e_ineq_eq,
+            e_ineq_equal, e_ineq_ne,  e_ineq_nequal,
+            e_ineq_gte,   e_ineq_gt
+         };
+
          static const std::size_t compile_all_opts = e_replacer          +
                                                      e_joiner            +
                                                      e_numeric_check     +
@@ -17080,6 +17436,30 @@
             return *this;
          }
 
+         settings_store& enable_all_arithmetic_ops()
+         {
+            disabled_arithmetic_set_.clear();
+            return *this;
+         }
+
+         settings_store& enable_all_assignment_ops()
+         {
+            disabled_assignment_set_.clear();
+            return *this;
+         }
+
+         settings_store& enable_all_inequality_ops()
+         {
+            disabled_inequality_set_.clear();
+            return *this;
+         }
+
+         settings_store& enable_local_vardef()
+         {
+            disable_vardef_ = false;
+            return *this;
+         }
+
          settings_store& disable_all_base_functions()
          {
             std::copy(details::base_function_list,
@@ -17107,6 +17487,39 @@
             return *this;
          }
 
+         settings_store& disable_all_arithmetic_ops()
+         {
+            std::copy(details::arithmetic_ops_list,
+                      details::arithmetic_ops_list + details::arithmetic_ops_list_size,
+                      std::insert_iterator<disabled_entity_set_t>
+                        (disabled_arithmetic_set_,disabled_arithmetic_set_.begin()));
+            return *this;
+         }
+
+         settings_store& disable_all_assignment_ops()
+         {
+            std::copy(details::assignment_ops_list,
+                      details::assignment_ops_list + details::assignment_ops_list_size,
+                      std::insert_iterator<disabled_entity_set_t>
+                        (disabled_assignment_set_,disabled_assignment_set_.begin()));
+            return *this;
+         }
+
+         settings_store& disable_all_inequality_ops()
+         {
+            std::copy(details::inequality_ops_list,
+                      details::inequality_ops_list + details::inequality_ops_list_size,
+                      std::insert_iterator<disabled_entity_set_t>
+                        (disabled_inequality_set_,disabled_inequality_set_.begin()));
+            return *this;
+         }
+
+         settings_store& disable_local_vardef()
+         {
+            disable_vardef_ = true;
+            return *this;
+         }
+
          bool replacer_enabled           () const { return enable_replacer_;           }
          bool commutative_check_enabled  () const { return enable_commutative_check_;  }
          bool joiner_enabled             () const { return enable_joiner_;             }
@@ -17145,6 +17558,30 @@
                return (disabled_logic_set_.end() == disabled_logic_set_.find(logic_operation));
          }
 
+         bool arithmetic_enabled(const details::operator_type& arithmetic_operation)
+         {
+            if (disabled_logic_set_.empty())
+               return true;
+            else
+               return (disabled_arithmetic_set_.end() == disabled_arithmetic_set_.find(arith_opr_to_string(arithmetic_operation)));
+         }
+
+         bool assignment_enabled(const details::operator_type& assignment)
+         {
+            if (disabled_assignment_set_.empty())
+               return true;
+            else
+               return (disabled_assignment_set_.end() == disabled_assignment_set_.find(assign_opr_to_string(assignment)));
+         }
+
+         bool inequality_enabled(const details::operator_type& inequality)
+         {
+            if (disabled_inequality_set_.empty())
+               return true;
+            else
+               return (disabled_inequality_set_.end() == disabled_inequality_set_.find(inequality_opr_to_string(inequality)));
+         }
+
          bool function_disabled(const std::string& function_name)
          {
             if (disabled_func_set_.empty())
@@ -17169,11 +17606,35 @@
                return (disabled_logic_set_.end() != disabled_logic_set_.find(logic_operation));
          }
 
+         bool assignment_disabled(const details::operator_type assignment_operation)
+         {
+            if (disabled_assignment_set_.empty())
+               return false;
+            else
+               return (disabled_assignment_set_.end() != disabled_assignment_set_.find(assign_opr_to_string(assignment_operation)));
+         }
+
+         bool arithmetic_disabled(const details::operator_type arithmetic_operation)
+         {
+            if (disabled_arithmetic_set_.empty())
+               return false;
+            else
+               return (disabled_arithmetic_set_.end() != disabled_arithmetic_set_.find(arith_opr_to_string(arithmetic_operation)));
+         }
+
+         bool inequality_disabled(const details::operator_type& inequality)
+         {
+            if (disabled_inequality_set_.empty())
+               return false;
+            else
+               return (disabled_inequality_set_.end() != disabled_inequality_set_.find(inequality_opr_to_string(inequality)));
+         }
+
          settings_store& disable_base_function(settings_base_funcs bf)
          {
             if (
                  (e_bf_unknown != bf) &&
-                 (bf < details::base_function_list_size)
+                 (static_cast<std::size_t>(bf) < details::base_function_list_size)
                )
             {
                disabled_func_set_.insert(details::base_function_list[bf - 1]);
@@ -17186,7 +17647,7 @@
          {
             if (
                  (e_ctrl_unknown != ctrl_struct) &&
-                 (ctrl_struct < details::cntrl_struct_list_size)
+                 (static_cast<std::size_t>(ctrl_struct) < details::cntrl_struct_list_size)
                )
             {
                disabled_ctrl_set_.insert(details::cntrl_struct_list[ctrl_struct - 1]);
@@ -17199,7 +17660,7 @@
          {
             if (
                  (e_logic_unknown != logic) &&
-                 (logic < details::logic_ops_list_size)
+                 (static_cast<std::size_t>(logic) < details::logic_ops_list_size)
                )
             {
                disabled_logic_set_.insert(details::logic_ops_list[logic - 1]);
@@ -17208,11 +17669,50 @@
             return *this;
          }
 
+         settings_store& disable_arithmetic_operation(settings_arithmetic_opr arithmetic)
+         {
+            if (
+                 (e_arith_unknown != arithmetic) &&
+                 (static_cast<std::size_t>(arithmetic) < details::arithmetic_ops_list_size)
+               )
+            {
+               disabled_arithmetic_set_.insert(details::arithmetic_ops_list[arithmetic - 1]);
+            }
+
+            return *this;
+         }
+
+         settings_store& disable_assignment_operation(settings_assignment_opr assignment)
+         {
+            if (
+                 (e_assign_unknown != assignment) &&
+                 (static_cast<std::size_t>(assignment) < details::assignment_ops_list_size)
+               )
+            {
+               disabled_assignment_set_.insert(details::assignment_ops_list[assignment - 1]);
+            }
+
+            return *this;
+         }
+
+         settings_store& disable_inequality_operation(settings_inequality_opr inequality)
+         {
+            if (
+                 (e_assign_unknown != inequality) &&
+                 (static_cast<std::size_t>(inequality) < details::inequality_ops_list_size)
+               )
+            {
+               disabled_inequality_set_.insert(details::inequality_ops_list[inequality - 1]);
+            }
+
+            return *this;
+         }
+
          settings_store& enable_base_function(settings_base_funcs bf)
          {
             if (
                  (e_bf_unknown != bf) &&
-                 (bf < details::base_function_list_size)
+                 (static_cast<std::size_t>(bf) < details::base_function_list_size)
                )
             {
                des_itr_t itr = disabled_func_set_.find(details::base_function_list[bf - 1]);
@@ -17230,7 +17730,7 @@
          {
             if (
                  (e_ctrl_unknown != ctrl_struct) &&
-                 (ctrl_struct < details::cntrl_struct_list_size)
+                 (static_cast<std::size_t>(ctrl_struct) < details::cntrl_struct_list_size)
                )
             {
                des_itr_t itr = disabled_ctrl_set_.find(details::cntrl_struct_list[ctrl_struct - 1]);
@@ -17248,7 +17748,7 @@
          {
             if (
                  (e_logic_unknown != logic) &&
-                 (logic < details::logic_ops_list_size)
+                 (static_cast<std::size_t>(logic) < details::logic_ops_list_size)
                )
             {
                des_itr_t itr = disabled_logic_set_.find(details::logic_ops_list[logic - 1]);
@@ -17262,6 +17762,60 @@
             return *this;
          }
 
+         settings_store& enable_arithmetic_operation(settings_arithmetic_opr arithmetic)
+         {
+            if (
+                 (e_arith_unknown != arithmetic) &&
+                 (static_cast<std::size_t>(arithmetic) < details::arithmetic_ops_list_size)
+               )
+            {
+               des_itr_t itr = disabled_arithmetic_set_.find(details::arithmetic_ops_list[arithmetic - 1]);
+
+               if (disabled_arithmetic_set_.end() != itr)
+               {
+                  disabled_arithmetic_set_.erase(itr);
+               }
+            }
+
+            return *this;
+         }
+
+         settings_store& enable_assignment_operation(settings_assignment_opr assignment)
+         {
+            if (
+                 (e_assign_unknown != assignment) &&
+                 (static_cast<std::size_t>(assignment) < details::assignment_ops_list_size)
+               )
+            {
+               des_itr_t itr = disabled_assignment_set_.find(details::assignment_ops_list[assignment - 1]);
+
+               if (disabled_assignment_set_.end() != itr)
+               {
+                  disabled_assignment_set_.erase(itr);
+               }
+            }
+
+            return *this;
+         }
+
+         settings_store& enable_inequality_operation(settings_inequality_opr inequality)
+         {
+            if (
+                 (e_ineq_unknown != inequality) &&
+                 (static_cast<std::size_t>(inequality) < details::inequality_ops_list_size)
+               )
+            {
+               des_itr_t itr = disabled_inequality_set_.find(details::inequality_ops_list[inequality - 1]);
+
+               if (disabled_inequality_set_.end() != itr)
+               {
+                  disabled_inequality_set_.erase(itr);
+               }
+            }
+
+            return *this;
+         }
+
       private:
 
          void load_compile_options(const std::size_t compile_options)
@@ -17281,6 +17835,49 @@
             disable_zero_return_       = (compile_options & e_disable_zero_return ) == e_disable_zero_return;
          }
 
+         std::string assign_opr_to_string(details::operator_type opr)
+         {
+            switch (opr)
+            {
+               case details::e_assign : return ":=";
+               case details::e_addass : return "+=";
+               case details::e_subass : return "-=";
+               case details::e_mulass : return "*=";
+               case details::e_divass : return "/=";
+               case details::e_modass : return "%=";
+               default                : return   "";
+            }
+         }
+
+         std::string arith_opr_to_string(details::operator_type opr)
+         {
+            switch (opr)
+            {
+               case details::e_add : return "+";
+               case details::e_sub : return "-";
+               case details::e_mul : return "*";
+               case details::e_div : return "/";
+               case details::e_mod : return "%";
+               default             : return  "";
+            }
+         }
+
+         std::string inequality_opr_to_string(details::operator_type opr)
+         {
+            switch (opr)
+            {
+               case details::e_lt    : return  "<";
+               case details::e_lte   : return "<=";
+               case details::e_eq    : return "==";
+               case details::e_equal : return  "=";
+               case details::e_ne    : return "!=";
+               case details::e_nequal: return "<>";
+               case details::e_gte   : return ">=";
+               case details::e_gt    : return  ">";
+               default               : return   "";
+            }
+         }
+
          bool enable_replacer_;
          bool enable_joiner_;
          bool enable_numeric_check_;
@@ -17298,6 +17895,9 @@
          disabled_entity_set_t disabled_func_set_ ;
          disabled_entity_set_t disabled_ctrl_set_ ;
          disabled_entity_set_t disabled_logic_set_;
+         disabled_entity_set_t disabled_arithmetic_set_;
+         disabled_entity_set_t disabled_assignment_set_;
+         disabled_entity_set_t disabled_inequality_set_;
 
          friend class parser<T>;
       };
@@ -17489,7 +18089,7 @@
             sem_.cleanup  ();
             return_cleanup();
 
-            if (0 != e)
+            if ((0 != e) && branch_deletable(e))
             {
                delete e;
             }
@@ -17729,6 +18329,21 @@
                settings_.function_enabled(symbol);
       }
 
+      bool is_invalid_arithmetic_operation(const details::operator_type operation)
+      {
+         return settings_.arithmetic_disabled(operation);
+      }
+
+      bool is_invalid_assignment_operation(const details::operator_type operation)
+      {
+         return settings_.assignment_disabled(operation);
+      }
+
+      bool is_invalid_inequality_operation(const details::operator_type operation)
+      {
+         return settings_.inequality_disabled(operation);
+      }
+
       #ifdef exprtk_enable_debugging
       inline void next_token()
       {
@@ -17849,8 +18464,9 @@
 
          inline void reset()
          {
-            left  = e_level00;
-            right = e_level00;
+            left      = e_level00;
+            right     = e_level00;
+            operation = details::e_default;
          }
 
          precedence_level left;
@@ -17960,17 +18576,17 @@
                                            }
                                            else if (details::imatch(current_token().value,s_in))
                                            {
-                                              current_state.set(e_level03,e_level04,details::e_in);
+                                              current_state.set(e_level04,e_level04,details::e_in);
                                               break;
                                            }
                                            else if (details::imatch(current_token().value,s_like))
                                            {
-                                              current_state.set(e_level03,e_level04,details::e_like);
+                                              current_state.set(e_level04,e_level04,details::e_like);
                                               break;
                                            }
                                            else if (details::imatch(current_token().value,s_ilike))
                                            {
-                                              current_state.set(e_level03,e_level04,details::e_ilike);
+                                              current_state.set(e_level04,e_level04,details::e_ilike);
                                               break;
                                            }
                                         }
@@ -17993,7 +18609,41 @@
             expression_node_ptr right_branch   = error_node();
             expression_node_ptr new_expression = error_node();
 
-            if ((right_branch = parse_expression(current_state.right)))
+            if (is_invalid_arithmetic_operation(current_state.operation))
+            {
+               free_node(node_allocator_,expression);
+
+               set_error(
+                  make_error(parser_error::e_syntax,
+                             prev_token,
+                             "ERR008 - Invalid arithmetic operation '" + details::to_str(current_state.operation) + "'"));
+
+               return error_node();
+            }
+            else if (is_invalid_inequality_operation(current_state.operation))
+            {
+               free_node(node_allocator_,expression);
+
+               set_error(
+                  make_error(parser_error::e_syntax,
+                             prev_token,
+                             "ERR009 - Invalid inequality operation '" + details::to_str(current_state.operation) + "'"));
+
+               return error_node();
+            }
+            else if (is_invalid_assignment_operation(current_state.operation))
+            {
+               free_node(node_allocator_,expression);
+
+               set_error(
+                  make_error(parser_error::e_syntax,
+                             prev_token,
+                             "ERR010 - Invalid assignment operation '" + details::to_str(current_state.operation) + "'"));
+
+               return error_node();
+            }
+
+            if (0 != (right_branch = parse_expression(current_state.right)))
             {
                if (
                     details::is_return_node(  expression) ||
@@ -18006,7 +18656,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 prev_token,
-                                "ERR008 - Return statements cannot be part of sub-expressions"));
+                                "ERR011 - Return statements cannot be part of sub-expressions"));
 
                   return error_node();
                }
@@ -18028,7 +18678,7 @@
                                 prev_token,
                                 !synthesis_error_.empty() ?
                                 synthesis_error_ :
-                                "ERR009 - General parsing error at token: '" + prev_token.value + "'"));
+                                "ERR012 - General parsing error at token: '" + prev_token.value + "'"));
                }
 
                free_node(node_allocator_,expression);
@@ -18069,9 +18719,9 @@
          }
 
          {
-            typedef details::unary_variable_node<T,details::neg_op<T> > ubn_t;
+            typedef details::unary_variable_node<T,details::neg_op<T> > uvn_t;
 
-            ubn_t* n = dynamic_cast<ubn_t*>(node);
+            uvn_t* n = dynamic_cast<uvn_t*>(node);
 
             if (n)
             {
@@ -18079,8 +18729,8 @@
                expression_node_ptr return_node = error_node();
 
                if (
-                    (return_node = symtab_store_.get_variable(v)) ||
-                    (return_node = sem_         .get_variable(v))
+                    (0 != (return_node = symtab_store_.get_variable(v))) ||
+                    (0 != (return_node = sem_         .get_variable(v)))
                   )
                {
                   free_node(node_allocator_,node);
@@ -18093,7 +18743,8 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR010 - Failed to find variable node in symbol table"));
+                                "ERR013 - Failed to find variable node in symbol table"));
+
                   free_node(node_allocator_,node);
 
                   return false;
@@ -18271,7 +18922,7 @@
                          set_error(
                             make_error(parser_error::e_syntax,
                                        current_token(),
-                                       "ERR011 - Invalid number of parameters for function: '" + function_name + "'"));
+                                       "ERR014 - Invalid number of parameters for function: '" + function_name + "'"));
 
                          return error_node();
                       }
@@ -18284,7 +18935,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR012 - Failed to generate call to function: '" + function_name + "'"));
+                          "ERR015 - Failed to generate call to function: '" + function_name + "'"));
 
             return error_node();
          }
@@ -18298,7 +18949,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR013 - Expecting ifunction '" + function_name + "' to have non-zero parameter count"));
+                          "ERR016 - Expecting ifunction '" + function_name + "' to have non-zero parameter count"));
 
             return error_node();
          }
@@ -18316,7 +18967,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR014 - Expecting argument list for function: '" + function_name + "'"));
+                          "ERR017 - Expecting argument list for function: '" + function_name + "'"));
 
             return error_node();
          }
@@ -18330,7 +18981,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR015 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'"));
+                             "ERR018 - Failed to parse argument " + details::to_str(i) + " for function: '" + function_name + "'"));
 
                return error_node();
             }
@@ -18341,7 +18992,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR016 - Invalid number of arguments for function: '" + function_name + "'"));
+                                "ERR019 - Invalid number of arguments for function: '" + function_name + "'"));
 
                   return error_node();
                }
@@ -18353,7 +19004,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR017 - Invalid number of arguments for function: '" + function_name + "'"));
+                          "ERR020 - Invalid number of arguments for function: '" + function_name + "'"));
 
             return error_node();
          }
@@ -18381,7 +19032,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR018 - Expecting '()' to proceed call to function: '" + function_name + "'"));
+                          "ERR021 - Expecting '()' to proceed call to function: '" + function_name + "'"));
 
             free_node(node_allocator_,result);
 
@@ -18405,7 +19056,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR019 - Expected a '(' at start of function call, instead got: '" + current_token().value + "'"));
+                          "ERR022 - Expected a '(' at start of function call, instead got: '" + current_token().value + "'"));
 
             return 0;
          }
@@ -18417,9 +19068,7 @@
             param_list[param_index] = parse_expression();
 
             if (0 == param_list[param_index])
-            {
                return 0;
-            }
             else if (token_is(token_t::e_rbracket))
                break;
             else if (token_is(token_t::e_comma))
@@ -18429,7 +19078,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR020 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'"));
+                             "ERR023 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'"));
 
                return 0;
             }
@@ -18452,7 +19101,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR021 - No entry found for base operation: " + operation_name));
+                          "ERR024 - No entry found for base operation: " + operation_name));
 
             return error_node();
          }
@@ -18502,7 +19151,7 @@
          set_error(
             make_error(parser_error::e_syntax,
                        current_token(),
-                       "ERR022 - Invalid number of parameters for call to function: '" + operation_name + "'"));
+                       "ERR025 - Invalid number of parameters for call to function: '" + operation_name + "'"));
 
          return error_node();
       }
@@ -18521,7 +19170,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR023 - Expected ',' between if-statement condition and consequent"));
+                          "ERR026 - Expected ',' between if-statement condition and consequent"));
             result = false;
          }
          else if (0 == (consequent = parse_expression()))
@@ -18529,7 +19178,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR024 - Failed to parse consequent for if-statement"));
+                          "ERR027 - Failed to parse consequent for if-statement"));
             result = false;
          }
          else if (!token_is(token_t::e_comma))
@@ -18537,7 +19186,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR025 - Expected ',' between if-statement consequent and alternative"));
+                          "ERR028 - Expected ',' between if-statement consequent and alternative"));
             result = false;
          }
          else if (0 == (alternative = parse_expression()))
@@ -18545,7 +19194,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR026 - Failed to parse alternative for if-statement"));
+                          "ERR029 - Failed to parse alternative for if-statement"));
             result = false;
          }
          else if (!token_is(token_t::e_rbracket))
@@ -18553,7 +19202,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR027 - Expected ')' at the end of if-statement"));
+                          "ERR030 - Expected ')' at the end of if-statement"));
             result = false;
          }
 
@@ -18574,7 +19223,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR028 - Return types of ternary if-statement differ"));
+                             "ERR031 - Return types of ternary if-statement differ"));
 
                result = false;
             }
@@ -18608,7 +19257,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR029 - Failed to parse body of consequent for if-statement"));
+                             "ERR032 - Failed to parse body of consequent for if-statement"));
                result = false;
             }
          }
@@ -18629,7 +19278,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR030 - Expected ';' at the end of the consequent for if-statement"));
+                                "ERR033 - Expected ';' at the end of the consequent for if-statement"));
                   result = false;
                }
             }
@@ -18638,7 +19287,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR031 - Failed to parse body of consequent for if-statement"));
+                             "ERR034 - Failed to parse body of consequent for if-statement"));
                result = false;
             }
          }
@@ -18656,7 +19305,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR032 - Failed to parse body of the 'else' for if-statement"));
+                                   "ERR035 - Failed to parse body of the 'else' for if-statement"));
                      result = false;
                   }
                }
@@ -18667,7 +19316,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR033 - Failed to parse body of if-else statement"));
+                                   "ERR036 - Failed to parse body of if-else statement"));
                      result = false;
                   }
                }
@@ -18678,7 +19327,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR034 - Expected ';' at the end of the 'else-if' for the if-statement"));
+                                   "ERR037 - Expected ';' at the end of the 'else-if' for the if-statement"));
                      result = false;
                   }
                }
@@ -18687,7 +19336,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR035 - Failed to parse body of the 'else' for if-statement"));
+                                "ERR038 - Failed to parse body of the 'else' for if-statement"));
                   result = false;
                }
             }
@@ -18710,7 +19359,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR036 - Return types of ternary if-statement differ"));
+                             "ERR039 - Return types of ternary if-statement differ"));
 
                result = false;
             }
@@ -18741,7 +19390,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR037 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'"));
+                          "ERR040 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'"));
 
             return error_node();
          }
@@ -18750,7 +19399,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR038 - Failed to parse condition for if-statement"));
+                          "ERR041 - Failed to parse condition for if-statement"));
 
             return error_node();
          }
@@ -18781,7 +19430,7 @@
          set_error(
             make_error(parser_error::e_syntax,
                        current_token(),
-                       "ERR039 - Invalid if-statement"));
+                       "ERR042 - Invalid if-statement"));
 
          free_node(node_allocator_,condition);
 
@@ -18801,7 +19450,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR040 - Encountered invalid condition branch for ternary if-statement"));
+                          "ERR043 - Encountered invalid condition branch for ternary if-statement"));
 
             return error_node();
          }
@@ -18810,7 +19459,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR041 - Expected '?' after condition of ternary if-statement"));
+                          "ERR044 - Expected '?' after condition of ternary if-statement"));
 
             result = false;
          }
@@ -18819,7 +19468,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR042 - Failed to parse consequent for ternary if-statement"));
+                          "ERR045 - Failed to parse consequent for ternary if-statement"));
 
             result = false;
          }
@@ -18828,7 +19477,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR043 - Expected ':' between ternary if-statement consequent and alternative"));
+                          "ERR046 - Expected ':' between ternary if-statement consequent and alternative"));
 
             result = false;
          }
@@ -18837,7 +19486,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR044 - Failed to parse alternative for ternary if-statement"));
+                          "ERR047 - Failed to parse alternative for ternary if-statement"));
 
             result = false;
          }
@@ -18859,7 +19508,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR045 - Return types of ternary if-statement differ"));
+                             "ERR048 - Return types of ternary if-statement differ"));
 
                result = false;
             }
@@ -18895,7 +19544,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR046 - Expected '(' at start of while-loop condition statement"));
+                          "ERR049 - Expected '(' at start of while-loop condition statement"));
 
             return error_node();
          }
@@ -18904,7 +19553,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR047 - Failed to parse condition for while-loop"));
+                          "ERR050 - Failed to parse condition for while-loop"));
 
             return error_node();
          }
@@ -18913,7 +19562,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR048 - Expected ')' at end of while-loop condition statement"));
+                          "ERR051 - Expected ')' at end of while-loop condition statement"));
             result = false;
          }
 
@@ -18926,7 +19575,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR049 - Failed to parse body of while-loop"));
+                             "ERR052 - Failed to parse body of while-loop"));
                result = false;
             }
             else if (0 == (result_node = expression_generator_.while_loop(condition,
@@ -18936,7 +19585,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR050 - Failed to synthesize while-loop"));
+                             "ERR053 - Failed to synthesize while-loop"));
                result = false;
             }
          }
@@ -19010,7 +19659,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR051 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop"));
+                                "ERR054 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop"));
 
                   return error_node();
                }
@@ -19024,14 +19673,16 @@
 
             branch = simplify(arg_list,side_effect_list);
 
-            if ((sdd.delete_ptr = (0 == branch)))
+            sdd.delete_ptr = (0 == branch);
+
+            if (sdd.delete_ptr)
             {
                brkcnt_list_.pop_front();
 
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR052 - Failed to parse body of repeat until loop"));
+                             "ERR055 - Failed to parse body of repeat until loop"));
 
                return error_node();
             }
@@ -19044,7 +19695,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR053 - Expected '(' before condition statement of repeat until loop"));
+                          "ERR056 - Expected '(' before condition statement of repeat until loop"));
 
             free_node(node_allocator_,branch);
 
@@ -19057,7 +19708,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR054 - Failed to parse condition for repeat until loop"));
+                          "ERR057 - Failed to parse condition for repeat until loop"));
 
             free_node(node_allocator_,branch);
 
@@ -19068,7 +19719,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR055 - Expected ')' after condition of repeat until loop"));
+                          "ERR058 - Expected ')' after condition of repeat until loop"));
 
             free_node(node_allocator_,    branch);
             free_node(node_allocator_, condition);
@@ -19088,7 +19739,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR056 - Failed to synthesize repeat until loop"));
+                          "ERR059 - Failed to synthesize repeat until loop"));
 
             free_node(node_allocator_, condition);
             brkcnt_list_.pop_front();
@@ -19122,7 +19773,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR057 - Expected '(' at start of for-loop"));
+                          "ERR060 - Expected '(' at start of for-loop"));
 
             return error_node();
          }
@@ -19141,7 +19792,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR058 - Expected a variable at the start of initialiser section of for-loop"));
+                                "ERR061 - Expected a variable at the start of initialiser section of for-loop"));
 
                   return error_node();
                }
@@ -19150,7 +19801,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR059 - Expected variable assignment of initialiser section of for-loop"));
+                                "ERR062 - Expected variable assignment of initialiser section of for-loop"));
 
                   return error_node();
                }
@@ -19164,7 +19815,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR060 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration"));
+                                "ERR063 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration"));
 
                   return error_node();
                }
@@ -19195,7 +19846,7 @@
                         set_error(
                            make_error(parser_error::e_syntax,
                                       current_token(),
-                                      "ERR061 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM"));
+                                      "ERR064 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM"));
 
                         sem_.free_element(nse);
 
@@ -19216,7 +19867,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR062 - Failed to parse initialiser of for-loop"));
+                             "ERR065 - Failed to parse initialiser of for-loop"));
                result = false;
             }
             else if (!token_is(token_t::e_eof))
@@ -19224,7 +19875,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR063 - Expected ';' after initialiser of for-loop"));
+                             "ERR066 - Expected ';' after initialiser of for-loop"));
                result = false;
             }
          }
@@ -19236,7 +19887,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR064 - Failed to parse condition of for-loop"));
+                             "ERR067 - Failed to parse condition of for-loop"));
                result = false;
             }
             else if (!token_is(token_t::e_eof))
@@ -19244,7 +19895,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR065 - Expected ';' after condition section of for-loop"));
+                             "ERR068 - Expected ';' after condition section of for-loop"));
                result = false;
             }
          }
@@ -19256,7 +19907,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR066 - Failed to parse incrementor of for-loop"));
+                             "ERR069 - Failed to parse incrementor of for-loop"));
                result = false;
             }
             else if (!token_is(token_t::e_rbracket))
@@ -19264,7 +19915,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR067 - Expected ')' after incrementor section of for-loop"));
+                             "ERR070 - Expected ')' after incrementor section of for-loop"));
                result = false;
             }
          }
@@ -19277,7 +19928,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR068 - Failed to parse body of for-loop"));
+                             "ERR071 - Failed to parse body of for-loop"));
                result = false;
             }
          }
@@ -19327,7 +19978,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR069 - Expected keyword 'switch'"));
+                          "ERR072 - Expected keyword 'switch'"));
 
             return error_node();
          }
@@ -19341,7 +19992,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR070 - Expected '{' for call to switch statement"));
+                          "ERR073 - Expected '{' for call to switch statement"));
 
             return error_node();
          }
@@ -19353,7 +20004,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR071 - Expected either a 'case' or 'default' statement"));
+                             "ERR074 - Expected either a 'case' or 'default' statement"));
 
                return error_node();
             }
@@ -19369,7 +20020,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR072 - Expected ':' for case of switch statement"));
+                             "ERR075 - Expected ':' for case of switch statement"));
 
                return error_node();
             }
@@ -19383,7 +20034,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR073 - Expected ';' at end of case for switch statement"));
+                             "ERR076 - Expected ';' at end of case for switch statement"));
 
                return error_node();
             }
@@ -19411,7 +20062,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR074 - Expected ':' for default of switch statement"));
+                                "ERR077 - Expected ':' for default of switch statement"));
 
                   return error_node();
                }
@@ -19432,7 +20083,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR075 - Expected ';' at end of default for switch statement"));
+                                "ERR078 - Expected ';' at end of default for switch statement"));
 
                   return error_node();
                }
@@ -19447,7 +20098,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR076 - Expected '}' at end of switch statement"));
+                          "ERR079 - Expected '}' at end of switch statement"));
 
             return error_node();
          }
@@ -19469,7 +20120,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR077 - Expected token '[*]'"));
+                          "ERR080 - Expected token '[*]'"));
 
             return error_node();
          }
@@ -19483,7 +20134,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR078 - Expected '{' for call to [*] statement"));
+                          "ERR081 - Expected '{' for call to [*] statement"));
 
             return error_node();
          }
@@ -19495,7 +20146,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR079 - Expected a 'case' statement for multi-switch"));
+                             "ERR082 - Expected a 'case' statement for multi-switch"));
 
                return error_node();
             }
@@ -19512,7 +20163,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR080 - Expected ':' for case of [*] statement"));
+                             "ERR083 - Expected ':' for case of [*] statement"));
 
                return error_node();
             }
@@ -19527,7 +20178,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR081 - Expected ';' at end of case for [*] statement"));
+                             "ERR084 - Expected ';' at end of case for [*] statement"));
 
                return error_node();
             }
@@ -19558,7 +20209,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR082 - Expected '}' at end of [*] statement"));
+                          "ERR085 - Expected '}' at end of [*] statement"));
 
             return error_node();
          }
@@ -19599,7 +20250,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR083 - Unsupported vararg function: " + symbol));
+                          "ERR086 - Unsupported vararg function: " + symbol));
 
             return error_node();
          }
@@ -19614,7 +20265,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR084 - Expected '(' for call to vararg function: " + symbol));
+                          "ERR087 - Expected '(' for call to vararg function: " + symbol));
 
             return error_node();
          }
@@ -19635,7 +20286,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR085 - Expected ',' for call to vararg function: " + symbol));
+                             "ERR088 - Expected ',' for call to vararg function: " + symbol));
 
                return error_node();
             }
@@ -19655,7 +20306,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR086 - Expected '[' as start of string range definition"));
+                          "ERR089 - Expected '[' as start of string range definition"));
 
             free_node(node_allocator_,expression);
 
@@ -19682,7 +20333,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR087 - Failed to generate string range node"));
+                          "ERR090 - Failed to generate string range node"));
 
             free_node(node_allocator_,expression);
          }
@@ -19814,7 +20465,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR088 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" +
+                             "ERR091 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" +
                              ((!source.empty()) ? std::string(" section of " + source): "")));
 
                return error_node();
@@ -19860,7 +20511,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR089 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source));
+                             "ERR092 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source));
 
                return error_node();
             }
@@ -19893,7 +20544,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR090 - Expected '[' for start of range"));
+                          "ERR093 - Expected '[' for start of range"));
 
             return false;
          }
@@ -19913,7 +20564,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR091 - Failed parse begin section of range"));
+                             "ERR094 - Failed parse begin section of range"));
 
                return false;
 
@@ -19936,7 +20587,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR092 - Range lower bound less than zero! Constraint: r0 >= 0"));
+                                "ERR095 - Range lower bound less than zero! Constraint: r0 >= 0"));
 
                   return false;
                }
@@ -19952,7 +20603,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR093 - Expected ':' for break  in range"));
+                             "ERR096 - Expected ':' for break  in range"));
 
                rp.free();
                return false;
@@ -19973,7 +20624,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR094 - Failed parse end section of range"));
+                             "ERR097 - Failed parse end section of range"));
 
                rp.free();
                return false;
@@ -19997,7 +20648,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR095 - Range upper bound less than zero! Constraint: r1 >= 0"));
+                                "ERR098 - Range upper bound less than zero! Constraint: r1 >= 0"));
 
                   return false;
                }
@@ -20013,7 +20664,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR096 - Expected ']' for start of range"));
+                             "ERR099 - Expected ']' for start of range"));
 
                rp.free();
                return false;
@@ -20032,7 +20683,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR097 - Invalid range, Constraint: r0 <= r1"));
+                             "ERR100 - Invalid range, Constraint: r0 <= r1"));
 
                return false;
             }
@@ -20047,6 +20698,7 @@
          dec_.add_symbol(symbol,st);
       }
 
+      #ifndef exprtk_disable_string_capabilities
       inline expression_node_ptr parse_string()
       {
          const std::string symbol = current_token().value;
@@ -20056,7 +20708,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR098 - Unknown string symbol"));
+                          "ERR101 - Unknown string symbol"));
 
             return error_node();
          }
@@ -20120,7 +20772,14 @@
 
          return result;
       }
+      #else
+      inline expression_node_ptr parse_string()
+      {
+         return error_node();
+      }
+      #endif
 
+      #ifndef exprtk_disable_string_capabilities
       inline expression_node_ptr parse_const_string()
       {
          const std::string const_str = current_token().value;
@@ -20165,7 +20824,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR099 - Overflow in range for string: '" + const_str + "'[" +
+                             "ERR102 - Overflow in range for string: '" + const_str + "'[" +
                              (rp.n0_c.first ? details::to_str(rp.n0_c.second) : "?") + ":" +
                              (rp.n1_c.first ? details::to_str(rp.n1_c.second) : "?") + "]"));
 
@@ -20182,6 +20841,12 @@
 
          return result;
       }
+      #else
+      inline expression_node_ptr parse_const_string()
+      {
+         return error_node();
+      }
+      #endif
 
       inline expression_node_ptr parse_vector()
       {
@@ -20202,7 +20867,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR100 - Symbol '" + symbol+ " not a vector"));
+                             "ERR103 - Symbol '" + symbol+ " not a vector"));
 
                return error_node();
             }
@@ -20227,7 +20892,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR101 - Failed to parse index for vector: '" + symbol + "'"));
+                          "ERR104 - Failed to parse index for vector: '" + symbol + "'"));
 
             return error_node();
          }
@@ -20236,7 +20901,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR102 - Expected ']' for index of vector: '" + symbol + "'"));
+                          "ERR105 - Expected ']' for index of vector: '" + symbol + "'"));
 
             free_node(node_allocator_,index_expr);
 
@@ -20264,7 +20929,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR103 - Zero parameter call to vararg function: "
+                                "ERR106 - Zero parameter call to vararg function: "
                                 + vararg_function_name + " not allowed"));
 
                   return error_node();
@@ -20288,7 +20953,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR104 - Expected ',' for call to vararg function: "
+                                   "ERR107 - Expected ',' for call to vararg function: "
                                    + vararg_function_name));
 
                      return error_node();
@@ -20301,12 +20966,35 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR105 - Zero parameter call to vararg function: "
+                          "ERR108 - Zero parameter call to vararg function: "
                           + vararg_function_name + " not allowed"));
 
             return error_node();
          }
 
+         if (arg_list.size() < vararg_function->min_num_args())
+         {
+            set_error(
+               make_error(parser_error::e_syntax,
+                          current_token(),
+                          "ERR109 - Invalid number of parameters to call to vararg function: "
+                          + vararg_function_name + ", require at least "
+                          + details::to_str( vararg_function->min_num_args()) + " parameters"));
+
+            return error_node();
+         }
+         else if (arg_list.size() > vararg_function->max_num_args())
+         {
+            set_error(
+               make_error(parser_error::e_syntax,
+                          current_token(),
+                          "ERR110 - Invalid number of parameters to call to vararg function: "
+                          + vararg_function_name + ", require no more than "
+                          + details::to_str( vararg_function->max_num_args()) + " parameters"));
+
+            return error_node();
+         }
+
          result = expression_generator_.vararg_function_call(vararg_function,arg_list);
 
          sdd.delete_ptr = (0 == result);
@@ -20362,7 +21050,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 parser_.current_token(),
-                                "ERR106 - Failed parameter type check for function '" + function_name_ + "', "
+                                "ERR111 - Failed parameter type check for function '" + function_name_ + "', "
                                 "Expected '" + param_seq_list_[0] + "'  call set: '" + param_seq +"'"));
             }
             else
@@ -20382,7 +21070,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 parser_.current_token(),
-                                "ERR107 - Failed parameter type check for function '" + function_name_ + "', "
+                                "ERR112 - Failed parameter type check for function '" + function_name_ + "', "
                                 "Best match: '" + param_seq_list_[max_diff_index] + "'  call set: '" + param_seq +"'"));
             }
 
@@ -20453,7 +21141,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    parser_.current_token(),
-                                   "ERR108 - Invalid parameter sequence of '" + err_param_seq +
+                                   "ERR113 - Invalid parameter sequence of '" + err_param_seq +
                                    "'  for function: " + function_name_));
 
                   return;
@@ -20474,7 +21162,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    parser_.current_token(),
-                                   "ERR109 - Invalid parameter sequence of '" + err_param_seq +
+                                   "ERR114 - Invalid parameter sequence of '" + err_param_seq +
                                    "'  for function: " + function_name_));
                   return;
                }
@@ -20507,7 +21195,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR110 - Type checker instantiation failure for generic function: " + function_name));
+                          "ERR115 - Type checker instantiation failure for generic function: " + function_name));
 
             return error_node();
          }
@@ -20521,7 +21209,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR111 - Zero parameter call to generic function: "
+                                "ERR116 - Zero parameter call to generic function: "
                                 + function_name + " not allowed"));
 
                   return error_node();
@@ -20552,7 +21240,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR112 - Expected ',' for call to generic function: " + function_name));
+                                   "ERR117 - Expected ',' for call to generic function: " + function_name));
 
                      return error_node();
                   }
@@ -20564,7 +21252,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR113 - Zero parameter call to generic function: "
+                          "ERR118 - Zero parameter call to generic function: "
                           + function_name + " not allowed"));
 
             return error_node();
@@ -20577,7 +21265,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR114 - Expected ',' for call to generic function: " + function_name));
+                          "ERR119 - Expected ',' for call to generic function: " + function_name));
 
             return error_node();
          }
@@ -20643,7 +21331,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR115 - Expected ',' for call to string function: " + function_name));
+                                   "ERR120 - Expected ',' for call to string function: " + function_name));
 
                      return error_node();
                   }
@@ -20658,7 +21346,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR116 - Expected ',' for call to string function: " + function_name));
+                          "ERR121 - Expected ',' for call to string function: " + function_name));
 
             return error_node();
          }
@@ -20694,7 +21382,7 @@
                p.set_error(
                     make_error(parser_error::e_syntax,
                                p.current_token(),
-                               "ERR117 - Expected '(' for special function"));
+                               "ERR122 - Expected '(' for special function"));
 
                return error_node();
             }
@@ -20714,7 +21402,7 @@
                      p.set_error(
                           make_error(parser_error::e_syntax,
                                      p.current_token(),
-                                     "ERR118 - Expected ',' before next parameter of special function"));
+                                     "ERR123 - Expected ',' before next parameter of special function"));
 
                      return p.error_node();
                   }
@@ -20743,7 +21431,7 @@
             set_error(
                make_error(parser_error::e_token,
                           current_token(),
-                          "ERR119 - Invalid special function[1]: " + current_token().value));
+                          "ERR124 - Invalid special function[1]: " + current_token().value));
 
             return error_node();
          }
@@ -20755,7 +21443,7 @@
             set_error(
                make_error(parser_error::e_token,
                           current_token(),
-                          "ERR120 - Invalid special function[2]: " + current_token().value));
+                          "ERR125 - Invalid special function[2]: " + current_token().value));
 
             return error_node();
          }
@@ -20786,7 +21474,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR121 - Break call within a break call is not allowed"));
+                          "ERR126 - Break call within a break call is not allowed"));
 
             return error_node();
          }
@@ -20808,7 +21496,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR122 - Failed to parse return expression for 'break' statement"));
+                                "ERR127 - Failed to parse return expression for 'break' statement"));
 
                   return error_node();
                }
@@ -20817,7 +21505,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR123 - Expected ']' at the completion of break's return expression"));
+                                "ERR128 - Expected ']' at the completion of break's return expression"));
 
                   free_node(node_allocator_,return_expr);
 
@@ -20834,7 +21522,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR124 - Invalid use of 'break', allowed only in the scope of a loop"));
+                          "ERR129 - Invalid use of 'break', allowed only in the scope of a loop"));
          }
 
          return error_node();
@@ -20856,7 +21544,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR125 - Invalid use of 'continue', allowed only in the scope of a loop"));
+                          "ERR130 - Invalid use of 'continue', allowed only in the scope of a loop"));
 
             return error_node();
          }
@@ -20872,7 +21560,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR126 - Expected '[' as part of vector size definition"));
+                          "ERR131 - Expected '[' as part of vector size definition"));
 
             return error_node();
          }
@@ -20881,7 +21569,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR127 - Failed to determine size of vector '" + vec_name + "'"));
+                          "ERR132 - Failed to determine size of vector '" + vec_name + "'"));
 
             return error_node();
          }
@@ -20892,7 +21580,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR128 - Expected a literal number as size of vector '" + vec_name + "'"));
+                          "ERR133 - Expected a literal number as size of vector '" + vec_name + "'"));
 
             return error_node();
          }
@@ -20910,7 +21598,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR129 - Invalid vector size. Must be an integer greater than zero, size: " +
+                          "ERR134 - Invalid vector size. Must be an integer greater than zero, size: " +
                           details::to_str(details::numeric::to_int32(vector_size))));
 
             return error_node();
@@ -20927,7 +21615,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR130 - Expected ']' as part of vector size definition"));
+                          "ERR135 - Expected ']' as part of vector size definition"));
 
             return error_node();
          }
@@ -20938,7 +21626,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR131 - Expected ':=' as part of vector definition"));
+                             "ERR136 - Expected ':=' as part of vector definition"));
 
                return error_node();
             }
@@ -20951,7 +21639,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR132 - Failed to parse single vector initialiser"));
+                                "ERR137 - Failed to parse single vector initialiser"));
 
                   return error_node();
                }
@@ -20963,7 +21651,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR133 - Expected ']' to close single value vector initialiser"));
+                                "ERR138 - Expected ']' to close single value vector initialiser"));
 
                   return error_node();
                }
@@ -20975,7 +21663,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR134 - Expected '{' as part of vector initialiser list"));
+                             "ERR139 - Expected '{' as part of vector initialiser list"));
 
                return error_node();
             }
@@ -20990,7 +21678,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR135 - Expected '{' as part of vector initialiser list"));
+                                   "ERR140 - Expected '{' as part of vector initialiser list"));
 
                      return error_node();
                   }
@@ -21007,7 +21695,7 @@
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR136 - Expected ',' between vector initialisers"));
+                                   "ERR141 - Expected ',' between vector initialisers"));
 
                      return error_node();
                   }
@@ -21028,7 +21716,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR137 - Expected ';' at end of vector definition"));
+                                "ERR142 - Expected ';' at end of vector definition"));
 
                   return error_node();
                }
@@ -21039,7 +21727,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR138 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'"));
+                             "ERR143 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'"));
 
                return error_node();
             }
@@ -21058,7 +21746,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR139 - Illegal redefinition of local vector: '" + vec_name + "'"));
+                             "ERR144 - Illegal redefinition of local vector: '" + vec_name + "'"));
 
                return error_node();
             }
@@ -21091,7 +21779,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR140 - Failed to add new local vector '" + vec_name + "' to SEM"));
+                             "ERR145 - Failed to add new local vector '" + vec_name + "' to SEM"));
 
                sem_.free_element(nse);
 
@@ -21136,7 +21824,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR141 - Illegal redefinition of local variable: '" + str_name + "'"));
+                             "ERR146 - Illegal redefinition of local variable: '" + str_name + "'"));
 
                free_node(node_allocator_,initialisation_expression);
 
@@ -21167,7 +21855,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR142 - Failed to add new local string variable '" + str_name + "' to SEM"));
+                             "ERR147 - Failed to add new local string variable '" + str_name + "' to SEM"));
 
                free_node(node_allocator_,initialisation_expression);
 
@@ -21212,7 +21900,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR143 - Illegal variable definition"));
+                          "ERR148 - Illegal variable definition"));
 
             return error_node();
          }
@@ -21232,7 +21920,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR144 - Expected a symbol for variable definition"));
+                          "ERR149 - Expected a symbol for variable definition"));
 
             return error_node();
          }
@@ -21241,7 +21929,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR145 - Illegal redefinition of reserved keyword: '" + var_name + "'"));
+                          "ERR150 - Illegal redefinition of reserved keyword: '" + var_name + "'"));
 
             return error_node();
          }
@@ -21250,7 +21938,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR146 - Illegal redefinition of variable '" + var_name + "'"));
+                          "ERR151 - Illegal redefinition of variable '" + var_name + "'"));
 
             return error_node();
          }
@@ -21259,7 +21947,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR147 - Illegal redefinition of local variable: '" + var_name + "'"));
+                          "ERR152 - Illegal redefinition of local variable: '" + var_name + "'"));
 
             return error_node();
          }
@@ -21278,7 +21966,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR148 - Failed to parse initialisation expression"));
+                             "ERR153 - Failed to parse initialisation expression"));
 
                return error_node();
             }
@@ -21295,7 +21983,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR149 - Expected ';' after variable definition"));
+                             "ERR154 - Expected ';' after variable definition"));
 
                free_node(node_allocator_,initialisation_expression);
 
@@ -21322,7 +22010,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR150 - Illegal redefinition of local variable: '" + var_name + "'"));
+                             "ERR155 - Illegal redefinition of local variable: '" + var_name + "'"));
 
                free_node(node_allocator_,initialisation_expression);
 
@@ -21353,7 +22041,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR151 - Failed to add new local variable '" + var_name + "' to SEM"));
+                             "ERR156 - Failed to add new local variable '" + var_name + "' to SEM"));
 
                free_node(node_allocator_,initialisation_expression);
 
@@ -21389,7 +22077,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR152 - Expected a '{}' for uninitialised var definition"));
+                          "ERR157 - Expected a '{}' for uninitialised var definition"));
 
             return error_node();
          }
@@ -21398,7 +22086,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR153 - Expected ';' after uninitialised variable definition"));
+                          "ERR158 - Expected ';' after uninitialised variable definition"));
 
             return error_node();
          }
@@ -21414,7 +22102,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR154 - Illegal redefinition of local variable: '" + var_name + "'"));
+                             "ERR159 - Illegal redefinition of local variable: '" + var_name + "'"));
 
                return error_node();
             }
@@ -21443,7 +22131,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR155 - Failed to add new local variable '" + var_name + "' to SEM"));
+                             "ERR160 - Failed to add new local variable '" + var_name + "' to SEM"));
 
                sem_.free_element(nse);
 
@@ -21475,7 +22163,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR156 - Expected '(' at start of swap statement"));
+                          "ERR161 - Expected '(' at start of swap statement"));
 
             return error_node();
          }
@@ -21493,7 +22181,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR157 - Expected a symbol for variable or vector element definition"));
+                          "ERR162 - Expected a symbol for variable or vector element definition"));
 
             return error_node();
          }
@@ -21504,7 +22192,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR158 - First parameter to swap is an invalid vector element: '" + var0_name + "'"));
+                             "ERR163 - First parameter to swap is an invalid vector element: '" + var0_name + "'"));
 
                return error_node();
             }
@@ -21536,7 +22224,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR159 - First parameter to swap is an invalid variable: '" + var0_name + "'"));
+                             "ERR164 - First parameter to swap is an invalid variable: '" + var0_name + "'"));
 
                return error_node();
             }
@@ -21549,7 +22237,7 @@
             set_error(
                 make_error(parser_error::e_syntax,
                            current_token(),
-                           "ERR160 - Expected ',' between parameters to swap"));
+                           "ERR165 - Expected ',' between parameters to swap"));
 
             if (variable0_generated)
             {
@@ -21566,7 +22254,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR161 - Expected a symbol for variable or vector element definition"));
+                          "ERR166 - Expected a symbol for variable or vector element definition"));
 
             if (variable0_generated)
             {
@@ -21582,7 +22270,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR162 - Second parameter to swap is an invalid vector element: '" + var1_name + "'"));
+                             "ERR167 - Second parameter to swap is an invalid vector element: '" + var1_name + "'"));
 
                if (variable0_generated)
                {
@@ -21619,7 +22307,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR163 - Second parameter to swap is an invalid variable: '" + var1_name + "'"));
+                             "ERR168 - Second parameter to swap is an invalid variable: '" + var1_name + "'"));
 
                if (variable0_generated)
                {
@@ -21637,7 +22325,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR164 - Expected ')' at end of swap statement"));
+                          "ERR169 - Expected ')' at end of swap statement"));
 
             if (variable0_generated)
             {
@@ -21690,7 +22378,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR165 - Return call within a return call is not allowed"));
+                          "ERR170 - Return call within a return call is not allowed"));
 
             return error_node();
          }
@@ -21713,13 +22401,12 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR166 - Expected '[' at start of return statement"));
+                          "ERR171 - Expected '[' at start of return statement"));
 
             return error_node();
          }
          else if (!token_is(token_t::e_rsqrbracket))
          {
-
             for ( ; ; )
             {
                expression_node_ptr arg = parse_expression();
@@ -21736,7 +22423,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR167 - Expected ',' between values during call to return"));
+                                "ERR172 - Expected ',' between values during call to return"));
 
                   return error_node();
                }
@@ -21747,7 +22434,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR168 - Zero parameter return statement not allowed"));
+                          "ERR173 - Zero parameter return statement not allowed"));
 
             return error_node();
          }
@@ -21761,7 +22448,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              prev_token,
-                             "ERR169 - Invalid ']' found during return call"));
+                             "ERR174 - Invalid ']' found during return call"));
 
                return error_node();
             }
@@ -21807,7 +22494,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR170 - Invalid sequence of variable '"+ symbol + "' and bracket"));
+                             "ERR175 - Invalid sequence of variable '"+ symbol + "' and bracket"));
 
                return false;
             }
@@ -21852,7 +22539,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR171 - Invalid sequence of brackets"));
+                             "ERR176 - Invalid sequence of brackets"));
 
                return false;
             }
@@ -21953,7 +22640,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR172 - Failed to generate node for function: '" + symbol + "'"));
+                                "ERR177 - Failed to generate node for function: '" + symbol + "'"));
 
                   return error_node();
                }
@@ -21978,7 +22665,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR173 - Failed to generate node for vararg function: '" + symbol + "'"));
+                                "ERR178 - Failed to generate node for vararg function: '" + symbol + "'"));
 
                   return error_node();
                }
@@ -22003,7 +22690,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR174 - Failed to generate node for generic function: '" + symbol + "'"));
+                                "ERR179 - Failed to generate node for generic function: '" + symbol + "'"));
 
                   return error_node();
                }
@@ -22028,7 +22715,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR175 - Failed to generate node for string function: '" + symbol + "'"));
+                                "ERR180 - Failed to generate node for string function: '" + symbol + "'"));
 
                   return error_node();
                }
@@ -22049,7 +22736,7 @@
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR176 - Invalid use of reserved symbol '" + symbol + "'"));
+                                "ERR181 - Invalid use of reserved symbol '" + symbol + "'"));
 
                   return error_node();
                }
@@ -22106,7 +22793,7 @@
                   set_error(
                      make_error(parser_error::e_symtab,
                                 current_token(),
-                                "ERR177 - Failed to create variable: '" + symbol + "'"));
+                                "ERR182 - Failed to create variable: '" + symbol + "'"));
 
                   return error_node();
                }
@@ -22116,7 +22803,7 @@
          set_error(
             make_error(parser_error::e_syntax,
                        current_token(),
-                       "ERR178 - Undefined symbol: '" + symbol + "'"));
+                       "ERR183 - Undefined symbol: '" + symbol + "'"));
 
          return error_node();
       }
@@ -22217,7 +22904,7 @@
             set_error(
                make_error(parser_error::e_symtab,
                           current_token(),
-                          "ERR179 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value));
+                          "ERR184 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value));
 
             return error_node();
          }
@@ -22242,7 +22929,7 @@
                set_error(
                   make_error(parser_error::e_numeric,
                              current_token(),
-                             "ERR180 - Failed to convert '" + current_token().value + "' to a number"));
+                             "ERR185 - Failed to convert '" + current_token().value + "' to a number"));
 
                return error_node();
             }
@@ -22268,7 +22955,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR181 - Expected ')' instead of: '" + current_token().value + "'"));
+                             "ERR186 - Expected ')' instead of: '" + current_token().value + "'"));
 
                free_node(node_allocator_,branch);
 
@@ -22292,7 +22979,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR182 - Expected ']' instead of: '" + current_token().value + "'"));
+                             "ERR187 - Expected ']' instead of: '" + current_token().value + "'"));
 
                free_node(node_allocator_,branch);
 
@@ -22316,7 +23003,7 @@
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR183 - Expected '}' instead of: '" + current_token().value + "'"));
+                             "ERR188 - Expected '}' instead of: '" + current_token().value + "'"));
 
                free_node(node_allocator_,branch);
 
@@ -22355,7 +23042,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR184 - Premature end of expression[1]"));
+                          "ERR189 - Premature end of expression[1]"));
 
             return error_node();
          }
@@ -22364,7 +23051,7 @@
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR185 - Premature end of expression[2]"));
+                          "ERR190 - Premature end of expression[2]"));
 
             return error_node();
          }
@@ -22547,6 +23234,7 @@
             return node_allocator_->allocate<literal_node_t>(v);
          }
 
+         #ifndef exprtk_disable_string_capabilities
          inline expression_node_ptr operator()(const std::string& s) const
          {
             return node_allocator_->allocate<string_literal_node_t>(s);
@@ -22569,6 +23257,7 @@
             else
                return error_node();
          }
+         #endif
 
          inline bool unary_optimizable(const details::operator_type& operation) const
          {
@@ -22664,11 +23353,14 @@
 
          inline bool is_assignment_operation(const details::operator_type& operation) const
          {
-            return (details::e_addass == operation) ||
-                   (details::e_subass == operation) ||
-                   (details::e_mulass == operation) ||
-                   (details::e_divass == operation) ||
-                   (details::e_modass == operation) ;
+            return (
+                      (details::e_addass == operation) ||
+                      (details::e_subass == operation) ||
+                      (details::e_mulass == operation) ||
+                      (details::e_divass == operation) ||
+                      (details::e_modass == operation)
+                   ) &&
+                   parser_->settings_.assignment_enabled(operation);
          }
 
          #ifndef exprtk_disable_string_capabilities
@@ -23236,8 +23928,6 @@
                         allocate<conditional_string_node_t>(condition,consequent,alternative);
             else
                return error_node();
-               //return node_allocator_->
-               //         allocate<cons_conditional_str_node_t>(condition,consequent);
          }
          #else
          inline expression_node_ptr conditional_string(expression_node_ptr ,
@@ -23530,6 +24220,7 @@
                     )
             {
                details::free_all_nodes(*node_allocator_,arg_list);
+
                return error_node();
             }
             else if (is_constant_foldable(arg_list))
@@ -23704,7 +24395,7 @@
             }
 
             T v = temp_node->value();
-            node_allocator_->free(temp_node);
+
             details::free_node(*node_allocator_,temp_node);
 
             return node_allocator_->allocate<literal_node_t>(v);
@@ -24217,19 +24908,24 @@
                )
             {
                strfunc_node_ptr->init_branches();
+
                Type v = result->value();
+
                details::free_node(*node_allocator_,result);
+
                return node_allocator_->allocate<literal_node_t>(v);
             }
             else if (strfunc_node_ptr->init_branches())
             {
                parser_->state_.activate_side_effect("string_function_call()");
+
                return result;
             }
             else
             {
                details::free_node(*node_allocator_,result);
                details::free_all_nodes(*node_allocator_,arg_list);
+
                return error_node();
             }
          }
@@ -24252,12 +24948,14 @@
             if (return_node_ptr->init_branches())
             {
                parser_->state_.activate_side_effect("return_call()");
+
                return result;
             }
             else
             {
                details::free_node(*node_allocator_,result);
                details::free_all_nodes(*node_allocator_,arg_list);
+
                return error_node();
             }
          }
@@ -24285,7 +24983,9 @@
             if (details::is_constant_node(index))
             {
                std::size_t i = static_cast<std::size_t>(details::numeric::to_int64(index->value()));
+
                details::free_node(*node_allocator_,index);
+
                Type* v = (*vector_base)[i];
 
                scope_element& se = parser_->sem_.get_element(symbol,i);
@@ -24323,7 +25023,7 @@
                }
             }
             else
-               result = node_allocator_->allocate<details::vector_elem_node<Type> >(index,(*vector_base)[0]);
+               result = node_allocator_->allocate<details::vector_elem_node<Type> >(index,vector_base);
 
             return result;
          }
@@ -24390,6 +25090,17 @@
                                     }
                                     break;
 
+               case e_st_vecelem   : {
+                                       typedef details::vector_holder<T> vector_holder_t;
+
+                                       vector_holder_t& vh = static_cast<vector_elem_node_t*>(node)->vec_holder();
+
+                                       symbol_name = parser_->symtab_store_.get_vector_name(&vh);
+
+                                       cst = e_st_vector;
+                                    }
+                                    break;
+
                default            : return;
             }
 
@@ -24408,7 +25119,11 @@
                return synthesize_expression<assignment_node_t,2>(operation,branch);
             }
             else if (details::is_vector_elem_node(branch[0]))
-               return synthesize_expression<assignment_vec_elem_node_t,2>(operation,branch);
+            {
+               lodge_assignment(e_st_vecelem,branch[0]);
+
+               return synthesize_expression<assignment_vec_elem_node_t, 2>(operation, branch);
+            }
             #ifndef exprtk_disable_string_capabilities
             else if (details::is_string_node(branch[0]))
             {
@@ -25179,8 +25894,26 @@
                                                       expression_node_ptr (&branch)[2])
             {
                const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
+
                free_node(*expr_gen.node_allocator_,branch[0]);
 
+               if ((T(0) == c) && (details::e_mul == operation))
+               {
+                  free_node(*expr_gen.node_allocator_,branch[1]);
+
+                  return expr_gen(T(0));
+               }
+               else if ((T(0) == c) && (details::e_div == operation))
+               {
+                  free_node(*expr_gen.node_allocator_, branch[1]);
+
+                  return expr_gen(T(0));
+               }
+               else if ((T(0) == c) && (details::e_add == operation))
+                  return branch[1];
+               else if ((T(1) == c) && (details::e_mul == operation))
+                  return branch[1];
+
                if (details::is_cob_node(branch[1]))
                {
                   // Simplify expressions of the form:
@@ -25295,8 +26028,26 @@
                                                       expression_node_ptr (&branch)[2])
             {
                const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
+
                details::free_node(*(expr_gen.node_allocator_),branch[1]);
 
+               if ((T(0) == c) && (details::e_mul == operation))
+               {
+                  free_node(*expr_gen.node_allocator_,branch[0]);
+
+                  return expr_gen(T(0));
+               }
+               else if ((T(0) == c) && (details::e_div == operation))
+               {
+                  free_node(*expr_gen.node_allocator_, branch[0]);
+
+                  return expr_gen(std::numeric_limits<T>::quiet_NaN());
+               }
+               else if ((T(0) == c) && (details::e_add == operation))
+                  return branch[0];
+               else if ((T(1) == c) && (details::e_mul == operation))
+                  return branch[0];
+
                if (details::is_boc_node(branch[0]))
                {
                   // Simplify expressions of the form:
@@ -25386,6 +26137,36 @@
                   details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[0]);
                   const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
 
+                  if ((T(0) == c) && (details::e_mul == operation))
+                  {
+                     free_node(*expr_gen.node_allocator_,branch[0]);
+                     free_node(*expr_gen.node_allocator_,branch[1]);
+
+                     return expr_gen(T(0));
+                  }
+                  else if ((T(0) == c) && (details::e_div == operation))
+                  {
+                     free_node(*expr_gen.node_allocator_,branch[0]);
+                     free_node(*expr_gen.node_allocator_,branch[1]);
+
+                     return expr_gen(T(std::numeric_limits<T>::quiet_NaN()));
+                  }
+                  else if ((T(0) == c) && (details::e_add == operation))
+                  {
+                     free_node(*expr_gen.node_allocator_, branch[1]);
+                     return branch[0];
+                  }
+                  else if ((T(1) == c) && (details::e_mul == operation))
+                  {
+                     free_node(*expr_gen.node_allocator_, branch[1]);
+                     return branch[0];
+                  }
+                  else if ((T(1) == c) && (details::e_div == operation))
+                  {
+                     free_node(*expr_gen.node_allocator_, branch[1]);
+                     return branch[0];
+                  }
+
                   bool op_addsub = (details::e_add == cobnode->operation()) ||
                                    (details::e_sub == cobnode->operation());
 
@@ -25439,6 +26220,31 @@
                   details::cob_base_node<Type>* cobnode = static_cast<details::cob_base_node<Type>*>(branch[1]);
                   const Type c = static_cast<details::literal_node<Type>*>(branch[0])->value();
 
+                  if ((T(0) == c) && (details::e_mul == operation))
+                  {
+                     free_node(*expr_gen.node_allocator_,branch[0]);
+                     free_node(*expr_gen.node_allocator_,branch[1]);
+
+                     return expr_gen(T(0));
+                  }
+                  else if ((T(0) == c) && (details::e_div == operation))
+                  {
+                     free_node(*expr_gen.node_allocator_,branch[0]);
+                     free_node(*expr_gen.node_allocator_,branch[1]);
+
+                     return expr_gen(T(0));
+                  }
+                  else if ((T(0) == c) && (details::e_add == operation))
+                  {
+                     free_node(*expr_gen.node_allocator_, branch[0]);
+                     return branch[1];
+                  }
+                  else if ((T(1) == c) && (details::e_mul == operation))
+                  {
+                     free_node(*expr_gen.node_allocator_, branch[0]);
+                     return branch[1];
+                  }
+
                   if (details::e_add == cobnode->operation())
                   {
                      if (details::e_add == operation)
@@ -25716,6 +26522,15 @@
 
                details::free_node(*(expr_gen.node_allocator_),branch[0]);
 
+               if ((T(0) == c) && (details::e_mul == operation))
+                  return expr_gen(T(0));
+               else if ((T(0) == c) && (details::e_div == operation))
+                  return expr_gen(T(0));
+               else if ((T(0) == c) && (details::e_add == operation))
+                  return static_cast<details::variable_node<Type>*>(branch[1]);
+               else if ((T(1) == c) && (details::e_mul == operation))
+                  return static_cast<details::variable_node<Type>*>(branch[1]);
+
                switch (operation)
                {
                   #define case_stmt(op0,op1)                                                       \
@@ -25749,6 +26564,16 @@
                   else
                      return expr_gen.cardinal_pow_optimization(v,c);
                }
+               else if ((T(0) == c) && (details::e_mul == operation))
+                  return expr_gen(T(0));
+               else if ((T(0) == c) && (details::e_div == operation))
+                  return expr_gen(std::numeric_limits<T>::quiet_NaN());
+               else if ((T(0) == c) && (details::e_add == operation))
+                  return static_cast<details::variable_node<Type>*>(branch[0]);
+               else if ((T(1) == c) && (details::e_mul == operation))
+                  return static_cast<details::variable_node<Type>*>(branch[0]);
+               else if ((T(1) == c) && (details::e_div == operation))
+                  return static_cast<details::variable_node<Type>*>(branch[0]);
 
                switch (operation)
                {
@@ -25876,6 +26701,7 @@
                   case_stmt(details::e_sf4ext54,details::sfext54_op) case_stmt(details::e_sf4ext55,details::sfext55_op)
                   case_stmt(details::e_sf4ext56,details::sfext56_op) case_stmt(details::e_sf4ext57,details::sfext57_op)
                   case_stmt(details::e_sf4ext58,details::sfext58_op) case_stmt(details::e_sf4ext59,details::sfext59_op)
+                  case_stmt(details::e_sf4ext60,details::sfext60_op)
 
                   #undef case_stmt
                   default : return error_node();
@@ -26993,6 +27819,39 @@
 
                      return (synthesis_result) ? result : error_node();
                   }
+                  // (v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
+                  else if ((details::e_add == o0) && (details::e_div == o1) && (details::e_div == o2))
+                  {
+                     const bool synthesis_result =
+                        synthesize_sf4ext_expression::
+                           template compile<vtype,vtype,vtype,vtype>(expr_gen,"(t+t)*(t/t)",v0,v1,v3,v2,result);
+
+                     exprtk_debug(("(v0 + v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)\n"));
+
+                     return (synthesis_result) ? result : error_node();
+                  }
+                  // (v0 - v1) / (v2 / v3) --> (vovovov) (v0 + v1) * (v3 / v2)
+                  else if ((details::e_sub == o0) && (details::e_div == o1) && (details::e_div == o2))
+                  {
+                     const bool synthesis_result =
+                        synthesize_sf4ext_expression::
+                           template compile<vtype,vtype,vtype,vtype>(expr_gen,"(t-t)*(t/t)",v0,v1,v3,v2,result);
+
+                     exprtk_debug(("(v0 - v1) / (v2 / v3) --> (vovovov) (v0 - v1) * (v3 / v2)\n"));
+
+                     return (synthesis_result) ? result : error_node();
+                  }
+                  // (v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2
+                  else if ((details::e_mul == o0) && (details::e_div == o1) && (details::e_div == o2))
+                  {
+                     const bool synthesis_result =
+                        synthesize_sf4ext_expression::
+                           template compile<vtype,vtype,vtype,vtype>(expr_gen,"((t*t)*t)/t",v0,v1,v3,v2,result);
+
+                     exprtk_debug(("(v0 * v1) / (v2 / v3) --> (vovovov) ((v0 * v1) * v3) / v2\n"));
+
+                     return (synthesis_result) ? result : error_node();
+                  }
                }
 
                if (synthesize_sf4ext_expression::template compile<T0,T1,T2,T3>(expr_gen,id(expr_gen,o0,o1,o2),v0,v1,v2,v3,result))
@@ -27727,7 +28586,7 @@
 
                      const bool synthesis_result =
                         synthesize_sf3ext_expression::
-                           template compile<ctype,vtype,vtype>(expr_gen,specfunc,c0,v0,v1,result);
+                           template compile<vtype,vtype,ctype>(expr_gen,specfunc,v0,v1,c0,result);
 
                      exprtk_debug(("(v0 / c) +/- (v1 / c) --> (vovoc) (v0 +/- v1) / c\n"));
 
@@ -28086,6 +28945,7 @@
                           )
                   {
                      std::string specfunc;
+
                      switch (o1)
                      {
                         case details::e_add : specfunc = "t*(t+t)"; break;
@@ -28138,9 +28998,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 (v1 o1 (v2 o2 v3))
-               typedef typename synthesize_vovov_expression1::node_type vovov_t;
+               typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
 
-               const vovov_t* vovov = static_cast<const vovov_t*>(branch[1]);
+               const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type& v1 = vovov->t0();
                const Type& v2 = vovov->t1();
@@ -28190,9 +29050,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 (v1 o1 (v2 o2 c))
-               typedef typename synthesize_vovoc_expression1::node_type vovoc_t;
+               typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
 
-               const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[1]);
+               const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type& v1 = vovoc->t0();
                const Type& v2 = vovoc->t1();
@@ -28242,9 +29102,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 (v1 o1 (c o2 v2))
-               typedef typename synthesize_vocov_expression1::node_type vocov_t;
+               typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
 
-               const vocov_t* vocov = static_cast<const vocov_t*>(branch[1]);
+               const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type& v1 = vocov->t0();
                const Type   c = vocov->t1();
@@ -28294,9 +29154,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 (c o1 (v1 o2 v2))
-               typedef typename synthesize_covov_expression1::node_type covov_t;
+               typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
 
-               const covov_t* covov = static_cast<const covov_t*>(branch[1]);
+               const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type   c = covov->t0();
                const Type& v1 = covov->t1();
@@ -28346,9 +29206,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // c o0 (v0 o1 (v1 o2 v2))
-               typedef typename synthesize_vovov_expression1::node_type vovov_t;
+               typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
 
-               const vovov_t* vovov = static_cast<const vovov_t*>(branch[1]);
+               const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
                const Type   c = static_cast<details::literal_node<Type>*>(branch[0])->value();
                const Type& v0 = vovov->t0();
                const Type& v1 = vovov->t1();
@@ -28399,9 +29259,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // c0 o0 (v0 o1 (c1 o2 v1))
-               typedef typename synthesize_vocov_expression1::node_type vocov_t;
+               typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
 
-               const vocov_t* vocov = static_cast<const vocov_t*>(branch[1]);
+               const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
                const Type& v0 = vocov->t0();
                const Type  c1 = vocov->t1();
@@ -28452,9 +29312,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 (c0 o1 (v1 o2 c2))
-               typedef typename synthesize_covoc_expression1::node_type covoc_t;
+               typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
 
-               const covoc_t* covoc = static_cast<const covoc_t*>(branch[1]);
+               const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type  c0 = covoc->t0();
                const Type& v1 = covoc->t1();
@@ -28503,9 +29363,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // c0 o0 (v0 o1 (v1 o2 c1))
-               typedef typename synthesize_vovoc_expression1::node_type vovoc_t;
+               typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
 
-               const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[1]);
+               const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
                const Type& v0 = vovoc->t0();
                const Type& v1 = vovoc->t1();
@@ -28556,9 +29416,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 (c0 o1 (c1 o2 v1))
-               typedef typename synthesize_cocov_expression1::node_type cocov_t;
+               typedef typename synthesize_cocov_expression1::node_type lcl_cocov_t;
 
-               const cocov_t* cocov = static_cast<const cocov_t*>(branch[1]);
+               const lcl_cocov_t* cocov = static_cast<const lcl_cocov_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type  c0 = cocov->t0();
                const Type  c1 = cocov->t1();
@@ -28608,9 +29468,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 ((v1 o1 v2) o2 v3)
-               typedef typename synthesize_vovov_expression0::node_type vovov_t;
+               typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
 
-               const vovov_t* vovov = static_cast<const vovov_t*>(branch[1]);
+               const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type& v1 = vovov->t0();
                const Type& v2 = vovov->t1();
@@ -28660,9 +29520,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 ((v1 o1 v2) o2 c)
-               typedef typename synthesize_vovoc_expression0::node_type vovoc_t;
+               typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
 
-               const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[1]);
+               const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type& v1 = vovoc->t0();
                const Type& v2 = vovoc->t1();
@@ -28712,9 +29572,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 ((v1 o1 c) o2 v2)
-               typedef typename synthesize_vocov_expression0::node_type vocov_t;
+               typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
 
-               const vocov_t* vocov = static_cast<const vocov_t*>(branch[1]);
+               const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type& v1 = vocov->t0();
                const Type   c = vocov->t1();
@@ -28764,9 +29624,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 ((c o1 v1) o2 v2)
-               typedef typename synthesize_covov_expression0::node_type covov_t;
+               typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
 
-               const covov_t* covov = static_cast<const covov_t*>(branch[1]);
+               const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type   c = covov->t0();
                const Type& v1 = covov->t1();
@@ -28816,9 +29676,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // c o0 ((v1 o1 v2) o2 v3)
-               typedef typename synthesize_vovov_expression0::node_type vovov_t;
+               typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
 
-               const vovov_t* vovov = static_cast<const vovov_t*>(branch[1]);
+               const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[1]);
                const Type   c = static_cast<details::literal_node<Type>*>(branch[0])->value();
                const Type& v0 = vovov->t0();
                const Type& v1 = vovov->t1();
@@ -28869,9 +29729,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // c0 o0 ((v0 o1 c1) o2 v1)
-               typedef typename synthesize_vocov_expression0::node_type vocov_t;
+               typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
 
-               const vocov_t* vocov = static_cast<const vocov_t*>(branch[1]);
+               const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[1]);
                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
                const Type& v0 = vocov->t0();
                const Type  c1 = vocov->t1();
@@ -28922,9 +29782,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // v0 o0 ((c0 o1 v1) o2 c1)
-               typedef typename synthesize_covoc_expression0::node_type covoc_t;
+               typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
 
-               const covoc_t* covoc = static_cast<const covoc_t*>(branch[1]);
+               const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[1]);
                const Type& v0 = static_cast<details::variable_node<Type>*>(branch[0])->ref();
                const Type  c0 = covoc->t0();
                const Type& v1 = covoc->t1();
@@ -28974,9 +29834,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // c0 o0 ((v0 o1 v1) o2 c1)
-               typedef typename synthesize_vovoc_expression0::node_type vovoc_t;
+               typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
 
-               const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[1]);
+               const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[1]);
                const Type  c0 = static_cast<details::literal_node<Type>*>(branch[0])->value();
                const Type& v0 = vovoc->t0();
                const Type& v1 = vovoc->t1();
@@ -29044,9 +29904,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 v1) o1 v2) o2 v3
-               typedef typename synthesize_vovov_expression0::node_type vovov_t;
+               typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
 
-               const vovov_t* vovov = static_cast<const vovov_t*>(branch[0]);
+               const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
                const Type& v0 = vovov->t0();
                const Type& v1 = vovov->t1();
                const Type& v2 = vovov->t2();
@@ -29096,9 +29956,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 v1) o1 v2) o2 c
-               typedef typename synthesize_vovov_expression0::node_type vovov_t;
+               typedef typename synthesize_vovov_expression0::node_type lcl_vovov_t;
 
-               const vovov_t* vovov = static_cast<const vovov_t*>(branch[0]);
+               const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
                const Type& v0 = vovov->t0();
                const Type& v1 = vovov->t1();
                const Type& v2 = vovov->t2();
@@ -29149,9 +30009,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 v1) o1 c) o2 v2
-               typedef typename synthesize_vovoc_expression0::node_type vovoc_t;
+               typedef typename synthesize_vovoc_expression0::node_type lcl_vovoc_t;
 
-               const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[0]);
+               const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
                const Type& v0 = vovoc->t0();
                const Type& v1 = vovoc->t1();
                const Type   c = vovoc->t2();
@@ -29201,9 +30061,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 c) o1 v1) o2 v2
-               typedef typename synthesize_vocov_expression0::node_type vocov_t;
+               typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
 
-               const vocov_t* vocov = static_cast<const vocov_t*>(branch[0]);
+               const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
                const Type& v0 = vocov->t0();
                const Type   c = vocov->t1();
                const Type& v1 = vocov->t2();
@@ -29253,9 +30113,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((c o0 v0) o1 v1) o2 v2
-               typedef typename synthesize_covov_expression0::node_type covov_t;
+               typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
 
-               const covov_t* covov = static_cast<const covov_t*>(branch[0]);
+               const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
                const Type   c = covov->t0();
                const Type& v0 = covov->t1();
                const Type& v1 = covov->t2();
@@ -29305,9 +30165,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((c0 o0 v0) o1 c1) o2 v1
-               typedef typename synthesize_covoc_expression0::node_type covoc_t;
+               typedef typename synthesize_covoc_expression0::node_type lcl_covoc_t;
 
-               const covoc_t* covoc = static_cast<const covoc_t*>(branch[0]);
+               const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
                const Type  c0 = covoc->t0();
                const Type& v0 = covoc->t1();
                const Type  c1 = covoc->t2();
@@ -29357,9 +30217,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 c0) o1 v1) o2 c1
-               typedef typename synthesize_vocov_expression0::node_type vocov_t;
+               typedef typename synthesize_vocov_expression0::node_type lcl_vocov_t;
 
-               const vocov_t* vocov = static_cast<const vocov_t*>(branch[0]);
+               const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
                const Type& v0 = vocov->t0();
                const Type  c0 = vocov->t1();
                const Type& v1 = vocov->t2();
@@ -29410,9 +30270,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((c0 o0 v0) o1 v1) o2 c1
-               typedef typename synthesize_covov_expression0::node_type covov_t;
+               typedef typename synthesize_covov_expression0::node_type lcl_covov_t;
 
-               const covov_t* covov = static_cast<const covov_t*>(branch[0]);
+               const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
                const Type  c0 = covov->t0();
                const Type& v0 = covov->t1();
                const Type& v1 = covov->t2();
@@ -29463,9 +30323,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 c0) o1 c1) o2 v1
-               typedef typename synthesize_vococ_expression0::node_type vococ_t;
+               typedef typename synthesize_vococ_expression0::node_type lcl_vococ_t;
 
-               const vococ_t* vococ = static_cast<const vococ_t*>(branch[0]);
+               const lcl_vococ_t* vococ = static_cast<const lcl_vococ_t*>(branch[0]);
                const Type& v0 = vococ->t0();
                const Type  c0 = vococ->t1();
                const Type  c1 = vococ->t2();
@@ -29515,9 +30375,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // (v0 o0 (v1 o1 v2)) o2 v3
-               typedef typename synthesize_vovov_expression1::node_type vovov_t;
+               typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
 
-               const vovov_t* vovov = static_cast<const vovov_t*>(branch[0]);
+               const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
                const Type& v0 = vovov->t0();
                const Type& v1 = vovov->t1();
                const Type& v2 = vovov->t2();
@@ -29567,9 +30427,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 (v1 o1 v2)) o2 c)
-               typedef typename synthesize_vovov_expression1::node_type vovov_t;
+               typedef typename synthesize_vovov_expression1::node_type lcl_vovov_t;
 
-               const vovov_t* vovov = static_cast<const vovov_t*>(branch[0]);
+               const lcl_vovov_t* vovov = static_cast<const lcl_vovov_t*>(branch[0]);
                const Type& v0 = vovov->t0();
                const Type& v1 = vovov->t1();
                const Type& v2 = vovov->t2();
@@ -29620,9 +30480,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 (v1 o1 c)) o2 v1)
-               typedef typename synthesize_vovoc_expression1::node_type vovoc_t;
+               typedef typename synthesize_vovoc_expression1::node_type lcl_vovoc_t;
 
-               const vovoc_t* vovoc = static_cast<const vovoc_t*>(branch[0]);
+               const lcl_vovoc_t* vovoc = static_cast<const lcl_vovoc_t*>(branch[0]);
                const Type& v0 = vovoc->t0();
                const Type& v1 = vovoc->t1();
                const Type   c = vovoc->t2();
@@ -29672,9 +30532,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 (c o1 v1)) o2 v2)
-               typedef typename synthesize_vocov_expression1::node_type vocov_t;
+               typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
 
-               const vocov_t* vocov = static_cast<const vocov_t*>(branch[0]);
+               const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
                const Type& v0 = vocov->t0();
                const Type   c = vocov->t1();
                const Type& v1 = vocov->t2();
@@ -29723,9 +30583,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((c o0 (v0 o1 v1)) o2 v2)
-               typedef typename synthesize_covov_expression1::node_type covov_t;
+               typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
 
-               const covov_t* covov = static_cast<const covov_t*>(branch[0]);
+               const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
                const Type   c = covov->t0();
                const Type& v0 = covov->t1();
                const Type& v1 = covov->t2();
@@ -29775,9 +30635,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((c0 o0 (v0 o1 c1)) o2 v1)
-               typedef typename synthesize_covoc_expression1::node_type covoc_t;
+               typedef typename synthesize_covoc_expression1::node_type lcl_covoc_t;
 
-               const covoc_t* covoc = static_cast<const covoc_t*>(branch[0]);
+               const lcl_covoc_t* covoc = static_cast<const lcl_covoc_t*>(branch[0]);
                const Type  c0 = covoc->t0();
                const Type& v0 = covoc->t1();
                const Type  c1 = covoc->t2();
@@ -29827,9 +30687,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((v0 o0 (c0 o1 v1)) o2 c1)
-               typedef typename synthesize_vocov_expression1::node_type vocov_t;
+               typedef typename synthesize_vocov_expression1::node_type lcl_vocov_t;
 
-               const vocov_t* vocov = static_cast<const vocov_t*>(branch[0]);
+               const lcl_vocov_t* vocov = static_cast<const lcl_vocov_t*>(branch[0]);
                const Type& v0 = vocov->t0();
                const Type  c0 = vocov->t1();
                const Type& v1 = vocov->t2();
@@ -29880,9 +30740,9 @@
                                                       expression_node_ptr (&branch)[2])
             {
                // ((c0 o0 (v0 o1 v1)) o2 c1)
-               typedef typename synthesize_covov_expression1::node_type covov_t;
+               typedef typename synthesize_covov_expression1::node_type lcl_covov_t;
 
-               const covov_t* covov = static_cast<const covov_t*>(branch[0]);
+               const lcl_covov_t* covov = static_cast<const lcl_covov_t*>(branch[0]);
                const Type  c0 = covov->t0();
                const Type& v0 = covov->t1();
                const Type& v1 = covov->t2();
@@ -30958,6 +31818,7 @@
          register_sf4ext(48) register_sf4ext(49) register_sf4ext(50) register_sf4ext(51)
          register_sf4ext(52) register_sf4ext(53) register_sf4ext(54) register_sf4ext(55)
          register_sf4ext(56) register_sf4ext(57) register_sf4ext(58) register_sf4ext(59)
+         register_sf4ext(60)
          #undef register_sf4ext
       }
 
@@ -31474,6 +32335,9 @@
          disable_has_side_effects(*this);
       }
 
+      virtual ~polynomial()
+      {}
+
       inline virtual T operator()(const T& x, const T& c1, const T& c0)
       {
          return ((1 == N) ? poly_impl<T,1>::evaluate(x,c1,c0) : std::numeric_limits<T>::quiet_NaN());
@@ -32704,9 +33568,9 @@
    namespace information
    {
       static const char* library = "Mathematical Expression Toolkit";
-      static const char* version = "2.71828182845904523536028747135"
-                                   "2662497757247093699959574966967";
-      static const char* date    = "20150505";
+      static const char* version = "2.7182818284590452353602874713526"
+                                   "624977572470936999595749669676277";
+      static const char* date    = "20150731";
 
       static inline std::string data()
       {
diff --git a/exprtk_test.cpp b/exprtk_test.cpp
index 93a3d10..e5f7b32 100644
--- a/exprtk_test.cpp
+++ b/exprtk_test.cpp
@@ -32,7 +32,7 @@
 typedef double numeric_type;
 typedef std::pair<std::string,numeric_type> test_t;
 
-static const test_t test_list[] =
+static const test_t global_test_list[] =
                   {
                     // Note: Each of following tests must compile down
                     // to a single literal node.
@@ -1061,7 +1061,7 @@
                     test_t("if (1 > 2) { 1+2; 3;} else if (1 > 2) {1+2; 4;} == null",1.0)
                   };
 
-static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_t);
+static const std::size_t global_test_list_size = sizeof(global_test_list) / sizeof(test_t);
 
 template <typename T>
 inline bool not_equal_impl(const T& t1,
@@ -1165,9 +1165,9 @@
    for (std::size_t r = 0; r < rounds; ++r)
    {
       bool result = true;
-      for (std::size_t i = 0; i < test_list_size; ++i)
+      for (std::size_t i = 0; i < global_test_list_size; ++i)
       {
-         if (!test_expression<T>(test_list[i].first,T(test_list[i].second)))
+         if (!test_expression<T>(global_test_list[i].first,T(global_test_list[i].second)))
          {
             result = false;
          }
@@ -1576,7 +1576,14 @@
                                 test_xy<T>("for(var i := 0; (i < 10) and (i != y); i+=2) { x += i; }; x;" ,T(1),T(20),T(21)),
                                 test_xy<T>("for(var i := 0; (i < 10) and (i != y);) { x += i; i+=2; }; x;",T(1),T(20),T(21)),
                                 test_xy<T>("for(var i := 0; (i < y); i += 1) { if (i <= (y / 2)) x += i; else break; }; x;" ,T(0),T(10),T(15)),
-                                test_xy<T>("for(var i := 0; (i < y); i += 1) { if (i <= (y / 2)) continue; else x += i; }; x;" ,T(0),T(10),T(30))
+                                test_xy<T>("for(var i := 0; (i < y); i += 1) { if (i <= (y / 2)) continue; else x += i; }; x;" ,T(0),T(10),T(30)),
+                                test_xy<T>("var a := 2; (0 * a) == 0",T(0),T(0),T(1)),
+                                test_xy<T>("var a := 2; (0 / a) == 0",T(0),T(0),T(1)),
+                                test_xy<T>("var a := 2; (a * 0) == 0",T(0),T(0),T(1)),
+                                test_xy<T>("var a := 2; (a / 1) == a",T(0),T(0),T(1)),
+                                test_xy<T>("var a := 2; (0 + a) == a",T(0),T(0),T(1)),
+                                test_xy<T>("var a := 2; (a + 0) == a",T(0),T(0),T(1)),
+                                test_xy<T>("var a := 2; (1 * a) == a",T(0),T(0),T(1))
                               };
 
       static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_xy<T>);
@@ -2270,81 +2277,112 @@
                              test_ab<T>("'a\\'\\\\b' == a" ,"a'\\b","",T(1.0)),
                              test_ab<T>("'a\\\\\\'b' == a" ,"a\\'b","",T(1.0)),
                              test_ab<T>("'a\\'\\\\\\\\b' == a" ,"a'\\\\b","",T(1.0)),
-                             test_ab<T>("'a\\0x30\\'\\0x31\\\\\\0x32b' == a" ,"a0'1\\2b","",T(1.0))
+                             test_ab<T>("'a\\0x30\\'\\0x31\\\\\\0x32b' == a" ,"a0'1\\2b","",T(1.0)),
+
+                             test_ab<T>("var x := 3; x > 2 and 'abc' like  '*bc'"   ,"","",T(1.0)),
+                             test_ab<T>("var x := 3; x > 2 and 'abc' ilike '*Bc'"   ,"","",T(1.0)),
+                             test_ab<T>("var x := 3; x > 2 and 'abc' in '123abc123'","","",T(1.0)),
+
+                             test_ab<T>("var x := 3; var s := 'abc'; x > 2 and s like  '*bc'"   ,"","",T(1.0)),
+                             test_ab<T>("var x := 3; var s := 'abc'; x > 2 and s ilike '*Bc'"   ,"","",T(1.0)),
+                             test_ab<T>("var x := 3; var s := 'abc'; x > 2 and s in '123abc123'","","",T(1.0)),
+
+                             test_ab<T>("var x := 3; var s := 'abc'; var t := '*bc'; x > 2 and s like  t"   ,"","",T(1.0)),
+                             test_ab<T>("var x := 3; var s := 'abc'; var t := '*Bc'; x > 2 and s ilike t"   ,"","",T(1.0)),
+                             test_ab<T>("var x := 3; var s := 'abc'; var t := '123abc123'; x > 2 and s in t","","",T(1.0)),
+
+                             test_ab<T>("var x := 3; x > 2 and a like  '*bc'"   ,"abc","",T(1.0)),
+                             test_ab<T>("var x := 3; x > 2 and a ilike '*Bc'"   ,"abc","",T(1.0)),
+                             test_ab<T>("var x := 3; x > 2 and a in '123abc123'","abc","",T(1.0)),
+
+                             test_ab<T>("var x := 3; x > 2 and a like b ","abc","*bc",T(1.0)),
+                             test_ab<T>("var x := 3; x > 2 and a ilike b","abc","*Bc",T(1.0)),
+                             test_ab<T>("var x := 3; x > 2 and a in b   ","abc","123abc123",T(1.0)),
+
+                             test_ab<T>("a[] > 2 and a like  '*bc'"   ,"abc","",T(1.0)),
+                             test_ab<T>("a[] > 2 and a ilike '*Bc'"   ,"abc","",T(1.0)),
+                             test_ab<T>("a[] > 2 and a in '123abc123'","abc","",T(1.0)),
+
+                             test_ab<T>("a[] > 2 and a like b ","abc","*bc",T(1.0)),
+                             test_ab<T>("a[] > 2 and a ilike b","abc","*Bc",T(1.0)),
+                             test_ab<T>("a[] > 2 and a in b   ","abc","123abc123",T(1.0))
                            };
 
    static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_ab<T>);
 
-   const std::size_t rounds = 50;
-   for (std::size_t r = 0; r < rounds; ++r)
    {
-      bool result = true;
+      const std::size_t rounds = 50;
 
-      for (std::size_t i = 0; i < test_list_size; ++i)
+      for (std::size_t r = 0; r < rounds; ++r)
       {
-         test_ab<T>& test = const_cast<test_ab<T>&>(test_list[i]);
+         bool result = true;
 
-         std::string str_a;
-         std::string str_b;
-         std::string str_c;
-
-         T r0 = T(2);
-         T r1 = T(6);
-         T r2 = T(7);
-         T r3 = T(3);
-
-         exprtk::symbol_table<T> symbol_table;
-         symbol_table.add_stringvar("a" ,str_a);
-         symbol_table.add_stringvar("b" ,str_b);
-         symbol_table.add_stringvar("c" ,str_c);
-         symbol_table.add_variable ("r0",   r0);
-         symbol_table.add_variable ("r1",   r1);
-         symbol_table.add_variable ("r2",   r2);
-         symbol_table.add_variable ("r3",   r3);
-
-         exprtk::expression<T> expression;
-         expression.register_symbol_table(symbol_table);
-
+         for (std::size_t i = 0; i < test_list_size; ++i)
          {
-            exprtk::parser<T> parser;
+            test_ab<T>& test = const_cast<test_ab<T>&>(test_list[i]);
 
-            if (!parser.compile(test.expr,expression))
+            std::string str_a;
+            std::string str_b;
+            std::string str_c;
+
+            T r0 = T(2);
+            T r1 = T(6);
+            T r2 = T(7);
+            T r3 = T(3);
+
+            exprtk::symbol_table<T> symbol_table;
+            symbol_table.add_stringvar("a", str_a);
+            symbol_table.add_stringvar("b", str_b);
+            symbol_table.add_stringvar("c", str_c);
+            symbol_table.add_variable("r0", r0);
+            symbol_table.add_variable("r1", r1);
+            symbol_table.add_variable("r2", r2);
+            symbol_table.add_variable("r3", r3);
+
+            exprtk::expression<T> expression;
+            expression.register_symbol_table(symbol_table);
+
             {
-               printf("run_test02() - Error: %s   Expression: %s\n",
-                      parser.error().c_str(),
-                      test.expr.c_str());
+               exprtk::parser<T> parser;
+
+               if (!parser.compile(test.expr, expression))
+               {
+                  printf("run_test02() - Error: %s   Expression: %s\n",
+                     parser.error().c_str(),
+                     test.expr.c_str());
+
+                  result = false;
+                  continue;
+               }
+            }
+
+            str_a = test.a;
+            str_b = test.b;
+            str_c = test.c;
+
+            T expr_result = expression.value();
+
+            if (not_equal(expr_result, test.result))
+            {
+               printf("run_test02() - Computation Error:  Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\t"
+                  "a='%s'\tb='%s'\tc='%s'\n",
+                  test.expr.c_str(),
+                  (double)test.result,
+                  (double)expr_result,
+                  str_a.c_str(),
+                  str_b.c_str(),
+                  str_c.c_str());
 
                result = false;
                continue;
             }
          }
 
-         str_a = test.a;
-         str_b = test.b;
-         str_c = test.c;
-
-         T expr_result = expression.value();
-
-         if (not_equal(expr_result,test.result))
+         if (!result)
          {
-            printf("run_test02() - Computation Error:  Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\t"
-                   "a='%s'\tb='%s'\tc='%s'\n",
-                   test.expr.c_str(),
-                   (double)test.result,
-                   (double)expr_result,
-                   str_a.c_str(),
-                   str_b.c_str(),
-                   str_c.c_str());
-
-            result = false;
-            continue;
+            return false;
          }
       }
-
-      if (!result)
-      {
-         return false;
-      }
    }
 
    {
@@ -2492,6 +2530,117 @@
       expression.value();
    }
 
+   {
+      static const std::string invalid_expr[] =
+                                 {
+                                   "x y",
+                                   "x y z",
+                                   "x y z w",
+                                   "x 1",
+                                   "x 1 2",
+                                   "x 1 2 3",
+                                   "x 'abc'",
+                                   "x 1 'abc'",
+                                   "x 'abc' 1",
+                                   "1 2",
+                                   "1 2 3",
+                                   "1 2 3 4",
+                                   "'abc' 'xyz'",
+                                   "'abc' 1",
+                                   "1 'abc'",
+                                   "x sin(1)",
+                                   "s 'abc'",
+                                   "s x",
+                                   "s y",
+                                   "s 1",
+                                   "s 1 x",
+                                   "s 1 y",
+                                   "s x 1",
+                                   "s y 1",
+                                   "x s ",
+                                   "y s ",
+                                   "1 s ",
+                                   "1 s x",
+                                   "1 s y",
+                                   "x s 1",
+                                   "y s 1",
+                                   "v 'abc'",
+                                   "v x  ",
+                                   "v y  ",
+                                   "v s  ",
+                                   "v 1  ",
+                                   "v 1 x",
+                                   "v 1 y",
+                                   "v 1 s",
+                                   "v x 1",
+                                   "v y 1",
+                                   "v s 1",
+                                   "x v  ",
+                                   "y v  ",
+                                   "1 v  ",
+                                   "1 v x",
+                                   "1 v y",
+                                   "x v 1",
+                                   "y v 1"
+                                 };
+
+      const std::size_t invalid_expr_size = sizeof(invalid_expr) / sizeof(std::string);
+
+      {
+         for (std::size_t i = 0; i < invalid_expr_size; ++i)
+         {
+            exprtk::symbol_table<T> symbol_table;
+
+            exprtk::expression<T> expression;
+
+            T x = T(0);
+            std::string s;
+            std::vector<T> v(10, T(1.234));
+
+            symbol_table.add_variable ("x",x);
+            symbol_table.add_stringvar("s",s);
+            symbol_table.add_vector   ("v",v);
+
+            exprtk::parser<T> parser;
+
+            if (parser.compile(invalid_expr[i],expression))
+            {
+               printf("run_test03() - Error: [1] Invalid expression compiled successfuly.   Expression: %s\n",
+                      invalid_expr[i].c_str());
+
+               return false;
+            }
+         }
+      }
+
+      {
+         T x = T(0);
+         std::string s;
+         std::vector<T> v(10, T(1.234));
+
+         exprtk::symbol_table<T> symbol_table;
+
+         symbol_table.add_variable ("x",x);
+         symbol_table.add_stringvar("s",s);
+         symbol_table.add_vector   ("v",v);
+
+         exprtk::parser<T> parser;
+
+         for (std::size_t i = 0; i < invalid_expr_size; ++i)
+         {
+            exprtk::expression<T> expression;
+
+            if (parser.compile(invalid_expr[i],expression))
+            {
+               printf("run_test03() - Error: [2] Invalid expression compiled successfuly.   Expression: %s\n",
+                      invalid_expr[i].c_str());
+
+               return false;
+            }
+         }
+      }
+   }
+
    return true;
 }
 
@@ -2977,95 +3126,149 @@
    }
 };
 
+double foo1(double v0) { return v0; }
+double foo2(double v0, double v1) { return v0 + v1; }
+double foo3(double v0, double v1, double v2) { return v0 + v1 + v2; }
+double foo4(double v0, double v1, double v2, double v3) { return v0 + v1 + v2 + v3; }
+double foo5(double v0, double v1, double v2, double v3, double v4) { return v0 + v1 + v2 + v3 + v4; }
+
 template <typename T>
 inline bool run_test09()
 {
-   static const std::size_t rounds = 1000;
-   for (std::size_t i = 0; i < rounds; ++i)
    {
-      typedef exprtk::expression<T> expression_t;
-      std::string expression_string = "myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
-                                      "myfunc2(sin(x * pi),y / 2) + myfunc3(sin(x * pi),y / 2)+"
-                                      "myfunc4(sin(x * pi),y / 2) + myfunc5(sin(x * pi),y / 2)+"
-                                      "myfunc6(sin(x * pi),y / 2) + myfunc7(sin(x * pi),y / 2)+"
-                                      "myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)+"
-                                      "myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
-                                      "myfunc2(sin(x * pi),y / 2) + myfunc3(sin(x * pi),y / 2)+"
-                                      "myfunc4(sin(x * pi),y / 2) + myfunc5(sin(x * pi),y / 2)+"
-                                      "myfunc6(sin(x * pi),y / 2) + myfunc7(sin(x * pi),y / 2)+"
-                                      "myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)+"
-                                      "myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
-                                      "myfunc2(sin(x * pi),y / 2) + myfunc3(sin(x * pi),y / 2)+"
-                                      "myfunc4(sin(x * pi),y / 2) + myfunc5(sin(x * pi),y / 2)+"
-                                      "myfunc6(sin(x * pi),y / 2) + myfunc7(sin(x * pi),y / 2)+"
-                                      "myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)+"
-                                      "myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
-                                      "myfunc2(sin(x * pi),y / 2) + myfunc3(sin(x * pi),y / 2)+"
-                                      "myfunc4(sin(x * pi),y / 2) + myfunc5(sin(x * pi),y / 2)+"
-                                      "myfunc6(sin(x * pi),y / 2) + myfunc7(sin(x * pi),y / 2)+"
-                                      "myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)";
-
-      T x = T(1) + (i / T(10000));
-      T y = T(2) + (i / T(10000));
-      myfunc<T> mf;
-
-      exprtk::symbol_table<T> symbol_table;
-      symbol_table.add_variable("x",x);
-      symbol_table.add_variable("y",y);
-      symbol_table.add_function("myfunc0",mf);
-      symbol_table.add_function("myfunc1",mf);
-      symbol_table.add_function("myfunc2",mf);
-      symbol_table.add_function("myfunc3",mf);
-      symbol_table.add_function("myfunc4",mf);
-      symbol_table.add_function("myfunc5",mf);
-      symbol_table.add_function("myfunc6",mf);
-      symbol_table.add_function("myfunc7",mf);
-      symbol_table.add_function("myfunc8",mf);
-      symbol_table.add_function("myfunc9",mf);
-      symbol_table.add_constants();
-
-      expression_t expression;
-      expression.register_symbol_table(symbol_table);
-
+      static const std::size_t rounds = 1000;
+      for (std::size_t i = 0; i < rounds; ++i)
       {
-         exprtk::parser<T> parser;
+         typedef exprtk::expression<T> expression_t;
+         std::string expression_string = "myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
+                                         "myfunc2(sin(x * pi),y / 2) + myfunc3(sin(x * pi),y / 2)+"
+                                         "myfunc4(sin(x * pi),y / 2) + myfunc5(sin(x * pi),y / 2)+"
+                                         "myfunc6(sin(x * pi),y / 2) + myfunc7(sin(x * pi),y / 2)+"
+                                         "myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)+"
+                                         "myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
+                                         "myfunc2(sin(x * pi),y / 2) + myfunc3(sin(x * pi),y / 2)+"
+                                         "myfunc4(sin(x * pi),y / 2) + myfunc5(sin(x * pi),y / 2)+"
+                                         "myfunc6(sin(x * pi),y / 2) + myfunc7(sin(x * pi),y / 2)+"
+                                         "myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)+"
+                                         "myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
+                                         "myfunc2(sin(x * pi),y / 2) + myfunc3(sin(x * pi),y / 2)+"
+                                         "myfunc4(sin(x * pi),y / 2) + myfunc5(sin(x * pi),y / 2)+"
+                                         "myfunc6(sin(x * pi),y / 2) + myfunc7(sin(x * pi),y / 2)+"
+                                         "myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)+"
+                                         "myfunc0(sin(x * pi),y / 2) + myfunc1(sin(x * pi),y / 2)+"
+                                         "myfunc2(sin(x * pi),y / 2) + myfunc3(sin(x * pi),y / 2)+"
+                                         "myfunc4(sin(x * pi),y / 2) + myfunc5(sin(x * pi),y / 2)+"
+                                         "myfunc6(sin(x * pi),y / 2) + myfunc7(sin(x * pi),y / 2)+"
+                                         "myfunc8(sin(x * pi),y / 2) + myfunc9(sin(x * pi),y / 2)";
 
-         if (!parser.compile(expression_string,expression))
+         T x = T(1) + (i / T(10000));
+         T y = T(2) + (i / T(10000));
+         myfunc<T> mf;
+
+         exprtk::symbol_table<T> symbol_table;
+         symbol_table.add_variable("x",x);
+         symbol_table.add_variable("y",y);
+         symbol_table.add_function("myfunc0",mf);
+         symbol_table.add_function("myfunc1",mf);
+         symbol_table.add_function("myfunc2",mf);
+         symbol_table.add_function("myfunc3",mf);
+         symbol_table.add_function("myfunc4",mf);
+         symbol_table.add_function("myfunc5",mf);
+         symbol_table.add_function("myfunc6",mf);
+         symbol_table.add_function("myfunc7",mf);
+         symbol_table.add_function("myfunc8",mf);
+         symbol_table.add_function("myfunc9",mf);
+         symbol_table.add_constants();
+
+         expression_t expression;
+         expression.register_symbol_table(symbol_table);
+
          {
-            printf("run_test09() - Error: %s   Expression: %s\n",
-                   parser.error().c_str(),
-                   expression_string.c_str());
+            exprtk::parser<T> parser;
+
+            if (!parser.compile(expression_string,expression))
+            {
+               printf("run_test09() - Error: %s   Expression: %s\n",
+                      parser.error().c_str(),
+                      expression_string.c_str());
+
+               return false;
+            }
+         }
+
+         const T pi = T(3.141592653589793238462);
+
+         T result = expression.value();
+
+         T expected = T(4) *
+                      (
+                         mf(sin(x*pi),y / T(2)) +
+                         mf(sin(x*pi),y / T(2)) +
+                         mf(sin(x*pi),y / T(2)) +
+                         mf(sin(x*pi),y / T(2)) +
+                         mf(sin(x*pi),y / T(2)) +
+                         mf(sin(x*pi),y / T(2)) +
+                         mf(sin(x*pi),y / T(2)) +
+                         mf(sin(x*pi),y / T(2)) +
+                         mf(sin(x*pi),y / T(2)) +
+                         mf(sin(x*pi),y / T(2))
+                      );
+
+         if (not_equal(result,expected,T(0.0000001)))
+         {
+            printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n",
+                   (double)expected,
+                   (double)result);
 
             return false;
          }
       }
+   }
 
-      const T pi = T(3.141592653589793238462);
+   {
+      typedef exprtk::expression<T>   expression_t;
+      typedef exprtk::symbol_table<T> symbol_table_t;
 
-      T result = expression.value();
+      bool result = true;
 
-      T expected = T(4) *
-                   (
-                      mf(sin(x*pi),y / T(2)) +
-                      mf(sin(x*pi),y / T(2)) +
-                      mf(sin(x*pi),y / T(2)) +
-                      mf(sin(x*pi),y / T(2)) +
-                      mf(sin(x*pi),y / T(2)) +
-                      mf(sin(x*pi),y / T(2)) +
-                      mf(sin(x*pi),y / T(2)) +
-                      mf(sin(x*pi),y / T(2)) +
-                      mf(sin(x*pi),y / T(2)) +
-                      mf(sin(x*pi),y / T(2))
-                   );
+      const std::string expression_list[] =
+                           {
+                             "foo1(1)         == 1",
+                             "foo2(1,2)       == (1 + 2)",
+                             "foo3(1,2,3)     == (1 + 2 + 3)",
+                             "foo4(1,2,3,4)   == (1 + 2 + 3 + 4)",
+                             "foo5(1,2,3,4,5) == (1 + 2 + 3 + 4 + 5)"
+                           };
 
-      if (not_equal(result,expected,T(0.0000001)))
+      const std::size_t expression_list_size = sizeof(expression_list) / sizeof(std::string);
+
+      symbol_table_t symbol_table;
+
+      symbol_table.add_function("foo1",foo1);
+      symbol_table.add_function("foo2",foo2);
+      symbol_table.add_function("foo3",foo3);
+      symbol_table.add_function("foo4",foo4);
+      symbol_table.add_function("foo5",foo5);
+
+      for (std::size_t i = 0; i < expression_list_size; ++i)
       {
-         printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n",
-                (double)expected,
-                (double)result);
+         expression_t expression;
+         expression.register_symbol_table(symbol_table);
 
-         return false;
+         exprtk::parser<T> parser;
+
+         if (!parser.compile(expression_list[i],expression))
+         {
+            printf("run_test09() - Error: %s   Expression: %s\n",
+                   parser.error().c_str(),
+                   expression_list[i].c_str());
+
+            result = false;
+         }
       }
+
+      if (!result)
+         return false;
    }
 
    return true;
@@ -3081,12 +3284,10 @@
    T xx = T(3.3);
    T yy = T(4.4);
 
-   std::string i  = "A String";
-   std::string j  = "Another String";
-   std::string ii = "A String";
-   std::string jj = "Another String";
-
-   exprtk::symbol_table<T> symbol_table;
+   std::string i_s  = "A String";
+   std::string j_s  = "Another String";
+   std::string ii_s = "A String";
+   std::string jj_s = "Another String";
 
    struct test
    {
@@ -3111,361 +3312,365 @@
       }
    };
 
-   static const std::size_t rounds = 10;
-
-   for (std::size_t r = 0; r < rounds; ++r)
    {
-      symbol_table.add_variable("x",  x);
-      symbol_table.add_variable("y",  y);
-      symbol_table.add_variable("xx",xx);
-      symbol_table.add_variable("yy",yy);
+      static const std::size_t rounds = 10;
 
-      if (!symbol_table.symbol_exists("x"))
-      {
-         printf("run_test10() - Symbol 'x' does not exist!\n");
-         return false;
-      }
-      else if (!symbol_table.symbol_exists("y"))
-      {
-         printf("run_test10() - Symbol 'y' does not exist!\n");
-         return false;
-      }
-      else if (!symbol_table.symbol_exists("xx"))
-      {
-         printf("run_test10() - Symbol 'xx' does not exist!\n");
-         return false;
-      }
-      else if (!symbol_table.symbol_exists("yy"))
-      {
-         printf("run_test10() - Symbol 'yy' does not exist!\n");
-         return false;
-      }
-      else if (!test::variable(symbol_table,"x",x))
-      {
-         printf("run_test10() - Symbol 'x' value failure!\n");
-         return false;
-      }
-      else if (!test::variable(symbol_table,"y",y))
-      {
-         printf("run_test10() - Symbol 'y' value failure!\n");
-         return false;
-      }
-      else if (!test::variable(symbol_table,"xx",xx))
-      {
-         printf("run_test10() - Symbol 'xx' value failure!\n");
-         return false;
-      }
-      else if (!test::variable(symbol_table,"yy",yy))
-      {
-         printf("run_test10() - Symbol 'yy' value failure!\n");
-         return false;
-      }
+      exprtk::symbol_table<T> symbol_table;
 
-      if (!symbol_table.remove_variable("x"))
+      for (std::size_t r = 0; r < rounds; ++r)
       {
-         printf("run_test10() - Failed to remove symbol 'x'!\n");
-         return false;
-      }
-      else if (!symbol_table.remove_variable("y"))
-      {
-         printf("run_test10() - Failed to remove symbol 'y'!\n");
-         return false;
-      }
-      else if (!symbol_table.remove_variable("xx"))
-      {
-         printf("run_test10() - Failed to remove symbol 'xx'!\n");
-         return false;
-      }
-      else if (!symbol_table.remove_variable("yy"))
-      {
-         printf("run_test10() - Failed to remove symbol 'yy'!\n");
-         return false;
-      }
-   }
+         symbol_table.add_variable("x", x);
+         symbol_table.add_variable("y", y);
+         symbol_table.add_variable("xx", xx);
+         symbol_table.add_variable("yy", yy);
 
-   for (std::size_t r = 0; r < rounds; ++r)
-   {
-      myfunc<T> mf;
-
-      symbol_table.add_function("f",mf);
-      symbol_table.add_function("f1",mf);
-
-      if (!symbol_table.symbol_exists("f"))
-      {
-         printf("run_test10() - function 'f' does not exist!\n");
-         return false;
-      }
-      else if (!symbol_table.symbol_exists("f1"))
-      {
-         printf("run_test10() - function 'f1' does not exist!\n");
-         return false;
-      }
-
-      if (!symbol_table.remove_function("f"))
-      {
-         printf("run_test10() - Failed to remove function 'f'!\n");
-         return false;
-      }
-      else if (!symbol_table.remove_function("f1"))
-      {
-         printf("run_test10() - Failed to remove function 'f1'!\n");
-         return false;
-      }
-   }
-
-   for (std::size_t r = 0; r < rounds; ++r)
-   {
-      symbol_table.add_stringvar("i",i);
-      symbol_table.add_stringvar("j",j);
-
-      symbol_table.add_stringvar("ii",ii);
-      symbol_table.add_stringvar("jj",jj);
-
-      if (!symbol_table.symbol_exists("i"))
-      {
-         printf("run_test10() - String 'i' does not exist!\n");
-         return false;
-      }
-      else if (!symbol_table.symbol_exists("j"))
-      {
-         printf("run_test10() - String 'j' does not exist!\n");
-         return false;
-      }
-      else if (!symbol_table.symbol_exists("ii"))
-      {
-         printf("run_test10() - String 'ii' does not exist!\n");
-         return false;
-      }
-      else if (!symbol_table.symbol_exists("jj"))
-      {
-         printf("run_test10() - String 'jj' does not exist!\n");
-         return false;
-      }
-      else if (!test::string(symbol_table,"i",i))
-      {
-         printf("run_test10() - String 'i' value failure!\n");
-         return false;
-      }
-      else if (!test::string(symbol_table,"j",j))
-      {
-         printf("run_test10() - String 'j' value failure!\n");
-         return false;
-      }
-      else if (!test::string(symbol_table,"ii",ii))
-      {
-         printf("run_test10() - String 'ii' value failure!\n");
-         return false;
-      }
-      else if (!test::string(symbol_table,"jj",jj))
-      {
-         printf("run_test10() - String 'jj' value failure!\n");
-         return false;
-      }
-      else if (!symbol_table.remove_stringvar("i"))
-      {
-         printf("run_test10() - Failed to remove String 'i'!\n");
-         return false;
-      }
-      else if (!symbol_table.remove_stringvar("j"))
-      {
-         printf("run_test10() - Failed to remove String 'j'!\n");
-         return false;
-      }
-      else if (!symbol_table.remove_stringvar("ii"))
-      {
-         printf("run_test10() - Failed to remove String 'ii'!\n");
-         return false;
-      }
-      else if (!symbol_table.remove_stringvar("jj"))
-      {
-         printf("run_test10() - Failed to remove String 'jj'!\n");
-         return false;
-      }
-   }
-
-   for (std::size_t r = 0; r < rounds; ++r)
-   {
-      symbol_table.add_variable("x",  x);
-      symbol_table.add_variable("y",  y);
-      symbol_table.add_variable("xx",xx);
-      symbol_table.add_variable("yy",yy);
-
-      std::vector<std::string> expected_var_list;
-
-      expected_var_list.push_back( "x");
-      expected_var_list.push_back( "y");
-      expected_var_list.push_back("xx");
-      expected_var_list.push_back("yy");
-
-      std::deque<std::pair<std::string,T> > variable_list;
-
-      symbol_table.get_variable_list(variable_list);
-
-      if (variable_list.size() != expected_var_list.size())
-      {
-         printf("run_test10() - Failed to get variable list (1)\n");
-         return false;
-      }
-
-      std::size_t found_count = 0;
-
-      for (std::size_t i = 0; i < variable_list.size(); ++i)
-      {
-         for (std::size_t j = 0; j < expected_var_list.size(); ++j)
+         if (!symbol_table.symbol_exists("x"))
          {
-            if (variable_list[i].first == expected_var_list[j])
-            {
-               ++found_count;
-               break;
-            }
+            printf("run_test10() - Symbol 'x' does not exist!\n");
+            return false;
+         }
+         else if (!symbol_table.symbol_exists("y"))
+         {
+            printf("run_test10() - Symbol 'y' does not exist!\n");
+            return false;
+         }
+         else if (!symbol_table.symbol_exists("xx"))
+         {
+            printf("run_test10() - Symbol 'xx' does not exist!\n");
+            return false;
+         }
+         else if (!symbol_table.symbol_exists("yy"))
+         {
+            printf("run_test10() - Symbol 'yy' does not exist!\n");
+            return false;
+         }
+         else if (!test::variable(symbol_table, "x", x))
+         {
+            printf("run_test10() - Symbol 'x' value failure!\n");
+            return false;
+         }
+         else if (!test::variable(symbol_table, "y", y))
+         {
+            printf("run_test10() - Symbol 'y' value failure!\n");
+            return false;
+         }
+         else if (!test::variable(symbol_table, "xx", xx))
+         {
+            printf("run_test10() - Symbol 'xx' value failure!\n");
+            return false;
+         }
+         else if (!test::variable(symbol_table, "yy", yy))
+         {
+            printf("run_test10() - Symbol 'yy' value failure!\n");
+            return false;
+         }
+
+         if (!symbol_table.remove_variable("x"))
+         {
+            printf("run_test10() - Failed to remove symbol 'x'!\n");
+            return false;
+         }
+         else if (!symbol_table.remove_variable("y"))
+         {
+            printf("run_test10() - Failed to remove symbol 'y'!\n");
+            return false;
+         }
+         else if (!symbol_table.remove_variable("xx"))
+         {
+            printf("run_test10() - Failed to remove symbol 'xx'!\n");
+            return false;
+         }
+         else if (!symbol_table.remove_variable("yy"))
+         {
+            printf("run_test10() - Failed to remove symbol 'yy'!\n");
+            return false;
          }
       }
 
-      if (found_count != expected_var_list.size())
+      for (std::size_t r = 0; r < rounds; ++r)
       {
-         printf("run_test10() - Failed to get variable list (2)\n");
-         return false;
-      }
-   }
+         myfunc<T> mf;
 
-   for (std::size_t r = 0; r < rounds; ++r)
-   {
-      symbol_table.add_variable("x",  x);
-      symbol_table.add_variable("y",  y);
-      symbol_table.add_variable("xx",xx);
-      symbol_table.add_variable("yy",yy);
+         symbol_table.add_function("f", mf);
+         symbol_table.add_function("f1", mf);
 
-      std::vector<std::string> expected_var_list;
-
-      expected_var_list.push_back( "x");
-      expected_var_list.push_back( "y");
-      expected_var_list.push_back("xx");
-      expected_var_list.push_back("yy");
-
-      std::deque<std::string> variable_list;
-
-      symbol_table.get_variable_list(variable_list);
-
-      if (variable_list.size() != expected_var_list.size())
-      {
-         printf("run_test10() - Failed to get variable list (3)\n");
-         return false;
-      }
-
-      std::size_t found_count = 0;
-
-      for (std::size_t i = 0; i < variable_list.size(); ++i)
-      {
-         for (std::size_t j = 0; j < expected_var_list.size(); ++j)
+         if (!symbol_table.symbol_exists("f"))
          {
-            if (variable_list[i] == expected_var_list[j])
-            {
-               ++found_count;
-               break;
-            }
+            printf("run_test10() - function 'f' does not exist!\n");
+            return false;
+         }
+         else if (!symbol_table.symbol_exists("f1"))
+         {
+            printf("run_test10() - function 'f1' does not exist!\n");
+            return false;
+         }
+
+         if (!symbol_table.remove_function("f"))
+         {
+            printf("run_test10() - Failed to remove function 'f'!\n");
+            return false;
+         }
+         else if (!symbol_table.remove_function("f1"))
+         {
+            printf("run_test10() - Failed to remove function 'f1'!\n");
+            return false;
          }
       }
 
-      if (found_count != expected_var_list.size())
+      for (std::size_t r = 0; r < rounds; ++r)
       {
-         printf("run_test10() - Failed to get variable list (4)\n");
-         return false;
-      }
-   }
+         symbol_table.add_stringvar("i", i_s);
+         symbol_table.add_stringvar("j", j_s);
 
-   for (std::size_t r = 0; r < rounds; ++r)
-   {
-      symbol_table.add_stringvar( "i", i);
-      symbol_table.add_stringvar( "j", j);
-      symbol_table.add_stringvar("ii",ii);
-      symbol_table.add_stringvar("jj",jj);
+         symbol_table.add_stringvar("ii", ii_s);
+         symbol_table.add_stringvar("jj", jj_s);
 
-      std::vector<std::string> expected_var_list;
-
-      expected_var_list.push_back( "i");
-      expected_var_list.push_back( "j");
-      expected_var_list.push_back("ii");
-      expected_var_list.push_back("jj");
-
-      std::deque<std::pair<std::string,std::string> > stringvar_list;
-
-      symbol_table.get_stringvar_list(stringvar_list);
-
-      if (stringvar_list.size() != expected_var_list.size())
-      {
-         printf("run_test10() - Failed to get stringvar list (1)\n");
-         return false;
-      }
-
-      std::size_t found_count = 0;
-
-      for (std::size_t i = 0; i < stringvar_list.size(); ++i)
-      {
-         for (std::size_t j = 0; j < expected_var_list.size(); ++j)
+         if (!symbol_table.symbol_exists("i"))
          {
-            if (stringvar_list[i].first == expected_var_list[j])
-            {
-               ++found_count;
-               break;
-            }
+            printf("run_test10() - String 'i' does not exist!\n");
+            return false;
+         }
+         else if (!symbol_table.symbol_exists("j"))
+         {
+            printf("run_test10() - String 'j' does not exist!\n");
+            return false;
+         }
+         else if (!symbol_table.symbol_exists("ii"))
+         {
+            printf("run_test10() - String 'ii' does not exist!\n");
+            return false;
+         }
+         else if (!symbol_table.symbol_exists("jj"))
+         {
+            printf("run_test10() - String 'jj' does not exist!\n");
+            return false;
+         }
+         else if (!test::string(symbol_table, "i", i_s))
+         {
+            printf("run_test10() - String 'i' value failure!\n");
+            return false;
+         }
+         else if (!test::string(symbol_table, "j", j_s))
+         {
+            printf("run_test10() - String 'j' value failure!\n");
+            return false;
+         }
+         else if (!test::string(symbol_table, "ii", ii_s))
+         {
+            printf("run_test10() - String 'ii' value failure!\n");
+            return false;
+         }
+         else if (!test::string(symbol_table, "jj", jj_s))
+         {
+            printf("run_test10() - String 'jj' value failure!\n");
+            return false;
+         }
+         else if (!symbol_table.remove_stringvar("i"))
+         {
+            printf("run_test10() - Failed to remove String 'i'!\n");
+            return false;
+         }
+         else if (!symbol_table.remove_stringvar("j"))
+         {
+            printf("run_test10() - Failed to remove String 'j'!\n");
+            return false;
+         }
+         else if (!symbol_table.remove_stringvar("ii"))
+         {
+            printf("run_test10() - Failed to remove String 'ii'!\n");
+            return false;
+         }
+         else if (!symbol_table.remove_stringvar("jj"))
+         {
+            printf("run_test10() - Failed to remove String 'jj'!\n");
+            return false;
          }
       }
 
-      if (found_count != expected_var_list.size())
+      for (std::size_t r = 0; r < rounds; ++r)
       {
-         printf("run_test10() - Failed to get stringvar list (2)\n");
-         return false;
-      }
-   }
+         symbol_table.add_variable("x", x);
+         symbol_table.add_variable("y", y);
+         symbol_table.add_variable("xx", xx);
+         symbol_table.add_variable("yy", yy);
 
-   for (std::size_t r = 0; r < rounds; ++r)
-   {
-      symbol_table.add_stringvar( "i", i);
-      symbol_table.add_stringvar( "j", j);
-      symbol_table.add_stringvar("ii",ii);
-      symbol_table.add_stringvar("jj",jj);
+         std::vector<std::string> expected_var_list;
 
-      std::vector<std::string> expected_var_list;
+         expected_var_list.push_back("x");
+         expected_var_list.push_back("y");
+         expected_var_list.push_back("xx");
+         expected_var_list.push_back("yy");
 
-      expected_var_list.push_back( "i");
-      expected_var_list.push_back( "j");
-      expected_var_list.push_back("ii");
-      expected_var_list.push_back("jj");
+         std::deque<std::pair<std::string, T> > variable_list;
 
-      std::deque<std::string> stringvar_list;
+         symbol_table.get_variable_list(variable_list);
 
-      symbol_table.get_stringvar_list(stringvar_list);
-
-      if (stringvar_list.size() != expected_var_list.size())
-      {
-         printf("run_test10() - Failed to get stringvar list (3.0)\n");
-         return false;
-      }
-
-      if (symbol_table.stringvar_count() != expected_var_list.size())
-      {
-         printf("run_test10() - Failed to get stringvar list (3.1)\n");
-         return false;
-      }
-
-      std::size_t found_count = 0;
-
-      for (std::size_t i = 0; i < stringvar_list.size(); ++i)
-      {
-         for (std::size_t j = 0; j < expected_var_list.size(); ++j)
+         if (variable_list.size() != expected_var_list.size())
          {
-            if (stringvar_list[i] == expected_var_list[j])
+            printf("run_test10() - Failed to get variable list (1)\n");
+            return false;
+         }
+
+         std::size_t found_count = 0;
+
+         for (std::size_t i = 0; i < variable_list.size(); ++i)
+         {
+            for (std::size_t j = 0; j < expected_var_list.size(); ++j)
             {
-               ++found_count;
-               break;
+               if (variable_list[i].first == expected_var_list[j])
+               {
+                  ++found_count;
+                  break;
+               }
             }
          }
+
+         if (found_count != expected_var_list.size())
+         {
+            printf("run_test10() - Failed to get variable list (2)\n");
+            return false;
+         }
       }
 
-      if (found_count != expected_var_list.size())
+      for (std::size_t r = 0; r < rounds; ++r)
       {
-         printf("run_test10() - Failed to get stringvar list (4)\n");
-         return false;
+         symbol_table.add_variable("x", x);
+         symbol_table.add_variable("y", y);
+         symbol_table.add_variable("xx", xx);
+         symbol_table.add_variable("yy", yy);
+
+         std::vector<std::string> expected_var_list;
+
+         expected_var_list.push_back("x");
+         expected_var_list.push_back("y");
+         expected_var_list.push_back("xx");
+         expected_var_list.push_back("yy");
+
+         std::deque<std::string> variable_list;
+
+         symbol_table.get_variable_list(variable_list);
+
+         if (variable_list.size() != expected_var_list.size())
+         {
+            printf("run_test10() - Failed to get variable list (3)\n");
+            return false;
+         }
+
+         std::size_t found_count = 0;
+
+         for (std::size_t i = 0; i < variable_list.size(); ++i)
+         {
+            for (std::size_t j = 0; j < expected_var_list.size(); ++j)
+            {
+               if (variable_list[i] == expected_var_list[j])
+               {
+                  ++found_count;
+                  break;
+               }
+            }
+         }
+
+         if (found_count != expected_var_list.size())
+         {
+            printf("run_test10() - Failed to get variable list (4)\n");
+            return false;
+         }
+      }
+
+      for (std::size_t r = 0; r < rounds; ++r)
+      {
+         symbol_table.add_stringvar("i", i_s);
+         symbol_table.add_stringvar("j", j_s);
+         symbol_table.add_stringvar("ii", ii_s);
+         symbol_table.add_stringvar("jj", jj_s);
+
+         std::vector<std::string> expected_var_list;
+
+         expected_var_list.push_back("i");
+         expected_var_list.push_back("j");
+         expected_var_list.push_back("ii");
+         expected_var_list.push_back("jj");
+
+         std::deque<std::pair<std::string, std::string> > stringvar_list;
+
+         symbol_table.get_stringvar_list(stringvar_list);
+
+         if (stringvar_list.size() != expected_var_list.size())
+         {
+            printf("run_test10() - Failed to get stringvar list (1)\n");
+            return false;
+         }
+
+         std::size_t found_count = 0;
+
+         for (std::size_t i = 0; i < stringvar_list.size(); ++i)
+         {
+            for (std::size_t j = 0; j < expected_var_list.size(); ++j)
+            {
+               if (stringvar_list[i].first == expected_var_list[j])
+               {
+                  ++found_count;
+                  break;
+               }
+            }
+         }
+
+         if (found_count != expected_var_list.size())
+         {
+            printf("run_test10() - Failed to get stringvar list (2)\n");
+            return false;
+         }
+      }
+
+      for (std::size_t r = 0; r < rounds; ++r)
+      {
+         symbol_table.add_stringvar("i", i_s);
+         symbol_table.add_stringvar("j", j_s);
+         symbol_table.add_stringvar("ii", ii_s);
+         symbol_table.add_stringvar("jj", jj_s);
+
+         std::vector<std::string> expected_var_list;
+
+         expected_var_list.push_back("i");
+         expected_var_list.push_back("j");
+         expected_var_list.push_back("ii");
+         expected_var_list.push_back("jj");
+
+         std::deque<std::string> stringvar_list;
+
+         symbol_table.get_stringvar_list(stringvar_list);
+
+         if (stringvar_list.size() != expected_var_list.size())
+         {
+            printf("run_test10() - Failed to get stringvar list (3.0)\n");
+            return false;
+         }
+
+         if (symbol_table.stringvar_count() != expected_var_list.size())
+         {
+            printf("run_test10() - Failed to get stringvar list (3.1)\n");
+            return false;
+         }
+
+         std::size_t found_count = 0;
+
+         for (std::size_t i = 0; i < stringvar_list.size(); ++i)
+         {
+            for (std::size_t j = 0; j < expected_var_list.size(); ++j)
+            {
+               if (stringvar_list[i] == expected_var_list[j])
+               {
+                  ++found_count;
+                  break;
+               }
+            }
+         }
+
+         if (found_count != expected_var_list.size())
+         {
+            printf("run_test10() - Failed to get stringvar list (4)\n");
+            return false;
+         }
       }
    }
 
@@ -3977,6 +4182,9 @@
         "2 == for (var i := 0; i < 10; i += 1) { if (i > 2) { continue; return [i * 8];"
         "i += 1; i += 2; i += 3; } else i; }",
 
+        "var x[10] := [-1]; var y[10] := [-1]; for (var i := 0; i < 10; i += 1) { x[i] := i; "
+        "y[i] := 2 * x[i]; }; (sum(x) == 45) and (sum(y) == (2 * sum(x)));"
+
         "7 == (for (var i := 0; i < 10; i += 1) { ~{break[7]; continue; i += i} })",
         "0 == (for (var i := 0; i < 10; i += 1) { ~{break[i]; continue; i += i} })",
         "0 == (for (var i := 0; i < 10; i += 1) { ~{continue; break[7]; i += i} })",
@@ -4932,6 +5140,8 @@
    va_func()
    {
       exprtk::enable_zero_parameters(*this);
+      exprtk::set_min_num_args(*this,  0);
+      exprtk::set_max_num_args(*this, 20);
    }
 
    inline T operator()(const std::vector<T>& arglist)
@@ -5084,12 +5294,13 @@
 template <typename T>
 struct rem_space_and_uppercase : public exprtk::igeneric_function<T>
 {
-   typedef typename exprtk::igeneric_function<T>::generic_type generic_type;
-   typedef typename exprtk::igeneric_function<T>::parameter_list_t parameter_list_t;
-   typedef typename generic_type::string_view string_t;
+   typedef typename exprtk::igeneric_function<T> igenfunc_t;
+   typedef typename igenfunc_t::generic_type     generic_type;
+   typedef typename igenfunc_t::parameter_list_t parameter_list_t;
+   typedef typename generic_type::string_view    string_t;
 
    rem_space_and_uppercase()
-   : exprtk::igeneric_function<T>("S")
+   : igenfunc_t("S",igenfunc_t::e_rtrn_string)
    {}
 
    inline T operator()(std::string& result, parameter_list_t params)
@@ -5104,7 +5315,7 @@
       for (std::size_t i = 0; i < string.size(); ++i)
       {
          if (' ' != (c = string[i]))
-            result += std::toupper(c);
+            result += static_cast<char>(std::toupper(c));
       }
 
       return T(0);
@@ -5613,7 +5824,7 @@
       symbol_table.add_stringvar("s3", s3);
       symbol_table.add_stringvar("s4", s4);
 
-      symbol_table.add_function("remspc_uc",rsauc,symbol_table_t::e_ft_strfunc);
+      symbol_table.add_function("remspc_uc",rsauc);
 
       std::string program = " s0 := 'How now ';                                   "
                             " s1 := 'brown cow?';                                 "
diff --git a/readme.txt b/readme.txt
index a3f3ecd..ce2c8d1 100644
--- a/readme.txt
+++ b/readme.txt
@@ -610,9 +610,9 @@
 ExprTk supports three fundamental types which can be used freely in
 expressions. The types are as follows:
 
-   1. Scalar
-   2. Vector
-   3. String
+   (1) Scalar
+   (2) Vector
+   (3) String
 
 
 (1) Scalar Type
@@ -706,7 +706,7 @@
    expression.value(); // 3.7 * -9 + 3
 
    // 'x * -9 + 3' for x in range of [0,100) in steps of 0.0001
-   for (x = 0; x < 100; x += 0.0001)
+   for (x = 0.0; x < 100.0; x += 0.0001)
    {
       expression.value(); // x * -9 + 3
    }
@@ -860,7 +860,10 @@
    (i) '*' '='  --->  '*='  (multiplication assignment)
    (j) '/' '='  --->  '/='  (division assignment)
    (k) '%' '='  --->  '%='  (modulo assignment)
-   (l) '<=' '>' --->  '<=>' (swap)
+   (l) '+' '-'  --->  '-'   (subtraction)
+   (m) '-' '+'  --->  '-'   (subtraction)
+   (n) '-' '-'  --->  '+'   (addition)
+   (o) '<=' '>' --->  '<=>' (swap)
 
 
 An example of the transformation that takes place is as follows:
@@ -926,7 +929,7 @@
 attempt at computing the average  between x and y will  be transformed
 as follows:
 
-   (x * 0.5) + (y * 0.5) ---> 0.5 * (x + y)
+   (0.5 * x) + (y * 0.5) ---> 0.5 * (x + y)
 
 There  may be  situations where  the above  transformation will  cause
 numerical overflows and  that the original  form of the  expression is
@@ -1216,11 +1219,15 @@
 
 There are five types of function interface:
 
-   (1) ifunction
-   (2) ivararg_function
-   (3) igeneric_function
-   (4) igeneric_function II
-   (5) function_compositor
+   +---+----------------------+-------------+
+   | # |         Name         | Return Type |
+   +---+----------------------+-------------+
+   | 1 | ifunction            | Scalar      |
+   | 2 | ivararg_function     | Scalar      |
+   | 3 | igeneric_function    | Scalar      |
+   | 4 | igeneric_function II | String      |
+   | 5 | function_compositor  | Scalar      |
+   +---+----------------------+-------------+
 
 
 (1) ifunction
@@ -1446,17 +1453,21 @@
       typedef typename generic_t::string_view string_t;
 
       toupper()
-      : exprtk::igeneric_function<T>("S")
+      : exprtk::igeneric_function<T>("S",igenfunct_t::e_rtrn_string)
       {}
 
       inline T operator()(std::string& result,
                           parameter_list_t parameters)
       {
          result.clear();
+
+         string_t string(params[0]);
+
          for (std::size_t i = 0; i < string.size(); ++i)
          {
             result += std::toupper(string[i]);
          }
+
          return T(0);
       }
    };
@@ -1464,27 +1475,27 @@
 
 In the example above the  generic function 'toupper' expects only  one
 input parameter  of type  string, as  noted by  the parameter sequence
-string passed during the constructor. When executed, the function will
-return as a result a copy  of the input string converted to  uppercase
-form. An example expression  using the toupper function  registered as
-the symbol 'toupper' is as follows:
+string passed during the  constructor. Furthermore a second  parameter
+is passed to the constructor indicating that it should be treated as a
+string returning function -  by default it is  assumed to be a  scalar
+returning function.
+
+When executed,  the function  will return  as a  result a  copy of the
+input string converted to uppercase form. An example expression  using
+the toupper function registered as the symbol 'toupper' is as follows:
 
    "'ABCDEF' == toupper('aBc') + toupper('DeF')"
 
 
 Note: When adding a string type returning generic function to a symbol
-table,  the  'add_function'  is   invoked  with  an  extra   parameter
-(e_ft_strfunc) that denotes the function should be treated as a string
-returning function type. The  following example demonstrates how  this
-is done:
+table the  'add_function' is invoked.  The example  below demonstrates
+how this can be done:
 
    toupper<T> tu;
 
    exprtk::symbol_table<T> symbol_table;
 
-   symbol_table.add_function("toupper",
-                             tu,
-                             symbol_table_t::e_ft_strfunc);
+   symbol_table.add_function("toupper",tu);
 
 
 Note: Two further  refinements to the  type checking facility  are the
@@ -1689,7 +1700,7 @@
    {
       foo() : exprtk::ifunction<T>(3)
       {
-         disable_has_side_effects(*this);
+          exprtk::disable_has_side_effects(*this);
       }
 
       T operator()(const T& v1, const T& v2, const T& v3)
@@ -1757,6 +1768,14 @@
 completed, the  caller can  then obtain  a list  of symbols  and their
 associated types from the DEC.
 
+The kinds of  questions one can  ask regarding the  dependent entities
+within an expression are as follows:
+
+  * What user defined or local variables, vectors or strings are used?
+  * What functions or custom user functions are used?
+  * Which variables, vectors or strings have values assigned to them?
+
+
 The following example demonstrates usage of the DEC in determining the
 dependents of the given expression:
 
@@ -1766,9 +1785,15 @@
    std::string expression_string =
                   "z := abs(x + sin(2 * pi / y))";
 
+   T x,y,z;
+
    parser_t parser;
    symbol_table_t symbol_table;
 
+   symbol_table.add_variable("x",x);
+   symbol_table.add_variable("y",y);
+   symbol_table.add_variable("z",z);
+
    expression_t expression;
    expression.register_symbol_table(symbol_table);
 
@@ -1799,7 +1824,7 @@
    }
 
 
-Note: The  'symbol_t' type  is a  pair comprising  of the  symbol name
+Note: The 'symbol_t' type is a std::pair comprising of the symbol name
 (std::string) and the associated type of the symbol as denoted by  the
 cases in the switch statement.
 
@@ -1866,6 +1891,9 @@
    (1) Base Functions
    (2) Control Flow Structures
    (3) Logical Operators
+   (4) Arithmetic Operators
+   (5) Inequality Operators
+   (6) Assignment Operators
 
 
 (1) Base Functions
@@ -1967,13 +1995,13 @@
        " }                                ";
 
     parser.settings()
-      .disable_all_control_structures(settings_t::e_ctrl_for_loop);
+      .disable_control_structure(settings_t::e_ctrl_for_loop);
 
     parser
       .compile(program,expression); // failure
 
     parser.settings()
-      .enable_all_control_structures(settings_t::e_ctrl_for_loop);
+      .enable_control_structure(settings_t::e_ctrl_for_loop);
 
     parser
       .compile(program,expression); // success
@@ -2009,18 +2037,158 @@
     expression_t expression;
 
     parser.settings()
-      .disable_base_function(settings_t::e_logic_and);
+      .disable_logic_operation(settings_t::e_logic_and);
 
     parser
       .compile("1 or not(0 and 1)",expression); // failure
 
     parser.settings()
-      .enable_base_function(settings_t::e_logic_and);
+      .enable_logic_operation(settings_t::e_logic_and);
 
     parser
       .compile("1 or not(0 and 1)",expression); // success
 
 
+(4) Arithmetic Operators
+The list of available arithmetic operators is as follows:
+
+   +, -, *, /, %, ^
+
+
+The  above  mentioned  arithmetic  operators  can  be  either  enabled or
+disabled 'all' at once, as is demonstrated below:
+
+    parser_t parser;
+    expression_t expression;
+
+    parser.settings().disable_all_arithmetic_ops();
+
+    parser
+      .compile("1 + 2 / 3",expression); // compilation failure
+
+    parser.settings().enable_all_arithmetic_ops();
+
+    parser
+      .compile("1 + 2 / 3",expression); // compilation success
+
+
+One can also enable or disable specific arithmetic operators. The  following
+example demonstrates the disabling of  the addition '+' arithmetic operator:
+
+    parser_t parser;
+    expression_t expression;
+
+    parser.settings()
+      .disable_arithmetic_operation(settings_t::e_arith_add);
+
+    parser
+      .compile("1 + 2 / 3",expression); // failure
+
+    parser.settings()
+      .enable_arithmetic_operation(settings_t::e_arith_add);
+
+    parser
+      .compile("1 + 2 / 3",expression); // success
+
+
+(5) Inequality Operators
+The list of available inequality operators is as follows:
+
+   <, <=, >, >=, ==, =, != <>
+
+
+The  above  mentioned  inequality  operators  can  be  either  enabled or
+disabled 'all' at once, as is demonstrated below:
+
+    parser_t parser;
+    expression_t expression;
+
+    parser.settings().disable_all_inequality_ops();
+
+    parser
+      .compile("1 < 3",expression); // compilation failure
+
+    parser.settings().enable_all_inequality_ops();
+
+    parser
+      .compile("1 < 3",expression); // compilation success
+
+
+One can also enable or disable specific inequality operators. The  following
+example demonstrates the disabling of the less-than '<' inequality operator:
+
+    parser_t parser;
+    expression_t expression;
+
+    parser.settings()
+      .disable_inequality_operation(settings_t::e_ineq_lt);
+
+    parser
+      .compile("1 < 3",expression); // failure
+
+    parser.settings()
+      .enable_inequality_operation(settings_t::e_ineq_lt);
+
+    parser
+      .compile("1 < 3",expression); // success
+
+
+(6) Assignment Operators
+The list of available assignment operators is as follows:
+
+   :=, +=, -=, *=, /=, %=
+
+
+The  above  mentioned  assignment  operators  can  be  either  enabled or
+disabled 'all' at once, as is demonstrated below:
+
+    parser_t parser;
+    expression_t expression;
+    symbol_table_t symbol_table;
+
+    T x = T(0);
+
+    symbol_table.add_variable("x",x);
+
+    expression.register_symbol_table(symbol_table);
+
+    parser.settings().disable_all_assignment_ops();
+
+    parser
+      .compile("x := 3",expression); // compilation failure
+
+    parser.settings().enable_all_assignment_ops();
+
+    parser
+      .compile("x := 3",expression); // compilation success
+
+
+One can also enable or disable specific assignment operators. The  following
+example demonstrates the disabling of the '+=' addition assignment operator:
+
+    parser_t parser;
+    expression_t expression;
+    symbol_table_t symbol_table;
+
+    T x = T(0);
+
+    symbol_table.add_variable("x",x);
+
+    expression.register_symbol_table(symbol_table);
+
+    parser.settings()
+      .disable_assignment_operation(settings_t::e_assign_addass);
+
+    parser
+      .compile("x += 3",expression); // failure
+
+    parser.settings()
+      .enable_assignment_operation(settings_t::e_assign_addass);
+
+    parser
+      .compile("x += 3",expression); // success
+
+
 Note: In the event of a base function being disabled, one can redefine
 the  base  function  using  the  standard  custom  function definition
 process. In the  following example the 'sin' function is disabled then
@@ -2161,7 +2329,7 @@
    if (!parser.compile(expression_string,expression))
    {
       printf("Error: %s\n", parser.error().c_str());
-      return 1;
+      return false;
    }
 
 
@@ -2189,7 +2357,7 @@
                 error.diagnostic.c_str());
       }
 
-      return 1;
+      return false;
    }
 
 
@@ -2214,7 +2382,7 @@
                 error.column_no);
       }
 
-      return 1;
+      return false;
    }
 
 
@@ -2530,7 +2698,15 @@
 When building ExprTk there are a number of defines that will enable or
 disable certain features and  capabilities. The defines can  either be
 part of a compiler command line switch or scoped around the include to
-the ExprTk header.
+the ExprTk header. The defines are as follows:
+
+   (1) exprtk_enable_debugging
+   (2) exprtk_disable_comments
+   (3) exprtk_disable_break_continue
+   (4) exprtk_disable_sc_andor
+   (5) exprtk_disable_enhanced_features
+   (6) exprtk_disable_string_capabilities
+
 
 (1) exprtk_enable_debugging
 This define will enable printing of debug information to stdout during