{ ³ I've written a pwoerfull formula evaluator which can be extended ³ during run-time by adding fuctions, vars and strings containing ³ Because its not very small post me a message if you want to receive it. Here it goes. It's a unit and an example/demo of some features. {---------------------------------------------------------} { Project : Text Formula Parser } { Auteur : G.W. van der Vegt } {---------------------------------------------------------} { Datum .tijd Revisie } { 900530.1900 Creatie (function call/exits removed) } { 900531.1900 Revisie (Boolean expressions) } { 900104.2100 Revisie (HEAP Function Storage) } { 910327.1345 External Real string vars (tfp_realstr) } { are corrected the same way as the parser } { corrects them before using TURBO's VAL } {---------------------------------------------------------} UNIT Tfp_01; INTERFACE {---------------------------------------------------------} {----Initializes function database } {---------------------------------------------------------} PROCEDURE Tfp_init(no : INTEGER); {---------------------------------------------------------} {----Parses s and returns REAL or STR(REAL:m:n) } {---------------------------------------------------------} FUNCTION Tfp_parse2real(s : STRING) : REAL; FUNCTION Tfp_parse2str(s : STRING;m,n : INTEGER) : STRING; {---------------------------------------------------------} {----Tfp_errormsg(tfp_ernr) returns errormessage } {---------------------------------------------------------} VAR Tfp_ernr : BYTE; {----Errorcode} FUNCTION Tfp_errormsg(nr : INTEGER) : STRING; {---------------------------------------------------------} {----Internal structure for functions/vars } {---------------------------------------------------------} TYPE tfp_fname = STRING[12]; {----String name } tfp_ftype = (tfp_noparm, {----Function or Function() } tfp_1real, {----Function(VAR r) } tfp_2real, {----Function(VAR r1,r2) } tfp_nreal, {----Function(VAR r;n INTEGER) } tfp_realvar, {----Real VAR } tfp_intvar, {----Integer VAR } tfp_boolvar, {----Boolean VAR } tfp_realstr); {----Real String VAR } CONST tfp_true = 1.0; {----REAL value for BOOLEAN TRUE } tfp_false = 0.0; {----REAL value for BOOLEAN FALSE } {---------------------------------------------------------} {----Adds own FUNCTION or VAR to the parser } { All FUNCTIONS & VARS must be compiled } { with the FAR switch on } {---------------------------------------------------------} PROCEDURE Tfp_addobj(a : pointer;n : tfp_fname;t : tfp_ftype); {---------------------------------------------------------} {----Add Internal Function Packs } {---------------------------------------------------------} PROCEDURE Tfp_addgonio; PROCEDURE Tfp_addlogic; PROCEDURE Tfp_addmath; PROCEDURE Tfp_addmisc; {---------------------------------------------------------} IMPLEMENTATION CONST maxreal = +9.99999999e37; {----Internal maxreal } maxparm = 16; {----Maximum number of parameters } VAR maxfie : INTEGER; {----max no of functions & vars } fiesiz : INTEGER; {----current no of functions & vars } TYPE fie = RECORD fname : tfp_fname; {----Name of function or var } faddr : POINTER; {----FAR POINTER to function or var } ftype : tfp_ftype; {----Type of entry } END; fieptr = ARRAY[1..1] OF fie; {----Will be used as [1..maxfie] } VAR fiearr : ^fieptr; {----Array of functions & vars } {---------------------------------------------------------} VAR Line : STRING; {----Internal copy of string to Parse} Lp : INTEGER; {----Parsing Pointer into Line } Nextchar : CHAR; {----Character at Lp Postion } {---------------------------------------------------------} {----Tricky stuff to call FUNCTIONS } {---------------------------------------------------------} {$F+} VAR GluePtr : POINTER; FUNCTION Call_noparm : REAL; INLINE($FF/$1E/GluePtr); {CALL DWORD PTR GluePtr} FUNCTION Call_1real(VAR r) : REAL; INLINE($FF/$1E/GluePtr); {CALL DWORD PTR GluePtr} FUNCTION Call_2real(VAR r1,r2) : REAL; INLINE($FF/$1E/GluePtr); {CALL DWORD PTR GluePtr} FUNCTION Call_nreal(VAR r,n) : REAL; INLINE($FF/$1E/GluePtr); {CALL DWORD PTR GluePtr} {$F-} {---------------------------------------------------------} {----This routine skips one character } {---------------------------------------------------------} PROCEDURE Newchar; BEGIN IF (lp' '); END; {---------------------------------------------------------} { Number = Real (Bv 23.4E-5) } { Integer (Bv -45) } {---------------------------------------------------------} FUNCTION Eval_number : REAL; VAR Temp : STRING; Err : INTEGER; value : REAL; BEGIN {----Correct .xx to 0.xx} IF (Nextchar='.') THEN Temp:='0'+Nextchar ELSE Temp:=Nextchar; Newchar; {----Correct ñ.xx to ñ0.xx} IF (LENGTH(temp)=1) AND (Temp[1] IN ['+','-']) AND (Nextchar='.') THEN Temp:=Temp+'0'; WHILE Nextchar IN ['0'..'9','.','E'] DO BEGIN Temp:=Temp+Nextchar; IF (Nextchar='E') THEN BEGIN {----Correct ñxxx.E to ñxxx.0E} IF (Temp[LENGTH(Temp)-1]='.') THEN INSERT('0',Temp,LENGTH(Temp)); Newchar; IF (Nextchar IN ['+','-']) THEN BEGIN Temp:=Temp+Nextchar; Newchar; END; END ELSE Newchar; END; {----Skip trailing spaces} IF (line[lp]=' ') THEN WHILE (Line[lp]=' ') DO INC(lp); nextchar:=line[lp]; {----Correct ñxx. to ñxx.0 but NOT ñxxEñyy.} IF (temp[LENGTH(temp)]='.') AND (POS('E',temp)=0) THEN Temp:=Temp+'0'; VAL(Temp,value,Err); IF (Err<>0) THEN tfp_ernr:=1; IF (tfp_ernr=0) THEN Eval_number:=value ELSE Eval_number:=0; END; {---------------------------------------------------------} FUNCTION Eval_b_expr : REAL; FORWARD; {---------------------------------------------------------} { Factor = Number } { (External) Function() } { (External) Function(Expr) } { (External) Function(Expr,Expr) } { External Var Real } { External Var Integer } { External Var Boolean } { External Var realstring } { (R_Expr) } {---------------------------------------------------------} FUNCTION Eval_factor : REAL; VAR ferr : BOOLEAN; param : INTEGER; dummy : ARRAY[0..maxparm] OF REAL; value, dummy1, dummy2 : REAL; temp : tfp_fname; e, i, index : INTEGER; temps : STRING; BEGIN CASE Nextchar OF '+' : BEGIN Newchar; value:=+Eval_factor; END; '-' : BEGIN Newchar; value:=-Eval_factor; END; '0'..'9', '.' : value:=Eval_number; 'A'..'Z' : BEGIN ferr:=TRUE; Temp:=Nextchar; Skip; WHILE Nextchar IN ['0'..'9','_','A'..'Z'] DO BEGIN Temp:=Temp+Nextchar; Skip; END; {----Seek function and CALL it} {$R-} FOR Index:=1 TO Fiesiz DO WITH fiearr^[index] DO IF (fname=temp) THEN BEGIN ferr:=FALSE; CASE ftype OF {----Function or Function()} tfp_noparm : IF (nextchar='(') THEN BEGIN Skip; IF (nextchar<>')') THEN tfp_ernr:=15; Skip; END; {----Function(r)} tfp_1real : IF (nextchar='(') THEN BEGIN Skip; dummy1:=Eval_b_expr; IF (tfp_ernr=0) AND (nextchar<>')') THEN tfp_ernr:=15; Skip; {----Dump the ')'} END ELSE tfp_ernr:=15; {----Function(r1,r2)} tfp_2real : IF (nextchar='(') THEN BEGIN Skip; dummy1:=Eval_b_expr; IF (tfp_ernr=0) AND (nextchar<>',') THEN tfp_ernr:=15; Skip; {----Dump the ','} dummy2:=Eval_b_expr; IF (tfp_ernr=0) AND (nextchar<>')') THEN tfp_ernr:=15; Skip; {----Dump the ')'} END ELSE tfp_ernr:=15; {----Function(r,n)} tfp_nreal : IF (nextchar='(') THEN BEGIN param:=0; Skip; dummy[param]:=Eval_b_expr; IF (tfp_ernr=0) AND (nextchar<>',') THEN tfp_ernr:=15 ELSE WHILE (tfp_ernr=0) AND (nextchar=',') AND (param')') THEN tfp_ernr:=15; Skip; {----Dump the ')'} END ELSE tfp_ernr:=15; {----Real Var} tfp_realvar : dummy1:=REAL(faddr^); {----Integer Var} tfp_intvar : dummy1:=1.0*INTEGER(faddr^); {----Boolean Var} tfp_boolvar : dummy1:=1.0*ORD(BOOLEAN(faddr^)); {----Real string Var} tfp_realstr : BEGIN temps:=STRING(faddr^); {----Delete Leading Spaces} WHILE (Length(temps)>0) AND (temps[1]=' ') DO Delete(temps,1,1); {----Delete Trailing Spaces} WHILE (Length(temps)>0) AND (temps[Length(temps)]=' ') Do Delete(temps,Length(temps),1); {----Correct .xx to 0.xx} IF (LENGTH(temps)>=1) AND (LENGTH(temps)<255) AND (temps[1]='.') THEN Insert('0',temps,1); {----Correct ñ.xx to ñ0.xx} IF (LENGTH(temps)>=2) AND (LENGTH(temps)<255) AND (temps[1] IN ['+','-']) AND (temps[2]='.') THEN Insert('0',temps,2); {----Correct xx.Eyy to xx0.Exx} IF (Pos('.E',temps)>0) AND (Length(temps)<255) THEN Insert('0',temps,Pos('.E',temps)); {----Correct xx.eyy to xx0.exx} IF (Pos('.e',temps)>0) AND (Length(temps)<255) THEN Insert('0',temps,Pos('.e',temps)); {----Correct ñxx. to ñxx.0 but NOT ñ} IF (temps[LENGTH(temps)]='.') AND (POS('E',temps)=0) AND (POS('e',temps)=0) AND (Length(temps)<255) THEN Temps:=Temps+'0'; VAL(temps,dummy1,e); IF (e<>0) THEN tfp_ernr:=1; END; END; IF (tfp_ernr=0) THEN BEGIN glueptr:=faddr; CASE ftype OF tfp_noparm : value:=call_noparm; tfp_1real : value:=call_1real(dummy1); tfp_2real : value:=call_2real(dummy1,dummy2); tfp_nreal : value:=call_nreal(dummy,param); tfp_realvar, tfp_intvar, tfp_boolvar, tfp_realstr : value:=dummy1; END; END; END; IF (ferr=TRUE) THEN tfp_ernr:=2; {$R+} END; '(' : BEGIN Skip; value:=Eval_b_expr; IF (tfp_ernr=0) AND (nextchar<>')') THEN tfp_ernr:=3; Skip; {----Dump the ')'} END; ELSE tfp_ernr:=2; END; IF (tfp_ernr=0) THEN Eval_factor:=value ELSE Eval_factor:=0; END; {---------------------------------------------------------} { Term = Factor ^ Factor } {---------------------------------------------------------} FUNCTION Eval_term : REAL; VAR value, Exponent, dummy, Base : REAL; BEGIN value:=Eval_factor; WHILE (tfp_ernr=0) AND (Nextchar='^') DO BEGIN Skip; Exponent:=Eval_factor; Base:=value; IF (tfp_ernr=0) AND (Base=0) THEN value:=0 ELSE BEGIN {----Over/Underflow Protected} dummy:=Exponent*LN(ABS(Base)); IF (dummy<=LN(MAXREAL)) THEN value:=EXP(dummy) ELSE tfp_ernr:=11; END; IF (tfp_ernr=0) AND (Base<0) THEN BEGIN {----allow only whole number exponents} IF (INT(Exponent)<>Exponent) THEN tfp_ernr:=4; IF (tfp_ernr=0) AND ODD(ROUND(exponent)) THEN value:=-value; END; END; IF (tfp_ernr=0) THEN Eval_term:=value ELSE Eval_term:=0; END; {---------------------------------------------------------} {----Subterm = Term * Term } { Term / Term } {---------------------------------------------------------} FUNCTION Eval_subterm : REAL; VAR value, dummy : REAL; BEGIN value:=Eval_term; WHILE (tfp_ernr=0) AND (Nextchar IN ['*','/']) DO CASE Nextchar OF {----Over/Underflow Protected} '*' : BEGIN Skip; dummy:=Eval_term; IF (tfp_ernr<>0) OR (value=0) OR (dummy=0) THEN value:=0 ELSE IF (ABS( LN(ABS(value)) + LN(ABS(dummy)) )0) THEN BEGIN {----Underflow Protected} IF (value<>0) THEN IF (ABS( LN(ABS(value))-LN(ABS(dummy)) ) dummy2) THEN tfp_ernr:=11; END; END; END; {----At this point the current char must be 1. the EOLN marker or 2. a right bracket 3. start of a boolean operator } IF NOT (Nextchar IN [#00,')','>','<','=',',']) THEN tfp_ernr:=2; IF (tfp_ernr=0) THEN Eval_r_expr:=value ELSE Eval_r_expr:=0; END; {---------------------------------------------------------} { Boolean Expr = R_Expr < R_Expr } { R_Expr <= R_Expr } { R_Expr <> R_Expr } { R_Expr = R_Expr } { R_Expr >= R_Expr } { R_Expr > R_Expr } {---------------------------------------------------------} FUNCTION Eval_b_expr : REAL; VAR value : REAL; BEGIN value:=Eval_r_expr; IF (tfp_ernr=0) AND (Nextchar IN ['<','>','=']) THEN CASE Nextchar OF '<' : BEGIN Skip; IF (Nextchar IN ['>','=']) THEN CASE Nextchar OF '>' : BEGIN Skip; IF (value<>Eval_r_expr) THEN value:=tfp_true ELSE value:=tfp_false; END; '=' : BEGIN Skip; IF (value<=Eval_r_expr) THEN value:=tfp_true ELSE value:=tfp_false; END; END ELSE BEGIN IF (value' : BEGIN Skip; IF (Nextchar='=') THEN BEGIN Skip; IF (value>=Eval_r_expr) THEN value:=tfp_true ELSE value:=tfp_false; END ELSE BEGIN IF (value>Eval_r_expr) THEN value:=tfp_true ELSE value:=tfp_false; END; END; '=' : BEGIN Skip; IF (value=Eval_r_expr) THEN value:=tfp_true ELSE value:=tfp_false; END; END; IF (tfp_ernr=0) THEN Eval_b_expr:=value ELSE Eval_b_expr:=0.0; END; {---------------------------------------------------------} PROCEDURE Tfp_init(no : INTEGER); BEGIN IF (maxfie>0) THEN FREEMEM(fiearr,maxfie*SIZEOF(fiearr^)); GETMEM(fiearr,no*SIZEOF(fiearr^)); maxfie:=no; fiesiz:=0; END; {---------------------------------------------------------} FUNCTION Tfp_parse2real(s : string) : REAL; VAR i,h : INTEGER; value : REAL; BEGIN tfp_ernr:=0; {----Test for match on numbers of ( and ) } h:=0; FOR i:=1 TO LENGTH(s) DO CASE s[i] OF '(' : INC(h); ')' : DEC(h); END; IF (h=0) THEN BEGIN {----Continue init} lp:=0; {----Add a CHR(0) as an EOLN marker} line:=S+#00; Skip; {----Try parsing if any characters left} IF (Line[Lp]<>#00) THEN value:=Eval_b_expr ELSE tfp_ernr:=6; END ELSE tfp_ernr:=3; IF (tfp_ernr<>0) THEN tfp_parse2real:=0.0 ELSE tfp_parse2real:=value; END; {---------------------------------------------------------} FUNCTION Tfp_parse2str(s : STRING;m,n : INTEGER) : STRING; VAR r : REAL; tmp : STRING; BEGIN r:=Tfp_parse2real(s); IF (tfp_ernr=0) THEN STR(r:m:n,tmp) ELSE tmp:=''; Tfp_parse2str:=tmp; END; {---------------------------------------------------------} FUNCTION Tfp_errormsg; BEGIN CASE nr OF 0 : Tfp_errormsg:='Correct resultaat'; {Error 0 } 1 : Tfp_errormsg:='Ongeldig getal formaat'; {Error 1 } 2 : Tfp_errormsg:='Onbekende functie'; {Error 2 } 3 : Tfp_errormsg:='Een haakje mist'; {Error 3 } 4 : Tfp_errormsg:='Reele exponent geeft een complex getal'; {Error 4 } 5 : Tfp_errormsg:='TAN( (2n+1)*PI/2 ) bestaat niet'; {Error 5 } 6 : Tfp_errormsg:='Lege string'; {Error 6 } 7 : Tfp_errormsg:='LN(x) of LOG(x) met x<=0 bestaat niet'; {Error 7 } 8 : Tfp_errormsg:='SQRT(x) met x<0 bestaat niet'; {Error 8 } 9 : Tfp_errormsg:='Deling door nul'; {Error 9 } 10 : Tfp_errormsg:='Teveel functies & constanten'; {Error 10} 11 : Tfp_errormsg:='Tussenresultaat buiten getalbereik'; {Error 11} 12 : Tfp_errormsg:='Illegale tekens in functienaam'; {Error 12} 13 : Tfp_errormsg:='Geen (on)gelijkheid / te complex'; {Error 13} 14 : Tfp_errormsg:='Geen booleaanse expressie'; {Error 14} 15 : Tfp_errormsg:='Verkeerd aantal parameters'; {Error 15} ELSE Tfp_errormsg:='Onbekende fout'; {Error xx} END; END; {---------------------------------------------------------} PROCEDURE Tfp_addobj(a : pointer;n : tfp_fname;t : tfp_ftype); VAR i : INTEGER; BEGIN {$R-} IF (fiesiz0) AND NOT (fname[1] IN ['A'..'Z']) THEN tfp_ernr:=12; ftype:=t; END END ELSE tfp_ernr:=10 {$R+} END; {---------------------------------------------------------} {----Internal Functions } {---------------------------------------------------------} {$F+} FUNCTION xABS(VAR r : REAL) : REAL; BEGIN xabs:=ABS(r); END; FUNCTION xAND(VAR r;VAR n : INTEGER) : REAL; TYPE tmp = ARRAY[0..0] OF REAL; VAR x : REAL; i : INTEGER; BEGIN {$R-} FOR i:=0 TO n DO IF (tmp(r)[i]<>tfp_false) AND (tmp(r)[i]<>tfp_true) THEN BEGIN IF (tfp_ernr=0) THEN tfp_ernr:=14; END; IF (tfp_ernr=0) AND (n>0) THEN BEGIN x:=tfp_true*ORD(tmp(r)[0]=tfp_true); FOR i:=1 TO n DO x:=tfp_true*ORD((x=tfp_true) AND (tmp(r)[i]=tfp_true)) END ELSE tfp_ernr:=15; IF tfp_ernr=0 THEN xAND:=x ELSE xAND:=0.0; {$R+} END; FUNCTION xARCTAN(VAR r : REAL) : REAL; BEGIN xARCTAN:=ARCTAN(r); END; FUNCTION xCOS(VAR r : REAL) : REAL; BEGIN xCOS:=COS(r); END; FUNCTION xDEG(VAR r : REAL) : REAL; BEGIN xDEG:=(r/pi)*180; END; FUNCTION xE : REAL; BEGIN xE:=EXP(1); END; FUNCTION xEXP(VAR r : REAL) : REAL; BEGIN xEXP:=0; IF (ABS(r)0) THEN xLN:=LN(r) ELSE tfp_ernr:=7; END; FUNCTION xLOG(VAR r : REAL) : REAL; BEGIN xLOG:=0; IF (r>0) THEN xLOG:=LN(r)/LN(10) ELSE tfp_ernr:=7; END; FUNCTION xMAX(VAR r;VAR n : INTEGER) : REAL; TYPE tmp = ARRAY[0..0] OF REAL; VAR max : REAL; i : INTEGER; BEGIN {$R-} max:=tmp(r)[0]; FOR i:=1 TO n DO IF (tmp(r)[i]>max) THEN max:=tmp(r)[i]; xMAX:=max; {$R+} END; FUNCTION xMIN(VAR r;VAR n : INTEGER) : REAL; TYPE tmp = ARRAY[0..0] OF REAL; VAR min : REAL; i : INTEGER; BEGIN {$R-} min:=tmp(r)[0]; FOR i:=1 TO n DO IF (tmp(r)[i]tfp_false) AND (tmp(r)[i]<>tfp_true) THEN BEGIN IF (tfp_ernr=0) THEN tfp_ernr:=14; END; IF (tfp_ernr=0) AND (n>0) THEN BEGIN x:=tfp_true*ORD(tmp(r)[0]=tfp_true); FOR i:=1 TO n DO x:=tfp_true*ORD((x=tfp_true) OR (tmp(r)[i]=tfp_true)) END ELSE tfp_ernr:=15; IF tfp_ernr=0 THEN xIOR:=x ELSE xIOR:=0.0; {$R+} END; FUNCTION xPI : REAL; BEGIN xPI:=PI; END; FUNCTION xRAD(VAR r : REAL) : REAL; BEGIN xRAD:=(r/180)*pi; END; FUNCTION xROUND(VAR r : REAL) : REAL; BEGIN xROUND:=ROUND(r); END; FUNCTION xSGN(VAR r : REAL) : REAL; BEGIN IF (r>=0) THEN xSgn:=+1 ELSE xSgn:=-1; END; FUNCTION xSIN(VAR r : REAL) : REAL; BEGIN xSIN:=SIN(r); END; FUNCTION xSQR(VAR r : REAL) : REAL; BEGIN xSQR:=0; IF ( ABS(2*LN(ABS(r))) )=0) THEN xSQRT:=SQRT(r) ELSE tfp_ernr:=8; END; FUNCTION xTAN(VAR r : REAL) : REAL; BEGIN xTAN:=0; IF (COS(r)=0) THEN tfp_ernr:=5 ELSE xTAN:=SIN(r)/COS(r); END; FUNCTION xTRUE : REAL; BEGIN xTRUE:=tfp_true; END; FUNCTION xXOR(VAR r1,r2 : REAL) : REAL; BEGIN IF ((r1<>tfp_false) AND (r1<>tfp_true)) OR ((r2<>tfp_false) AND (r2<>tfp_true)) THEN BEGIN IF (tfp_ernr=0) THEN tfp_ernr:=14; END ELSE xxor:=tfp_true*ORD((r1=tfp_true) XOR (r2=tfp_true)); END; {$F-} {---------------------------------------------------------} PROCEDURE Tfp_addgonio; BEGIN Tfp_addobj(@xARCTAN,'ARCTAN',tfp_1real); Tfp_addobj(@xCOS ,'COS' ,tfp_1real); Tfp_addobj(@xDEG ,'DEG' ,tfp_1real); Tfp_addobj(@xPI ,'PI' ,tfp_noparm); Tfp_addobj(@xRAD ,'RAD' ,tfp_1real); Tfp_addobj(@xSIN ,'SIN' ,tfp_1real); Tfp_addobj(@xTAN ,'TAN' ,tfp_1real); END; {---------------------------------------------------------} PROCEDURE Tfp_addlogic; BEGIN Tfp_addobj(@xAND ,'AND' ,tfp_nreal); Tfp_addobj(@xFALSE ,'FALSE' ,tfp_noparm); Tfp_addobj(@xIOR ,'OR' ,tfp_nreal); Tfp_addobj(@xTRUE ,'TRUE' ,tfp_noparm); Tfp_addobj(@xXOR ,'XOR' ,tfp_2real); END; {---------------------------------------------------------} PROCEDURE Tfp_addmath; BEGIN Tfp_addobj(@xABS ,'ABS' ,tfp_1real); Tfp_addobj(@xEXP ,'EXP' ,tfp_1real); Tfp_addobj(@xE ,'E' ,tfp_noparm); Tfp_addobj(@xLN ,'LN' ,tfp_1real); Tfp_addobj(@xLOG ,'LOG' ,tfp_1real); Tfp_addobj(@xSQR ,'SQR' ,tfp_1real); Tfp_addobj(@xSQRT ,'SQRT' ,tfp_1real); END; {---------------------------------------------------------} PROCEDURE Tfp_addmisc; BEGIN Tfp_addobj(@xFRAC ,'FRAC' ,tfp_1real); Tfp_addobj(@xINT ,'INT' ,tfp_1real); Tfp_addobj(@xMAX ,'MAX' ,tfp_nreal); Tfp_addobj(@xMIN ,'MIN' ,tfp_nreal); Tfp_addobj(@xROUND ,'ROUND' ,tfp_1real); Tfp_addobj(@xSGN ,'SGN' ,tfp_1real); END; {---------------------------------------------------------} BEGIN {----Module Init} tfp_ernr:=0; fiesiz:=0; maxfie:=0; fiearr:=NIL; END. -------------------------------------------------------------0.5) THEN xFUZZY:=0.5 ELSE xFUZZY:=0.4; END; {of xFUZZY} FUNCTION xAGE : REAL; VAR s : string; e : Integer; r : Real; BEGIN {----default value in case of error} xAGE:=0; Write('Enter your age : '); Readln(s); Val(s,r,e); {----Setting tfp_ernr will flag an error. Can be a user defined value} IF e<>0 THEN tfp_ernr:=1 ELSE xAGE:=r; END; {of xAge} {$F-} Begin Tfp_init(40); {----Add internal function packs} Tfp_addgonio; Tfp_addlogic; Tfp_addmath; Tfp_addmisc; {----Add external functions} Tfp_addobj(@r ,'TEMP' ,tfp_realvar); Tfp_addobj(@i ,'COUNTER',tfp_intvar); Tfp_addobj(@t ,'USER' ,tfp_realstr); Tfp_addobj(@xfuzzy,'FUZZY' ,tfp_1real); Tfp_addobj(@xage ,'AGE' ,tfp_noparm); i:=1; t:='1.25'; s:='2*COUNTER'; Clrscr; {----Example #1 using FOR index in expression} Writeln(tfp_errormsg(tfp_ernr)); FOR i:=1 TO 3 DO Writeln(s,' := ',Tfp_parse2real(s):0:2); Writeln(tfp_errormsg(tfp_ernr)); {----Example #2 using a real from the main program} r:=15; s:='TEMP'; Writeln(r:0:2,' := ',Tfp_parse2real(s):0:2); {----Example #3 using a function that does something strange} s:='AGE-1'; Writeln('Last years AGE := ',Tfp_parse2real(s):0:2); {----Example #4 using a number in a string This version doesn't allow recusive formula's yet Have a version that does!} s:='USER'; Writeln('USER := ',Tfp_parse2real(s):0:2); {----All of the above + Internal function PI, & Boolean expressions should return 1 because it can't be 1 Booleans are reals with values of 1.0 and 0.0} s:='(SIN(COUNTER+TEMP*FUZZY(AGE)*PI)<>1)=TRUE'; Writeln('? := ',Tfp_parse2real(s):0:6); {----Your example goes here, try a readln(s)} Writeln(tfp_errormsg(tfp_ernr)); End.