Logo Search packages:      
Sourcecode: sagcad version File versions  Download package

StringCulc.c

/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 * 
 *    Project              : SagCAD
 *    Description          : CAD/CAM
 *    Source               : StringCulc.c
 * 
 *    ----------------------------------
 * 
 *    License              : GNU General Public License (GPL)
 *    Copyright            : (C) 1998-2007 by Yutaka Sagiya
 *    email                : kappa@a6s.highway.ne.jp
 *                         : yutaka@sagiya.com
 *    Begin                : 2000/12/05
 *    Last                 : 2007/11/08
 * ====================================================================
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#include "culcfunc.h"
#define _STRINGCULC_
#include "StringCulc.h"



#ifdef DOCUMENT
      式は項を「+」or「-」でつないだもの。
      項は因子を「*」or「/」でつないだもの。
      因子は数あるいは '()' で囲んだ式
#endif



//#define TEST_MODE
#ifdef TEST_MODE
/* -------------------------------------------------------------------
 * main
 */
int main(void)
{
      char str[256];

      printf(" > ");
      scanf( "%s", str);
      printf("%s = %f\n", str, StringCulc(str));

      return 1;
}
#endif



/* -------------------------------------------------------------------
 * 式の計算をして返す
 */
double StringCulc(char *expression)
{
      double ans;

      sprintf(Buf, "%s", expression);
//    if (s_stxchk())
//    {
//          printf("文法エラーです。\n");
//          ans = 0;
//    }
//    else
//    {
            Pos = 0;
            ans = s_getexp();
//    }
      return ans;
}



/* -------------------------------------------------------------------
 * 式の計算
 */
double s_getexp(void)
{
      double ans;

      /* 項の評価関数呼び出し */
      ans = s_gettrm();
      while (1) {
            if (Buf[Pos] == '+' || Buf[Pos] == '-') {
                  Pos++;
            }
            else {
                  break;
            }

            /* 項を加・減算する */
            if (Buf[Pos - 1] == '+') {
                  ans = ans + s_gettrm();
            }
            else {
                  ans = ans - s_gettrm();
            }
      }
      return ans;
}



/* -------------------------------------------------------------------
 * 項の評価関数
 */
double s_gettrm(void)
{
      double ans;

      /* 因子の評価関数呼び出し */
      ans = s_getfct();
      while (1) {
            if (Buf[Pos] == '*' || Buf[Pos] == '/') {
                  Pos++;
            }
            else {
                  break;
            }

            /* 因子を乗・除算する */
            if (Buf[Pos - 1] == '*') {
                  ans = ans * s_getfct();
            }
            else {
                  ans = ans / s_getfct();
            }
      }
      return ans;
}



/* -------------------------------------------------------------------
 * 因子の評価関数
 */
double s_getfct(void)
{
      double ans;

      /* 「(」 でないなら */
      if (Buf[Pos] != '(') {
            return (s_getnum());
      }
      /* 「(」 なら */
      Pos++;
      ans = s_getexp();
      Pos++;

      return ans;
}



/* -------------------------------------------------------------------
 * 数の評価関数
 */
double s_getnum(void)
{
      double ans, poch;
      int sign = '+';
      int keta = 3;

      if (Buf[Pos] == '+' || Buf[Pos] == '-' )
            sign = Buf[Pos++];

      /* 因子の評価関数呼び出し */
      if (Buf[Pos] == '(') {
            ans = s_getfct();
      }

      /* 関数を評価し数値に変更 */
      /* sin */
      else if (   Buf[Pos] == 's' && 
                        Buf[Pos + 1] == 'i' && 
                        Buf[Pos + 2] == 'n' && 
                        Buf[Pos + 3] == '(')
      {
            Pos = Pos + 3;
            ans = sin(s_getfct() * (3.14159265358979 / 180));
      }

      /* cos */
      else if (   Buf[Pos] == 'c' && 
                        Buf[Pos + 1] == 'o' && 
                        Buf[Pos + 2] == 's' && 
                        Buf[Pos + 3] == '(')
      {
            Pos = Pos + 3;
            ans = cos(s_getfct() * (3.14159265358979 / 180));
      }
      /* tan */
      else if (   Buf[Pos] == 't' && 
                        Buf[Pos + 1] == 'a' && 
                        Buf[Pos + 2] == 'n' && 
                        Buf[Pos + 3] == '(')
      {
            Pos = Pos + 3;
            ans = tan(s_getfct() * (3.14159265358979 / 180));
      }
      /* atan */
      else if (   Buf[Pos] == 'a' && 
                        Buf[Pos + 1] == 't' && 
                        Buf[Pos + 2] == 'a' && 
                        Buf[Pos + 3] == 'n' && 
                        Buf[Pos + 4] == '(')
      {
            Pos = Pos + 4;
            ans = atan(s_getfct() * (3.14159265358979 / 180));
      }
      /* sqrt */
      else if (   Buf[Pos] == 's' && 
                        Buf[Pos + 1] == 'q' && 
                        Buf[Pos + 2] == 'r' && 
                        Buf[Pos + 3] == 't' && 
                        Buf[Pos + 4] == '(')
      {
            Pos = Pos + 4;
            ans = sqrt(s_getfct());
      }
      /* abs */
      else if (   Buf[Pos] == 'a' && 
                        Buf[Pos + 1] == 'b' && 
                        Buf[Pos + 2] == 's' && 
                        Buf[Pos + 3] == '(')
      {
            Pos = Pos + 3;
            ans = fabs(s_getfct());
      }
      /* round */
      else if (   Buf[Pos] == 'r' && 
                        Buf[Pos + 1] == 'o' && 
                        Buf[Pos + 2] == 'u' && 
                        Buf[Pos + 3] == 'n' && 
                        Buf[Pos + 4] == 'd' && 
                        Buf[Pos + 5] == '(')
      {
            Pos = Pos + 5;
            ans = sg(s_getfct(), keta);
      }

#ifdef AFTER // --------------------------------------------
      /* fix */
      else if (   Buf[Pos] == 'f' && 
                        Buf[Pos + 1] == 'i' && 
                        Buf[Pos + 2] == 'x' && 
                        Buf[Pos + 3] == '(')
      {
            Pos = Pos + 3;
// floor   ceil
            ans = Fix(s_getfct());
      }
      /* fup */
      else if (   Buf[Pos] == 'f' && 
                        Buf[Pos + 1] == 'u' && 
                        Buf[Pos + 2] == 'p' && 
                        Buf[Pos + 3] == '(')
      {
            Pos = Pos + 3;
            TEST = s_getfct();
            if (TEST != Fix(TEST))
                  ans = Fix(TEST) + 1;
            else
                  ans = TEST;
            ans = Fix(s_getfct());
      }
#endif // --------------------------------------------------



      else {
            ans = Buf[Pos++] - '0';
            while (isdigit(Buf[Pos])) {
                  ans = 10 * ans + Buf[Pos++] - '0';
            }
            if (Buf[Pos] == '.') {
                  poch = 1;
                  Pos++;
                  while(isdigit(Buf[Pos]))
                        ans += (poch /= 10) * (Buf[Pos++] - '0');
            }
      }
      if(sign == '-')
            return (-1 * ans);
      else
            return ans;
}



/* -------------------------------------------------------------------
 * 式のチェック
 */
int s_stxchk(void)
{
      char *search, str[256];
      int i, j, chk = 0;

      sprintf(str, "%s", Buf);


      /* sin */
      search = strstr(str,"sin");
      if (search != NULL) {
            i = search - str;
            str[i] = ' ';
            str[i+1] = ' ';
            str[i+2] = ' ';
      }

      /* cos */
      search = strstr(str,"cos");
      if (search != NULL) {
            i = search - str;
            str[i] = ' ';
            str[i+1] = ' ';
            str[i+2] = ' ';
      }

      /* tan */
      search = strstr(str,"tan");
      if (search != NULL) {
            i = search - str;
            str[i] = ' ';
            str[i+1] = ' ';
            str[i+2] = ' ';
      }

      /* atan */
      search = strstr(str,"atan");
      if (search != NULL) {
            i = search - str;
            str[i] = ' ';
            str[i+1] = ' ';
            str[i+2] = ' ';
            str[i+3] = ' ';
      }

      /* sqrt */
      search = strstr(str,"sqrt");
      if (search != NULL) {
            i = search - str;
            str[i] = ' ';
            str[i+1] = ' ';
            str[i+2] = ' ';
            str[i+3] = ' ';
      }

      /* abs */
      search = strstr(str,"abs");
      if (search != NULL) {
            i = search - str;
            str[i] = ' ';
            str[i+1] = ' ';
            str[i+2] = ' ';
      }

      /* round */
      search = strstr(str,"round");
      if (search != NULL) {
            i = search - str;
            str[i] = ' ';
            str[i+1] = ' ';
            str[i+2] = ' ';
            str[i+3] = ' ';
            str[i+4] = ' ';
      }

      /* fix */
      search = strstr(str,"fix");
      if (search != NULL) {
            i = search - str;
            str[i] = ' ';
            str[i+1] = ' ';
            str[i+2] = ' ';
      }

      /* fup */
      search = strstr(str,"fup");
      if (search != NULL) {
            i = search - str;
            str[i] = ' ';
            str[i+1] = ' ';
            str[i+2] = ' ';
      }

      for(i = j = 0 ; str[i] != '\0' ; i++) {
            if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' || 
                  str[i] == '.' || str[i] == '(' || str[i] == ')' || isdigit(str[i]))
                  str[j++] = str[i];
            else if (!isspace(str[i]))
                  return -1;
            if (str[i] == '(')
                  chk++;
            if (str[i] == ')')
                  chk--;
      }
      str[j] = '\0';
      return chk;
}



/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 *    Project              : StringCulc
 *    Source               : StringCulc.c
 * ====================================================================
 */

Generated by  Doxygen 1.6.0   Back to index