home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / gle / util / manip / polish.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-29  |  10.2 KB  |  397 lines

  1. char *un_quote();
  2. char *ns[3] = {"Nothing","Number","String"};
  3. extern int gle_debug;
  4. /*---------------------------------------------------------------------------*/
  5. #include "all.h"
  6.  
  7. #include <math.h>
  8. int add_strvar(char *pcode,int *plen,int i);
  9. int token_norm(void);
  10. int token_space(void);
  11.  
  12. #define true (!false)
  13. #define false 0
  14. #define tok(n)  tk[n]
  15. #define abort goto fatal_err
  16. /*---------------------------------------------------------------------------*/
  17. /* bin = 10..29, binstr = 30..49, fn= 60...139, userfn=200..nnn */
  18. #define stack_bin(i,p)     stack_op(pcode,plen,stk,stkp,&nstk,i-10+(last_typ*20),p+curpri)
  19. #define stack_fn(i)     stack_op(pcode,plen,stk,stkp,&nstk,i,10+curpri)
  20. #define dbg if ((gle_debug & 4)>0)
  21. /*---------------------------------------------------------------------------*/
  22. /* Input is token array, and pointer to current point, output is pcode */
  23.  
  24. /* typedef struct op_key (*OPKEY)[100];  */
  25. /* typedef char (*(*TOKENS)[500]); */
  26.  
  27. int zpolish(TOKENS tk,int *ntok,int *curtok,char *pcode,int *plen,int *rtype);
  28. polish(char *expr,char *pcode,int *plen,int *rtype)
  29. {
  30. static char inbuff[200];
  31. static char *tk[500];
  32. static char tkbuff[500];
  33. static int ntk,ct;
  34. char *space_str=" ";
  35.     static char buff[50];
  36.     static int start_token;
  37.     double xxx;
  38.     int idx,ret,np,*plist,saveplen,term_bracket;
  39.     int curpri=0;
  40.     int i,j,v,p,savelen,isa_string,not_string,last_typ;
  41.     int nstk=0,stk[50],stkp[50];    /* stack for operators */
  42.     int unary=1;        /* binary or unary operation expected */
  43.     int ln;            /* length of current token */
  44.     char *cts;        /* current token */
  45.     /* last_typ, 1=number,2=string */
  46.  
  47.     *plen = 0;
  48.     if (tk[400]==NULL) for (i=0;i<500;i++) tk[i] = space_str;
  49.     isa_string = false;
  50.     not_string = false;
  51.     if (*rtype==1) not_string = true;
  52.     /* if (*rtype==2) isa_string = true; */
  53.     *plen = *plen*4;    /* change into byte count */
  54.     if (*rtype>0) term_bracket = true;
  55.     last_typ = *rtype;
  56.     saveplen = *plen;
  57.  
  58.     add_i(pcode,plen,1);    /* expression follows */
  59.     savelen = *plen;    /* Used to set acutal length at end */
  60.     add_i(pcode,plen,0);    /* Length of expression */
  61.     dbg gprint("====Start of expression {%s} \n",expr);
  62.     if (strlen(expr)==0) {gprint("Zero length expression\n"); return;}
  63.     if (!start_token) {
  64.         ntk = 0; ct=1;
  65.         token_norm();
  66.         token(expr,tk,&ntk,tkbuff);
  67.         token_space();
  68.     }
  69.     for (;;) {
  70.       cts = tok(ct);
  71.       dbg gprint("First word token=%d via (1=unary %d) cts {%s} %d \n "
  72.         ,ct,unary,cts,strlen(cts));
  73.       ln = strlen(cts);
  74.        switch (unary) {
  75.       case 1:  /* a unary operator, or function, or number or variable */
  76.         if (ln==1 && (*cts=='E')) goto notnumber;
  77.         if (ln==1 && (*cts=='-')) goto notnumber;
  78.         if (isnumber(cts))  {
  79. evalagain:            dbg gprint("Found number {%s}\n",cts);
  80.             if (lastchar(cts,'E'))  {
  81.                 strcpy(buff,cts);
  82.                 strcat(buff,tok(++ct));
  83.                 if (*tok(ct)=='-' || *tok(ct)=='+') {
  84.                     strcat(buff,tok(++ct));
  85.                 }
  86.                 tok(ct) = buff;
  87.                 cts = tok(ct);
  88.                 goto evalagain;
  89.             }
  90.             xxx = atof(cts);
  91.             add_f(pcode,plen,xxx);
  92.             if (last_typ==2) gprint("Expecting string {%s} \n",cts);
  93.             last_typ = 1;
  94.             unary=2; break;
  95.         }
  96. notnumber:    /* NOT a number, Is it a built in function */
  97.         /* int idx,ret,np,*plist; */
  98.         find_un(cts,&idx,&ret,&np,&plist);    /* 1,2 = +,- */
  99.         if (idx>63) {
  100.           dbg gprint("Found built in function \n");
  101.             if (*tok(++ct)!='(') {
  102.                 gprint("Expecting left bracket after functsion name");
  103.                 abort;
  104.             }
  105.             {
  106.              char fcode[400];
  107.              char *fp;
  108.              int flen,vtype,nparam=0;
  109.              if (*tok(ct+1)!=')') {
  110.                while (*tok(ct)!=')') {
  111.                 nparam++;
  112.                 vtype = *(plist+nparam-1);
  113.                 flen = 0;
  114.                 (ct)++;
  115.                 start_token = true;
  116.                 polish("xx",fcode,&flen,&vtype);
  117.                 start_token = false;
  118.                 flen = flen * 4;
  119.                 if (nparam>np) {gprint("Too many paramters got=%d want=%d \n",nparam,np);abort;}
  120.                 if (vtype==0) abort;
  121.                 add_pcode(pcode,plen,fcode,&flen);
  122.                }
  123.              } else {
  124.                 ct++;
  125.              }
  126.             }
  127.             if (last_typ==(3-ret)) {
  128.                 gprint("Function of wrong type Expecting {%s} \n",ns[ret]);
  129.                 abort;
  130.             }
  131.             last_typ = ret;
  132.             add_fn(pcode,plen,idx);
  133.             unary = 2; break;
  134.         } else if (idx>0) {
  135.             stack_fn(idx);
  136.             unary=1; break;
  137.         }
  138.  
  139.          /* Is it a user-defined function, identical code too above. */
  140.           sub_find(cts,&idx,&ret,&np,&plist);    /* 1,2 = +,- */
  141.           if (idx>0) {
  142.           dbg gprint("Found user function \n");
  143.             if (*tok(++ct)!='(') {
  144.                 gprint("Expecting left bracket after function name");
  145.                 abort;
  146.             }
  147.             {
  148.             char fcode[400];
  149.             char *fp;
  150.             int flen,nnn,vtype,nparam=0;
  151.             if (*tok(ct+1)!=')') {
  152.              while (*tok(ct)!=')') {
  153.                 ct++;
  154.                 nparam++;
  155.                 vtype = *(plist+nparam-1);
  156.                 nnn = *(plist+nparam);
  157.                 flen = 0;
  158.                 start_token = true;
  159.                 polish("xx",fcode,&flen,&vtype);
  160.                 start_token = false;
  161.                 flen = flen * 4;
  162.                 if (nparam>np) {gprint("Too many U paramters got=%d want=%d \n",nparam,np);abort;}
  163.                 if (vtype==0) abort;
  164.                 add_pcode(pcode,plen,fcode,&flen);
  165.               }
  166.              } else {
  167.                 ct++;
  168.              }
  169.             }
  170.             if (last_typ==(3-ret)) {
  171.                 gprint("Function of wrong type Expecting {%s} \n",ns[ret]);
  172.                 abort;
  173.             }
  174.             if (ret>0 && ret<3) last_typ = ret;
  175.             add_fn(pcode,plen,idx+200);
  176.             unary = 2; break;
  177.         } else if (idx>0) {
  178.             stack_fn(idx);
  179.             unary=1; break;
  180.         }
  181.  
  182.  
  183.         /* Is it a 'known' variable */
  184.         var_find(cts,&v,&ret);
  185.         if (v>=0) {
  186.             dbg gprint("Found variable %d \n",v);
  187.             if (last_typ==(3-ret)) {
  188.                 gprint("Expecting {%s} \n",ns[last_typ]);
  189.                 abort;
  190.             }
  191.             last_typ=ret;
  192.             if (ret==2) add_strvar(pcode,plen,v);
  193.             else add_var(pcode,plen,v);
  194.             unary=2; break;
  195.         }
  196.         /* Is it a atring */
  197.         if (*cts=='"') {
  198.           dbg gprint("Found string \n");
  199.             if (last_typ==1) {
  200.                 gprint("Expecting number {%s} \n",cts);
  201.                 abort;
  202.             }
  203.             last_typ = 2;
  204.             add_string(pcode,plen,un_quote(cts));    /* remove quotes */
  205.             unary = 2; break;
  206.         }
  207.         if (*cts=='(') { curpri = curpri + 100; break; }
  208.         if (*cts==')') {
  209.             if (curpri>0) {
  210.                 curpri = curpri - 100;
  211.                 unary = 2; break;
  212.             }
  213.             gprint("Too many right brackets found in exp \n");
  214.  
  215.         }
  216.         /* must be unquoted string, unless a binary operator
  217.         was found, in which case it is an undelcared variable */
  218.         if (not_string) {
  219.             dbg gprint("Found un-initialized variable {%s} /n",cts);
  220.             var_add(cts,&v,&ret);
  221.             last_typ=ret;
  222.             add_var(pcode,plen,v) ;
  223.             unary=2;
  224.             break;
  225.         }
  226.         last_typ = 2;
  227.         dbg printf("Unquoted string (%s) \n",cts);
  228.         add_string(pcode,plen,un_quote(cts));    /* remove quotes */
  229.         isa_string = true;
  230.         unary = 2; break;
  231.         isa_string = true;
  232.         add_string(pcode,plen,cts);
  233.         unary = 2;  /* Expecting end of expression next !! */
  234.         break;
  235.       case 2:  /* a binary operator, or space, or end of line */
  236.         if (ct>ntk || *cts==' ' || *cts==',' ) {
  237.             goto end_expression;
  238.         }
  239.         if (*cts==')' && curpri==0) {
  240.             goto end_expression;
  241.         }
  242. /* MIGHT (gives error with a$ = b$+c$) */
  243.         if (isa_string) {
  244.             gprint("Expression contained unquoted string\n");
  245.             abort;
  246.         }
  247.  
  248.         not_string = true;
  249.         /* Binary operators, +,-,*,/,^,<,>,<=,>=,.and.,.or. */
  250.         switch (*cts) {
  251.           case '+' : v = 1; p=2; break;
  252.           case '-' : v = 2; p=2; break;
  253.           case '*' : v = 3; p=3; break;
  254.           case '/' : v = 4; p=3; break;
  255.           case '^' : v = 5; p=4; break;
  256.           case '=' : v = 6; p=1; break;
  257.           case '<' : v = 7; p=1;
  258.             if (*tok(ct+1)=='=') {v=8;++ct;} break;
  259.           case '>' : v = 9;p=1;
  260.             if (*tok(ct+1)=='=') {v=10;++ct;} break;
  261.           case '.' : p=1;
  262.             if (strcmp(cts,".AND.")) {v=11;} break;
  263.             if (strcmp(cts,".OR.")) {v=12;} break;
  264.            default : v = 0 ; break;
  265.         }
  266.         if (v>0) {
  267.             if (last_typ<1 || last_typ > 3) last_typ = 1;
  268.             stack_bin(v,p);
  269.             dbg gprint("Found binary operator \n");
  270.             unary=1; break;
  271.         }
  272.         if (*cts==')') {
  273.             if (curpri>0) {
  274.                 curpri = curpri - 100;
  275.                 unary = 2; break;
  276.             }
  277.             if (term_bracket!=true) {
  278.                 gprint("Too many right brackets, expecting binary operator \n");
  279.                 abort;
  280.             }
  281.             goto end_expression;
  282.         }
  283.       }
  284.       if (++ct>ntk) { goto end_expression; }
  285. /*    gprint("Next token is {%s} \n",tok(ct)); */
  286.     }
  287. end_expression:
  288.     if (*tok(ct)==' ') (ct)++;
  289.     dbg gprint("Got expression , curtok=%d {%s} \n",ct,tok(ct));
  290.     *rtype = last_typ;
  291.       dbg gprint("Found END OF EXPRESSION \n");
  292.     if (!start_token) if (curpri!=0) {gprint("Missing right brackets");}
  293.     /* Pop everything off the stack */
  294.     for (i=nstk;i>0;i--) {
  295.         dbg gprint("Adding left over operators  I = %d  op=%d \n",i,stk[i]);
  296.         add_i(pcode,plen,stk[i]);
  297.     }
  298.     * ((long *) (pcode+savelen)) = (*plen - savelen)/4-1;  /* Set length of expression */
  299.     *plen = *plen/4;    /* change back to int count */
  300. return;
  301. fatal_err:
  302.     gprint("Aborting expression parsing. \n");
  303.     *plen = saveplen;
  304.     *rtype = 0;
  305. }
  306.  
  307. /*------------------------------------------------------------------*/
  308. /* append fcode to pcode */
  309. add_pcode(char *pcode,int *plen,char *fcode,int *flen)
  310. {
  311.     char *p;
  312.     p = pcode + *plen;
  313.     memcpy(p,fcode,*flen);
  314.     *plen = *plen + *flen;
  315. }
  316. add_i(char *pcode,int *plen,long i)
  317. {
  318.     long *p;
  319.     p = (long *) (pcode + *plen);
  320.     *p = i;
  321.     *plen += 4;
  322. }
  323. add_f(char *pcode,int *plen,double f)
  324. {
  325.     union { double d ; long l[2]; short s[4]; } both;
  326.     both.d = f;
  327.     add_i(pcode,plen,2);
  328.     add_i(pcode,plen,both.l[0]);
  329.     add_i(pcode,plen,both.l[1]);
  330. }
  331. add_var(char *pcode,int *plen,int i)
  332. {
  333.     add_i(pcode,plen,3);
  334.     add_i(pcode,plen,i);
  335. }
  336. add_strvar(char *pcode,int *plen,int i)
  337. {
  338.     add_i(pcode,plen,4);
  339.     add_i(pcode,plen,i);
  340. }
  341. add_fn(char *pcode, int *plen, int i)
  342. {
  343.     add_i(pcode,plen,i);
  344.     dbg gprint(" add Function %d \n",i);
  345. }
  346. add_string(char *pcode, int *plen, char *s)
  347. {
  348.     char *p;
  349.     int sl;
  350.     dbg gprint("adding string {%s} \n",s);
  351.     add_i(pcode,plen,5);
  352.     sl = strlen(s)+1;
  353.     p = pcode + *plen;
  354.     sl = ((sl + 3) & 0xfffc);
  355.      strncpy(p,s,sl);
  356.     *plen = *plen + sl;
  357. }
  358. /*------------------------------------------------------------------*/
  359. /* Remove the quotes from a string and return a modified pointer */
  360. char *un_quote(char *cts)
  361. {
  362.     int i,j;
  363.     i = strlen(cts);
  364.     if (*cts=='"') {
  365.         *(cts+i-1) = 0;
  366.         cts = cts + 1;
  367.     }
  368.     return cts;
  369. }
  370. /*------------------------------------------------------------------*/
  371. stack_op(char *pcode, int *plen, int stk[]
  372.     , int stkp[], int *nstk,  int i, int p)
  373. {
  374.     dbg gprint("Stack oper %d priority %d \n",i,p);
  375.     while (p<=stkp[*nstk] &&(*nstk)>0) {
  376.         dbg gprint("ADDING oper stack = %d  oper=%d \n",*nstk,stk[(*nstk)]);
  377.         add_i(pcode,plen,stk[(*nstk)--]);
  378.     }
  379.     stk[++(*nstk)] = i;
  380.     stkp[*nstk] = p;
  381. }
  382. isnumber(char *s)
  383. {
  384.     while (*s!='\0') {
  385.         if (isdigit(*s) || *s=='.' || *s=='E' ) s++;
  386.         else  return false;
  387.     }
  388.     return true;
  389. }
  390. lastchar(char *s, char c)
  391. {
  392.     while (*s!='\0') {s++;}
  393.     return *(--s)==c;
  394. }
  395.  
  396.  
  397.