home *** CD-ROM | disk | FTP | other *** search
- char *un_quote();
- char *ns[3] = {"Nothing","Number","String"};
- extern int gle_debug;
- /*---------------------------------------------------------------------------*/
- #include "all.h"
-
- #include <math.h>
- int add_strvar(char *pcode,int *plen,int i);
- int token_norm(void);
- int token_space(void);
-
- #define true (!false)
- #define false 0
- #define tok(n) tk[n]
- #define abort goto fatal_err
- /*---------------------------------------------------------------------------*/
- /* bin = 10..29, binstr = 30..49, fn= 60...139, userfn=200..nnn */
- #define stack_bin(i,p) stack_op(pcode,plen,stk,stkp,&nstk,i-10+(last_typ*20),p+curpri)
- #define stack_fn(i) stack_op(pcode,plen,stk,stkp,&nstk,i+60,10+curpri)
- #define dbg if ((gle_debug & 4)>0)
- /*---------------------------------------------------------------------------*/
- /* Input is token array, and pointer to current point, output is pcode */
-
- /* typedef struct op_key (*OPKEY)[100]; */
- /* typedef char (*(*TOKENS)[500]); */
-
- int zpolish(TOKENS tk,int *ntok,int *curtok,char *pcode,int *plen,int *rtype);
- polish(char *expr,char *pcode,int *plen,int *rtype)
- {
- static char inbuff[200];
- static char *tk[500];
- static char tkbuff[500];
- static int ntk,ct;
- char *space_str=" ";
- static char buff[50];
- static int start_token;
- double xxx;
- int idx,ret,np,*plist,saveplen,term_bracket;
- int curpri=0;
- int i,j,v,p,savelen,isa_string,not_string,last_typ;
- int nstk=0,stk[50],stkp[50]; /* stack for operators */
- int unary=1; /* binary or unary operation expected */
- int ln; /* length of current token */
- char *cts; /* current token */
- /* last_typ, 1=number,2=string */
-
- if (tk[400]==NULL) for (i=0;i<500;i++) tk[i] = space_str;
- isa_string = false;
- not_string = false;
- if (*rtype==1) not_string = true;
- /* if (*rtype==2) isa_string = true; */
- *plen = *plen*4; /* change into byte count */
- if (*rtype>0) term_bracket = true;
- last_typ = *rtype;
- saveplen = *plen;
-
- add_i(pcode,plen,1); /* expression follows */
- savelen = *plen; /* Used to set acutal length at end */
- add_i(pcode,plen,0); /* Length of expression */
- dbg gprint("====Start of expression {%s} \n",expr);
- if (strlen(expr)==0) {gprint("Zero length expression\n"); return;}
- if (!start_token) {
- ntk = 0; ct=1;
- token_norm();
- token(expr,(TOKENS) tk,&ntk,tkbuff);
- token_space();
- }
- for (;;) {
- cts = tok(ct);
- dbg gprint("First word token=%d via (1=unary %d) cts {%s} %d \n "
- ,ct,unary,cts,strlen(cts));
- ln = strlen(cts);
- switch (unary) {
- case 1: /* a unary operator, or function, or number or variable */
- if (ln==1 && (*cts=='-' || *cts=='E')) goto notnumber;
- if (isnumber(cts)) {
- evalagain: dbg gprint("Found number {%s}\n",cts);
- if (lastchar(cts,'E')) {
- strcpy(buff,cts);
- strcat(buff,tok(++ct));
- if (*tok(ct)=='-' || *tok(ct)=='+') {
- strcat(buff,tok(++ct));
- }
- tok(ct) = buff;
- cts = tok(ct);
- goto evalagain;
- }
- xxx = atof(cts);
- add_f(pcode,plen,xxx);
- if (last_typ==2) gprint("Expecting string {%s} \n",cts);
- last_typ = 1;
- unary=2; break;
- }
- notnumber: /* NOT a number, Is it a built in function */
- /* int idx,ret,np,*plist; */
- find_un(cts,&idx,&ret,&np,&plist); /* 1,2 = +,- */
- if (idx>3) {
- dbg gprint("Found built in function \n");
- if (*tok(++ct)!='(') {
- gprint("Expecting left bracket after function name");
- abort;
- }
- {
- char fcode[400];
- char *fp;
- int flen,vtype,nparam=0;
- if (*tok(ct+1)!=')') {
- while (*tok(ct)!=')') {
- nparam++;
- vtype = *(plist+nparam-1);
- flen = 0;
- (ct)++;
- start_token = true;
- polish("xx",fcode,&flen,&vtype);
- start_token = false;
- flen = flen * 4;
- if (nparam>np) {gprint("Too many parameters got=%d want=%d \n",nparam,np);abort;}
- if (vtype==0) abort;
- add_pcode(pcode,plen,fcode,&flen);
- }
- } else {
- ct++;
- }
- }
- if (last_typ==(3-ret)) {
- gprint("Function of wrong type Expecting {%s} \n",ns[ret]);
- abort;
- }
- last_typ = ret;
- add_fn(pcode,plen,idx+60);
- unary = 2; break;
- } else if (idx>0) {
- stack_fn(idx);
- unary=1; break;
- }
-
- /* Is it a user-defined function, identical code too above. */
- sub_find(cts,&idx,&ret,&np,&plist); /* 1,2 = +,- */
- if (idx>0) {
- dbg gprint("Found user function \n");
- if (*tok(++ct)!='(') {
- gprint("Expecting left bracket after function name");
- abort;
- }
- {
- char fcode[400];
- char *fp;
- int flen,nnn,vtype,nparam=0;
- if (*tok(ct+1)!=')') {
- while (*tok(ct)!=')') {
- ct++;
- nparam++;
- vtype = *(plist+nparam-1);
- nnn = *(plist+nparam);
- flen = 0;
- start_token = true;
- polish("xx",fcode,&flen,&vtype);
- start_token = false;
- flen = flen * 4;
- if (nparam>np) {gprint("Too many U paramters got=%d want=%d \n",nparam,np);abort;}
- if (vtype==0) abort;
- add_pcode(pcode,plen,fcode,&flen);
- }
- } else {
- ct++;
- }
- }
- if (last_typ==(3-ret)) {
- gprint("Function of wrong type Expecting {%s} \n",ns[ret]);
- abort;
- }
- if (ret>0 && ret<3) last_typ = ret;
- add_fn(pcode,plen,idx+200);
- unary = 2; break;
- } else if (idx>0) {
- stack_fn(idx);
- unary=1; break;
- }
-
-
- /* Is it a 'known' variable */
- var_find(cts,&v,&ret);
- if (v>=0) {
- dbg gprint("Found variable %d \n",v);
- /* if (last_typ==(3-ret)) {
- gprint("Expecting {%s} \n",ns[last_typ]);
- abort;
- }*/
- last_typ=ret;
- if (ret==2) add_strvar(pcode,plen,v);
- else add_var(pcode,plen,v);
- unary=2; break;
- }
- /* Is it a atring */
- if (*cts=='"') {
- dbg gprint("Found string \n");
- /*if (last_typ==1) {
- gprint("Expecting number {%s} \n",cts);
- abort;
- }*/
- last_typ = 2;
- add_string(pcode,plen,un_quote(cts)); /* remove quotes */
- unary = 2; break;
- }
- if (*cts=='(') { curpri = curpri + 100; break; }
- if (*cts==')') {
- if (curpri>0) {
- curpri = curpri - 100;
- unary = 2; break;
- }
- gprint("Too many right brackets found in exp \n");
-
- }
- /* must be unquoted string, unless a binary operator
- was found, in which case it is an undelcared variable */
- if (not_string) {
- dbg gprint("Found un-initialized variable {%s} /n",cts);
- var_add(cts,&v,&ret);
- last_typ=ret;
- add_var(pcode,plen,v) ;
- unary=2;
- break;
- }
- last_typ = 2;
- dbg printf("Unquoted string (%s) \n",cts);
- add_string(pcode,plen,un_quote(cts)); /* remove quotes */
- isa_string = true;
- unary = 2; break;
- #if 0
- /* this code fragment is redundant ! */
- isa_string = true;
- add_string(pcode,plen,cts);
- unary = 2; /* Expecting end of expression next !! */
- break;
- #endif
- case 2: /* a binary operator, or space, or end of line */
- if (ct>ntk || *cts==' ' || *cts==',' ) {
- goto end_expression;
- }
- if (*cts==')' && curpri==0) {
- goto end_expression;
- }
- /* MIGHT (gives error with a$ = b$+c$) */
- if (isa_string) {
- gprint("Expression contained unquoted string\n");
- abort;
- }
-
- not_string = true;
- /* Binary operators, +,-,*,/,^,<,>,<=,>=,.and.,.or. */
- switch (*cts) {
- case '+' : v = 1; p=2; break;
- case '-' : v = 2; p=2; break;
- case '*' : v = 3; p=3; break;
- case '/' : v = 4; p=3; break;
- case '^' : v = 5; p=4; break;
- case '=' : v = 6; p=1; break;
- case '&' : v = 12; p=1; break;
- case '|' : v = 13; p=1; break;
- case '<' : v = 7; p=1;
- if (*tok(ct+1)=='=') {v=8;++ct; break;}
- if (*tok(ct+1)=='>') {v=11;++ct; break;}
- break;
- case '>' : v = 9;p=1;
- if (*tok(ct+1)=='=') {v=10;++ct; break;}
- break;
- case '.' : p=1;
- if (strcmp(cts,".AND.")==0) {v=12; break;}
- if (strcmp(cts,".OR.")==0) {v=13; break;}
- break;
- default : v = 0 ; break;
- }
- if (v>0) {
- if (last_typ<1 || last_typ > 3) last_typ = 1;
- dbg gprint("stack, i %d, type %d \n",v,last_typ);
- stack_bin(v,p);
- dbg gprint("Found binary operator \n");
- unary=1; break;
- }
- if (*cts==')') {
- if (curpri>0) {
- curpri = curpri - 100;
- unary = 2; break;
- }
- if (term_bracket!=true) {
- gprint("Too many right brackets, expecting binary operator \n");
- abort;
- }
- goto end_expression;
- }
- }
- if (++ct>ntk) { goto end_expression; }
- /* gprint("Next token is {%s} \n",tok(ct)); */
- }
- end_expression:
- if (*tok(ct)==' ') (ct)++;
- dbg gprint("Got expression , curtok=%d {%s} \n",ct,tok(ct));
- *rtype = last_typ;
- dbg gprint("Found END OF EXPRESSION \n");
- if (!start_token) if (curpri!=0) {gprint("Missing right brackets");}
- /* Pop everything off the stack */
- for (i=nstk;i>0;i--) {
- dbg gprint("Adding left over operators I = %d op=%d \n",i,stk[i]);
- add_i(pcode,plen,stk[i]);
- }
- *(long *) (pcode+savelen) = (*plen - savelen)/4-1; /* Set length of expression */
- *plen = *plen/4; /* change back to int count */
- /* printf("pcode ");
- for (i=saveplen;i<4*(*plen);i++) printf("%d ",*(pcode+i));
- printf("\n");
- */
-
- return;
- fatal_err:
- gprint("Aborting expression parsing. \n");
- *plen = saveplen;
- *rtype = 0;
- }
-
- /*------------------------------------------------------------------*/
- /* append fcode to pcode */
- add_pcode(char *pcode,int *plen,char *fcode,int *flen)
- {
- char *p;
- p = pcode + *plen;
- memcpy(p,fcode,*flen);
- *plen = *plen + *flen;
- }
- add_i(char *pcode,int *plen,long i)
- {
- long *p;
- p = (long *) (pcode + *plen);
- *p = i;
- *plen += 4;
- }
- add_f(char *pcode,int *plen,double f)
- {
- union { double d ; long l[2]; short s[4]; } both;
- both.d = f;
- add_i(pcode,plen,2);
- add_i(pcode,plen,both.l[0]);
- add_i(pcode,plen,both.l[1]);
- }
- add_var(char *pcode,int *plen,int i)
- {
- add_i(pcode,plen,3);
- add_i(pcode,plen,i);
- }
- add_strvar(char *pcode,int *plen,int i)
- {
- add_i(pcode,plen,4);
- add_i(pcode,plen,i);
- }
- add_fn(char *pcode, int *plen, int i)
- {
- add_i(pcode,plen,i);
- dbg gprint(" add Function %d \n",i);
- }
- add_string(char *pcode, int *plen, char *s)
- {
- char *p;
- int sl;
- dbg gprint("adding string {%s} \n",s);
- add_i(pcode,plen,5);
- sl = strlen(s)+1;
- p = pcode + *plen;
- sl = ((sl + 3) & 0xfffc);
- strncpy(p,s,sl);
- *plen = *plen + sl;
- }
- /*------------------------------------------------------------------*/
- /* Remove the quotes from a string and return a modified pointer */
- char *un_quote(char *cts)
- {
- int i,j;
- i = strlen(cts);
- if (*cts=='"') {
- *(cts+i-1) = 0;
- cts = cts + 1;
- }
- return cts;
- }
- /*------------------------------------------------------------------*/
- stack_op(char *pcode, int *plen, int stk[]
- , int stkp[], int *nstk, int i, int p)
- {
- dbg gprint("Stack oper %d priority %d \n",i,p);
- while (p<=stkp[*nstk] &&(*nstk)>0) {
- dbg gprint("ADDING oper stack = %d oper=%d \n",*nstk,stk[(*nstk)]);
- add_i(pcode,plen,stk[(*nstk)--]);
- }
- stk[++(*nstk)] = i;
- stkp[*nstk] = p;
- }
- isnumber(char *s)
- {
- while (*s!='\0') {
- if (isdigit(*s) || *s=='.' || *s=='E' ) s++;
- else return false;
- }
- return true;
- }
- lastchar(char *s, char c)
- {
- while (*s!='\0') {s++;}
- return *(--s)==c;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-