home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / Programming / Atmel / Asm / src / math.c < prev    next >
C/C++ Source or Header  |  2000-08-22  |  5KB  |  294 lines

  1. /*******************************************************
  2. * Maths routines for the Atmel cross assembler         *
  3. * (c)1999 LJS                                          *
  4. *                                                      *
  5. * Takes an expression and evaluates it.                *
  6. *******************************************************/
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <ctype.h>
  12.  
  13. #include "errors.h"
  14.  
  15. #define MAXBUFFER 1024
  16. extern int Error;
  17.  
  18. void InsertChar(char *S, char Ch);
  19. int Evaluate(char *Exp);
  20. int EvalBit(char *Bit);
  21. int BracketOut(char *Str);
  22. int CheckBrackets(char *Str);
  23. int Math(char *Str);
  24. void RemoveSpace(char *S);
  25.  
  26. int StrToInt(char *Str);     /*Converts hex,dec,bin*/
  27.  
  28. int Math(char *Str)
  29. {
  30.     int Result;
  31.   char *Local, *Bit, Sign;
  32.  
  33.   if(strlen(Str)>=MAXBUFFER)
  34.   {
  35.     Error = MEM;
  36.     return 0;
  37.   }
  38.  
  39.   Local=(char*)malloc(MAXBUFFER);
  40.   if(Local==NULL)
  41.   {
  42.     Error=MEM;
  43.     return 0;
  44.   }
  45.   strcpy(Local,Str);            /*Take a local copy of the original expression*/
  46.   if(CheckBrackets(Local)==0)
  47.   {
  48.     Bit = Local;
  49.     while(*Bit)
  50.     {
  51.       Sign = *Bit;
  52.       Bit++;
  53.       if( (*Bit == '>') || (*Bit == '<') )  /*Splat >> & << to > & <*/
  54.       {
  55.         if(Sign == *Bit)
  56.         {
  57.           *Bit = ' ';    /*Change the second one to a space*/
  58.         }
  59.       }
  60.     }
  61.     RemoveSpace(Local);
  62.       Result=BracketOut(Local);
  63.         if(Result)
  64.         {
  65.           Result=Evaluate(Local);
  66.          }
  67.   }
  68.   else
  69.   {
  70.     Error=BRACKETS;
  71.   }
  72.   free(Local);
  73.  return Result;
  74. }
  75.  
  76. int Evaluate(char *Exp)
  77. {
  78.     char *Work, *Double, *Temp;
  79.     int Result;
  80.  
  81.   if(CheckBrackets(Exp))
  82.   {
  83.     return 0;
  84.   }
  85.  
  86.   if( (strlen(Exp)+2) >=MAXBUFFER)
  87.   {
  88.     Error = MEM;
  89.     return 0;
  90.   }
  91.  
  92.     Work=(char*)malloc(MAXBUFFER);
  93.     if(Work==NULL)
  94.     {
  95.         Error=MEM;
  96.         return 0;
  97.     }
  98.     Double=(char*)malloc(MAXBUFFER);
  99.     if(Double==NULL)
  100.     {
  101.         Error=MEM;
  102.         free(Work);
  103.         return 0;
  104.     }
  105.  
  106.     Work[0]='(';
  107.     Work[1]=0;
  108.     strcat(Work,Exp);
  109.     strcat(Work,")");
  110.     Temp=Work;
  111.     do
  112.     {
  113.         while( (*Temp!=')') && (*Temp) )
  114.         {
  115.             Temp++;
  116.         }
  117.         if(*Temp)
  118.         {
  119.             while(*Temp!='(')
  120.             {
  121.                 Temp--;
  122.             }
  123.             Result=EvalBit(Temp);
  124.             *Temp=0;
  125.             sprintf(Double,"%s%d",Work,Result);
  126.             while(*Temp!=')')
  127.             {
  128.                 Temp++;
  129.             }
  130.             Temp++;
  131.             strcat(Double,Temp);
  132.             strcpy(Work,Double);
  133.         }
  134.         Temp=Work;
  135.     }while(*Temp=='(');
  136.  
  137.     free(Work);
  138.     free(Double);
  139.     return Result;
  140. }
  141.  
  142. int EvalBit(char *Bit)
  143. {
  144.     int Result=0, Os, Loop, Left, Right;
  145.     char Part[2][8],Sign;
  146.  
  147.     for(Loop=0; Loop<2; Loop++)
  148.     {
  149.         Sign=*Bit;
  150.         Bit++;
  151.         Os=0;
  152.         do
  153.         {
  154.             Part[Loop][Os]=*Bit;
  155.             Os++;
  156.             Bit++;                /*Gets -'s as well*/
  157.         }while( (isxdigit(*Bit) || (*Bit=='$') || (*Bit=='%')) && (Os<8) );
  158.         Part[Loop][Os]=0;
  159.     }
  160.  
  161.     Left=StrToInt(Part[0]);
  162.   if(Sign!=')')
  163.   {
  164.       Right=StrToInt(Part[1]);
  165.   }
  166.  
  167.     switch(Sign)
  168.     {
  169.         case '+':Result=Left+Right;
  170.                         break;
  171.         case '-':Result=Left-Right;
  172.                         break;
  173.         case '*':Result=Left*Right;
  174.                         break;
  175.         case '/':if(Right)
  176.                          {
  177.                              Result=Left/Right;
  178.                          }
  179.                          else
  180.                          {
  181.                              Error=DIVZERO;
  182.                          }
  183.                         break;
  184.         case '&':Result=Left&Right;
  185.                         break;
  186.         case '|':Result=Left|Right;
  187.                         break;
  188.         case '>':Result=Left>>Right;
  189.                         break;
  190.         case '<':Result=Left<<Right;
  191.                         break;
  192.         default:Result=Left;
  193.                      break;
  194.     }
  195.  return Result;
  196. }
  197.  
  198. void InsertChar(char *S, char Ch)
  199. {
  200.     char TempA, TempB;
  201.  
  202.   if( (strlen(S)+1) >= MAXBUFFER)
  203.   {
  204.     Error = TOOCOMPLEX;
  205.     return;
  206.   }
  207.  
  208.     TempA=*S;
  209.     *S=Ch;
  210.     while(*S)
  211.     {
  212.         S++;
  213.         TempB=*S;
  214.         *S=TempA;
  215.         TempA=TempB;
  216.     }
  217. }
  218.  
  219. int BracketOut(char *Str)
  220. {
  221.     char *Order="/*+-&|<>";
  222.     char *Temp,*StrPtr;
  223.     int Bracket;
  224.  
  225.     while(*Order)
  226.     {
  227.         Temp=Str;
  228.         while(*Temp)
  229.         {
  230.             if(*Temp==*Order)
  231.             {
  232.                 StrPtr=Temp;
  233.                 Bracket=0;
  234.                 do
  235.                 {
  236.                     StrPtr--;
  237.                     if(*StrPtr==')')
  238.                         Bracket++;
  239.                     else if(*StrPtr=='(')
  240.                         Bracket--;
  241.                 }while( ((Bracket) || isxdigit(*StrPtr) || (*StrPtr=='$') || (*StrPtr=='%')) && (StrPtr>Str) );
  242.                 if(StrPtr>Str)
  243.                 {
  244.                     StrPtr++;
  245.                 }
  246.         else if(StrPtr<Str)
  247.         {
  248.           return 1;
  249.         }
  250.                 Temp++;
  251.                 InsertChar(StrPtr,'(');
  252.         if(Error) return 0;
  253.                 Temp++;
  254.                 Bracket=0;
  255.                 if(*Temp)
  256.                 {
  257.                     do
  258.                     {
  259.                         if(*Temp=='(')
  260.                             Bracket++;
  261.                         else if(*Temp==')')
  262.                             Bracket--;
  263.  
  264.                         Temp++;
  265.                     }while( ((Bracket) || isxdigit(*Temp)  || (*Temp=='$') || (*Temp=='%')) && (*Temp));
  266.                 }
  267.                 InsertChar(Temp,')');
  268.         if(Error) return 0;
  269.             }
  270.             else
  271.             {
  272.                 Temp++;
  273.             }
  274.         }
  275.         Order++;
  276.     }
  277.     return 1;
  278. }
  279.  
  280. int CheckBrackets(char *Str)
  281. {
  282.   int result=0;
  283.  
  284.   while(*Str)
  285.   {
  286.     if(*Str=='(')
  287.       result++;
  288.     if(*Str==')')
  289.       result--;
  290.     Str++;
  291.   }
  292.  return result;
  293. }
  294.