{---------------------------------------------------------} { 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. } { 910829.1200 Support added for recursion with string } { variables so they may contain formula's } { now. } { 940411.1300 Hyperbolic, reciproke & inverse } { goniometric functions added, } { Type of tfp_lnr changed to Byte. } { Bug fixed in tfp_check (tfp_lnr not always} { initialized to 0) } {---------------------------------------------------------} UNIT Tfp_02; INTERFACE CONST tfp_true = 1.0; {----REAL value for BOOLEAN TRUE } tfp_false = 0.0; {----REAL value for BOOLEAN FALSE } tfp_maxparm = 16; {----Maximum number of parameters } tfp_funclen = 12; {----Maximum function name length } TYPE tfp_fname = STRING[tfp_funclen]; {----Function Name or Alias } 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_strvar); {----String VAR (Formula) } tfp_rarray = ARRAY[0..tfp_maxparm-1] OF REAL; FUNCTION Tfp_parse2real(s : STRING): REAL; FUNCTION Tfp_parse2str(s : STRING;m,n : INTEGER) : STRING; {---------------------------------------------------------} {----Interface to error functions for external addons } {---------------------------------------------------------} VAR tfp_erpos, tfp_ernr : BYTE; PROCEDURE Tfp_seternr(ernr : INTEGER); FUNCTION Tfp_errormsg(nr : INTEGER) : STRING; {---------------------------------------------------------} {----Initialize & Expand internal parser datastructure } {---------------------------------------------------------} PROCEDURE Tfp_init (no : WORD); PROCEDURE Tfp_expand(no : WORD); {---------------------------------------------------------} {----Keep first no function+vars of parser } {---------------------------------------------------------} PROCEDURE Tfp_keep (no : WORD); {---------------------------------------------------------} {----Number of functions+vars added to parser } {---------------------------------------------------------} FUNCTION Tfp_noobj : WORD; {---------------------------------------------------------} {----Adds own FUNCTION or VAR to the parser } { All FUNCTIONS & VARS must be compiled } { with the FAR switch on } {---------------------------------------------------------} PROCEDURE Tfp_addobj(adres : POINTER; name : tfp_fname; ftype : tfp_ftype); {---------------------------------------------------------} {----Add Internal Function Packs } {---------------------------------------------------------} PROCEDURE Tfp_addgonio; PROCEDURE Tfp_addlogic; PROCEDURE Tfp_addmath; PROCEDURE Tfp_addmisc; PROCEDURE Tfp_addall; {---------------------------------------------------------} IMPLEMENTATION TYPE tfp_parse_state = RECORD tfp_line : STRING; {----Copy of string to Parse } tfp_lp : BYTE; {----Parsing Pointer into Line } tfp_nextchar : CHAR; {----Character at Lp Postion } END; tfp_state_ptr = ^tfp_parse_state; CONST tfp_maxreal = +9.99999999e37; {----Internal maxreal } tfp_maxlongint = maxlongint-1; {----Internal longint } VAR maxfie : INTEGER; {----max no of functions & vars } fiesiz : INTEGER; {----current no of functions & vars } p : tfp_state_ptr; {----Top level formula } TYPE tfp_fie_typ = RECORD tfp_fname : tfp_fname;{----Name of function or var } tfp_faddr : POINTER; {----FAR POINTER to function or var} tfp_ftype : tfp_ftype;{----Type of entry } END; tfp_fieptr = ARRAY[1..1] OF tfp_fie_typ; {----Open Array Construction } VAR fiearr : ^tfp_fieptr; {----Array of functions & vars } {---------------------------------------------------------} {----Tricky stuff to call FUNCTIONS } { Idea from Borland's DataBase ToolKit } {---------------------------------------------------------} {$F+} VAR glueptr : POINTER; FUNCTION Tfp_call_noparm : REAL; INLINE($ff/$1e/glueptr); {CALL DWORD PTR GluePtr} FUNCTION Tfp_call_1real(VAR lu_r) : REAL; INLINE($ff/$1e/glueptr); {CALL DWORD PTR GluePtr} FUNCTION Tfp_call_2real(VAR lu_r1,lu_r2) : REAL; INLINE($ff/$1e/glueptr); {CALL DWORD PTR GluePtr} FUNCTION Tfp_call_nreal(VAR lu_r,lu_n) : REAL; INLINE($ff/$1e/glueptr); {CALL DWORD PTR GluePtr} {$F-} {---------------------------------------------------------} {----TP round function not useable } {---------------------------------------------------------} FUNCTION Tfp_round(VAR r : REAL) : LONGINT; BEGIN IF (r<0) THEN Tfp_round:= Trunc(r - 0.5) ELSE Tfp_round:= Trunc(r + 0.5); END; {of Tfp_round} {---------------------------------------------------------} {----This routine set the tfp_ernr if not set already } {---------------------------------------------------------} PROCEDURE Tfp_seternr(ernr : INTEGER); BEGIN IF (tfp_ernr=0) THEN BEGIN tfp_erpos:=p^.tfp_lp; tfp_ernr :=ernr; END; END; {of Tfp_Seternr} {---------------------------------------------------------} {----This routine skips one character } {---------------------------------------------------------} PROCEDURE Tfp_newchar(p : tfp_state_ptr); BEGIN WITH p^ DO BEGIN IF (tfp_lp' '); END; {of Tfp_Skip} {---------------------------------------------------------} {----This Routine does some trivial check & } { Inits Tfp_State_Ptr^ } {---------------------------------------------------------} PROCEDURE Tfp_check(s : STRING;p : tfp_state_ptr); VAR i,j : INTEGER; BEGIN WITH p^ DO BEGIN tfp_lp:=0; {----Test for match on numbers of ( and ) } j:=0; FOR i:=1 TO Length(s) DO CASE s[i] OF '(' : Inc(j); ')' : Dec(j); END; IF (j=0) THEN {----Continue init} BEGIN {----Add a CHR(0) as an EOLN marker} tfp_line:=s+#00; Tfp_skip(p); {----Try parsing if any characters left} IF (tfp_line[tfp_lp]=#00) THEN Tfp_seternr(6); END ELSE Tfp_seternr(3); END; END; {of Tfp_Check} {---------------------------------------------------------} { Number = Real (Bv 23.4E-5) } { Integer (Bv -45) } {---------------------------------------------------------} FUNCTION Tfp_eval_number(p : tfp_state_ptr) : REAL; VAR temp : STRING; err : INTEGER; value : REAL; BEGIN WITH p^ DO BEGIN {----Correct .xx to 0.xx} IF (tfp_nextchar='.') THEN temp:='0'+tfp_nextchar ELSE temp:=tfp_nextchar; Tfp_newchar(p); {----Correct ñ.xx to ñ0.xx} IF (Length(temp)=1) AND (temp[1] IN ['+','-']) AND (tfp_nextchar='.') THEN temp:=temp+'0'; WHILE tfp_nextchar IN ['0'..'9','.','E'] DO BEGIN temp:=temp+tfp_nextchar; IF (tfp_nextchar='E') THEN BEGIN {----Correct ñxxx.E to ñxxx.0E} IF (temp[Length(temp)-1]='.') THEN Insert('0',temp,Length(temp)); Tfp_newchar(p); IF (tfp_nextchar IN ['+','-']) THEN BEGIN temp:=temp+tfp_nextchar; Tfp_newchar(p); END; END ELSE Tfp_newchar(p); END; {----Skip trailing spaces} IF (tfp_nextchar=' ') THEN Tfp_skip(p); {----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_seternr(1); END; IF (tfp_ernr=0) THEN Tfp_eval_number:=value ELSE Tfp_eval_number:=0; END; {of Tfp_Eval_Number} {---------------------------------------------------------} { 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 Tfp_eval_b_expr(p : tfp_state_ptr) : REAL; forward; FUNCTION Tfp_eval_factor(p : tfp_state_ptr) : REAL; VAR ferr : BOOLEAN; param : INTEGER; dummy : tfp_rarray; value, dummy1, dummy2 : REAL; temp : tfp_fname; e, i, index : INTEGER; temps : STRING; tmpstate : tfp_state_ptr; BEGIN WITH p^ DO CASE tfp_nextchar OF '+' : BEGIN Tfp_newchar(p); value:=+Tfp_eval_factor(p); END; '-' : BEGIN Tfp_newchar(p); value:=-Tfp_eval_factor(p); END; '0'.. '9', '.' : value:=Tfp_eval_number(p); 'A'.. 'Z' : BEGIN ferr:=true; temp:=tfp_nextchar; Tfp_skip(p); WHILE tfp_nextchar IN ['0'..'9','_','A'..'Z'] DO BEGIN temp:=temp+tfp_nextchar; Tfp_skip(p); END; {----Seek function and CALL it} {$R-} FOR index:=1 TO fiesiz DO WITH fiearr^[index] DO IF (tfp_fname=temp) THEN BEGIN ferr:=false; CASE tfp_ftype OF {----Function or Function()} tfp_noparm : IF (tfp_nextchar='(') THEN BEGIN Tfp_skip(p); IF (tfp_nextchar<>')') THEN Tfp_seternr(14); Tfp_skip(p); END; {----Function(r)} tfp_1real : IF (tfp_nextchar='(') THEN BEGIN Tfp_skip(p); dummy1:=Tfp_eval_b_expr(p); IF (tfp_ernr=0) AND (tfp_nextchar<>')') THEN Tfp_seternr(14); Tfp_skip(p); {----Dump the ')'} END ELSE Tfp_seternr(14); {----Function(r1,r2)} tfp_2real : IF (tfp_nextchar='(') THEN BEGIN Tfp_skip(p); dummy1:=Tfp_eval_b_expr(p); IF (tfp_ernr=0) AND (tfp_nextchar<>',') THEN Tfp_seternr(14); Tfp_skip(p); {----Dump the ','} dummy2:=Tfp_eval_b_expr(p); IF (tfp_ernr=0) AND (tfp_nextchar<>')') THEN Tfp_seternr(14); Tfp_skip(p); {----Dump the ')'} END ELSE Tfp_seternr(14); {----Function(r,n)} tfp_nreal : IF (tfp_nextchar='(') THEN BEGIN param:=0; Tfp_skip(p); dummy[param]:=Tfp_eval_b_expr(p); IF (tfp_ernr=0) AND (tfp_nextchar<>',') THEN Tfp_seternr(14) ELSE WHILE (tfp_ernr=0) AND (tfp_nextchar=',') AND (param')') THEN Tfp_seternr(14); Tfp_skip(p); {----Dump the ')'} END ELSE Tfp_seternr(14); {----Real Var} tfp_realvar : dummy1:=REAL(tfp_faddr^); {----Integer Var} tfp_intvar : dummy1:=1.0*INTEGER(tfp_faddr^); {----Boolean Var} tfp_boolvar : dummy1:=1.0*Ord(BOOLEAN(tfp_faddr^)); {----Real string Var} tfp_strvar : BEGIN temps:=STRING(tfp_faddr^); IF (Maxavail>=Sizeof(tfp_parse_state)) THEN BEGIN New(tmpstate); Tfp_check(temps,tmpstate); dummy1:=Tfp_eval_b_expr(tmpstate); Dispose(tmpstate); END ELSE Tfp_seternr(15); END; END; IF (tfp_ernr=0) THEN BEGIN glueptr:=tfp_faddr; CASE tfp_ftype OF tfp_noparm : value:=Tfp_call_noparm; tfp_1real : value:=Tfp_call_1real(dummy1); tfp_2real : value:=Tfp_call_2real(dummy1,dummy2); tfp_nreal : value:=Tfp_call_nreal(dummy,param); tfp_realvar, tfp_intvar, tfp_boolvar, tfp_strvar : value:=dummy1; END; END; END; {$R+} IF (ferr=true) THEN Tfp_seternr(2); END; '(' : BEGIN Tfp_skip(p); value:=Tfp_eval_b_expr(p); IF (tfp_ernr=0) AND (tfp_nextchar<>')') THEN Tfp_seternr(3); Tfp_skip(p); {----Dump the ')'} END; ELSE Tfp_seternr(2); END; IF (tfp_ernr=0) THEN Tfp_eval_factor:=value ELSE Tfp_eval_factor:=0; END; {of Tfp_Eval_factor} {---------------------------------------------------------} { Term = Factor ^ Factor } {---------------------------------------------------------} FUNCTION Tfp_eval_term(p : tfp_state_ptr) : REAL; VAR value, exponent, dummy, base : REAL; BEGIN WITH p^ DO BEGIN value:=Tfp_eval_factor(p); WHILE (tfp_ernr=0) AND (tfp_nextchar='^') DO BEGIN Tfp_skip(p); exponent:=Tfp_eval_factor(p); 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(tfp_maxreal)) THEN value:=Exp(dummy) ELSE Tfp_seternr(11); END; IF (tfp_ernr=0) AND (base<0) THEN BEGIN {----Allow only whole number exponents, others will result in complex numbers} IF (Int(exponent)<>exponent) THEN Tfp_seternr(4); IF (tfp_ernr=0) AND Odd(Tfp_round(exponent)) THEN value:=-value; END; END; END; IF (tfp_ernr=0) THEN Tfp_eval_term:=value ELSE Tfp_eval_term:=0; END; {of Tfp_Eval_term} {---------------------------------------------------------} {----Subterm = Term * Term } { Term / Term } {---------------------------------------------------------} FUNCTION Tfp_eval_subterm(p : tfp_state_ptr) : REAL; VAR value, dummy : REAL; BEGIN WITH p^ DO BEGIN value:=Tfp_eval_term(p); WHILE (tfp_ernr=0) AND (tfp_nextchar IN ['*','/']) DO CASE tfp_nextchar OF {----Over/Underflow Protected} '*' : BEGIN Tfp_skip(p); dummy:=Tfp_eval_term(p); IF (tfp_ernr<>0) OR (value=0) OR (dummy=0) THEN value:=0 ELSE IF (Abs( Ln(Abs(value)) + Ln(Abs(dummy)) ) < Ln(tfp_maxreal)) THEN value:= value * dummy ELSE Tfp_seternr(11); END; {----Over/Underflow Protected} '/' : BEGIN Tfp_skip(p); dummy:=Tfp_eval_term(p); IF (tfp_ernr=0) THEN BEGIN {----Division by ZERO Protected} IF (dummy<>0) THEN BEGIN {----Underflow Protected} IF (value<>0) THEN BEGIN IF (Abs( Ln(Abs(value)) - Ln(Abs(dummy)) ) < Ln(tfp_maxreal)) THEN value:=value/dummy ELSE Tfp_seternr(11) END ELSE value:=0; END ELSE Tfp_seternr(9); END; END; END; END; IF (tfp_ernr=0) THEN Tfp_eval_subterm:=value ELSE Tfp_eval_subterm:=0; END;{of Tfp_Eval_subterm} {---------------------------------------------------------} { Real Expr = Subterm + Subterm } { Subterm - Subterm } {---------------------------------------------------------} FUNCTION Tfp_eval_r_expr(p : tfp_state_ptr) : REAL; VAR dummy, dummy2, value : REAL; BEGIN WITH p^ DO BEGIN value:=Tfp_eval_subterm(p); WHILE (tfp_ernr=0) AND (tfp_nextchar IN ['+','-']) DO CASE tfp_nextchar OF '+' : BEGIN Tfp_skip(p); dummy:=Tfp_eval_subterm(p); IF (tfp_ernr=0) THEN BEGIN {----Overflow Protected} IF (Abs( (value/10) + (dummy/10) ) < (tfp_maxreal/10)) THEN value:=value+dummy ELSE Tfp_seternr(11); END; END; '-' : BEGIN Tfp_skip(p); dummy2:=value; dummy:=Tfp_eval_subterm(p); IF (tfp_ernr=0) THEN BEGIN {----Overflow Protected} IF (Abs( (value/10) - (dummy/10) )<(tfp_maxreal/10)) THEN value:=value-dummy ELSE Tfp_seternr(11); {----Underflow Protected} IF (value=0) AND (dummy<>dummy2) THEN Tfp_seternr(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 (tfp_nextchar IN [#00,')','>','<','=',',']) THEN Tfp_seternr(2); END; IF (tfp_ernr=0) THEN Tfp_eval_r_expr:=value ELSE Tfp_eval_r_expr:=0; END; {of Tfp_Eval_R_Expr} {---------------------------------------------------------} { 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 Tfp_eval_b_expr(p : tfp_state_ptr) : REAL; VAR value : REAL; BEGIN WITH p^ DO BEGIN value:=Tfp_eval_r_expr(p); IF (tfp_ernr=0) AND (tfp_nextchar IN ['<','>','=']) THEN CASE tfp_nextchar OF '<' : BEGIN Tfp_skip(p); IF (tfp_nextchar IN ['>','=']) THEN CASE tfp_nextchar OF '>' : BEGIN Tfp_skip(p); IF (value<>Tfp_eval_r_expr(p)) THEN value:=tfp_true ELSE value:=tfp_false; END; '=' : BEGIN Tfp_skip(p); IF (value<=Tfp_eval_r_expr(p)) THEN value:=tfp_true ELSE value:=tfp_false; END; END ELSE BEGIN IF (value' : BEGIN Tfp_skip(p); IF (tfp_nextchar='=') THEN BEGIN Tfp_skip(p); IF (value>=Tfp_eval_r_expr(p)) THEN value:=tfp_true ELSE value:=tfp_false; END ELSE BEGIN IF (value>Tfp_eval_r_expr(p)) THEN value:=tfp_true ELSE value:=tfp_false; END; END; '=' : BEGIN Tfp_skip(p); IF (value=Tfp_eval_r_expr(p)) THEN value:=tfp_true ELSE value:=tfp_false; END; END; END; IF (tfp_ernr=0) THEN Tfp_eval_b_expr:=value ELSE Tfp_eval_b_expr:=0.0; END; {of Tfp_Eval_B_Expr} {---------------------------------------------------------} FUNCTION Tfp_parse2real(s : STRING): REAL; VAR value : REAL; BEGIN tfp_erpos:=0; tfp_ernr :=0; IF Maxavail>=Sizeof(tfp_parse_state) THEN BEGIN New(p); Tfp_check(s,p); IF (tfp_ernr=0) THEN value:=Tfp_eval_b_expr(p); Dispose(p); END ELSE Tfp_seternr(15); IF (tfp_ernr<>0) THEN Tfp_parse2real:=0.0 ELSE Tfp_parse2real:=value; END; {of Tfp_Parse2Real} {---------------------------------------------------------} 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; {of Tfp_Parse2str} {---------------------------------------------------------} FUNCTION Tfp_errormsg(nr : INTEGER) : STRING; BEGIN CASE nr OF 0 : Tfp_errormsg:='Result ok'; {Error 0 } 1 : Tfp_errormsg:='Invalid format of a number'; {Error 1 } 2 : Tfp_errormsg:='Unkown function'; {Error 2 } 3 : Tfp_errormsg:='( ) mismatch'; {Error 3 } 4 : Tfp_errormsg:='Real exponent -> complex number'; {Error 4 } 5 : Tfp_errormsg:='TAN( (2n+1)*PI/2 ) not defined'; {Error 5 } 6 : Tfp_errormsg:='Empty string'; {Error 6 } 7 : Tfp_errormsg:='LN(x) or LOG(x) for x<=0 -> complex number'; {Error 7 } 8 : Tfp_errormsg:='SQRT(x) for x<0 -> complex number'; {Error 8 } 9 : Tfp_errormsg:='Divide by zero'; {Error 9 } 10 : Tfp_errormsg:='To many function or constants'; {Error 10} 11 : Tfp_errormsg:='Intermediate result out of range'; {Error 11} 12 : Tfp_errormsg:='Illegal characters in functionname'; {Error 12} 13 : Tfp_errormsg:='Not a boolean expression'; {Error 13} 14 : Tfp_errormsg:='Wrong number of parameters'; {Error 14} 15 : Tfp_errormsg:='Memory problems'; {Error 15} 16 : Tfp_errormsg:='Not enough functions or constants'; {Error 16} 17 : Tfp_errormsg:='Csc( n*PI ) not defined'; {Error 17} 18 : Tfp_errormsg:='Sec( (2n+1)*PI/2 ) not defined'; {Error 18} 19 : Tfp_errormsg:='Cot( n*PI ) not defined'; {Error 19} 20 : Tfp_errormsg:='Parameter to large'; {Error 20} 21 : Tfp_errormsg:='Csch(0) not defined'; {Error 21} 22 : Tfp_errormsg:='Coth(0) not defined'; {Error 22} 23 : Tfp_errormsg:='ArcCosh(x) not defined for x<1'; {Error 23} 24 : Tfp_errormsg:='ArcTanh(x) not defined for Abs(x)=>1'; {Error 24} 25 : Tfp_errormsg:='Arccsch(0) not defined'; {Error 25} 26 : Tfp_errormsg:='Arcsech(x) not defined for x<=0 or x>1'; {Error 26} 27 : Tfp_errormsg:='Arccoth(x) not defined for Abs(x)<=1'; {Error 27} ELSE Tfp_errormsg:='Unkown error'; {Error xx} END; END; {of Tfp_ermsg} {---------------------------------------------------------} PROCEDURE Tfp_init(no : WORD); BEGIN IF (maxfie>0) THEN Freemem(fiearr,maxfie*Sizeof(tfp_fie_typ)); maxfie:=0; fiesiz:=0; IF (Maxavail>=(no*Sizeof(tfp_fie_typ))) AND (no>0) THEN BEGIN getmem(fiearr,no*Sizeof(tfp_fie_typ)); maxfie:=no; END ELSE Tfp_seternr(15); END; {of Tfp_Init} {---------------------------------------------------------} PROCEDURE Tfp_expand(no : WORD); VAR temp : ^tfp_fieptr; BEGIN IF (maxfie>0) AND (no>0) THEN BEGIN IF (Maxavail>=(maxfie+no)*Sizeof(tfp_fie_typ)) THEN BEGIN getmem(temp,(maxfie+no)*Sizeof(tfp_fie_typ)); Move(fiearr^,temp^,maxfie*Sizeof(tfp_fie_typ)); Freemem(fiearr,maxfie*Sizeof(tfp_fie_typ)); fiearr:=POINTER(temp); maxfie:=maxfie+no; fiesiz:=fiesiz; END ELSE Tfp_seternr(15) END ELSE Tfp_init(no); END; {of Tfp_Expand} {---------------------------------------------------------} PROCEDURE Tfp_keep(no : WORD); BEGIN IF (maxfie0) AND NOT (tfp_fname[1] IN ['A'..'Z']) THEN Tfp_seternr(12); tfp_ftype:=ftype; END END ELSE Tfp_seternr(10); {$R+} END; {of Tfp_Addobject} {---------------------------------------------------------} {----Internal Functions } {---------------------------------------------------------} {$F+} FUNCTION Xabs(VAR r : REAL) : REAL; BEGIN Xabs:=Abs(r); END; {of xABS} {---------------------------------------------------------} FUNCTION Xand(VAR lu_r;VAR n : INTEGER) : REAL; VAR r : REAL; i : INTEGER; BEGIN FOR i:=0 TO n DO IF (tfp_rarray(lu_r)[i]<>tfp_false) AND (tfp_rarray(lu_r)[i]<>tfp_true) THEN BEGIN IF (tfp_ernr=0) THEN Tfp_seternr(13); END; IF (tfp_ernr=0) AND (n>0) THEN BEGIN r:=tfp_true*Ord(tfp_rarray(lu_r)[0]=tfp_true); FOR i:=1 TO n DO r:=tfp_true*Ord( (r=tfp_true) AND (tfp_rarray(lu_r)[i]=tfp_true)) END ELSE Tfp_seternr(14); IF tfp_ernr=0 THEN Xand:=r ELSE Xand:=0.0; END; {of xAND} {---------------------------------------------------------} FUNCTION Xarctan(VAR r : REAL) : REAL; BEGIN Xarctan:=Arctan(r); END; {of xArctan} {---------------------------------------------------------} FUNCTION Xcos(VAR r : REAL) : REAL; BEGIN Xcos:=Cos(r); END; {of xCos} {---------------------------------------------------------} FUNCTION Xdeg(VAR r : REAL) : REAL; BEGIN Xdeg:=(r/pi)*180; END; {of xDEG} {---------------------------------------------------------} FUNCTION Xe : REAL; BEGIN Xe:=Exp(1); END; {of xE} {---------------------------------------------------------} FUNCTION Xexp(VAR r : REAL) : REAL; BEGIN Xexp:=0; IF (Abs(r)0) THEN Xln:=Ln(r) ELSE Tfp_seternr(7); END; {of xLn} {---------------------------------------------------------} FUNCTION Xlog(VAR r : REAL) : REAL; BEGIN Xlog:=0; IF (r>0) THEN Xlog:=Ln(r)/ln(10) ELSE Tfp_seternr(7); END; {of xLog} {---------------------------------------------------------} FUNCTION Xmax(VAR lu_r;VAR n : INTEGER) : REAL; VAR max : REAL; i : INTEGER; BEGIN max:=tfp_rarray(lu_r)[0]; FOR i:=1 TO n DO IF (tfp_rarray(lu_r)[i]>max) THEN max:=tfp_rarray(lu_r)[i]; Xmax:=max; END; {of xMax} {---------------------------------------------------------} FUNCTION Xmin(VAR lu_r;VAR n : INTEGER) : REAL; VAR min : REAL; i : INTEGER; BEGIN min:=tfp_rarray(lu_r)[0]; FOR i:=1 TO n DO IF (tfp_rarray(lu_r)[i]tfp_false) AND (tfp_rarray(lu_r)[i]<>tfp_true) THEN BEGIN IF (tfp_ernr=0) THEN Tfp_seternr(13); END; IF (tfp_ernr=0) AND (n>0) THEN BEGIN r:=tfp_true*Ord(tfp_rarray(lu_r)[0]=tfp_true); FOR i:=1 TO n DO r:=tfp_true*Ord((r=tfp_true) OR (tfp_rarray(lu_r)[i]=tfp_true)) END ELSE Tfp_seternr(14); IF tfp_ernr=0 THEN Xior:=r ELSE Xior:=Tfp_false; END; {of xIor} {---------------------------------------------------------} FUNCTION Xpi : REAL; BEGIN Xpi:=Pi; END; {of xPi} {---------------------------------------------------------} FUNCTION Xrad(VAR r : REAL) : REAL; BEGIN Xrad:=(r/180)*Pi; END; {of xRad} {---------------------------------------------------------} FUNCTION Xround(VAR r : REAL) : REAL; BEGIN IF (Abs(r)=0) THEN Xsgn:=+1 ELSE Xsgn:=-1; END; {of xSgn} {---------------------------------------------------------} FUNCTION Xsin(VAR r : REAL) : REAL; BEGIN Xsin:=Sin(r); END; {of xSin} {---------------------------------------------------------} FUNCTION Xsqr(VAR r : REAL) : REAL; BEGIN Xsqr:=0; IF (Abs(r)>0) THEN BEGIN IF ( Abs(2*Ln(Abs(r))) )=0) THEN Xsqrt:=Sqrt(r) ELSE Tfp_seternr(8); END; {of xSqrt} {---------------------------------------------------------} FUNCTION Xtan(VAR r : REAL) : REAL; BEGIN Xtan:=0; IF (Cos(r)=0) THEN Tfp_seternr(5) ELSE Xtan:=Sin(r)/cos(r); END; {of xTan} {---------------------------------------------------------} FUNCTION Xtrue : REAL; BEGIN Xtrue:=tfp_true; END; {of xTrue} {---------------------------------------------------------} FUNCTION Xxor(VAR r1,r2 : REAL) : REAL; BEGIN Xxor:=tfp_false; IF ((r1<>tfp_false) AND (r1<>tfp_true)) OR ((r2<>tfp_false) AND (r2<>tfp_true)) THEN BEGIN IF (tfp_ernr=0) THEN Tfp_seternr(13); END ELSE Xxor:=tfp_true*Ord((r1=tfp_true) XOR (r2=tfp_true)); END; {of xXOR} {---------------------------------------------------------} {----Hyperbolic, reciproce and inverse goniometric } { functions } {---------------------------------------------------------} Function xCsc(VAR r: Real): Real; Begin; xCsc:=0; IF (Sin(r)=0) THEN Tfp_seternr(17) ELSE xCsc:=1/Sin(r); End; {xCsc} {---------------------------------------------------------} Function xSec(VAR r: Real): Real; Begin; xSec:=0; IF (Cos(r)=0) THEN Tfp_seternr(18) ELSE xSec:=1/Cos(r); End; {xSec} {---------------------------------------------------------} Function xCot(VAR r : Real): Real; Begin; xCot:=0; IF (Sin(r)=0) THEN Tfp_seternr(19) ELSE xCot:=Cos(r)/Sin(r); End; {xCot} {---------------------------------------------------------} FUNCTION xCosh(VAR r : REAL) : REAL; BEGIN xCosh:=0; IF (Abs(r)>Ln(tfp_maxreal)) THEN Tfp_seternr(20) ELSE xCosh:=(Exp(r)+Exp(-r))/2; END; {of xCosh} {---------------------------------------------------------} FUNCTION xSinh(VAR r : REAL) : REAL; BEGIN xSinh:=0; IF (Abs(r)>Ln(tfp_maxreal)) THEN Tfp_seternr(20) ELSE xSinh:=(Exp(r)-Exp(-r))/2; END; {of xSinh} {---------------------------------------------------------} FUNCTION xTanh(VAR r : REAL) : REAL; BEGIN xTanh:=0; IF (Abs(r)>Ln(tfp_maxreal)) THEN Tfp_seternr(20) ELSE xTanh:=(Exp(r)-Exp(-r))/(Exp(r)+Exp(-r)); END; {of xTanh} {---------------------------------------------------------} FUNCTION xCsch(VAR r : REAL) : REAL; BEGIN xCsch:=0; IF (Abs(r)>Ln(tfp_maxreal)) THEN Tfp_seternr(20) ELSE BEGIN IF (r=0) THEN Tfp_seternr(21) ELSE xCsch:=2/(Exp(r)-Exp(-r)) END; END; {of xCsch} {---------------------------------------------------------} FUNCTION xSech(VAR r : REAL) : REAL; BEGIN xSech:=0; IF (Abs(r)>Ln(tfp_maxreal)) THEN Tfp_seternr(20) ELSE xSech:=2/(Exp(r)+Exp(-r)); END; {of xSech} {---------------------------------------------------------} FUNCTION xCoth(VAR r : REAL) : REAL; BEGIN xCoth:=0; IF (Abs(r)>Ln(tfp_maxreal)) THEN Tfp_seternr(20) ELSE BEGIN IF (r=0) THEN Tfp_seternr(22) ELSE xCoth:=(Exp(r)+Exp(-r))/(Exp(r)-Exp(-r)) END; END; {of xCoth} {---------------------------------------------------------} FUNCTION xArcsinh(VAR r : REAL) : REAL; BEGIN xArcsinh:=0; IF (Abs(r)=1) THEN xArccosh:=ln(r+Sqrt(Sqr(r)-1)) ELSE Tfp_seternr(23); END ELSE Tfp_seternr(20) END; {of xArccosh} {---------------------------------------------------------} FUNCTION xArctanh(VAR r : REAL) : REAL; BEGIN xArctanh:=0; IF (Abs(r)<1) THEN xArctanh:=ln( (1+r)/(1-r) )/2 ELSE Tfp_seternr(24) END; {of xArctanh} {---------------------------------------------------------} FUNCTION xArccsch(VAR r : REAL) : REAL; BEGIN xArccsch:=0; IF (r0) THEN xArccsch:=Ln( (1/r) + SQRT( (1/SQR(r))+1)) ELSE Tfp_seternr(25) END ELSE Tfp_seternr(20); END; {of xArccsch} {---------------------------------------------------------} FUNCTION xArcsech(VAR r : REAL) : REAL; BEGIN xArcsech:=0; IF (r0) AND (r<=1) THEN xArcsech:=Ln( (1/r) + SQRT( (1/SQR(r))-1)) ELSE Tfp_seternr(26) END ELSE Tfp_seternr(20) END; {of xArcsech} {---------------------------------------------------------} FUNCTION xArccoth(VAR r : REAL) : REAL; BEGIN xArccoth:=0; IF (Abs(r)>1) THEN xArccoth:=Ln( (r+1)/(r-1) )/2 ELSE Tfp_seternr(27) END; {of xArccoth} {$F-} {---------------------------------------------------------} PROCEDURE Tfp_addgonio; BEGIN Tfp_expand(7); 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; {of Tfp_Addgonio} {---------------------------------------------------------} PROCEDURE Tfp_addlogic; BEGIN Tfp_expand(5); 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; {of Tfp_Addlogic} {---------------------------------------------------------} PROCEDURE Tfp_addmath; BEGIN Tfp_expand(7); 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; {of Tfp_Addmath} {---------------------------------------------------------} PROCEDURE Tfp_addmisc; BEGIN Tfp_expand(6); 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; {of Tfp_Addmisc} {---------------------------------------------------------} PROCEDURE Tfp_addinvarchyper; BEGIN Tfp_expand(15); Tfp_addobj(@xcsc ,'CSC' ,tfp_1real); Tfp_addobj(@xsec ,'SEC' ,tfp_1real); Tfp_addobj(@xcot ,'COT' ,tfp_1real); Tfp_addobj(@xsinh ,'SINH' ,tfp_1real); Tfp_addobj(@xcosh ,'COSH' ,tfp_1real); Tfp_addobj(@xtanh ,'TANH' ,tfp_1real); Tfp_addobj(@xcsch ,'CSCH' ,tfp_1real); Tfp_addobj(@xsech ,'SECH' ,tfp_1real); Tfp_addobj(@xcoth ,'COTH' ,tfp_1real); Tfp_addobj(@xarcsinh,'ARCSINH',tfp_1real); Tfp_addobj(@xarccosh,'ARCCOSH',tfp_1real); Tfp_addobj(@xarctanh,'ARCTANH',tfp_1real); Tfp_addobj(@xarccsch,'ARCCSCH',tfp_1real); Tfp_addobj(@xarcsech,'ARCSECH',tfp_1real); Tfp_addobj(@xarccoth,'ARCCOTH',tfp_1real); End; {of Add_invandhyper} {---------------------------------------------------------} PROCEDURE Tfp_addall; BEGIN Tfp_addgonio; Tfp_addlogic; Tfp_addmath; Tfp_addmisc; Tfp_addinvarchyper; END; {of Tfp_addall} {---------------------------------------------------------} BEGIN {----Module Init} tfp_erpos :=0; tfp_ernr :=0; fiesiz:=0; maxfie:=0; fiearr:=NIL; END.