home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * ....................................... *
- * . . *
- * . TOOLBOX - INTERPRETER . *
- * . TESTPROGRAMM FÜR WINDOWS-FUNKTIONEN . *
- * . FORMEL.C . *
- * . M.Beising & K.Bauer & TOOLBOX . *
- * ....................................... *
- *************************************************************************/
-
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <math.h>
- #include "txl.h"
-
- PTNODE CreateTree(char Fktzeile[],int *ErrorPos,int *ErrorNr);
- PTNODE faktor(char f[]);
- PTNODE vorzfaktor(char f[]);
- PTNODE potenz(char f[]);
- PTNODE produkt(char f[]);
- PTNODE summe(char f[]);
- PTNODE vergleich(char f[]);
- PTNODE verknuepf(char f[]);
- void DelTree(PTNODE *ptnode);
- void nextchar(int start,char f[]);
- void neuewurzel(PTNODE *wurzel,char f[]);
- void newnode(PTNODE *knoten);
- BOOL unaerefunktion(char f[],unsigned char *token);
- void getnumber(char f[],int *posi,char fhelp[30]);
- double Calc(PTNODE *ptnode);
- double arctanh(double x);
- double arccot(double x);
- double cot(double x);
- double frac(double f);
- long round(double x);
- float ran1(void);
- float ran2(void);
- float ran3(void);
- float random();
- void LiesDaten(void);
- void SaveDaten(void);
- extern char *GetFileName (void);
-
- extern int AktPos,ErrTyp,ErrPos,ErrNr,fio;
- extern BOOL TreeError;
- extern HWND hWndglob,hWndEdit;
- extern char FileName[FNAMLEN];
- extern HANDLE hEditText;
- extern OFSTRUCT fileInfo;
- extern BOOL bText;
- unsigned char aktchar;
-
- PTNODE CreateTree(char Fktzeile[],int *ErrorPos,int *ErrorNr)
- {
- PTNODE wurzel;
- AktPos=0;
- nextchar(AktPos,Fktzeile);
- TreeError=FALSE;
- wurzel=NULL;
- wurzel=verknuepf(Fktzeile);
- if ((AktPos<=strlen(Fktzeile)) && (Fktzeile[AktPos-1]!=' ') && (!TreeError)) {
- TreeError=TRUE;
- ErrTyp=4;
- }
- if (!TreeError) {
- *ErrorPos=-1;
- *ErrorNr=-1;
- } else {
- DelTree(&wurzel);
- *ErrorPos=AktPos;
- *ErrorNr=ErrTyp;
- }
- return wurzel;
- }
-
-
- void DelTree(PTNODE *ptnode)
- {
- if (*ptnode!=NULL) {
- DelTree(&((*ptnode)->LeftAst));
- DelTree(&((*ptnode)->RightAst));
- if (((*ptnode)->operator=='\0')) {
- LocalFree((LOCALHANDLE) (*ptnode)->operand);
- LocalFree((LOCALHANDLE)*ptnode);
- *ptnode=NULL;
- } else {
- LocalFree((LOCALHANDLE)*ptnode);
- *ptnode=NULL;
- }
- }
- }
-
- void nextchar(int start,char f[])
- {
- if (start > strlen(f)) aktchar='\0';
- else {
- do
- (start)++;
- while (!((f[start-1]!=' ') || (start>=strlen(f))));
- if (start<=strlen(f)) {
- AktPos=start;
- aktchar=(f[AktPos-1] != ';' ? f[AktPos-1]:f[AktPos++]);
- } else AktPos++;
- }
- }
-
- void neuewurzel(PTNODE *wurzel,char f[])
- {
- PTNODE helpnode;
- helpnode=(NODESTRUCT NEAR *)LocalAlloc (LPTR,sizeof(NODESTRUCT));
- if (helpnode != NULL)
- {
- helpnode->LeftAst=*wurzel;
- *wurzel=helpnode;
- (*wurzel)->RightAst=NULL;
- (*wurzel)->operator=aktchar;
- (*wurzel)->operand=NULL;
- nextchar(AktPos,f);
- } else SendMessage(hWndglob,WM_DESTROY,0,0L);
-
- }
-
- void newnode(PTNODE *knoten)
- {
- *knoten=(NODESTRUCT NEAR *)LocalAlloc(LPTR,sizeof(NODESTRUCT));
- if (*knoten != NULL)
- {
- (*knoten)->operator='\0';
- (*knoten)->operand=NULL;
- (*knoten)->RightAst=NULL;
- (*knoten)->LeftAst=NULL;
- } else SendMessage(hWndglob,WM_DESTROY,0,0L);
- }
-
- double Calc(PTNODE *ptnode)
- {
- double Wert;
- int links,rechts;
- switch ((*ptnode)->operator)
- {
- case '\0':
- Wert=(*((*ptnode)->operand));
- break;
- case EQV:
- case XOR:
- case OR:
- case AND:
- rechts = (int) Calc(&((*ptnode)->RightAst));
- case NOT:
- links = (int) Calc(&((*ptnode)->LeftAst));
- if((*ptnode)->operator == NOT)
- Wert=(links == 0 ? 1.0: 0.0); else
- if((*ptnode)->operator == AND)
- Wert=(links != 0 && rechts != 0 ? 1.0: 0.0); else
- if((*ptnode)->operator == OR)
- Wert=(links != 0 || rechts != 0 ? 1.0: 0.0); else
- if((*ptnode)->operator == XOR)
- Wert=((links != 0 && rechts == 0) ||
- (links == 0 && rechts != 0)) ? 1.0: 0.0; else
- if((*ptnode)->operator == EQV)
- Wert=((links == 0 && rechts == 0) ||
- (links != 0 && rechts != 0)) ? 1.0: 0.0;
- break;
- case KLGL:
- Wert=(Calc(&((*ptnode)->LeftAst))<=Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
- break;
- case UNGL:
- Wert=(Calc(&((*ptnode)->LeftAst))!=Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
- break;
- case GRGL:
- Wert=(Calc(&((*ptnode)->LeftAst))>=Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
- break;
- case GL:
- Wert=(Calc(&((*ptnode)->LeftAst))==Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
- break;
- case KL:
- Wert=(Calc(&((*ptnode)->LeftAst))<Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
- break;
- case GR:
- Wert=(Calc(&((*ptnode)->LeftAst))>Calc(&((*ptnode)->RightAst)) ? 1.0: 0.0);
- break;
- case '+':
- Wert=(Calc(&((*ptnode)->LeftAst))+Calc(&((*ptnode)->RightAst)));
- break;
- case '-':
- Wert=(Calc(&((*ptnode)->LeftAst))-Calc(&((*ptnode)->RightAst)));
- break;
- case '*':
- Wert=(Calc(&((*ptnode)->LeftAst))*Calc(&((*ptnode)->RightAst)));
- break;
- case '/':
- if(Calc(&((*ptnode)->RightAst)) == 0.0)
- {
- Wert = Calc(&((*ptnode)->RightAst));
- PRINTF("# DIVIDE BY ZERO #");
- break;
- }
- else
- Wert=(Calc(&((*ptnode)->LeftAst))/Calc(&((*ptnode)->RightAst)));
- break;
- case '^':
- Wert=(pow(Calc(&((*ptnode)->LeftAst)),Calc(&((*ptnode)->RightAst))));
- break;
- case Ln:
- Wert=(log(Calc(&((*ptnode)->LeftAst))));
- break;
- case Log:
- Wert=(log10(Calc(&((*ptnode)->LeftAst))));
- break;
- case Exponent:
- Wert=(exp(Calc(&((*ptnode)->LeftAst))));
- break;
- case Sinus:
- Wert=(sin(Calc(&((*ptnode)->LeftAst))));
- break;
- case Cosinus:
- Wert=(cos(Calc(&((*ptnode)->LeftAst))));
- break;
- case Tangens:
- Wert=(tan(Calc(&((*ptnode)->LeftAst))));
- break;
- case ArcSin:
- Wert=(asin(Calc(&((*ptnode)->LeftAst))));
- break;
- case ArcCos:
- Wert=(acos(Calc(&((*ptnode)->LeftAst))));
- break;
- case ArcTan:
- Wert=(atan(Calc(&((*ptnode)->LeftAst))));
- break;
- case SinHyp:
- Wert=(sinh(Calc(&((*ptnode)->LeftAst))));
- break;
- case CosHyp:
- Wert=(cosh(Calc(&((*ptnode)->LeftAst))));
- break;
- case TanHyp:
- Wert=(tanh(Calc(&((*ptnode)->LeftAst))));
- break;
- case Sqrt:
- Wert=(sqrt(Calc(&((*ptnode)->LeftAst))));
- break;
- case Frac:
- Wert=(double)((double)frac(Calc(&((*ptnode)->LeftAst))));
- break;
- case Round:
- Wert=(double)((double)round(Calc(&((*ptnode)->LeftAst))));
- break;
- case Absolut:
- Wert=(double)((double)fabs(Calc(&((*ptnode)->LeftAst))));
- break;
- case Cotangens:
- Wert=(cot(Calc(&((*ptnode)->LeftAst))));
- break;
- case ArcCot:
- Wert=(arccot(Calc(&((*ptnode)->LeftAst))));
- break;
- case ArcTanHyp:
- Wert=(arctanh(Calc(&((*ptnode)->LeftAst))));
- break;
- case SIGN:
- Wert=(-Calc(&((*ptnode)->LeftAst)));
- break;
- }
- return Wert;
- }
-
- void getnumber(char f[],int *posi,char dbStr[])
- {
- int LenF;
- char *fhelp;
- LenF = strlen(f);
- fhelp = dbStr;
- while(*posi <= LenF && f[*posi] > '/' && f[*posi] < ':')
- {
- *fhelp++ = f[*posi];
- *posi += 1;
- }
- while(*posi <= LenF && f[*posi] == '.')
- {
- *fhelp++ = f[*posi];
- *posi += 1;
- }
- while(*posi <= LenF && f[*posi] > '/' && f[*posi] < ':')
- {
- *fhelp++ = f[*posi];
- *posi += 1;
- }
- while(*posi <= LenF && (f[*posi] == 'e' || f[*posi] == 'E'))
- {
- if (f[*posi] == 'e') f[*posi] = 'E';
- *fhelp++ = f[*posi];
- *posi += 1;
- if (*posi <= LenF && (f[*posi] == '+' || f[*posi] == '-'))
- {
- *fhelp++ = f[*posi];
- *posi += 1;
- }
- while(*posi <= LenF && f[*posi] > '/' && f[*posi] < ':')
- {
- *fhelp++ = f[*posi];
- *posi += 1;
- }
- }
- }
-
- void PosVar(char fkt[],unsigned char name[])
- {
- int count = 0;
- AktPos--;
- while ((isalpha (fkt[AktPos]) || isdigit (fkt[AktPos])) && (count < NAMLEN))
- name[count++] = fkt[AktPos++];
- name[count] = '\0';
- }
-
- BOOL LogicAusdruck(char f[],unsigned char *token)
- {
- *token='\0';
- if (!(memicmp("AND",&f[AktPos-1],3))) *token=AND;
- else if(!(memicmp("XOR",&f[AktPos-1],3))) *token=XOR;
- else if(!(memicmp("OR",&f[AktPos-1],2))) *token=OR;
- else if(!(memicmp("EQV",&f[AktPos-1],3))) *token=EQV;
- return (*token ? TRUE : FALSE);
- }
-
- BOOL unaerefunktion(char f[],unsigned char *token)
- {
- *token='\0';
- if (!(memicmp("ln",&f[AktPos-1],2))) *token=Ln;
- else if(!(memicmp("sinh",&f[AktPos-1],4))) *token=SinHyp;
- else if(!(memicmp("cosh",&f[AktPos-1],4))) *token=CosHyp;
- else if(!(memicmp("tanh",&f[AktPos-1],4))) *token=TanHyp;
- else if(!(memicmp("sqrt",&f[AktPos-1],4))) *token=Sqrt;
- else if(!(memicmp("frac",&f[AktPos-1],4))) *token=Frac;
- else if(!(memicmp("round",&f[AktPos-1],4))) *token=Round;
- else if(!(memicmp("log",&f[AktPos-1],3))) *token=Log;
- else if(!(memicmp("exp",&f[AktPos-1],3))) *token=Exponent;
- else if(!(memicmp("sin",&f[AktPos-1],3))) *token=Sinus;
- else if(!(memicmp("cos",&f[AktPos-1],3))) *token=Cosinus;
- else if(!(memicmp("tan",&f[AktPos-1],3))) *token=Tangens;
- else if(!(memicmp("abs",&f[AktPos-1],3))) *token=Absolut;
- else if(!(memicmp("cot",&f[AktPos-1],3))) *token=Cotangens;
- else if(!(memicmp("NOT",&f[AktPos-1],3))) *token=NOT;
- else if(!(memicmp("arctanh",&f[AktPos-1],7))) *token=ArcTanHyp;
- else if(!(memicmp("arcsin",&f[AktPos-1],6))) *token=ArcSin;
- else if(!(memicmp("arccos",&f[AktPos-1],6))) *token=ArcCos;
- else if(!(memicmp("arctan",&f[AktPos-1],6))) *token=ArcTan;
- else if(!(memicmp("arccot",&f[AktPos-1],6))) *token=ArcCot;
-
- switch (*token)
- {
- case ArcTanHyp:
- AktPos++;
- case ArcSin:
- case ArcCos:
- case ArcTan:
- case ArcCot:
- AktPos++;
- case Round:
- AktPos++;
- case SinHyp:
- case CosHyp:
- case TanHyp:
- case Sqrt:
- case Frac:
- AktPos++;
- case Log:
- case Exponent:
- case Sinus:
- case Cosinus:
- case Tangens:
- case Absolut:
- case Cotangens:
- case NOT:
- AktPos++;
- case Ln:
- AktPos++;
- nextchar(AktPos,f);
- break;
- }
- return (*token ? TRUE : FALSE);
- }
-
- PTNODE faktor(char f[])
- {
- PTNODE knoten;
- VAR *Variable;
- int valid,posi;
- unsigned char token;
- char DoubleStr[30];
- knoten=NULL;
- if (aktchar=='(') {
- nextchar(AktPos,f);
- knoten=verknuepf(f);
- if ((aktchar!=')') && (!TreeError))
- {
- TreeError=TRUE;
- ErrTyp=0;
- }
- if (!TreeError) nextchar(AktPos,f);
- }
- else if (unaerefunktion(f,&token))
- {
- if (aktchar!='(')
- {
- TreeError=TRUE;
- ErrTyp=1;
- } else
- {
- newnode(&knoten);
- knoten->operator=token;
- nextchar(AktPos,f);
- knoten->LeftAst=verknuepf(f);
- }
- if ((aktchar!=')') && (!TreeError))
- {
- TreeError=TRUE;
- ErrTyp=0;
- }
- if (!TreeError) nextchar(AktPos,f);
- } else if(isalpha(aktchar) && !LogicAusdruck(f,&token)) {
- newnode(&knoten);
- knoten->operand=(double NEAR *)LocalAlloc (LPTR,sizeof(double));
- if (knoten->operand== NULL)
- {
- TreeError=TRUE;
- ErrTyp=6;
- } else
- {
- PosVar(f,DoubleStr);
- if(!(strcmp("e",DoubleStr))) *(knoten->operand)= e;
- else
- if(!(strcmp("pi",DoubleStr))) *(knoten->operand)= pi;
- else
- if(!(strcmp("rnd",DoubleStr))) *(knoten->operand)= random();
- else if ((Variable = IsVariable (DoubleStr)) != NULL)
- {
- if(Variable->VarType == FLONUM)
- *(knoten->operand)= Variable->VarWert.variable.Flotype;
- else {
- TreeError=TRUE;
- ErrTyp=7;
- }
- }
- else {
- TreeError=TRUE;
- ErrTyp=5;
- }
- }
- if (!TreeError) nextchar(AktPos,f);
- } else if ((aktchar>='0') && (aktchar<='9') || (aktchar=='.')) {
- newnode(&knoten);
- knoten->operand=(double NEAR *)LocalAlloc (LPTR,sizeof(double));
- if (knoten->operand== NULL)
- {
- TreeError=TRUE;
- ErrTyp=6;
- }
- else
- {
- posi=AktPos-1;
- memset(DoubleStr,'\0',29);
- getnumber(f,&posi,DoubleStr);
- *(knoten->operand) = atof(DoubleStr);
- AktPos=posi;
- nextchar(AktPos,f);
- }
- } else {
- TreeError=TRUE;
- if ((aktchar==' ') || (AktPos==strlen(f)+1))
- ErrTyp=3;
- else ErrTyp=4;
- }
- return knoten;
- }
-
-
- PTNODE vorzfaktor(char f[])
- {
- PTNODE wurzel;
- wurzel=NULL;
- if ((aktchar=='-')) {
- newnode(&wurzel);
- wurzel->operator=SIGN;
- nextchar(AktPos,f);
- wurzel->LeftAst=faktor(f);
- } else if (aktchar=='+') {
- nextchar(AktPos,f);
- wurzel=faktor(f);
- } else {
- wurzel=faktor(f);
- }
- return wurzel;
- }
-
- PTNODE potenz(char f[])
- {
- PTNODE wurzel;
- wurzel=NULL;
- wurzel=vorzfaktor(f);
- while ((aktchar=='^') && (!TreeError)) {
- neuewurzel(&wurzel,f);
- wurzel->RightAst=vorzfaktor(f);
- }
- return wurzel;
- }
-
- PTNODE produkt(char f[])
- {
- PTNODE wurzel;
- wurzel=NULL;
- wurzel=potenz(f);
- while ((aktchar=='*' || aktchar=='/') && !TreeError) {
- neuewurzel(&wurzel,f);
- wurzel->RightAst=potenz(f);
- }
- return wurzel;
- }
- PTNODE summe(char f[])
- {
- PTNODE wurzel;
- wurzel=NULL;
- wurzel=produkt(f);
- while ((aktchar=='+' || aktchar=='-') && !TreeError) {
- neuewurzel(&wurzel,f);
- wurzel->RightAst=produkt(f);
- }
- return wurzel;
- }
- PTNODE vergleich(char f[])
- {
- PTNODE wurzel;
- wurzel=NULL;
- wurzel=summe(f);
-
- while ((aktchar==KL || aktchar==GR || aktchar==GL) && !TreeError)
- {
- if(aktchar==KL && f[AktPos] == GL) aktchar=KLGL;
- else
- if(aktchar==KL && f[AktPos] == GR) aktchar=UNGL;
- else
- if(aktchar==GR && f[AktPos] == GL) aktchar=GRGL;
-
- if(aktchar==KLGL || aktchar==UNGL || aktchar==GRGL) AktPos++;
-
- neuewurzel(&wurzel,f);
- wurzel->RightAst=summe(f);
- }
- return wurzel;
- }
-
- PTNODE verknuepf(char f[])
- {
- PTNODE wurzel;
- unsigned char token;
- wurzel=NULL;
- wurzel=vergleich(f);
-
- while (LogicAusdruck(f,&token) && !TreeError)
- {
- aktchar=token;
- AktPos++;
- if(aktchar!=OR) AktPos++;
- neuewurzel(&wurzel,f);
- wurzel->RightAst=vergleich(f);
- }
- return wurzel;
- }
-
- double cot(double x)
- {
- double r_cot;
-
- if (frac(x/PI_HALBE)!=0) r_cot = 1 / tan(x);
- return r_cot;
- }
-
- double arccot(double x)
- {
- double r_arccot;
-
- r_arccot=PI_HALBE-atan(x);
- return r_arccot;
- }
-
- long round(double x)
- {
- return ((x>0.0)?(long int)(x+0.5):(long int)(x-0.5));
- }
-
- double fsqr(double x)
- {
- return x*x;
- }
-
- double frac(double x)
- {
- double d;
- return modf(x,&d);
- }
-
- double arctanh(double x)
- {
- double r_arctanh;
-
- if (fabs(x)<1.0) r_arctanh=0.5*log((1.0+x)/(1.0-x));
- return r_arctanh;
- }
-
- float ran1(void)
- {
- static long int a = 100001;
- a = (a*125) % 2796203;
- return((float) a/2796203);
-
- }
- float ran2(void)
- {
- static long int a = 1;
- a = (a*32719+3) % 32749;
- return((float) a/32749);
-
- }
- float ran3(void)
- {
- static long int a = 203;
- a = (a*10001+3) % 1717;
- return((float) a/1717);
- }
-
- float random()
- {
- float f;
-
- f=ran3();
- if(f>.5) return ran1();
- else return ran2();
- }
-
- void LiesDaten(void)
- {
- BYTE *Text;
- long cnt;
- char *FName;
-
- if ((FName = GetFileName()) != NULL)
- fio = OpenFile((LPSTR)FName,(LPOFSTRUCT)&fileInfo,OF_READ);
- else return;
-
- if(fio == -1)
- {
- PRINTF("# ERROR OPEN #");
- return;
- }
-
- if((cnt = filelength(fio)) == -1)
- {
- PRINTF("# ERROR READ #");
- return;
- }
- if(cnt > 20000) return;
- if ((hEditText = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,(unsigned) cnt + 3 )) == NULL)
- {
- PRINTF("# ERROR ALLOCATE #");
- return;
- }
- if (read (fio,Text = LocalLock(hEditText),(unsigned) cnt) != (unsigned) cnt)
- {
- LocalUnlock(hEditText);
- PRINTF("# ERROR LOCK #");
- return;
- }
- bText=TRUE;
- LocalUnlock(hEditText);
- SendMessage(hWndEdit,EM_SETHANDLE,(WORD) hEditText,0L);
- if(close(fio)==-1) return;
- }
-
- void SaveDaten()
- {
- int cnt;
- char *FName;
- if ((FName = GetFileName()) != NULL)
- fio = OpenFile( (LPSTR) FName,(LPOFSTRUCT) &fileInfo, OF_CREATE | OF_WRITE);
- else return;
- if (fio == -1)
- return;
-
- if (((cnt =(unsigned) SendMessage(hWndEdit,WM_GETTEXTLENGTH,0,0l)) > 0) &&
- ((hEditText = (HANDLE) SendMessage(hWndEdit,EM_GETHANDLE,0,0l)) != NULL))
- {
- if (write (fio, LocalLock(hEditText), cnt) != cnt)
- {
- LocalUnlock(hEditText);
- return;
- }
- LocalUnlock(hEditText);
- }
- if (close(fio) == -1 ) return;
- }