/// <summary>
        ///     <Factor>::=  <number> | ( <expr> ) | {+|-} <factor>
        ///           <variable> | TRUE | FALSE
        /// </summary>
        public Exp Factor(ProcedureBuilder ctx)
        {
            TOKEN l_token;
            Exp   RetValue = null;



            if (Current_Token == TOKEN.TOK_NUMERIC)
            {
                RetValue      = new NumericConstant(GetNumber());
                Current_Token = GetToken();
            }
            else if (Current_Token == TOKEN.TOK_STRING)
            {
                RetValue      = new StringLiteral(last_str);
                Current_Token = GetToken();
            }
            else if (Current_Token == TOKEN.TOK_BOOL_FALSE ||
                     Current_Token == TOKEN.TOK_BOOL_TRUE)
            {
                RetValue = new BooleanConstant(
                    Current_Token == TOKEN.TOK_BOOL_TRUE ? true : false);
                Current_Token = GetToken();
            }
            else if (Current_Token == TOKEN.TOK_OPAREN)
            {
                Current_Token = GetToken();

                RetValue = BExpr(ctx);  // Recurse

                if (Current_Token != TOKEN.TOK_CPAREN)
                {
                    Console.WriteLine("Missing Closing Parenthesis\n");
                    throw new CParserException(-100, "Missing Closing Parenthesis\n", SaveIndex());
                }
                Current_Token = GetToken();
            }

            else if (Current_Token == TOKEN.TOK_PLUS || Current_Token == TOKEN.TOK_SUB)
            {
                l_token       = Current_Token;
                Current_Token = GetToken();
                RetValue      = Factor(ctx);
                if (l_token == TOKEN.TOK_PLUS)
                {
                    RetValue = new UnaryPlus(RetValue);
                }
                else
                {
                    RetValue = new UnaryMinus(RetValue);
                }
            }
            else if (Current_Token == TOKEN.TOK_NOT)
            {
                l_token       = Current_Token;
                Current_Token = GetToken();
                RetValue      = Factor(ctx);

                RetValue = new LogicalNot(RetValue);
            }
            else if (Current_Token == TOKEN.TOK_UNQUOTED_STRING)
            {
                String str = base.last_str;


                if (!prog.IsFunction(str))
                {
                    //
                    // if it is not a function..it ought to
                    // be a variable...
                    SYMBOL_INFO inf = ctx.GetSymbol(str);

                    if (inf == null)
                    {
                        throw new CParserException(-100, "Undefined symbol " + str, SaveIndex());
                    }

                    if (inf.Type != TYPE_INFO.TYPE_ARRAY &&
                        inf.Type != TYPE_INFO.TYPE_MAP)
                    {
                        GetNext();
                        return(new Variable(inf));
                    }

                    if (inf.Type == TYPE_INFO.TYPE_ARRAY)
                    {
                        GetNext();
                        if (Current_Token != TOKEN.TOK_OSUBSCRIPT)
                        {
                            CSyntaxErrorLog.AddLine("[ expected");
                            CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                            throw new CParserException(-100, "[ expected", SaveIndex());
                        }
                        GetNext();
                        Exp index = BExpr(ctx);
                        if (Current_Token != TOKEN.TOK_CSUBSCRIPT)
                        {
                            CSyntaxErrorLog.AddLine("] expected");
                            CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                            throw new CParserException(-100, "] expected", SaveIndex());
                        }

                        GetNext();
                        return(new IndexedExp(new IndexedVariable(inf, index, null)));
                    }
                    else
                    {
                        GetNext();

                        if (Current_Token != TOKEN.TOK_OSUBSCRIPT)
                        {
                            CSyntaxErrorLog.AddLine("[ expected");
                            CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                            throw new CParserException(-100, "[ expected", SaveIndex());
                        }
                        GetNext();
                        Exp index = BExpr(ctx);

                        if (Current_Token != TOKEN.TOK_CSUBSCRIPT)
                        {
                            CSyntaxErrorLog.AddLine("] expected");
                            CSyntaxErrorLog.AddLine(GetCurrentLine(SaveIndex()));
                            throw new CParserException(-100, "] expected", SaveIndex());
                        }

                        GetNext();
                        return(new HashExp(new HashedVariable(inf, index, null)));
                    }
                }

                //
                // P can be null , if we are parsing a
                // recursive function call
                //
                Procedure p = prog.GetProc(str);
                // It is a Function Call
                // Parse the function invocation
                //
                Exp ptr = ParseCallProc(ctx, p);
                GetNext();
                return(ptr);
            }



            else
            {
                //Console.WriteLine("Illegal Token");
                throw new CParserException(-100, "Illegal Token", SaveIndex());
            }


            return(RetValue);
        }
        /// <summary>
        ///     <Factor>::=  <number> | ( <expr> ) | {+|-} <factor>
        ///           <variable> | TRUE | FALSE
        /// </summary>
        public Exp Factor(ProcedureBuilder ctx)
        {
            TOKEN l_token;
            Exp   RetValue = null;



            if (Current_Token == TOKEN.TOK_NUMERIC)
            {
                RetValue      = new NumericConstant(GetNumber());
                Current_Token = GetToken();
            }
            else if (Current_Token == TOKEN.TOK_STRING)
            {
                RetValue      = new StringLiteral(last_str);
                Current_Token = GetToken();
            }
            else if (Current_Token == TOKEN.TOK_BOOL_FALSE ||
                     Current_Token == TOKEN.TOK_BOOL_TRUE)
            {
                RetValue = new BooleanConstant(
                    Current_Token == TOKEN.TOK_BOOL_TRUE ? true : false);
                Current_Token = GetToken();
            }
            else if (Current_Token == TOKEN.TOK_OPAREN)
            {
                Current_Token = GetToken();

                RetValue = Expr(ctx);  // Recurse

                if (Current_Token != TOKEN.TOK_CPAREN)
                {
                    Console.WriteLine("Missing Closing Parenthesis\n");
                    throw new Exception();
                }
                Current_Token = GetToken();
            }

            else if (Current_Token == TOKEN.TOK_PLUS || Current_Token == TOKEN.TOK_SUB)
            {
                l_token       = Current_Token;
                Current_Token = GetToken();
                RetValue      = Factor(ctx);
                if (l_token == TOKEN.TOK_PLUS)
                {
                    RetValue = new UnaryPlus(RetValue);
                }
                else
                {
                    RetValue = new UnaryMinus(RetValue);
                }
            }
            else if (Current_Token == TOKEN.TOK_UNQUOTED_STRING)
            {
                ///
                ///  Variables
                ///
                String      str = base.last_str;
                SYMBOL_INFO inf = ctx.TABLE.Get(str);

                if (inf == null)
                {
                    throw new Exception("Undefined symbol");
                }

                GetNext();
                RetValue = new Variable(inf);
            }



            else
            {
                Console.WriteLine("Illegal Token");
                throw new Exception();
            }


            return(RetValue);
        }