home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Photo CD Demo 1
/
Demo.bin
/
gle
/
gle
/
polish.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-29
|
11KB
|
425 lines
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;
}