/**
         * Parse the given expression
         * @param new_expr   A string containing an expression, for example "2+3"
         * @return ans       A string containing the answer, or an error when
         *                   an error occurred
         */
        public String ParseAndEval(String new_expr, ICheckModelName checkModelName, JongErrWarn errW)
        {
            try
            {
                _checkModelName = checkModelName;

                // initialize all variables
                expr = new_expr;
                ans  = 0.0;

                // Pare the expression into a function tree format
                JongFunction function = parse_start();

                String dbgString = FuncToString(function, "    ", "----", errW);
                dbgString += "\n";

                //System.out.print(dbgString);

                // evaluate the expression
                ans = function.eval();


                if (function is JongFunctionAssign)
                {
                    // function assignment
                    JongFunctionAssign fa   = (JongFunctionAssign)function;
                    String             desc = "";
                    desc += fa.getName();
                    desc += "(";
                    for (int i = 0; i < fa.getVariables().Count(); i++)
                    {
                        if (i > 0)
                        {
                            desc += ", ";
                        }
                        desc += fa.getVariables().ElementAt(i).getName();
                    }
                    desc += ")";

                    ans_str = "Function " + desc + " defined";
                }
                else if (function is JongVariableAssign)
                {
                    // variable assignment
                    JongVariableAssign JongVariableAssign = (JongVariableAssign)function;
                    ans_str = string.Format("%s = %g",
                                            JongVariableAssign.getName(),
                                            ans);

                    // add the answer to memory as variable "Ans"
                    variablelist["ANS"] = ans;
                }
                else
                {
                    //DecimalFormat formatter = new DecimalFormat("#.##########");
                    ans_str = string.Format("{0:#.##########}", ans);

                    // add the answer to memory as variable "Ans"
                    variablelist["ANS"] = ans;
                }
            }
            catch (JongError err)
            {
                errW.Init(ErrWStat.UNKNOWN_ERROR, err.get(), false);
                ans_str = err.get();
                expr    = "";
            }

            return(ans_str);
        }
        /*
         * assignment of variable, for example "a = 3.4/2"
         */
        private JongFunction parse_function_ass() //throws JongError
        {
            if (token_type == TOKENTYPE.FUNCTION)
            {
                // check for a function assignment like "f(a,b)=a*b"

                // copy current token (we may have to revert to it)
                char      t_now          = t;
                int       t_pos_now      = t_pos;
                TOKENTYPE token_type_now = token_type;
                String    token_now      = token;

                String name = token;        //.ToUpper();

                getToken();
                if (token.Equals("("))
                {
                    // possible assignment of a function.
                    // Verify this by checking if it has the form "f(a,b,c,...)="
                    bool hasCorrectParams = true;
                    localvariablelist = new List <JongLocalVariable>();
                    while (true)
                    {
                        getToken();
                        if (token_type != TOKENTYPE.VARIABLE)
                        {
                            // wrong, we would have expected a variable name.
                            // So this is no function assignment.
                            hasCorrectParams = false;
                            break;
                        }

                        // add this variable to the local variable list
                        String var_name = token;        //.ToUpper();
                        localvariablelist.Add(new JongLocalVariable(var_name));

                        getToken();
                        if (token.Equals(")"))
                        {
                            // closing parenthesis found
                            hasCorrectParams = true;
                            break;
                        }

                        if (!token.Equals(","))
                        {
                            // wrong, we would have expected a comma.
                            // So this is no function assignment.
                            hasCorrectParams = false;
                            break;
                        }
                    }

                    if (hasCorrectParams)
                    {
                        getToken();

                        if (token.Equals("="))
                        {
                            // we have a function assignment like "f(a,b)=a*b"

                            // assign a new function
                            // note: the localvariablelinks will be copied and owned by
                            // the assigned function. We do not need to delete the links
                            getToken();
                            JongFunctionAssign function =
                                new JongFunctionAssign(functionlist,
                                                       name,
                                                       localvariablelist,
                                                       parse_conditions());

                            return(function);
                        }
                    }

                    // Function not assigned. Clear the created local variables
                    localvariablelist.Clear();

                    // revert to previous token
                    t          = t_now;
                    t_pos      = t_pos_now;
                    token_type = token_type_now;
                    token      = token_now;
                }
            }

            return(parse_conditions());
        }