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