home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / Dloads / PROGRAMM / CTUTOR.ZIP / SOURCE.ZIP / DATA.C < prev    next >
Text File  |  1986-05-27  |  15KB  |  448 lines

  1. /*    DATA.C   DATA.C    DATA.C    DATA.C    DATA.C    DATA.C
  2.  
  3. DATA INITIALIZE AND CALCULATE      XXXX     X    XXXXX    X
  4.                                    X   X   X X     X     X X
  5. May 27, 1986                       X   X  X   X    X    X   X
  6.                                    X   X  X   X    X    X   X
  7.                                    X   X  XXXXX    X    XXXXX
  8.                                    X   X  X   X    X    X   X
  9.                                    XXXX   X   X    X    X   X
  10. */
  11. #include "ctype.h"
  12. #include "struct.def"
  13. extern struct vars allvars[];
  14. extern char inline[];
  15. extern int col;
  16. extern int errcode,colerr;
  17. extern char strngout[];
  18. extern int valattr;
  19.  
  20. /* ****************************************************** initdata */
  21. /* This function is used to initialize all of the variables to the */
  22. /* starting values including their variable names.                 */
  23. initdata(pnt)
  24. struct vars *pnt;
  25. {
  26. int index;
  27.     for (index = 0;index < 6;++index){
  28.        (pnt+index)->varname[0] = 'A' + index;
  29.        (pnt+index)->varname[1] = 0;
  30.        (pnt+index)->outtype = 'F';
  31.        (pnt+index)->value = 0.0;
  32.     }
  33.     for (index = 6;index < 12;++index){
  34.        (pnt+index)->varname[0] = 'I' + index - 6;
  35.        (pnt+index)->varname[1] = 0;
  36.        (pnt+index)->outtype = 'D';
  37.        (pnt+index)->value = 0;
  38.     } 
  39.     (pnt+4)->value = 2.718281828459045;
  40.     (pnt+5)->value = 3.141592653589793;
  41.     (pnt+11)->value = 16777215;
  42. }
  43.  
  44. /* ******************************************************* getnames */
  45. /* This function reads in a new list of variable names to be used   */
  46. /* in place of the names A to F. This is only as a convenience for  */
  47. /* the user, so he can use more meaningful names.                   */
  48. getnames()
  49. {
  50. char var,index;
  51. char dummy[80];
  52.  
  53.    col = 1;                      /* skip over and ignore the # sign */
  54.    do {
  55.       if (inline[col] == ' ') col++;   /* ignore all leading blanks */
  56.       else {
  57.          var = inline[col] - 'A';
  58.          if ((var >= 0) && (var <= 5)) {             /* A through F */
  59.             col++;
  60.             if (inline[col] != '-') {           /* should be a dash */
  61.                errchk(14);
  62.                errout();
  63.                return;
  64.             }
  65.             col++;
  66.             for (index = 0;index < 6;index++)
  67.                if (isalpha(inline[col]) || isdigit(inline[col])) {
  68.                   dummy[index] = inline[col];
  69.                   dummy[index + 1] = 0;
  70.                   col++;
  71.                }
  72.             if (index > 0) {
  73.                strcpy(allvars[var].varname,dummy);
  74.                strcpy(strngout,"      ");         /* this is for    */
  75.                strngout[6-strlen(dummy)] = 0;     /* leading blanks */
  76.                strcat(strngout,dummy);
  77.                strngdis(var + 1,1,valattr); 
  78.             }
  79.          }
  80.          else if ((var >= 8) && (var <= 13)) {       /* I through N */
  81.             col++;
  82.             if (inline[col] != '-') {           /* should be a dash */
  83.                errchk(14);
  84.                errout();
  85.                return;
  86.             }
  87.             col++;
  88.             if ((inline[col] == 'O') || (inline[col] == 'D') ||
  89.                 (inline[col] == 'H') || (inline[col] == 'X')) {
  90.                var -= 2;
  91.                allvars[var].outtype = inline[col];
  92.                col++;
  93.             }
  94.             else {
  95.                errchk(15);
  96.                errout();
  97.                return;
  98.             }
  99.          }
  100.          else {                            /* unknown variable name */
  101.             errchk(3);
  102.             errout();
  103.             return;
  104.          }
  105.       }
  106.    } while (inline[col] && (errcode == 0));
  107. }
  108.  
  109. /* ******************************************************* calcdata */
  110. /* This is the function that actually does the work of deciding     */
  111. /* what calculations need to be done. The method used is described  */
  112. /* in detail below.                                                 */
  113. /*    Three variables and two operators are         number1         */
  114. /*    stored as per the list. "op1" is always         op1           */
  115. /*    a plus or minus, and op2 is always a          number2         */
  116. /*    multiplication or divide. If a plus or          op2           */
  117. /*    minus is found for op2, number1 and           number3         */
  118. /*    number2 are combined according to op1                         */
  119. /*    and the result becomes number1, the new op2 becomes op1, and  */
  120. /*    number3 becomes number2. If op2 is either a multiplication or */
  121. /*    divide, number2 and number3 are combined according to op2 and */
  122. /*    the result is placed in number2. When a parentheses is found, */
  123. /*    a recursive call is made and the expression in the parenthe-  */
  124. /*    ses is evaluated. A bit of study will be very fruitful in     */
  125. /*    understanding this operation.                                 */
  126. calcdata(newval)
  127. double *newval;
  128. {
  129. double number1,number2,number3,getnum();
  130. char op1,op2,getop();
  131.    number1 = 0.0;
  132.    op1 = '+';
  133.    number2 = 0.0;
  134.    while (inline[col] == ' ') col++;               /* ignore blanks */
  135.                                         /* check for unary operator */
  136.    if ((inline[col] == '+') || (inline[col] == '-')) {
  137.       op1 = inline[col];
  138.       col++;
  139.    }
  140.  
  141.    number2 = getnum();          /* (inline[col]== 0 ) = End of line */
  142.                                 /* (inline[col]=='$') = End of line */
  143.    if ((inline[col] == 0) || (inline[col] =='$')) {
  144.       calcdat(&number1,&op1,&number2);
  145.       *newval = number1;
  146.       return;
  147.    }
  148.    for (;;){
  149.       op2 = getop(); 
  150.       col++;
  151.                                /* check for end of line  0, ), or $ */
  152.       if (op2 == '$') op2 = 0;        /* force a $ to lool like eol */
  153.       if ((op2 == 0) || (op2 == ')')) {
  154.          col++;
  155.          calcdat(&number1,&op1,&number2);
  156.          *newval = number1;
  157.          return;
  158.       }
  159.       number3 = getnum();
  160.       if ((op2 == '*') || (op2 == '/')){
  161.          calcdat(&number2,&op2,&number3);
  162.       }
  163.       else{
  164.          calcdat(&number1,&op1,&number2);
  165.          op1 = op2;
  166.          number2 = number3;
  167.       }
  168.    } /* end of infinite for loop */   
  169. }
  170.  
  171. /* ******************************************************** calcdat */
  172. /* This function actually does the calculations described in the    */
  173. /* function above.                                                  */
  174. calcdat(number1,op1,number2)
  175. double *number1,*number2;
  176. char *op1;
  177. {
  178.    switch (*op1) {
  179.       case '*' : *number1 = (*number1)*(*number2);
  180.                  break;
  181.       case '/' : if (*number2 == 0.0) {
  182.                      errchk(10);
  183.                      break;
  184.                  }
  185.                  *number1 = (*number1)/(*number2);
  186.                  break;
  187.       case '+' : *number1 = *number1 + *number2;
  188.                  break;
  189.       case '-' : *number1 = *number1 - *number2;
  190.                  break;
  191.       default  : break;
  192.    }
  193.    return;
  194. }
  195.  
  196. /* ********************************************************* getnum */
  197. /* This is the workhorse of the program. It actually scans the data */
  198. /* input field and converts the data into numbers which are in the  */
  199. /* internal format of the computer so the calculations can be done. */
  200. double getnum()
  201. {
  202. int index,i,decpt;
  203. double newval;
  204. char name[7];
  205. double sqrt(), exp(), log(), sin(), cos(), atan();
  206.  
  207.    while (inline[col] == ' ') col++;               /* ignore blanks */
  208.  
  209.    index = inline[col];
  210.    if (index == '('){
  211.        col++;
  212.        calcdata(&newval);                         /* recursive call */
  213.        col--;
  214.        return(newval);
  215.    }
  216.  
  217.    decpt = 0;                         /* search for a decimal point */
  218.    i = col;
  219.    index = inline[i];
  220.    while ((index >= '0') && (index <= '9')) {
  221.       i++;
  222.       index = inline[i];
  223.       if (index == '.') decpt = 1;
  224.    }
  225.  
  226.    index = inline[col];
  227.    if (((index > '0') && (index <= '9')) ||
  228.        ((index == '0') && (decpt == 1))  ||
  229.         (index == '.')) {                        /* floating number */
  230.       newval = 0.0;
  231.       while ((index >= '0') && (index <= '9')) {
  232.          newval = 10.0*newval + (index - '0');
  233.          col++;
  234.          index = inline[col];
  235.       }
  236.       if (index == '.') {
  237.          double const = 0.1;
  238.          col++;
  239.          index = inline[col];
  240.          while ((index >= '0') && (index <= '9')) {
  241.             newval = newval + (index - '0') * const;
  242.             const = const * .1;
  243.             col++;
  244.             index = inline[col];
  245.          }
  246.       }
  247.       return(newval);
  248.    }                                /* end of floating point number */
  249.  
  250.    if (index == '0') {                      /* octal or hexadecimal */
  251.       col++;
  252.       index = inline[col];
  253.       if ((index == 'x') || (index == 'X')){         /* hexadecimal */
  254.          col++;
  255.          index = inline[col];
  256.          newval = 0.0;
  257.          while (((index >= '0') && (index <= '9')) ||
  258.                 ((index >= 'A') && (index <= 'F')) ||
  259.                 ((index >= 'a') && (index <= 'f'))) {
  260.             switch (index) {
  261.                case '0':
  262.                case '1':
  263.                case '2':
  264.                case '3':
  265.                case '4':
  266.                case '5':
  267.                case '6':
  268.                case '7':
  269.                case '8':
  270.                case '9':i = index - '0';
  271.                         break;
  272.                case 'A':
  273.                case 'B':
  274.                case 'C':
  275.                case 'D':
  276.                case 'E':
  277.                case 'F':i = index - 'A' + 10;
  278.                         break;
  279.                case 'a':
  280.                case 'b':
  281.                case 'c':
  282.                case 'd':
  283.                case 'e':
  284.                case 'f':i = index - 'a' + 10;
  285.                         break;
  286.                default :break;
  287.             }
  288.             newval = 16.0*newval + i;
  289.             col++;
  290.             index = inline[col];
  291.          }
  292.       return(newval);
  293.       }                                  /* end of hexadecimal 'if' */
  294.  
  295.       else {                                               /* octal */
  296.          newval = 0.0;
  297.          while ((index >= '0') && (index <= '7')) {
  298.             newval = 8.0*newval + (index - '0');
  299.             col++;
  300.             index = inline[col];
  301.          }
  302.       return(newval);
  303.       }                                      /* end of octal 'else' */
  304.     
  305.    }                         /* end of octal or hexadecimal numbers */   
  306.  
  307.                                   /* find variable or function name */
  308.    if ((inline[col] >= 'A') && (inline[col] <= 'Z')) {
  309.       name[0] = inline[col++];
  310.       i = 1;
  311.       while ((((inline[col] >= 'A') && (inline[col] <= 'Z')) ||
  312.              ((inline[col] >= '0') && (inline[col] <= '9'))) &&
  313.              (i <= 5)) {           /* continue var or function name */
  314.          name[i++] = inline[col++];
  315.       }
  316.       name[i] = 0;                                    /* name found */
  317.  
  318.       if (inline[col] == '('){                     /* function call */
  319.          col++;
  320.          if (strcmp(name,"ABS") == 0) {
  321.             calcdata(&newval);
  322.             if (newval < 0.0) newval = -newval;
  323.          }
  324.          else if (strcmp(name,"SQRT") == 0) {
  325.             calcdata(&newval);
  326.             if (newval < 0.0) {
  327.                errchk(5);                     /* Neg value for SQRT */
  328.                newval = 0.0;
  329.             }
  330.             else newval = sqrt(newval);
  331.          }
  332.          else if (strcmp(name,"FACT") == 0) {
  333.             calcdata(&newval);
  334.             if (newval < 0.0) {
  335.                errchk(16);                    /* Neg value for FACT */
  336.                newval = 0.0;
  337.             }
  338.             else {
  339.             double count;
  340.             int howmany;
  341.                count = newval;
  342.                newval = 1.0;
  343.                for (howmany = count;howmany > 1;howmany--) {
  344.                   count = howmany;
  345.                   newval = newval * count;
  346.                }
  347.             }
  348.          }
  349.          else if (strcmp(name,"EXP") == 0) {
  350.             calcdata(&newval);
  351.             newval = exp(newval);
  352.          }
  353.          else if (strcmp(name,"LOG") == 0) {
  354.             calcdata(&newval);
  355.             if (newval < 0.0) {
  356.                errchk(7);                      /* Neg value for LOG */
  357.                newval = 0.0;
  358.             }
  359.             else newval = log(newval);
  360.          }
  361.          else if (strcmp(name,"SIN") == 0){
  362.             calcdata(&newval);
  363.             newval = sin(newval);
  364.          }
  365.          else if (strcmp(name,"COS") == 0){
  366.             calcdata(&newval);
  367.             newval = cos(newval);
  368.          }
  369.          else if (strcmp(name,"ATAN") == 0){
  370.             calcdata(&newval);
  371.             newval = atan(newval);
  372.          }
  373.          else {
  374.             errchk(6);                        /* function not found */
  375.             newval = 0.0;
  376.          }  
  377.          col--;
  378.          return(newval);
  379.       }                                     /* end of function call */
  380.  
  381.       else {                                       /* variable name */
  382.          for (i = 0;i < 12;i++) {
  383.             if ((strcmp(name,allvars[i].varname)) == 0) {
  384.                newval = allvars[i].value;
  385.                return(newval);
  386.             }
  387.          }
  388.          errchk(3);                           /* variable not found */
  389.          newval = 0.0;
  390.          return(newval);
  391.       }                                     /* end of variable call */
  392.  
  393.    }                            /* end of variable or function call */     
  394.    errchk(9);
  395.    return(0.0);                               /* invalid data found */
  396. }
  397.  
  398. /* ********************************************************** getop */
  399. /* A call to this function expects to find an operator, end of line */
  400. /* or a close parenthesis.                                          */
  401. char getop()
  402. {
  403.    while (inline[col] == ' ') col++;               /* ignore blanks */
  404.    switch (inline[col]){
  405.       case '$':
  406.       case ')':
  407.       case  0 :
  408.       case '+':
  409.       case '-':
  410.       case '*':
  411.       case '/': break;
  412.       default : errchk(4);                      /* invalid operator */
  413.    }
  414.    return(inline[col]);
  415. }
  416.  
  417. /* ********************************************************* errchk */
  418. /* The error code is stored by this function and the cursor column  */
  419. /* is adjusted in an attempt to put the cursor near the error that  */
  420. /* caused the problem.                                              */
  421. errchk(err)
  422. int err;
  423. {
  424.    if(errcode) return;                       /* error already found */
  425.    else {                         /* only the first error is stored */
  426.       errcode = err;                      /* store the error number */
  427.       switch (err){
  428.          case 2  : 
  429.          case 4  :
  430.          case 8  :
  431.          case 9  :
  432.          case 10 :
  433.          case 11 :
  434.          case 12 : colerr = col;
  435.                    break;
  436.          case 1  :
  437.          case 3  : colerr = col - 1;
  438.                    break;
  439.          case 6  : colerr = col - 2;
  440.                    break;
  441.          case 5  :
  442.          case 7  : colerr = col - 3;
  443.                    break;
  444.          default : colerr = col;
  445.       }
  446.    }
  447. }
  448.