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

  1. /*---------------------------------------------------------------------------*/
  2. #include "all.h"
  3. #include <math.h>
  4. #include <time.h>
  5. #include "mygraph.h"
  6. #include "eval.h"
  7. int debug_polish(long *pcode,int *zcp);
  8. typedef union {
  9.     struct {unsigned char r,g,b,f;} rgb ;
  10.     long l;
  11. } colortyp;
  12. colortyp colvar;
  13.  
  14. #define true (!false)
  15. #define false 0
  16. char *eval_str();
  17. int var_getstr(int varnum,char *s);
  18. int pass_marker(char *s);
  19. /*---------------------------------------------------------------------------*/
  20. /* bin = 10..29, binstr = 30..49, fn= 60...139, userfn=200..nnn */
  21. /* pcode:,  1=exp,len  2=double,val 3=var,long 4,string_var, 5=string,.../0 */
  22. /*---------------------------------------------------------------------------*/
  23. /* Input is exp-pcode, output is number or string */
  24.  
  25. char *binop[] = { "", "+", "-", "*", "/", "^", "=", "<", "<=", ">"
  26.             , ">=", "<>", ".AND.", ".OR." };
  27.  
  28. struct keyw { char *word; int index; int ret,np,p[5]; } ;
  29. extern struct keyw keywfn[] ;
  30.  
  31. double stk[60];
  32. int stk_var[100];
  33. char *stk_str[100];
  34. int stk_strlen[100];
  35. char sbuf[512];
  36. char sbuf2[112];
  37. int nstk=0;
  38. extern int gle_debug;
  39. #define dbg if ((gle_debug & 2)>0)
  40.  
  41. eval(long *pcode,int *cp,double *oval,char *ostr,int *otyp)
  42. {
  43.         /* a pointer to the pcode to execute         */
  44.         /* Current point in this line of pcode         */
  45.         /* place to put result number             */
  46.         /* place to put result string             */
  47.         /* place to put result type, 1=num, 2=str     */
  48.     union {double d; long l[1];} both;
  49.     int plen,i,j,l,c,cde;
  50.     time_t today;
  51.     double x1,y1,x2,y2;
  52.     double xx,yy,zz;
  53.  
  54.     dbg gprint("%%EXP-START, Current point in eval %d %d \n",*cp,(int) *(pcode+(*cp)));
  55.     dbg for (i=0;i<10;i++) gprint("%ld ",*(pcode+i));
  56.     dbg gprint("\n");
  57.     dbg debug_polish(pcode,cp);
  58.     if (*(pcode+(*cp))==8) {    /*  Single constant  */
  59.         both.l[0] = *(pcode+ ++(*cp));
  60.         both.l[1] = 0;
  61.         dbg gprint("Constant %ld \n",both.l[0]);
  62.         memcpy(oval,&both.d,sizeof(both.d));
  63.         memcpy(&both.d,oval,sizeof(both.d));
  64.         ++(*cp);
  65.         return;
  66.     }
  67.  
  68.     if (*(pcode+(*cp)++)!=1) {
  69.         gprint("PCODE, Expecting expression, v=%ld cp=%d \n",*(pcode+(--*(cp))),*cp);
  70.         return;
  71.     }
  72.     plen = *(pcode+*(cp));
  73.     dbg gprint(" plen = %d ",plen);
  74.     if (plen>1000) gprint("Expession is suspiciously long %d \n",plen);
  75.     for (c=(*cp)+1;c<=(plen+ *cp);c++) {
  76.       cde = *(pcode+c);
  77.       switch (*(pcode+c)) {
  78.         /* Special commands 1..9  ------------------------------- */
  79.         case 1:    /* Start of another expression (function param) */
  80.             c++;    /* skip over exp length */
  81.             break;
  82.         case 2: /* doubleing point number follows */
  83.             *otyp = 1;
  84.             both.l[0] = *(pcode+(++c));
  85.             both.l[1] = *(pcode+(++c));
  86.             stk[++nstk] =  both.d;
  87.              dbg gprint("Got double %f %d %f \n",stk[nstk],nstk,*(pcode+(c)));
  88.             break;
  89.         case 3: /* doubleing_point variable number follows */
  90.             *otyp = 1;
  91.             var_get(*(pcode+(++c)),&xx);
  92.             dbg gprint("Got variable value %ld %f \n",*(pcode+(c)),xx);
  93.             stk[++nstk] = xx;
  94.             break;
  95.         case 4: /* string variable number follows */
  96.             *otyp = 2;
  97.             var_getstr(*(pcode+(++c)),sbuf); nstk++;
  98.             if (stk_str[nstk]!=NULL)  myfree(stk_str[nstk]);
  99.             stk_str[nstk] = sdup(sbuf);
  100.              break;
  101.         case 5: /* Null terminated string follows (long alligned) */
  102.             *otyp = 2;
  103.             c++;nstk++;
  104.             strcpy(sbuf,eval_str(pcode,&c));
  105.             if (stk_str[nstk]!=NULL)  myfree(stk_str[nstk]);
  106.             stk_str[nstk] = sdup(sbuf);
  107.             break;
  108.         /* Numeric Binary operators 10..29 ----------------------- */
  109.         case 11:  /* + */
  110.             nstk--;
  111.             stk[nstk] = stk[nstk+1] + stk[nstk];
  112.             break;
  113.         case 12:  /* - */
  114.             stk[nstk-1] = stk[nstk-1] - stk[nstk];
  115.             nstk--;
  116.             break;
  117.         case 13:  /* * */
  118.             stk[nstk-1] = stk[nstk-1] * stk[nstk];
  119.             nstk--;
  120.             break;
  121.         case 14:  /* / */
  122.             if (stk[nstk]==0) {
  123.                 gprint("Divide by zero %g %g \n",
  124.                     stk[nstk-1],stk[nstk]);
  125.             } else {
  126.                 stk[nstk-1] = stk[nstk-1] / stk[nstk];
  127.             }
  128.             nstk--;
  129.             break;
  130.         case 15:  /* ^ */
  131.             stk[nstk-1] = pow(stk[nstk-1],stk[nstk]);
  132.             nstk--;
  133.             break;
  134.         case 16:  /* = */
  135.             nstk--;
  136.             if (stk[nstk] == stk[nstk+1]) stk[nstk]=true;
  137.             else stk[nstk]=false;
  138.             break;
  139.         case 17:  /* <   */
  140.             nstk--;
  141.             if (stk[nstk] < stk[nstk+1]) stk[nstk]=true;
  142.             else stk[nstk]=false;
  143.             break;
  144.         case 18:  /* <=  */
  145.             nstk--;
  146.             if (stk[nstk] <= stk[nstk+1]) stk[nstk]=true;
  147.             else stk[nstk]=false;
  148.             break;
  149.         case 19:  /* >   */
  150.             nstk--;
  151.             if (stk[nstk] > stk[nstk+1]) stk[nstk]=true;
  152.             else stk[nstk]=false;
  153.             break;
  154.         case 20:  /* >=  */
  155.             nstk--;
  156.             if (stk[nstk] >= stk[nstk+1]) stk[nstk]=true;
  157.             else stk[nstk]=false;
  158.             break;
  159.         case 21:  /*  <>  */
  160.             nstk--;
  161.             if (stk[nstk] != stk[nstk+1]) stk[nstk]=true;
  162.             else stk[nstk]=false;
  163.             break;
  164.         case 22:  /* .AND.  */
  165.             nstk--;
  166.             if (stk[nstk] && stk[nstk+1]) stk[nstk]=true;
  167.             else stk[nstk]=false;
  168.             break;
  169.         case 23:  /* .OR.   */
  170.             nstk--;
  171.             if (stk[nstk] || stk[nstk+1]) stk[nstk]=true;
  172.             else stk[nstk]=false;
  173.             break;
  174.         /* String Binary operators 30..49 ----------------------- */
  175.         case 31:  /* + */
  176.             *otyp = 2;
  177.             nstk--;
  178.             if (stk_str[nstk]!=NULL) strcpy(sbuf,stk_str[nstk]);
  179.             if (stk_str[nstk+1]!=NULL) strcat(sbuf,stk_str[nstk+1]);
  180.             if (stk_str[nstk] != NULL) myfree(stk_str[nstk]);
  181.             stk_str[nstk] = sdup(sbuf);
  182.             break;
  183.         case 32:  /* - */
  184.             break;
  185.         case 33:  /* * */
  186.             break;
  187.         case 34:  /* / */
  188.             break;
  189.         case 35:  /* ^ */
  190.             break;
  191.         case 36:  /* = */
  192.             break;
  193.         case 37:  /* <   */
  194.             break;
  195.         case 38:  /* <=  */
  196.             break;
  197.         case 39:  /* >   */
  198.             break;
  199.         case 40:  /* >=  */
  200.             break;
  201.         case 41:  /* .AND.  */
  202.             break;
  203.         case 42:  /* .OR.   */
  204.             break;
  205.  
  206.         /* Built in functions 60..199 ----------------------------- */
  207.         case f_plus: /* unary plus */
  208.             break;
  209.         case f_minus: /* unary minus */
  210.             stk[nstk] = -stk[nstk];
  211.             break;
  212.         case f_abs: /* abs */
  213.             stk[nstk] = fabs(stk[nstk]);
  214.             break;
  215.         case f_atn: /* atn */
  216.             if (stk[nstk]<0) stk[nstk] = -atan(-stk[nstk]);
  217.             else stk[nstk] = atan(stk[nstk]);
  218.             break;
  219.         case f_cell: /* cell(x,y) */
  220.                get_cell(stk[nstk-1],stk[nstk],&stk[nstk-1]);
  221.                nstk--;
  222.                break;
  223.         case f_miss: /* miss(x,y) */
  224.             nstk--;
  225.                if (strcmp(scell(stk[nstk],stk[nstk+1]),"-")==0) {
  226.                    stk[nstk]=true;
  227.                } else {
  228.                    stk[nstk]=false;
  229.                }
  230.                break;
  231.         case f_cos: /* cos */
  232.             stk[nstk] = cos(stk[nstk]);
  233.             break;
  234.         case f_date: /* date$ */
  235.             *otyp = 2;
  236.             time(&today);
  237.             strcpy(sbuf2,ctime(&today));
  238.             strcpy(sbuf,sbuf2);
  239.             strcpy(sbuf+11,sbuf2+20);
  240.             sbuf[strlen(sbuf)-1] = 0;
  241.             setdstr(&stk_str[++nstk],sbuf);
  242.             break;
  243.         case f_exp: /* exp */
  244.             stk[nstk] = exp(stk[nstk]);
  245.             break;
  246.         case f_fix: /* fix*/
  247.             stk[nstk] = floor(stk[nstk]);
  248.             break;
  249.         case f_left: /* left$ */
  250.             *otyp = 2;
  251.             ncpy(sbuf,stk_str[nstk-1],(int) stk[nstk]);
  252.             setdstr(&stk_str[--nstk],sbuf);
  253.             break;
  254.         case f_len: /* len */
  255.             *otyp = 1;
  256.             stk[nstk] = strlen(stk_str[nstk]);
  257.             break;
  258.         case f_log: /* log */
  259.             stk[nstk] = log(stk[nstk]);
  260.             break;
  261.         case f_log10: /* log10 */
  262.             stk[nstk] = log10(stk[nstk]);
  263.             break;
  264.         case f_not: /* not */
  265.             break;
  266.         case f_num: /* num$ */
  267.             *otyp = 2;
  268.             sprintf(sbuf,"%g ",stk[nstk]);
  269.             if (stk_str[nstk] != NULL) myfree(stk_str[nstk]);
  270.             stk_str[nstk] = sdup(sbuf);
  271.             break;
  272.         case f_num1: /* num1$ */
  273.             *otyp = 2;
  274.             sprintf(sbuf,"%g",stk[nstk]);
  275.             if (stk_str[nstk] != NULL) myfree(stk_str[nstk]);
  276.             stk_str[nstk] = sdup(sbuf);
  277.             break;
  278.         case f_pos: /* pos */
  279.             break;
  280.         case f_right: /* right$ */
  281.             *otyp = 2;
  282.             strcpy(sbuf,stk_str[nstk-1] + (int) stk[nstk] - 1);
  283.             setdstr(&stk_str[--nstk],sbuf);
  284.             break;
  285.         case f_rnd: /* rnd */
  286.             break;
  287.         case f_seg: /* seg$ */
  288.             *otyp = 2;
  289.             strcpy(sbuf,stk_str[nstk-2] + (int) stk[nstk-1] - 1);
  290.             ncpy(sbuf2,sbuf,(int) stk[nstk] -  stk[nstk-1] + 1);
  291.             nstk-=2;
  292.             setdstr(&stk_str[nstk],sbuf2);
  293.             break;
  294.         case f_sgn: /* sgn */
  295.             break;
  296.         case f_sin: /* sin */
  297.             stk[nstk] = sin(stk[nstk]);
  298.             break;
  299.         case f_sqr: /* sqr */
  300.             stk[nstk] = pow(stk[nstk],2.0);
  301.             break;
  302.         case f_sqrt: /* sqrt */
  303.             stk[nstk] = sqrt(stk[nstk]);
  304.             break;
  305.         case f_tan: /* tan */
  306.             stk[nstk] = tan(stk[nstk]);
  307.             break;
  308.         case f_time: /* time$ */
  309.             *otyp = 2;
  310.             time(&today);
  311.             ncpy(sbuf,ctime(&today)+11,9);
  312.             setdstr(&stk_str[++nstk],sbuf);
  313.             break;
  314.         case f_val: /* val */
  315.             break;
  316.         /* User function 200..nnn , or error */
  317.         default:
  318.               /* Is it a user defined function */
  319.             if (*(pcode+c)>200)  {
  320.     /*            pass the address of some numbers */
  321.     /*            pass address of variables if possible*/
  322.                 sub_call(*(pcode+c)-200,stk,stk_str,&nstk);
  323.             }
  324.             else gprint("Unrecognezed pcode exp prim %d at position=%d \n",*(pcode+c),c);
  325.             break;
  326.       }
  327.     }
  328.     dbg printf("RESULT ISa ==== %d [1] %f   [nstk] %f \n",nstk,stk[1],stk[nstk]);
  329.     dbg scr_getch();
  330.     memcpy( oval,&(stk[nstk]),sizeof(double));
  331.     *ostr = '\0';
  332.     if (*otyp==2) if (stk_str[nstk]!=NULL) strcpy(ostr,stk_str[nstk]);
  333.     if (*otyp==2) dbg gprint("Evaluated string = {%s} \n",ostr);
  334.     nstk--;
  335.     if (nstk<0) {
  336.          gprint("Stack stuffed up in EVAL %d \n",nstk);
  337.         nstk = 0;
  338.     }
  339.     *cp = *cp + plen + 1;
  340. }
  341.  
  342. debug_polish(long *pcode,int *zcp)
  343. {
  344.     long *cp,cpval;
  345.     int plen,i,j,c,cde;
  346.     cpval = *zcp;
  347.     cp = &cpval;
  348.     if (*(pcode+(*cp)++)!=1) {
  349.         gprint("Expecting expression, v=%d \n",(int) *(pcode+--(*cp)) );
  350.         return;
  351.     }
  352.     plen = *(pcode+*(cp));
  353.     gprint("Expression length %d current point %d \n",plen,(int) *cp);
  354.     if (plen>1000) gprint("Expession is suspiciously int %d \n",plen);
  355.     for (c=(*cp)+1;(c-*cp)<=plen;c++) {
  356.       cde = *(pcode+c);
  357.     gprint("Code=%d ",cde);
  358.         if (cde==0) {
  359.             gprint("# ZERO \n");
  360.         } else if (cde==1) {
  361.             gprint("# Expression, length ??? \n");
  362.             c++;
  363.         } else if (cde==2) {
  364.             gprint("# doubleing point number %8x \n",*(pcode+(++c)));
  365.             c++;    /* because it's a DOUBLE which is a quad word */
  366.         } else if (cde==3) {
  367.             gprint("# Variable \n");  c++;
  368.         } else if (cde==4) {
  369.             gprint("# String Variable \n"); c++;
  370.         } else if (cde==5) {
  371.             c++;
  372.             gprint("# String constant {%s} \n",eval_str(pcode,&c));
  373.         } else if (cde<29) {
  374.             gprint("# Binary operator {%s} \n",binop[cde-10]);
  375.         } else if (cde<49) {
  376.             gprint("# Binary string op {%s} \n",binop[cde-30]);
  377.         } else if (cde<200) {
  378.             gprint("# Built in function (with salt) {%s} \n",keywfn[cde-60].word);
  379.         } else {
  380.             gprint("# User defined function %d \n",cde);
  381.         }
  382.  
  383.     }
  384. }
  385.  
  386. char *eval_str(long *pcode,int *plen)
  387. {
  388.     char *s;
  389.     int sl;
  390.     s = (char *) (pcode+*plen);
  391.     sl = strlen(s)+1;
  392.     sl = ((sl + 3) & 0xfffc);
  393.     *plen = *plen + sl/4 - 1;
  394.     return s;
  395. }
  396.  
  397. setdstr(char **s,char *in)
  398. {
  399.     if (*s != NULL) myfree(*s);
  400.     *s = sdup(in);
  401. }
  402. eval_setxy(int x, int y)
  403. {
  404.     static int xx= -1,yy= -1,type;
  405.     if (xx== -1) var_findadd("C",&xx,&type);
  406.     if (yy== -1) var_findadd("R",&yy,&type);
  407.     var_set(xx,(double) x);
  408.     var_set(yy,(double) y);
  409. }
  410. eval_setxyd(int x, int y)
  411. {
  412.     static int xx= -1,yy= -1,type;
  413.     if (xx== -1) var_findadd("DC",&xx,&type);
  414.     if (yy== -1) var_findadd("DR",&yy,&type);
  415.     var_set(xx,(double) x);
  416.     var_set(yy,(double) y);
  417. }
  418.