MathgeomGLS
1279 строк · 24.0 Кб
1unit Graf.Parser1d;
2// This parser is used only for y = f(x) graphs
3
4interface
5
6uses
7System.Classes,
8System.Math,
9System.SysUtils;
10
11const
12Pi: extended = 3.1415926535897932385;
13PiOn2: extended = 1.5707963267948966192;
14twoPi: extended = 6.2831853071795864769;
15
16type
17TFuncDef = class
18public
19function DefName: string; virtual; abstract;
20function Eval(x: extended): extended; virtual; abstract;
21end;
22
23TVarDef = class
24public
25VarName: string;
26Value: extended;
27end;
28
29TCalculus = class
30public
31function Eval: extended; virtual; abstract;
32end;
33
34TFxParser = class(TObject)
35constructor Create(x: extended);
36destructor Destroy; override;
37private
38FunctionList: TList;
39VariableList: TList;
40function FunctionOf(i: integer): TFuncDef;
41function VariableOf(i: integer): TVarDef;
42function CheckBrackets(const s: string): Boolean;
43function CompileExpresion(const s: string; var Error: byte): TCalculus;
44function FactorCompile(const s: string; var Error: byte): TCalculus;
45function SimpleCompile(const s: string; var Error: byte): TCalculus;
46procedure Substitute(var s: string);
47procedure ClearLists;
48public
49VarX: TVarDef;
50Calculus: TCalculus;
51ErrorByte: byte;
52function Compile(s: string; var Error: byte): TCalculus;
53procedure AddVar(v: TVarDef);
54procedure ConstructLists;
55end;
56
57TConst = class(TCalculus)
58constructor Create(c: extended);
59public
60function Eval: extended; override;
61private
62Val: extended;
63end;
64
65TVar = class(TCalculus)
66public
67constructor Create(v: TVarDef);
68function Eval: extended; override;
69protected
70Def: TVarDef;
71end;
72
73TFunc = class(TCalculus)
74constructor Create(v: TCalculus; f: TFuncDef);
75destructor Destroy; override;
76public
77function Eval: extended; override;
78protected
79Variable: TCalculus;
80Def: TFuncDef;
81end;
82
83TOperator = class(TCalculus)
84constructor Create(c1, c2: TCalculus);
85destructor Destroy; override;
86public
87protected
88e1, e2: TCalculus;
89end;
90
91TMinus = class(TOperator)
92public
93function Eval: extended; override;
94end;
95
96TSum = class(TOperator)
97public
98function Eval: extended; override;
99end;
100
101TProduct = class(TOperator)
102public
103function Eval: extended; override;
104end;
105
106TDivision = class(TOperator)
107public
108function Eval: extended; override;
109end;
110
111TPower = class(TOperator)
112public
113function Eval: extended; override;
114end;
115
116TFactorial = class(TOperator)
117public
118function Eval: extended; override;
119end;
120
121TDegToRad = class(TOperator)
122public
123function Eval: extended; override;
124end;
125
126TAbs = class(TFuncDef)
127public
128function DefName: string; override;
129function Eval(x: extended): extended; override;
130end;
131
132TSqr = class(TFuncDef)
133public
134function DefName: string; override;
135function Eval(x: extended): extended; override;
136end;
137
138TSqrt = class(TFuncDef)
139public
140function DefName: string; override;
141function Eval(x: extended): extended; override;
142end;
143
144TSin = class(TFuncDef)
145public
146function DefName: string; override;
147function Eval(x: extended): extended; override;
148end;
149
150TCos = class(TFuncDef)
151public
152function DefName: string; override;
153function Eval(x: extended): extended; override;
154end;
155
156TTan = class(TFuncDef)
157public
158function DefName: string; override;
159function Eval(x: extended): extended; override;
160end;
161
162TCsc = class(TFuncDef)
163public
164function DefName: string; override;
165function Eval(x: extended): extended; override;
166end;
167
168TSec = class(TFuncDef)
169public
170function DefName: string; override;
171function Eval(x: extended): extended; override;
172end;
173
174TCot = class(TFuncDef)
175public
176function DefName: string; override;
177function Eval(x: extended): extended; override;
178end;
179
180TArcSin = class(TFuncDef)
181public
182function DefName: string; override;
183function Eval(x: extended): extended; override;
184end;
185
186TArcCos = class(TFuncDef)
187public
188function DefName: string; override;
189function Eval(x: extended): extended; override;
190end;
191
192TArcTan = class(TFuncDef)
193public
194function DefName: string; override;
195function Eval(x: extended): extended; override;
196end;
197
198TArcCsc = class(TFuncDef)
199public
200function DefName: string; override;
201function Eval(x: extended): extended; override;
202end;
203
204TArcSec = class(TFuncDef)
205public
206function DefName: string; override;
207function Eval(x: extended): extended; override;
208end;
209
210TArcCot = class(TFuncDef)
211public
212function DefName: string; override;
213function Eval(x: extended): extended; override;
214end;
215
216TLn = class(TFuncDef)
217public
218function DefName: string; override;
219function Eval(x: extended): extended; override;
220end;
221
222TExp = class(TFuncDef)
223public
224function DefName: string; override;
225function Eval(x: extended): extended; override;
226end;
227
228TLog10 = class(TFuncDef)
229public
230function DefName: string; override;
231function Eval(x: extended): extended; override;
232end;
233
234TLog2 = class(TFuncDef)
235public
236function DefName: string; override;
237function Eval(x: extended): extended; override;
238end;
239
240TSinh = class(TFuncDef)
241public
242function DefName: string; override;
243function Eval(x: extended): extended; override;
244end;
245
246TCosh = class(TFuncDef)
247public
248function DefName: string; override;
249function Eval(x: extended): extended; override;
250end;
251
252TTanh = class(TFuncDef)
253public
254function DefName: string; override;
255function Eval(x: extended): extended; override;
256end;
257
258TCsch = class(TFuncDef)
259public
260function DefName: string; override;
261function Eval(x: extended): extended; override;
262end;
263
264TSech = class(TFuncDef)
265public
266function DefName: string; override;
267function Eval(x: extended): extended; override;
268end;
269
270TCoth = class(TFuncDef)
271public
272function DefName: string; override;
273function Eval(x: extended): extended; override;
274end;
275
276TArcSinh = class(TFuncDef)
277public
278function DefName: string; override;
279function Eval(x: extended): extended; override;
280end;
281
282TArcCosh = class(TFuncDef)
283public
284function DefName: string; override;
285function Eval(x: extended): extended; override;
286end;
287
288TArcTanh = class(TFuncDef)
289public
290function DefName: string; override;
291function Eval(x: extended): extended; override;
292end;
293
294TArcCsch = class(TFuncDef)
295public
296function DefName: string; override;
297function Eval(x: extended): extended; override;
298end;
299
300TArcSech = class(TFuncDef)
301public
302function DefName: string; override;
303function Eval(x: extended): extended; override;
304end;
305
306TArcCoth = class(TFuncDef)
307public
308function DefName: string; override;
309function Eval(x: extended): extended; override;
310end;
311
312function ScanText(const s: string): string;
313function ParseAndEvaluate(const aText: string; var e: byte): extended;
314
315//================================================================
316implementation
317//================================================================
318
319uses
320faGraf1D;
321
322// TCalculus Class
323constructor TConst.Create(c: extended);
324begin
325Val := c;
326end;
327
328function TConst.Eval: extended;
329begin
330Result := Val;
331end;
332
333constructor TVar.Create(v: TVarDef);
334begin
335Def := v;
336end;
337
338function TVar.Eval: extended;
339begin
340Result := Def.value;
341end;
342
343constructor TFunc.Create(v: TCalculus; f: TFuncDef);
344begin
345Variable := v;
346Def := f;
347end;
348
349destructor TFunc.Destroy;
350begin
351Variable.Free;
352end;
353
354function TFunc.Eval: extended;
355begin
356Result := Def.Eval(Variable.Eval);
357end;
358
359constructor TOperator.Create(c1, c2: TCalculus);
360begin
361e1 := c1;
362e2 := c2;
363end;
364
365destructor TOperator.Destroy;
366begin
367e1.Free;
368e2.Free;
369end;
370{ TCalculus Class }
371
372{ TFxParser }
373constructor TFxParser.Create(x: extended);
374begin
375inherited Create;
376FunctionList := TList.Create;
377VariableList := TList.Create;
378
379ConstructLists;
380
381VarX := TVarDef.Create;
382VarX.VarName := 'x';
383VarX.Value := x;
384addVar(VarX);
385end;
386
387destructor TFxParser.Destroy;
388begin
389ClearLists;
390inherited Destroy;
391end;
392
393function TFxParser.FunctionOf(i: integer): TFuncDef;
394begin
395Result := TFuncDef(FunctionList.Items[i]);
396end;
397
398function TFxParser.VariableOf(i: integer): TVarDef;
399begin
400Result := TVarDef(VariableList.Items[i]);
401end;
402
403function TFxParser.CheckBrackets(const s: string): Boolean;
404var
405i, j, c1, c2: integer;
406
407begin
408c1 := 0;
409c2 := 0;
410i := 1;
411j := Length(s);
412while i <= j do
413begin
414if s[i] = '(' then Inc(c1);
415if s[i] = ')' then Inc(c2);
416Inc(i);
417end;
418Result := c1 = c2;
419end;
420
421function TFxParser.CompileExpresion(const s: string; var Error: byte): TCalculus;
422var
423i: integer;
424e1: byte;
425e2: byte;
426c1, c2: TCalculus;
427
428begin
429if s = '' then
430begin
431Error := 3;
432Result := nil;
433Exit;
434end;
435
436if not CheckBrackets(s) then
437begin
438Error := 1;
439Result := nil;
440Exit;
441end;
442
443{----- -factor -----}
444if s[1] = '-' then
445begin
446c1 := FactorCompile(copy(s, 2, length(s)-1), e1);
447if e1 = 0 then
448begin
449c2 := TConst.Create(0);
450Result := TMinus.Create(c2, c1);
451Error := 0;
452Exit;
453end;
454end;
455
456{----- exp+factor -----}
457{----- exp-factor -----}
458{----- exp!factor -----}
459{----- exp�factor -----}
460for i := length(s) downto 1 do
461begin
462case s[i] of
463'+': begin
464c1 := CompileExpresion(copy(s, 1, i -1), e1);
465if e1 = 0 then
466begin
467c2 := FactorCompile(copy(s, i +1, length(s) -i), e2);
468if e2 = 0 then
469begin
470Result := TSum.Create(c1, c2);
471Error := 0;
472Exit;
473end
474else c1.Free;
475end;
476end;
477'-': begin
478c1 := CompileExpresion(copy(s, 1, i -1), e1);
479if e1 = 0 then
480begin
481c2 := FactorCompile(copy(s, i +1, length(s) -i), e2);
482if e2 = 0 then
483begin
484Result := TMinus.Create(c1, c2);
485Error := 0;
486Exit;
487end
488else c1.Free;
489end;
490end;
491'!': begin
492c1 := CompileExpresion(copy(s, 1, i -1), e1);
493if e1 = 0 then
494begin
495c2 := FactorCompile(copy(s, 1, i -1), e2);
496if e2 = 0 then
497begin
498Result := TFactorial.Create(c1, c2);
499Error := 0;
500Exit;
501end
502else c1.Free;
503end;
504end;
505'�': begin
506c1 := CompileExpresion(copy(s, 1, i -1), e1);
507if e1 = 0 then
508begin
509c2 := FactorCompile(copy(s, 1, i -1), e2);
510if e2 = 0 then
511begin
512Result := TDegToRad.Create(c1, c2);
513Error := 0;
514Exit;
515end
516else c1.Free;
517end;
518end;
519end; { case s[i] of... }
520end; { for i := length(s) downto 1 do... }
521Result := FactorCompile(s, Error);
522end;
523
524function TFxParser.FactorCompile(const s: string; var Error: byte): TCalculus;
525var
526i: integer;
527e1, e2: byte;
528c1, c2: TCalculus;
529
530begin
531if s = '' then
532begin
533Error := 3;
534Result := nil;
535Exit;
536end;
537
538if not CheckBrackets(s) then
539begin
540Error := 1;
541Result := nil;
542Exit;
543end;
544
545{----- factor*simple -----}
546{----- factor/simple -----}
547for i := length(s) downto 1 do
548begin
549case s[i] of
550'*': begin
551c1 := FactorCompile(copy(s, 1, i -1), e1);
552if e1 = 0 then
553begin
554c2 := SimpleCompile(copy(s, i +1, length(s) -i), e2);
555if e2 = 0 then
556begin
557Result := TProduct.Create(c1, c2);
558Error := 0;
559Exit;
560end
561else c1.Free;
562end;
563end;
564'/': begin
565c1 := FactorCompile(copy(s, 1, i -1), e1);
566if e1 = 0 then
567begin
568c2 := SimpleCompile(copy(s, i +1, length(s) -i), e2);
569if e2 = 0 then
570begin
571Result := TDivision.Create(c1, c2);
572Error := 0;
573Exit;
574end
575else c1.Free;
576end;
577end;
578end; { case s[i] of... }
579end; { for i := length(s) downto 1 do... }
580Result := SimpleCompile(s, Error);
581end;
582
583function TFxParser.SimpleCompile(const s: string; var Error: byte): TCalculus;
584var
585i: integer;
586e1, e2: byte;
587c1, c2: TCalculus;
588d: extended;
589
590begin
591if s = '' then
592begin
593Error := 3;
594Result := nil;
595Exit;
596end;
597
598if not CheckBrackets(s) then
599begin
600Error := 1;
601Result := nil;
602Exit;
603end;
604
605{----- const -----}
606Val(s, d, i);
607if i = 0 then
608begin
609Result := TConst.Create(d);
610Error := 0;
611Exit;
612end;
613
614{----- (exp) -----}
615if (s[1] = '(') and (s[length(s)] = ')') then
616begin
617c1 := CompileExpresion(copy(s, 2, length(s)-2), e1);
618if e1 = 0 then
619begin
620Result := c1;
621Error := 0;
622Exit;
623end;
624end;
625
626{----- VarName -----}
627for i := 0 to VariableList.Count -1 do
628begin
629if s = VariableOf(i).VarName then
630begin
631Result := TVar.Create(VariableOf(i));
632Error := 0;
633Exit;
634end;
635end;
636
637{----- DefNameFunc(exp) -----}
638for i := 0 to FunctionList.Count -1 do
639begin
640if (Pos(FunctionOf(i).DefName + '(', s) = 1) and (s[length(s)] = ')')
641then
642begin
643c1 := CompileExpresion(copy(s, length(FunctionOf(i).DefName) +2,
644length(s) - length(FunctionOf(i).DefName) -2), e1);
645if e1 = 0 then
646begin
647Result := TFunc.Create(c1, FunctionOf(i));
648Error := 0;
649Exit;
650end;
651end;
652end;
653
654{----- simple^simple -----}
655for i := 1 to length(s) do
656begin
657case s[i] of
658'^': begin
659c1 := SimpleCompile(copy(s, 1, i -1), e1);
660if e1 = 0 then
661begin
662c2 := SimpleCompile(copy(s, i +1, length(s) -i), e2);
663if e2 = 0 then
664begin
665Result := TPower.Create(c1, c2);
666Error := 0;
667Exit;
668end
669else c1.Free;
670end;
671end;
672end; { case s[i] of... }
673end; { for i := 1 to length(s) do... }
674
675Error := 2;
676Result := nil;
677end;
678
679procedure TFxParser.Substitute(var s: string);
680var
681t: string;
682i: integer;
683
684begin
685t := '';
686for i := 1 to Length(s) do
687if s[i] <> ' ' then if s[i] = '�' then t := t + 'x' else t := t + s[i];
688s := t;
689end;
690
691function TFxParser.Compile(s: string; var Error: byte): TCalculus;
692begin
693Substitute(s); { this will substitute x for � }
694Result := CompileExpresion(s, Error);
695end;
696
697procedure TFxParser.AddVar(v: TVarDef);
698begin
699VariableList.Add(v);
700end;
701
702procedure TFxParser.ConstructLists;
703var
704v: TVarDef;
705begin
706with FunctionList do
707begin
708Add(TAbs.Create);
709Add(TSqr.Create);
710Add(TSqrt.Create);
711Add(TSin.Create);
712Add(TCos.Create);
713Add(TTan.Create);
714Add(TCsc.Create);
715Add(TSec.Create);
716Add(TCot.Create);
717
718Add(TArcSin.Create);
719Add(TArcCos.Create);
720Add(TArcTan.Create);
721Add(TArcCsc.Create);
722Add(TArcSec.Create);
723Add(TArcCot.Create);
724
725Add(TLn.Create);
726Add(TExp.Create);
727Add(TLog10.Create);
728Add(TLog2.Create);
729
730Add(TSinh.Create);
731Add(TCosh.Create);
732Add(TTanh.Create);
733Add(TCsch.Create);
734Add(TSech.Create);
735Add(TCoth.Create);
736
737Add(TArcSinh.Create);
738Add(TArcCosh.Create);
739Add(TArcTanh.Create);
740Add(TArcCsch.Create);
741Add(TArcSech.Create);
742Add(TArcCoth.Create);
743end;
744
745v := TVarDef.Create;
746v.VarName := 'pi';
747v.Value := Pi;
748VariableList.Add(v);
749v := TVarDef.Create;
750v.VarName := '2pi';
751v.Value := twoPi;
752VariableList.Add(v);
753end;
754
755procedure TFxParser.ClearLists;
756var
757i: integer;
758
759begin
760for i := 0 to FunctionList.Count -1 do TFuncDef(FunctionList[i]).Free;
761FunctionList.Free;
762for i := 0 to VariableList.Count -1 do TVarDef(VariableList[i]).Free;
763VariableList.Free;
764end;
765{ TFxParser }
766
767{ TOperator Class }
768function TMinus.Eval: extended;
769var
770n1, n2: extended;
771
772begin
773n1 := e1.Eval;
774n2 := e2.Eval;
775Result := n1 - n2;
776end;
777
778function TSum.Eval: extended;
779var
780n1, n2: extended;
781
782begin
783n1 := e1.Eval;
784n2 := e2.Eval;
785Result := n1 + n2;
786end;
787
788function TProduct.Eval: extended;
789var
790n1, n2: extended;
791begin
792n1 := e1.Eval;
793n2 := e2.Eval;
794Result := n1*n2;
795end;
796
797function TDivision.Eval: extended;
798var
799n1, n2: extended;
800begin
801n1 := e1.Eval; { numerator }
802n2 := e2.Eval; { deviser }
803
804if IsInfinite(n2) then
805begin
806Result := NaN;
807Exit;
808end;
809
810Result := n1/n2;
811end;
812
813function TPower.Eval: extended;
814var
815b, e: extended;
816{ For fractional exponents or exponents greater than MaxInt,
817base must be greater than 0. }
818begin
819b := e1.Eval; { base/mantissa }
820e := e2.Eval; { exponent }
821if b = 0 then Result := 0 else Result := Power(b, e)
822end;
823
824function TFactorial.Eval: extended;
825var
826i, j: integer;
827begin
828j := round(e1.Eval);
829if (j < 0) or (j > 1754)
830then Result := 0.0
831else
832begin
833Result := 1.0;
834for i := 2 to j do Result := i*Result;
835end;
836end;
837
838function TDegToRad.Eval: extended;
839begin
840Result := DegToRad(e1.Eval);
841end;
842
843function TAbs.DefName: string;
844begin
845Result := 'abs';
846end;
847
848function TAbs.Eval(x: extended): extended;
849begin
850Result := Abs(x);
851end;
852
853function TSqr.DefName: string;
854begin
855Result := 'sqr';
856end;
857
858function TSqr.Eval(x: extended): extended;
859begin
860Result := Sqr(x);
861end;
862
863function TSqrt.DefName: string;
864begin
865Result := 'sqrt';
866end;
867
868function TSqrt.Eval(x: extended): extended;
869begin
870Result := Sqrt(x);
871end;
872
873function TSin.DefName: string;
874begin
875Result := 'sin';
876end;
877
878function TSin.Eval(x: extended): extended;
879begin
880Result := Sin(x);
881end;
882
883function TCos.DefName: string;
884begin
885Result := 'cos';
886end;
887
888function TCos.Eval(x: extended): extended;
889begin
890Result := Cos(x);
891end;
892
893function TTan.DefName: string;
894begin
895Result := 'tan';
896end;
897
898function TTan.Eval(x: extended): extended;
899begin
900Result := Tan(x);
901end;
902
903function TCsc.DefName: string;
904begin
905Result := 'csc';
906end;
907
908function TCsc.Eval(x: extended): extended;
909begin
910Result := Csc(x);
911end;
912
913function TSec.DefName: string;
914begin
915Result := 'sec';
916end;
917
918function TSec.Eval(x: extended): extended;
919begin
920Result := Sec(x);
921end;
922
923function TCot.DefName: string;
924begin
925Result := 'cot';
926end;
927
928function TCot.Eval(x: extended): extended;
929begin
930Result := Cot(x);
931end;
932
933function TArcSin.DefName: string;
934begin
935Result := 'arcsin';
936end;
937
938function TArcSin.Eval(x: extended): extended;
939begin
940Result := ArcSin(x);
941end;
942
943function TArcCos.DefName: string;
944begin
945Result := 'arccos';
946end;
947
948function TArcCos.Eval(x: extended): extended;
949begin
950Result := ArcCos(x);
951end;
952
953function TArcTan.DefName: string;
954begin
955Result := 'arctan';
956end;
957
958function TArcTan.Eval(x: extended): extended;
959begin
960Result := ArcTan(x);
961end;
962
963function TArcCsc.DefName: string;
964begin
965Result := 'arccsc';
966end;
967
968function TArcCsc.Eval(x: extended): extended;
969begin
970Result := ArcCsc(x);
971end;
972
973function TArcSec.DefName: string;
974begin
975Result := 'arcsec';
976end;
977
978function TArcSec.Eval(x: extended): extended;
979begin
980Result := ArcSec(x);
981end;
982
983function TArcCot.DefName: string;
984begin
985Result := 'arccot';
986end;
987
988function TArcCot.Eval(x: extended): extended;
989begin
990Result := ArcCot(x);
991if (Result > Pion2) or (Result < -Pion2)
992then Result := NaN;
993end;
994
995function TLn.DefName: string;
996begin
997Result := 'ln';
998end;
999
1000function TLn.Eval(x: extended): extended;
1001begin
1002Result := Ln(x);
1003if isNaN(Result) then
1004begin
1005case Sign(Result) of
1006-1:Result := NegInfinity;
10070:Result := 0;
10081:Result := Infinity;
1009end;
1010end;
1011end;
1012
1013function TExp.DefName: string;
1014begin
1015Result := 'exp';
1016end;
1017
1018function TExp.Eval(x: extended): extended;
1019begin
1020Result := Exp(x);
1021end;
1022
1023function TLog10.DefName: string;
1024begin
1025Result := 'log';
1026end;
1027
1028function TLog10.Eval(x: extended): extended;
1029begin
1030Result := Log10(x);
1031if isNaN(Result) then
1032begin
1033case Sign(Result) of
1034-1:Result := NegInfinity;
10350:Result := 0;
10361:Result := Infinity;
1037end;
1038end;
1039end;
1040
1041function TLog2.DefName: string;
1042begin
1043Result := 'log2';
1044end;
1045
1046function TLog2.Eval(x: extended): extended;
1047begin
1048Result := Log2(x);
1049if isNaN(Result) then
1050begin
1051case Sign(Result) of
1052-1:Result := NegInfinity;
10530:Result := 0;
10541:Result := Infinity;
1055end;
1056end;
1057end;
1058
1059function TSinh.DefName: string;
1060begin
1061Result := 'sinh';
1062end;
1063
1064function TSinh.Eval(x: extended): extended;
1065begin
1066Result := Sinh(x);
1067end;
1068
1069function TCosh.DefName: string;
1070begin
1071Result := 'cosh';
1072end;
1073
1074function TCosh.Eval(x: extended): extended;
1075begin
1076Result := Cosh(x);
1077end;
1078
1079function TTanh.DefName: string;
1080begin
1081Result := 'tanh';
1082end;
1083
1084function TTanh.Eval(x: extended): extended;
1085begin
1086Result := Tanh(x);
1087end;
1088
1089function TCsch.DefName: string;
1090begin
1091Result := 'csch';
1092end;
1093
1094function TCsch.Eval(x: extended): extended;
1095begin
1096Result := Csch(x);
1097end;
1098
1099function TSech.DefName: string;
1100begin
1101Result := 'sech';
1102end;
1103
1104function TSech.Eval(x: extended): extended;
1105begin
1106Result := Sech(x);
1107end;
1108
1109function TCoth.DefName: string;
1110begin
1111Result := 'coth';
1112end;
1113
1114function TCoth.Eval(x: extended): extended;
1115begin
1116Result := Coth(x);
1117end;
1118
1119function TArcSinh.DefName: string;
1120begin
1121Result := 'arcsinh';
1122end;
1123
1124function TArcSinh.Eval(x: extended): extended;
1125begin
1126Result := ArcSinh(x);
1127end;
1128
1129function TArcCosh.DefName: string;
1130begin
1131Result := 'arccosh';
1132end;
1133
1134function TArcCosh.Eval(x: extended): extended;
1135begin
1136Result := ArcCosh(x);
1137end;
1138
1139function TArcTanh.DefName: string;
1140begin
1141Result := 'arctanh';
1142end;
1143
1144function TArcTanh.Eval(x: extended): extended;
1145begin
1146Result := ArcTanh(x)
1147end;
1148
1149function TArcCsch.DefName: string;
1150begin
1151Result := 'arccsch';
1152end;
1153
1154function TArcCsch.Eval(x: extended): extended;
1155begin
1156if x = 0 then Result := Infinity else Result := ArcCsch(x);
1157{ it would seem that Delphi 7 personal calculates ArcCsch incorrectly }
1158end;
1159
1160function TArcSech.DefName: string;
1161begin
1162Result := 'arcsech';
1163end;
1164
1165function TArcSech.Eval(x: extended): extended;
1166begin
1167if x <= 0 then Result := Infinity else Result := ArcSech(x);
1168end;
1169
1170function TArcCoth.DefName: string;
1171begin
1172Result := 'arccoth';
1173end;
1174
1175function TArcCoth.Eval(x: extended): extended;
1176begin
1177if (x >= -1) and (x < 0) then Result := NegInfinity else
1178if (x > 0) and (x <= 1) then Result := Infinity else
1179if x = 0 then Result := NaN else Result := ArcCoth(x);
1180end;
1181{ TOperator Class }
1182
1183function ScanText(const s: string): string;
1184function DropSpaces_Commas(const s: string): string;
1185var
1186i: integer;
1187
1188begin
1189Result := '';
1190for i := 1 to Length(s) do
1191if (s[i] <> ' ') and (s[i] <> ',') then Result := Result + s[i];
1192end; { DropSpaces_Commas }
1193
1194var
1195i, j: integer;
1196c0, c1, c2: char;
1197cc, ccc, isStr: string;
1198nostar: Boolean;
1199isExp: Boolean;
1200isLog: Boolean;
1201isPwr: Boolean;
1202t: string;
1203
1204begin { ScanText }
1205t := DropSpaces_Commas(s);
1206i := 1;
1207j := 1;
1208Result := t;
1209while i < Length(t) do
1210begin
1211c0 := UpCase(t[i]);
1212c1 := UpCase(t[i +1]);
1213if i < Length(t) - 1 then c2 := UpCase(t[i +2]) else c2 := #0;
1214
1215cc := c0+c1;
1216ccc := c0+c1+c2;
1217
1218isExp := ccc = 'XP(';
1219isStr := '';
1220isLog := false;
1221
1222if (i > 3) and ((cc = '0(') or (cc = '2(')) then
1223begin
1224if cc = '0('
1225then isStr := UpperCase(Copy(t, i -4, 3)) { Log10 }
1226else isStr := UpperCase(Copy(t, i -3, 3)); { Log2 }
1227isLog := isStr = 'LOG';
1228end;
1229
1230isPwr := CharInSet(c0, ['+', '-', '0'..'9']) and (UpCase(c1) = 'E') and
1231CharInSet(c2, ['+', '-', '0'..'9']);
1232nostar := isExp or isLog or isPwr;
1233
1234if not nostar and
1235CharInSet(c0, ['X', 'I', '0'..'9', ')']) and
1236CharInSet(c1, ['A'..'C', 'E', 'L', 'P', 'S', 'T', 'X', '�', '(']) then
1237begin
1238Insert('*', Result, i + j);
1239Inc(j);
1240end;
1241Inc(i);
1242end;
1243end; { ScanText }
1244
1245function ParseAndEvaluate(const aText: string; var e: byte): extended;
1246var
1247aParser: TFxParser;
1248
1249begin
1250aParser := TFxParser.Create(0);
1251with aParser do
1252begin
1253Calculus.Free;
1254ErrorByte := 0;
1255MainForm.StatusBar.Panels[2].Text := '';
1256Calculus := Compile(AnsiLowerCase(aText), ErrorByte);
1257e := ErrorByte;
1258if ErrorByte > 0 then
1259begin
1260with MainForm.StatusBar.Panels[2] do
1261case ErrorByte of
12621:Text := 'Check Brackets for "'+ aText+'"';
12632:Text := 'Unable to Parse "'+aText+'"';
1264end;
1265Result := 0;
1266end
1267else Result := Calculus.Eval;
1268Calculus.Free;
1269Calculus := nil;
1270Free;
1271end;
1272end;
1273
1274Initialization
1275{ Avoids arithmetic exceptions in the above code }
1276SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide,
1277exOverflow, exUnderflow, exPrecision]);
1278
1279end.
1280
1281