home *** CD-ROM | disk | FTP | other *** search
- /*---------------------------------------------------------------------------*/
- #include "all.h"
- #include <math.h>
- #include <time.h>
- #include "mygraph.h"
- #include "eval.h"
- int debug_polish(long *pcode,int *zcp);
- typedef union {
- struct {unsigned char r,g,b,f;} rgb ;
- long l;
- } colortyp;
- colortyp colvar;
-
- #define true (!false)
- #define false 0
- char *eval_str();
- int var_getstr(int varnum,char *s);
- int pass_marker(char *s);
- /*---------------------------------------------------------------------------*/
- /* bin = 10..29, binstr = 30..49, fn= 60...139, userfn=200..nnn */
- /* pcode:, 1=exp,len 2=double,val 3=var,long 4,string_var, 5=string,.../0 */
- /*---------------------------------------------------------------------------*/
- /* Input is exp-pcode, output is number or string */
-
- char *binop[] = { "", "+", "-", "*", "/", "^", "=", "<", "<=", ">"
- , ">=", "<>", ".AND.", ".OR." };
-
- struct keyw { char *word; int index; int ret,np,p[5]; } ;
- extern struct keyw keywfn[] ;
-
- double stk[60];
- int stk_var[100];
- char *stk_str[100];
- int stk_strlen[100];
- char sbuf[512];
- char sbuf2[112];
- int nstk=0;
- extern int gle_debug;
- #define dbg if ((gle_debug & 2)>0)
-
- eval(long *pcode,int *cp,double *oval,char *ostr,int *otyp)
- {
- /* a pointer to the pcode to execute */
- /* Current point in this line of pcode */
- /* place to put result number */
- /* place to put result string */
- /* place to put result type, 1=num, 2=str */
- union {double d; long l[1];} both;
- int plen,i,j,l,c,cde;
- time_t today;
- double x1,y1,x2,y2;
- double xx,yy,zz;
-
- dbg gprint("%%EXP-START, Current point in eval %d %d \n",*cp,(int) *(pcode+(*cp)));
- dbg for (i=0;i<10;i++) gprint("%ld ",*(pcode+i));
- dbg gprint("\n");
- dbg debug_polish(pcode,cp);
- if (*(pcode+(*cp))==8) { /* Single constant */
- both.l[0] = *(pcode+ ++(*cp));
- both.l[1] = 0;
- dbg gprint("Constant %ld \n",both.l[0]);
- memcpy(oval,&both.d,sizeof(both.d));
- memcpy(&both.d,oval,sizeof(both.d));
- ++(*cp);
- return;
- }
-
- if (*(pcode+(*cp)++)!=1) {
- gprint("PCODE, Expecting expression, v=%ld cp=%d \n",*(pcode+(--*(cp))),*cp);
- return;
- }
- plen = *(pcode+*(cp));
- dbg gprint(" plen = %d ",plen);
- if (plen>1000) gprint("Expession is suspiciously long %d \n",plen);
- for (c=(*cp)+1;c<=(plen+ *cp);c++) {
- cde = *(pcode+c);
- switch (*(pcode+c)) {
- /* Special commands 1..9 ------------------------------- */
- case 1: /* Start of another expression (function param) */
- c++; /* skip over exp length */
- break;
- case 2: /* doubleing point number follows */
- *otyp = 1;
- both.l[0] = *(pcode+(++c));
- both.l[1] = *(pcode+(++c));
- stk[++nstk] = both.d;
- dbg gprint("Got double %f %d %f \n",stk[nstk],nstk,*(pcode+(c)));
- break;
- case 3: /* doubleing_point variable number follows */
- *otyp = 1;
- var_get(*(pcode+(++c)),&xx);
- dbg gprint("Got variable value %ld %f \n",*(pcode+(c)),xx);
- stk[++nstk] = xx;
- break;
- case 4: /* string variable number follows */
- *otyp = 2;
- var_getstr(*(pcode+(++c)),sbuf); nstk++;
- if (stk_str[nstk]!=NULL) myfree(stk_str[nstk]);
- stk_str[nstk] = sdup(sbuf);
- break;
- case 5: /* Null terminated string follows (long alligned) */
- *otyp = 2;
- c++;nstk++;
- strcpy(sbuf,eval_str(pcode,&c));
- if (stk_str[nstk]!=NULL) myfree(stk_str[nstk]);
- stk_str[nstk] = sdup(sbuf);
- break;
- /* Numeric Binary operators 10..29 ----------------------- */
- case 11: /* + */
- nstk--;
- stk[nstk] = stk[nstk+1] + stk[nstk];
- break;
- case 12: /* - */
- stk[nstk-1] = stk[nstk-1] - stk[nstk];
- nstk--;
- break;
- case 13: /* * */
- stk[nstk-1] = stk[nstk-1] * stk[nstk];
- nstk--;
- break;
- case 14: /* / */
- if (stk[nstk]==0) {
- gprint("Divide by zero %g %g \n",
- stk[nstk-1],stk[nstk]);
- } else {
- stk[nstk-1] = stk[nstk-1] / stk[nstk];
- }
- nstk--;
- break;
- case 15: /* ^ */
- stk[nstk-1] = pow(stk[nstk-1],stk[nstk]);
- nstk--;
- break;
- case 16: /* = */
- nstk--;
- if (stk[nstk] == stk[nstk+1]) stk[nstk]=true;
- else stk[nstk]=false;
- break;
- case 17: /* < */
- nstk--;
- if (stk[nstk] < stk[nstk+1]) stk[nstk]=true;
- else stk[nstk]=false;
- break;
- case 18: /* <= */
- nstk--;
- if (stk[nstk] <= stk[nstk+1]) stk[nstk]=true;
- else stk[nstk]=false;
- break;
- case 19: /* > */
- nstk--;
- if (stk[nstk] > stk[nstk+1]) stk[nstk]=true;
- else stk[nstk]=false;
- break;
- case 20: /* >= */
- nstk--;
- if (stk[nstk] >= stk[nstk+1]) stk[nstk]=true;
- else stk[nstk]=false;
- break;
- case 21: /* <> */
- nstk--;
- if (stk[nstk] != stk[nstk+1]) stk[nstk]=true;
- else stk[nstk]=false;
- break;
- case 22: /* .AND. */
- nstk--;
- if (stk[nstk] && stk[nstk+1]) stk[nstk]=true;
- else stk[nstk]=false;
- break;
- case 23: /* .OR. */
- nstk--;
- if (stk[nstk] || stk[nstk+1]) stk[nstk]=true;
- else stk[nstk]=false;
- break;
- /* String Binary operators 30..49 ----------------------- */
- case 31: /* + */
- *otyp = 2;
- nstk--;
- if (stk_str[nstk]!=NULL) strcpy(sbuf,stk_str[nstk]);
- if (stk_str[nstk+1]!=NULL) strcat(sbuf,stk_str[nstk+1]);
- if (stk_str[nstk] != NULL) myfree(stk_str[nstk]);
- stk_str[nstk] = sdup(sbuf);
- break;
- case 32: /* - */
- break;
- case 33: /* * */
- break;
- case 34: /* / */
- break;
- case 35: /* ^ */
- break;
- case 36: /* = */
- break;
- case 37: /* < */
- break;
- case 38: /* <= */
- break;
- case 39: /* > */
- break;
- case 40: /* >= */
- break;
- case 41: /* .AND. */
- break;
- case 42: /* .OR. */
- break;
-
- /* Built in functions 60..199 ----------------------------- */
- case f_plus: /* unary plus */
- break;
- case f_minus: /* unary minus */
- stk[nstk] = -stk[nstk];
- break;
- case f_abs: /* abs */
- stk[nstk] = fabs(stk[nstk]);
- break;
- case f_atn: /* atn */
- if (stk[nstk]<0) stk[nstk] = -atan(-stk[nstk]);
- else stk[nstk] = atan(stk[nstk]);
- break;
- case f_cell: /* cell(x,y) */
- get_cell(stk[nstk-1],stk[nstk],&stk[nstk-1]);
- nstk--;
- break;
- case f_miss: /* miss(x,y) */
- nstk--;
- if (strcmp(scell(stk[nstk],stk[nstk+1]),"-")==0) {
- stk[nstk]=true;
- } else {
- stk[nstk]=false;
- }
- break;
- case f_cos: /* cos */
- stk[nstk] = cos(stk[nstk]);
- break;
- case f_date: /* date$ */
- *otyp = 2;
- time(&today);
- strcpy(sbuf2,ctime(&today));
- strcpy(sbuf,sbuf2);
- strcpy(sbuf+11,sbuf2+20);
- sbuf[strlen(sbuf)-1] = 0;
- setdstr(&stk_str[++nstk],sbuf);
- break;
- case f_exp: /* exp */
- stk[nstk] = exp(stk[nstk]);
- break;
- case f_fix: /* fix*/
- stk[nstk] = floor(stk[nstk]);
- break;
- case f_left: /* left$ */
- *otyp = 2;
- ncpy(sbuf,stk_str[nstk-1],(int) stk[nstk]);
- setdstr(&stk_str[--nstk],sbuf);
- break;
- case f_len: /* len */
- *otyp = 1;
- stk[nstk] = strlen(stk_str[nstk]);
- break;
- case f_log: /* log */
- stk[nstk] = log(stk[nstk]);
- break;
- case f_log10: /* log10 */
- stk[nstk] = log10(stk[nstk]);
- break;
- case f_not: /* not */
- break;
- case f_num: /* num$ */
- *otyp = 2;
- sprintf(sbuf,"%g ",stk[nstk]);
- if (stk_str[nstk] != NULL) myfree(stk_str[nstk]);
- stk_str[nstk] = sdup(sbuf);
- break;
- case f_num1: /* num1$ */
- *otyp = 2;
- sprintf(sbuf,"%g",stk[nstk]);
- if (stk_str[nstk] != NULL) myfree(stk_str[nstk]);
- stk_str[nstk] = sdup(sbuf);
- break;
- case f_pos: /* pos */
- break;
- case f_right: /* right$ */
- *otyp = 2;
- strcpy(sbuf,stk_str[nstk-1] + (int) stk[nstk] - 1);
- setdstr(&stk_str[--nstk],sbuf);
- break;
- case f_rnd: /* rnd */
- break;
- case f_seg: /* seg$ */
- *otyp = 2;
- strcpy(sbuf,stk_str[nstk-2] + (int) stk[nstk-1] - 1);
- ncpy(sbuf2,sbuf,(int) stk[nstk] - stk[nstk-1] + 1);
- nstk-=2;
- setdstr(&stk_str[nstk],sbuf2);
- break;
- case f_sgn: /* sgn */
- break;
- case f_sin: /* sin */
- stk[nstk] = sin(stk[nstk]);
- break;
- case f_sqr: /* sqr */
- stk[nstk] = pow(stk[nstk],2.0);
- break;
- case f_sqrt: /* sqrt */
- stk[nstk] = sqrt(stk[nstk]);
- break;
- case f_tan: /* tan */
- stk[nstk] = tan(stk[nstk]);
- break;
- case f_time: /* time$ */
- *otyp = 2;
- time(&today);
- ncpy(sbuf,ctime(&today)+11,9);
- setdstr(&stk_str[++nstk],sbuf);
- break;
- case f_val: /* val */
- break;
- /* User function 200..nnn , or error */
- default:
- /* Is it a user defined function */
- if (*(pcode+c)>200) {
- /* pass the address of some numbers */
- /* pass address of variables if possible*/
- sub_call(*(pcode+c)-200,stk,stk_str,&nstk);
- }
- else gprint("Unrecognezed pcode exp prim %d at position=%d \n",*(pcode+c),c);
- break;
- }
- }
- dbg printf("RESULT ISa ==== %d [1] %f [nstk] %f \n",nstk,stk[1],stk[nstk]);
- dbg scr_getch();
- memcpy( oval,&(stk[nstk]),sizeof(double));
- *ostr = '\0';
- if (*otyp==2) if (stk_str[nstk]!=NULL) strcpy(ostr,stk_str[nstk]);
- if (*otyp==2) dbg gprint("Evaluated string = {%s} \n",ostr);
- nstk--;
- if (nstk<0) {
- gprint("Stack stuffed up in EVAL %d \n",nstk);
- nstk = 0;
- }
- *cp = *cp + plen + 1;
- }
-
- debug_polish(long *pcode,int *zcp)
- {
- long *cp,cpval;
- int plen,i,j,c,cde;
- cpval = *zcp;
- cp = &cpval;
- if (*(pcode+(*cp)++)!=1) {
- gprint("Expecting expression, v=%d \n",(int) *(pcode+--(*cp)) );
- return;
- }
- plen = *(pcode+*(cp));
- gprint("Expression length %d current point %d \n",plen,(int) *cp);
- if (plen>1000) gprint("Expession is suspiciously int %d \n",plen);
- for (c=(*cp)+1;(c-*cp)<=plen;c++) {
- cde = *(pcode+c);
- gprint("Code=%d ",cde);
- if (cde==0) {
- gprint("# ZERO \n");
- } else if (cde==1) {
- gprint("# Expression, length ??? \n");
- c++;
- } else if (cde==2) {
- gprint("# doubleing point number %8x \n",*(pcode+(++c)));
- c++; /* because it's a DOUBLE which is a quad word */
- } else if (cde==3) {
- gprint("# Variable \n"); c++;
- } else if (cde==4) {
- gprint("# String Variable \n"); c++;
- } else if (cde==5) {
- c++;
- gprint("# String constant {%s} \n",eval_str(pcode,&c));
- } else if (cde<29) {
- gprint("# Binary operator {%s} \n",binop[cde-10]);
- } else if (cde<49) {
- gprint("# Binary string op {%s} \n",binop[cde-30]);
- } else if (cde<200) {
- gprint("# Built in function (with salt) {%s} \n",keywfn[cde-60].word);
- } else {
- gprint("# User defined function %d \n",cde);
- }
-
- }
- }
-
- char *eval_str(long *pcode,int *plen)
- {
- char *s;
- int sl;
- s = (char *) (pcode+*plen);
- sl = strlen(s)+1;
- sl = ((sl + 3) & 0xfffc);
- *plen = *plen + sl/4 - 1;
- return s;
- }
-
- setdstr(char **s,char *in)
- {
- if (*s != NULL) myfree(*s);
- *s = sdup(in);
- }
- eval_setxy(int x, int y)
- {
- static int xx= -1,yy= -1,type;
- if (xx== -1) var_findadd("C",&xx,&type);
- if (yy== -1) var_findadd("R",&yy,&type);
- var_set(xx,(double) x);
- var_set(yy,(double) y);
- }
- eval_setxyd(int x, int y)
- {
- static int xx= -1,yy= -1,type;
- if (xx== -1) var_findadd("DC",&xx,&type);
- if (yy== -1) var_findadd("DR",&yy,&type);
- var_set(xx,(double) x);
- var_set(yy,(double) y);
- }
-