Ask Question

Name:
Title:
Your Question:

Answer Question

Name:
Your Answer:
User Submitted Source Code!


Description:
  calc_var
Language: C/C++
Code:
#include "stdafx.h"
#include "calc_var.h"




//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

calc_var::calc_var()
{
     memset(Function,0,256);
     pCurrPos=Function;
     ClearVars();//обнуление переменных

}

calc_var::~calc_var()
{

}

calc_var::calc_var(char *lpszFunction)
{
     SetFunction(lpszFunction);
     ClearVars();
}

void calc_var::ClearVars()
{
     memset(variables,0,sizeof(double)*27);
}

double calc_var::prim()
{
     GetToken();
     switch(CurrTok)
     {
     case NUMBER:
          {
               double temp=atof(TokenValue);
               GetToken();
               return temp;
          }
     case VARIABLE:
          {
               char c=*TokenValue;/*Выделили певрую букву из переменной*/
               if(*pCurrPos=='=')
               {
                    *pCurrPos++;//Увеличиваем указатель, теперь он указывает на начало следующей после '=' лексемы
                    variables[c-'A']=add_sub();
               }
               GetToken();
               return variables[c-'A'];
          }
     case OPERATOR:
          {
               switch(*TokenValue)
               {
                    case '-':return -prim();
                    case '+':return prim();
                    case '(':
                         {
                              double temp=add_sub();
                              if(*TokenValue!=')') throw(SyntaxError(") expected"));
                              GetToken();
                              return temp;
                         }
               }//end switch(TokenValue)
               throw(SyntaxError("Incorrect operator"));
          }//end case OPERATOR
     case FUNC:
          {
     
               if(strcmp(TokenValue,"pi")==0){GetToken(); return 3.1415926535;}
               if(strcmp(TokenValue,"abs")==0)return fabs(prim());
               if(strcmp(TokenValue,"sin")==0)return sin(prim());
               if(strcmp(TokenValue,"cos")==0)return cos(prim());
               if(strcmp(TokenValue,"tg")==0)//тангенс
               {
                    double angle=prim();
                    double temp= cos(angle);
                    if(temp==0) throw(MathError("can't calculate tg"));
                    return sin(angle)/temp;

               }
               if (strcmp(TokenValue,"ctg")==0)
               {
                    double angle=prim();
                    double temp= sin(angle);
                    if(temp==0) throw(MathError("can't calculate сtg"));
                    return cos(angle)/temp;

               }
               if (strcmp(TokenValue,"ln")==0)
               {
                    double temp=prim();
                    if(temp<=0) throw(MathError("argument of lg is <= zero"));
                    return log(temp);
               }
               if (strcmp(TokenValue,"exp")==0) return exp(prim());
               if (strcmp(TokenValue,"asin")==0)
               {
                    double temp=prim();
                    if(temp<-1||temp>1)throw(MathError("argument of asin is out of ranges"));
                    return asin(temp);
               }
               if (strcmp(TokenValue,"acos")==0)
               {
                    double temp=prim();
                    if(temp<-1||temp>1)throw(MathError("argument of acos is out of ranges"));
                    return acos(temp);
               }
               throw(SyntaxError("Incorrect function"));
          }
     case PRINT://обрабатываем конец локального выражения(заканчивающегося ;
     case END: return 0;
     default:throw(SyntaxError("No Expression"));
     }

}

void calc_var::GetToken()
{
     if((!pCurrPos)||(!*pCurrPos)){ CurrTok=END; *TokenValue=0; return;}//конец выражения
     while((*pCurrPos==' ')||(*pCurrPos=='\n')||(*pCurrPos=='\r'))pCurrPos++;//Пропускаем пробелы в начале
//     TokenValue=UNDEF; //для отладки
     
     char* temp=TokenValue;
     if(isdigit(*pCurrPos))
     {
          CurrTok=NUMBER;
          while(isdigit(*pCurrPos)||(*pCurrPos=='.'))*temp++=*pCurrPos++;
//          *temp=0;

     }
     else if(strchr("+-*/%^()",*pCurrPos))
     {
          CurrTok=OPERATOR;
          //перейти к следующему символу
          *temp++=*pCurrPos++;//занесли в TokenValue оператор
//          *temp=0;
     }
     else if(islower(*pCurrPos))//проверка на функцию. функции можна записывать только маленькими буквами
     {
          while(islower(*pCurrPos))*temp++=*pCurrPos++;
          CurrTok=FUNC;
     }
     else if(isupper(*pCurrPos))//проверка на переменную. Переменные состоят только из болших букв. значима только первая буква
     {
          while(isupper(*pCurrPos))*temp++=*pCurrPos++;
          CurrTok=VARIABLE;
     }
     else if(*pCurrPos==';')
     {
          CurrTok=PRINT;
     }
     else CurrTok=END;
     *temp=0;
}

double calc_var::proceed()//функция, управляющая вычислением
{
     if (strlen(Function)<1) throw(SyntaxError("No Expression"));
     double t;
     CurrTok=PRINT;
     while (CurrTok!=END)
     {
          t=add_sub();
          if(CurrTok==PRINT)*pCurrPos++;
     }
     return t;//принимаем список операция, разделенных ; возвращаем результат последней операции
}
Comments: