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