yanera_postfix.c

Go to the documentation of this file.
00001 /*==============================================================================
00002 Copyright 2006 Thad Harroun, Kevin Yager
00003 
00004 This file is part of "yanera 2.0".
00005 
00006 "yanera 2.0" is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
00007 
00008 "yanera 2.0" is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00009 
00010 You should have received a copy of the GNU General Public License along with "yanera 2.0"; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 
00011 ==============================================================================*/ 
00012 /*============================================================================*/
00026 #define _CRT_SECURE_NO_DEPRECATE
00027 
00028 #include "yanera.h"
00029 #include "yanera_postfix.h"
00030 /*==========================================================================*/
00039 short parmindex(char c, char *parm_name)
00040 {
00041   unsigned int i;
00042   for (i=0; i<strlen(parm_name); i++)
00043   {
00044     if (parm_name[i] == c) break;
00045   }
00046   return i;
00047 }
00048 /*==========================================================================*/
00076 void parse_expression(yanera_postfix *pq, \
00077                       char *expression, char *parm_name, short *parm)
00078 {
00079   unsigned int                    i;
00080   short                           idx;
00081   short                           precedence;
00082   short                           precedence_level;
00083   struct operator_stack_element  *ose;
00084   enum operator_type              last;
00085   
00086   initizlize_operator_stack();
00087 
00088   number_string    = NULL;
00089   precedence_level = 0;
00090   last             = NONE;
00091   
00092   for (i=0; i<strlen(expression); i++)
00093   {
00094     switch(expression[i]) {
00095       case '0':
00096       case '1':
00097       case '2':
00098       case '3':
00099       case '4':
00100       case '5':
00101       case '6':
00102       case '7':
00103       case '8':
00104       case '9':
00105       case '.':
00106         /*
00107         ** A number should not be preceded by:
00108         */
00109         if ((last == ORDINATE) || \
00110             (last == PARAMETER) || \
00111             (last == OPERATOR_FUNCTION) || \
00112             (last == PARENTHESIS_CLOSE))
00113         {
00114            yanera_error("Invalid number in infix.", __FILE__, __LINE__, NULL);
00115         }
00116         /*
00117         ** If the character is a digit or decimal point,
00118         ** build the number_string for conversion to double later.
00119         */
00120         append_number_string(expression[i]);
00121         last = NUMBER;
00122         break;
00123       case '(':
00124         /*
00125         ** Open parentheis should not be preceded by:
00126         */
00127         if ((last == NUMBER) || \
00128             (last == ORDINATE) || \
00129             (last == PARAMETER) || \
00130             (last == PARENTHESIS_CLOSE))
00131         {
00132            yanera_error("Invalid ( in infix.", __FILE__, __LINE__, NULL);
00133         }
00134         precedence_level += 5;
00135         last = PARENTHESIS_OPEN;
00136         break;
00137       case ')':
00138         /*
00139         ** Close parentheis should not be preceded by:
00140         */
00141         if ((last == OPERATOR_MULTADD) || \
00142             (last == OPERATOR_UNARY) || \
00143             (last == OPERATOR_POWER) || \
00144             (last == OPERATOR_FUNCTION))
00145         {
00146           yanera_error("Invalid ) in infix.", __FILE__, __LINE__, NULL);
00147         }
00148         /*
00149         ** For close parentheis, and if preceded by a number, 
00150         ** make sure the number gets on postfix_queue.
00151         */
00152         if (last == NUMBER) stop_number_string(pq);
00153         precedence_level -= 5;
00154         last = PARENTHESIS_CLOSE;
00155         if (precedence_level < 0)
00156         {
00157           yanera_error("Invalid ) in infix.", __FILE__, __LINE__, NULL);
00158         }
00159         break;
00160       case '+':
00161         /*
00162         ** + should not be preceded by:
00163         */
00164         if ((last == OPERATOR_MULTADD) || \
00165             (last == OPERATOR_UNARY) || \
00166             (last == OPERATOR_POWER) || \
00167             (last == OPERATOR_FUNCTION))
00168         {
00169           yanera_error("Invalid operator + or - in infix.", \
00170                        __FILE__, __LINE__, NULL);
00171         }
00172         /* 
00173         ** If the previous character is a number...
00174         */
00175         if (last == NUMBER) stop_number_string(pq);
00176         /*
00177         ** ...or a close parantheis, an ordinate, or parameter, then this 
00178         **  operator is simple addition/subtration class (precedence 1).
00179         */
00180         if ((last == NUMBER) ||    \
00181             (last == ORDINATE) ||  \
00182             (last == PARAMETER) || \
00183             (last == PARENTHESIS_CLOSE))
00184         {
00185           precedence = precedence_level + 1;
00186           operator_decision(pq, "+  ", precedence, OPERATOR_MULTADD);
00187           last = OPERATOR_MULTADD;
00188         }
00189         /*
00190         ** Otherwise, its a unary/postive operator (precedence 4).
00191         ** Apend +1 to postfix_queue and * to operator stack.
00192         */
00193         else
00194         {
00195           append_number_string('+');
00196           append_number_string('1');
00197           stop_number_string(pq);
00198           precedence = precedence_level + 4;
00199           operator_decision(pq, "*  ", precedence, OPERATOR_MULTADD);
00200           last = OPERATOR_UNARY;
00201         }
00202         break;
00203       case '-':
00204         /*
00205         ** - should not be preceded by:
00206         */
00207         if ((last == OPERATOR_MULTADD) || \
00208             (last == OPERATOR_UNARY) || \
00209             (last == OPERATOR_POWER) || \
00210             (last == OPERATOR_FUNCTION))
00211         {
00212           yanera_error("Invalid operator + or - in infix.", \
00213                        __FILE__, __LINE__, NULL);
00214         }
00215         /* 
00216         ** If the previous character is a number...
00217         */
00218         if (last == NUMBER) stop_number_string(pq);
00219         /*
00220         ** ...or a close parantheis, an ordinate, or parameter, then this 
00221         **  operator is simple addition/subtration class (precedence 1).
00222         */
00223         if ((last == NUMBER) ||\
00224             (last == ORDINATE) ||\
00225             (last == PARAMETER) ||\
00226             (last == PARENTHESIS_CLOSE))
00227         {
00228           precedence = precedence_level + 1;
00229           operator_decision(pq, "-  ", precedence, OPERATOR_MULTADD);
00230           last = OPERATOR_MULTADD;
00231         }
00232         /*
00233         ** Otherwise, its a unary/negation operator (precedence 4).
00234         ** Apend -1 to postfix_queue and * to operator stack.
00235         */
00236         else
00237         {
00238           append_number_string('-');
00239           append_number_string('1');
00240           stop_number_string(pq);
00241           precedence = precedence_level + 4;
00242           operator_decision(pq, "*  ", precedence, OPERATOR_MULTADD);
00243           last = OPERATOR_UNARY;
00244         }
00245         break;
00246       case '*':
00247         /*
00248         ** / should not be preceded by :
00249         */
00250         if ((last == OPERATOR_MULTADD) || \
00251             (last == OPERATOR_UNARY) || \
00252             (last == OPERATOR_POWER) || \
00253             (last == OPERATOR_FUNCTION) || \
00254             (last == PARENTHESIS_OPEN))
00255         {
00256           yanera_error("Invalid operator * in infix.", \
00257                        __FILE__, __LINE__, NULL);
00258         }
00259         /*
00260         **  If the previous character is a number, then this 
00261         **  operator is simple multiply/divide class (precedence 2).
00262         */
00263         if (last == NUMBER) stop_number_string(pq);
00264         precedence = precedence_level + 2;
00265         operator_decision(pq, "*  ", precedence, OPERATOR_MULTADD);
00266         last = OPERATOR_MULTADD;
00267         break;
00268       case '/':
00269         /*
00270         ** / should not be preceded by :
00271         */
00272         if ((last == OPERATOR_MULTADD) || \
00273             (last == OPERATOR_UNARY) || \
00274             (last == OPERATOR_POWER) || \
00275             (last == OPERATOR_FUNCTION) || \
00276             (last == PARENTHESIS_OPEN))
00277         {
00278           yanera_error("Invalid operator / in infix.", \
00279                        __FILE__, __LINE__, NULL);
00280         }
00281         /*
00282         **  If the previous character is a number, then this 
00283         **  operator is simple multiply/divide class (precedence 2).
00284         */
00285         if (last == NUMBER) stop_number_string(pq);
00286         precedence = precedence_level + 2;
00287         operator_decision(pq, "/  ", precedence, OPERATOR_MULTADD);
00288         last = OPERATOR_MULTADD;
00289         break;
00290       case '^':
00291         /*
00292         ** ^ should not be preceded by:
00293         */
00294         if ((last == OPERATOR_MULTADD) || \
00295             (last == OPERATOR_UNARY) || \
00296             (last == OPERATOR_POWER) || \
00297             (last == OPERATOR_FUNCTION) || \
00298             (last == PARENTHESIS_OPEN))
00299         {
00300           yanera_error("Invalid operator ^ in infix.", \
00301                        __FILE__, __LINE__, NULL);
00302         }
00303         /*
00304         **  If the previous character is a number, add to postfix
00305         */
00306         if (last == NUMBER) stop_number_string(pq);
00307         precedence = precedence_level + 3;
00308         operator_decision(pq, "^  ", precedence, OPERATOR_POWER);
00309         last = OPERATOR_POWER;
00310         break;
00311       case 'a':
00312         /*
00313         ** a  should not be preceded by:
00314         */
00315         if ((last == NUMBER) || \
00316             (last == ORDINATE) || \
00317             (last == PARAMETER) || \
00318             (last == OPERATOR_FUNCTION) || \
00319             (last == PARENTHESIS_CLOSE))
00320         {
00321           yanera_error("Invalid letter a in infix.", __FILE__, __LINE__, NULL);
00322         }
00323         if ((expression[i+1]=='b')&&(expression[i+2]=='s'))
00324         {
00325           precedence = precedence_level + 5;
00326           operator_decision(pq, "abs", precedence, OPERATOR_FUNCTION);
00327           i+=2;       
00328           last  = OPERATOR_FUNCTION;
00329         }
00330         else
00331         {
00332           idx = parmindex('a', parm_name);
00333           parameter_decision(pq, "a  ", parm[idx]);
00334           last = PARAMETER;
00335         }
00336         break;
00337       case 'b':
00338         /*
00339         ** b  should not be preceded by:
00340         */
00341         if ((last == NUMBER) || \
00342             (last == ORDINATE) || \
00343             (last == PARAMETER) || \
00344             (last == OPERATOR_FUNCTION) || \
00345             (last == PARENTHESIS_CLOSE))
00346         {
00347           yanera_error("Invalid letter b in infix.", __FILE__, __LINE__, NULL);
00348         }
00349         else
00350         {
00351           idx = parmindex('b', parm_name);
00352           parameter_decision(pq, "b  ", parm[idx]);
00353           last = PARAMETER;
00354         }
00355         break;
00356       case 'c':
00357         /*
00358         ** c or cos should not be preceded by:
00359         */
00360         if ((last == NUMBER) || \
00361             (last == ORDINATE) || \
00362             (last == PARAMETER) || \
00363             (last == OPERATOR_FUNCTION) || \
00364             (last == PARENTHESIS_CLOSE))
00365         {
00366           yanera_error("Invalid letter c in infix.", __FILE__, __LINE__, NULL);
00367         }
00368         if ((expression[i+1]=='o')&&(expression[i+2]=='s'))
00369         {
00370           precedence = precedence_level + 5;
00371           operator_decision(pq, "cos", precedence, OPERATOR_FUNCTION);
00372           i+=2;       
00373           last  = OPERATOR_FUNCTION;
00374         }
00375         else
00376         {
00377           idx = parmindex('c', parm_name);
00378           parameter_decision(pq, "c  ", parm[idx]);
00379           last = PARAMETER;
00380         }
00381         break;
00382       case 'd':
00383         /*
00384         ** d should not be preceded by:
00385         */
00386         if ((last == NUMBER) || \
00387             (last == ORDINATE) || \
00388             (last == PARAMETER) || \
00389             (last == OPERATOR_FUNCTION) || \
00390             (last == PARENTHESIS_CLOSE))
00391         {
00392           yanera_error("Invalid letter d in infix.", __FILE__, __LINE__, NULL);
00393         }
00394         else
00395         {
00396           idx = parmindex('d', parm_name);
00397           parameter_decision(pq, "d  ", parm[idx]);
00398           last = PARAMETER;
00399         }
00400         break;
00401       case 'e':
00402         /*
00403         ** parameter e, exp, or exponent e should not be preceded by:
00404         */
00405         if ((last == ORDINATE) || \
00406             (last == PARAMETER) || \
00407             (last == OPERATOR_FUNCTION) || \
00408             (last == PARENTHESIS_CLOSE))
00409         {
00410           yanera_error("Invalid letter e in infix.", __FILE__, __LINE__, NULL);
00411         }
00412         if ((expression[i+1]=='x')&&(expression[i+2]=='p'))
00413         {
00414           precedence = precedence_level + 5;
00415           operator_decision(pq, "exp", precedence, OPERATOR_FUNCTION);
00416           i+=2;       
00417           last  = OPERATOR_FUNCTION;
00418         }
00419         else if ((expression[i+1]=='+')||(expression[i+1]=='-'))
00420         {
00421             append_number_string(expression[i]);
00422             append_number_string(expression[i+1]);
00423             last = NUMBER;
00424             i+=1;
00425         }
00426         else
00427         {
00428           idx = parmindex('e', parm_name);
00429           parameter_decision(pq, "e  ", parm[idx]);
00430           last = PARAMETER;
00431         }
00432         break;
00433       case 'f':
00434         /*
00435         ** f should not be preceded by:
00436         */
00437         if ((last == NUMBER) || \
00438             (last == ORDINATE) || \
00439             (last == PARAMETER) || \
00440             (last == OPERATOR_FUNCTION) || \
00441             (last == PARENTHESIS_CLOSE))
00442         {
00443           yanera_error("Invalid letter f in infix.", __FILE__, __LINE__, NULL);
00444         }
00445         else
00446         {
00447           idx = parmindex('f', parm_name);
00448           parameter_decision(pq, "f  ", parm[idx]);
00449           last = PARAMETER;
00450         }
00451         break;
00452       case 'g':
00453         /*
00454         ** g should not be preceded by:
00455         */
00456         if ((last == NUMBER) || \
00457             (last == ORDINATE) || \
00458             (last == PARAMETER) || \
00459             (last == OPERATOR_FUNCTION) || \
00460             (last == PARENTHESIS_CLOSE))
00461         {
00462           yanera_error("Invalid letter g in infix.", __FILE__, __LINE__, NULL);
00463         }
00464         else
00465         {
00466           idx = parmindex('g', parm_name);
00467           parameter_decision(pq, "g  ", parm[idx]);
00468           last = PARAMETER;
00469         }
00470         break;
00471     /*case 'h':
00472       case 'i':
00473       case 'j':
00474       case 'k':*/
00475       case 'l':
00476         /*
00477         ** l or log should not be preceded by:
00478         */
00479         if ((last == NUMBER) || \
00480             (last == ORDINATE) || \
00481             (last == PARAMETER) || \
00482             (last == OPERATOR_FUNCTION) || \
00483             (last == PARENTHESIS_CLOSE))
00484         {
00485           yanera_error("Invalid letter l in infix.", __FILE__, __LINE__, NULL);
00486         }
00487         if ((expression[i+1]=='o')&&(expression[i+2]=='g'))
00488         {
00489           precedence = precedence_level + 5;
00490           operator_decision(pq, "log", precedence, OPERATOR_FUNCTION);
00491           i+=2;       
00492           last  = OPERATOR_FUNCTION;
00493         }
00494         else
00495         {
00496           idx = parmindex('l', parm_name);
00497           parameter_decision(pq, "l  ", parm[idx]);
00498           last = PARAMETER;
00499         }
00500         break;
00501     /*case 'm':
00502       case 'n':
00503       case 'o':
00504       case 'p':
00505       case 'q':
00506       case 'r':*/
00507       case 's':
00508         /*
00509         ** s or sin should not be preceded by:
00510         */
00511         if ((last == NUMBER) || \
00512             (last == ORDINATE) || \
00513             (last == PARAMETER) || \
00514             (last == OPERATOR_FUNCTION) || \
00515             (last == PARENTHESIS_CLOSE))
00516         {
00517           yanera_error("Invalid letter s in infix.", __FILE__, __LINE__, NULL);
00518         }
00519         if ((expression[i+1]=='i')&&(expression[i+2]=='n'))
00520         {
00521           precedence = precedence_level + 5;
00522           operator_decision(pq, "sin", precedence, OPERATOR_FUNCTION);
00523           i+=2;       
00524           last  = OPERATOR_FUNCTION;
00525         }
00526         else
00527         {
00528           yanera_error("Parameter s in infix.", __FILE__, __LINE__, NULL);
00529           last = PARAMETER;
00530         }
00531         break;
00532       case 't':
00533         /*
00534         ** t or tan should not be preceded by:
00535         */
00536         if ((last == NUMBER) || \
00537             (last == ORDINATE) || \
00538             (last == PARAMETER) || \
00539             (last == OPERATOR_FUNCTION) || \
00540             (last == PARENTHESIS_CLOSE))
00541         {
00542           yanera_error("Invalid letter t in infix.", __FILE__, __LINE__, NULL);
00543         }
00544         if ((expression[i+1]=='a')&&(expression[i+2]=='n'))
00545         {
00546           precedence = precedence_level + 5;
00547           operator_decision(pq, "tan", precedence, OPERATOR_FUNCTION);
00548           i+=2;       
00549           last  = OPERATOR_FUNCTION;
00550         }
00551         else
00552         {
00553           yanera_error("Parameter t in infix.", __FILE__, __LINE__, NULL);
00554           last = PARAMETER;
00555         }
00556         break;
00557     /*case 'u':
00558       case 'v':
00559       case 'w':
00560       case 'x'
00561       case 'y'*/
00562       case 'z':
00563         /*
00564         ** z is reserved as the ordinate, and should not be preceded by:
00565         */
00566         if ((last == NUMBER) || \
00567             (last == ORDINATE) || \
00568             (last == PARAMETER) || \
00569             (last == OPERATOR_FUNCTION) || \
00570             (last == PARENTHESIS_CLOSE))
00571         {
00572           yanera_error("Invalid ordinate x in infix.", \
00573                        __FILE__, __LINE__, NULL);
00574         }
00575         enqueue_postfix_queue(pq, "x  ", 0.0, -1, ORDINATE);
00576         last  = ORDINATE;
00577         break;
00578       default:
00579         yanera_error("Cant parse function expression.", \
00580                      __FILE__, __LINE__, NULL);
00581         break;
00582     } /* End of switch */
00583     
00584   } /* End of for */
00585   /*
00586   ** If the epxression ends in a number, we need to append it to the
00587   ** postfix_queue.
00588   */
00589   if (last == NUMBER) stop_number_string(pq);
00590   if (precedence_level > 0) 
00591   {
00592     yanera_error("Invalid ( in infix.", \
00593                  __FILE__, __LINE__, NULL);
00594   }
00595   /*
00596   ** Any remaining operators on the operator_stack should be appended
00597   ** to the postfix_queue
00598   */
00599   while (operator_stack_is_empty()==NO) {
00600     ose = pop_operator_stack();
00601     enqueue_postfix_queue(pq, ose->oper, 0.0, -1, ose->type);
00602     free(ose);
00603   };
00604   
00605   return;
00606 }
00607 /*============================================================================*/
00615 void parameter_decision(yanera_postfix *pq, const char c[4], short indx)
00616 {
00617   struct _postfix_queue_element *p;
00618 
00619   /*
00620    * First, check to see if this parameter is already in the queue
00621    */
00622   p = pq->front;
00623   while (p != NULL) {
00624     if ((p->type == PARAMETER)&&(strncmp(c,p->oper,3) == 0))
00625     {
00626        enqueue_postfix_queue(pq, c, 0.0, p->indx, PARAMETER);
00627        return;
00628     }
00629     p=p->next;
00630   }
00631   /*
00632    * At this point, the paramter is not already in the queue, so add it.
00633    */
00634   enqueue_postfix_queue(pq, c, 0.0, indx, PARAMETER);
00635   return;
00636 }
00637 /*==============================================================================
00638   NUMBER_STRING
00639 ==============================================================================*/
00644 void append_number_string(char c)
00645 {
00646   unsigned short i;
00647   if (number_string == NULL)
00648   {
00649     number_string = (char *)malloc(2*sizeof(char));
00650     memset(number_string, '\0', 2);
00651     number_string[0] = c;
00652   }
00653   else
00654   {
00655     i = strlen(number_string);
00656     number_string = (char *)realloc(number_string, \
00657                                    (i+2)*sizeof(char));
00658     number_string[i+1] = '\0';                              
00659     number_string[i] = c;
00660   }
00661   return;
00662 }
00663 /* ------------------------------------------------------------------------- */
00669 void stop_number_string(yanera_postfix *pq)
00670 {
00671   enqueue_postfix_queue(pq, NULL, \
00672       strtod(number_string,NULL), \
00673       -1, NUMBER);
00674   free(number_string);
00675   number_string = NULL;
00676 }
00677 /*==============================================================================
00678  POSTFIX_QUEUE
00679 ==============================================================================*/
00684 yanera_postfix *initizlize_postfix_queue(void)
00685 {
00686   yanera_postfix *pq;
00687   
00688   pq = (yanera_postfix *)malloc(sizeof(yanera_postfix));
00689   
00690   pq->n      = 0;
00691   pq->front  = NULL;
00692   pq->rear   = NULL;
00693   return pq;
00694 }
00695 /* ------------------------------------------------------------------------- */
00711 void enqueue_postfix_queue(yanera_postfix *pq, \
00712                            const char *c, double d, short indx, short type)
00713 {
00714   struct _postfix_queue_element *p;
00715   /*
00716    * Allocate a new queue element
00717    */
00718   p = (struct _postfix_queue_element *)malloc( \
00719                                        sizeof(struct _postfix_queue_element));
00720   /*
00721    * Initalize the element
00722    */
00723   p->type = type;
00724   p->numb = d;
00725   p->indx = indx;
00726   memset(p->oper, '\0', 4);
00727   if (c!=NULL) strncpy(p->oper, c, 3);
00728   p->next = NULL;
00729   /*
00730    * Queue up the new element.
00731    */
00732   if (pq->n > 0)
00733   {
00734     pq->rear->next = p;
00735     pq->rear       = p;
00736   }
00737   else
00738   { 
00739     pq->front = p;
00740     pq->rear  = p;
00741   }
00742   pq->n++;
00743   return;
00744 }
00745 /* ------------------------------------------------------------------------- */
00756 void print_postfix(yanera_postfix *pq, double x, double *params)
00757 {
00758   struct _postfix_queue_element *p;
00759     
00760   /* Step through the queue */
00761   p = pq->front;
00762   do {
00763     /* Print numbers directly */
00764     if (p->type == NUMBER) fprintf(stderr, "%f\n", p->numb);
00765     /* Print operators as they are stored in the size 4 string */
00766     if ((p->type == OPERATOR_MULTADD) || \
00767         (p->type == OPERATOR_UNARY) || \
00768         (p->type == OPERATOR_POWER) || \
00769         (p->type == OPERATOR_FUNCTION) || \
00770         (p->type == ORDINATE) || \
00771         (p->type == PARAMETER))
00772     {
00773       fprintf(stderr, "%s", p->oper);
00774       /* If the ordinate \c x, then print the value 
00775          (passed into the function as the x parameter) */
00776       if (p->type == ORDINATE) fprintf(stderr, "= %f\n", x);
00777       /* If a varaible, then print the value from the array
00778          (passed into the function as the params array */
00779       else if (p->type == PARAMETER) 
00780         fprintf(stderr, "= %f\n", params[p->indx]);
00781       /* Add a new line between queue elementes.  */
00782       else fprintf(stderr, "\n");
00783     }
00784     p=p->next;
00785   } while (p!=NULL);
00786   
00787   return;
00788 }
00789 /* ------------------------------------------------------------------------- */
00800 double evaluate_postfix(yanera_postfix *pq, double z, double *params)
00801 {
00802   struct _postfix_queue_element *p;
00803   double v1, v2, tmp;
00804   
00805   initizlize_evaluation_stack();
00806   
00807   tmp = 0.0;
00808   p = pq->front;
00809   do {
00810     if (p->type==NUMBER)
00811     {
00812       push_evaluation_stack(p->numb);
00813     }
00814     else if (p->type == OPERATOR_MULTADD)
00815     {
00816       v1 = pop_evaluation_stack();
00817       v2 = pop_evaluation_stack();
00818       switch(p->oper[0]) {
00819         case '+':
00820           tmp = v2 + v1;
00821           break;
00822         case '-':
00823           tmp = v2 - v1;
00824           break;
00825         case '*':
00826           tmp = v2 * v1;
00827           break;
00828         case '/':
00829           tmp = v2 / v1;
00830           break;
00831       }
00832       push_evaluation_stack(tmp);
00833     }
00834     else if (p->type == OPERATOR_POWER)
00835     {
00836       v1 = pop_evaluation_stack();
00837       v2 = pop_evaluation_stack();
00838       tmp = pow(v2,v1);
00839       push_evaluation_stack(tmp);
00840     }
00841     else if (p->type == OPERATOR_FUNCTION)
00842     {
00843       v1 = pop_evaluation_stack();
00844       if (strncmp(p->oper,"abs",3)==0) tmp = fabs(v1);
00845       if (strncmp(p->oper,"cos",3)==0) tmp = cos(v1);
00846       if (strncmp(p->oper,"exp",3)==0) tmp = exp(v1);
00847       if (strncmp(p->oper,"log",3)==0) tmp = log(v1);
00848       if (strncmp(p->oper,"sin",3)==0) tmp = sin(v1);
00849       if (strncmp(p->oper,"tan",3)==0) tmp = tan(v1);
00850       push_evaluation_stack(tmp);
00851     }
00852     else if (p->type==ORDINATE)
00853     {
00854       push_evaluation_stack(z);   
00855     }
00856     else if (p->type==PARAMETER)
00857     {
00858       push_evaluation_stack(params[p->indx]);   
00859     }
00860     p=p->next;
00861   } while (p!=NULL);
00862   
00863   tmp = pop_evaluation_stack();
00864   return tmp;
00865 }
00866 /* ------------------------------------------------------------------------- */
00871 void free_postfix_queue(yanera_postfix *pq)
00872 {
00873   struct _postfix_queue_element *p;
00874   struct _postfix_queue_element *f;
00875   
00876   if (pq == NULL) return;
00877 
00878   f = pq->front;
00879   while (f != NULL) {
00880     p = f->next;
00881     free(f);
00882     f = p;
00883     pq->n--;
00884   };
00885   free(pq);
00886   return;
00887 }
00888 /*==============================================================================
00889  OPERATOR_STACK
00890 ==============================================================================*/
00891 /* ------------------------------------------------------------------------- */
00897 void initizlize_operator_stack(void)
00898 {
00899   operator_stack.n   = 0;
00900   operator_stack.top = NULL;
00901   return;
00902 }
00903 /* ------------------------------------------------------------------------- */
00908 struct operator_stack_element *operator_stack_element_new( \
00909                                const char *oper, short prec,short type)
00910 {
00911   struct operator_stack_element *o;
00912   
00913   o = malloc(sizeof(struct operator_stack_element));
00914   o->prec = prec;
00915   o->type = type;
00916   memset(o->oper, '\0', 4);
00917   strncpy(o->oper, oper, 3);
00918   return o;
00919 }
00920 /* ------------------------------------------------------------------------- */
00925 void push_operator_stack(struct operator_stack_element *o)
00926 {
00927   o->next = operator_stack.top;
00928   operator_stack.top = o;
00929   operator_stack.n++;
00930   return;
00931 }
00932 /* ------------------------------------------------------------------------- */
00938 struct operator_stack_element *pop_operator_stack(void)
00939 {
00940   struct operator_stack_element *o, *optr;
00941   
00942   /* 
00943    * Make a copy of the operator_stack_element to return.
00944    */
00945   o = (struct operator_stack_element *)malloc( \
00946        sizeof(struct operator_stack_element));
00947   o->prec = operator_stack.top->prec;
00948   o->type = operator_stack.top->type;
00949   memset(o->oper, '\0', 4);
00950   strncpy(o->oper,operator_stack.top->oper,3);
00951   /*
00952    * Free the top element of the stack.
00953    */
00954   optr = operator_stack.top;
00955   operator_stack.top = operator_stack.top->next;
00956   operator_stack.n--;
00957   free(optr);
00958   return o;
00959 }
00960 /* ------------------------------------------------------------------------- */
00965 short operator_stack_is_empty(void)
00966 {
00967   if (operator_stack.n == 0) return YES;
00968   return NO;
00969 }
00970 /* ------------------------------------------------------------------------- */
00976 short operator_stack_top_precedence(void)
00977 {
00978   int i;
00979   if (operator_stack.n == 0) i = 0;
00980   else i = operator_stack.top->prec;
00981   return (i);
00982 }
00983 /* ------------------------------------------------------------------------- */
00988 void operator_decision(yanera_postfix *pq, \
00989                        const char oper[4], short prec, short type)
00990 {
00991   struct operator_stack_element *ose = NULL;
00992   
00993   if ((operator_stack_is_empty()==YES) || \
00994       (prec > operator_stack_top_precedence()))
00995   { 
00996     ose = operator_stack_element_new(oper, prec, type);
00997     push_operator_stack(ose);
00998   }
00999   else
01000   {
01001     do {
01002       ose = pop_operator_stack();
01003       enqueue_postfix_queue(pq, ose->oper, 0.0, -1, ose->type);
01004       free(ose);
01005     } while ((operator_stack_is_empty() == NO) && \
01006              (prec <= operator_stack_top_precedence()));
01007     ose = operator_stack_element_new(oper, prec, type);
01008     push_operator_stack(ose);
01009   }
01010   return;
01011 }
01012 /*==============================================================================
01013   EVALUATION_STACK
01014 ==============================================================================*/
01015 /* ------------------------------------------------------------------------- */
01021 void initizlize_evaluation_stack(void)
01022 {
01023   evaluation_stack.n   = 0;
01024   evaluation_stack.top = NULL;
01025   return;
01026 }
01027 /* ------------------------------------------------------------------------- */
01032 void push_evaluation_stack(double d)
01033 {
01034   struct evaluation_stack_element *e;
01035   
01036   e = malloc(sizeof(struct evaluation_stack_element));
01037   e->d = d;
01038   e->next = evaluation_stack.top;
01039   evaluation_stack.top = e;
01040   evaluation_stack.n++;
01041   return;
01042 }
01043 /* ------------------------------------------------------------------------- */
01048 double pop_evaluation_stack(void)
01049 {
01050   double d;
01051   struct evaluation_stack_element *e;
01052 
01053   d = evaluation_stack.top->d;
01054   
01055   e = evaluation_stack.top;
01056   evaluation_stack.top = evaluation_stack.top->next;
01057   evaluation_stack.n--;
01058   free(e);
01059   return d;
01060 }
01061 

Generated on Thu May 29 10:56:33 2008 by  doxygen 1.5.5