Develop and Download Open Source Software

Browse Subversion Repository

Contents of /expressc.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Mon Nov 7 12:03:00 2011 UTC (12 years, 4 months ago) by shiraishikazuo
File MIME type: text/x-pascal
File size: 30067 byte(s)


1 unit expressc;
2 {$IFDEF FPC}
3 {$MODE DELPHI}{$H+}
4 {$ENDIF}
5 (***************************************)
6 (* Copyright (C) 2006, SHIRAISHI Kazuo *)
7 (***************************************)
8
9
10 interface
11 uses variabl,express,struct,arithmet,{variabls,}mathc,{variablc,}float;
12
13 procedure SwitchToComplexMode;
14
15 {********************}
16 {numerical expression}
17 {********************}
18
19 type
20 TNexpression=class(TPrincipal)
21 constructor create;
22 //function evalInteger:integer;override;
23 function evalLongint:longint;override;
24 //function str:ansistring;override;
25 //function str2:ansistring;override;
26 //function compare(p:TPrincipal):integer;override;
27 function kind:char;override;
28 function evalX:extended;override;
29 //procedure EvalN(var n:number);override;
30 end;
31
32 type
33 ComplexFunction1=procedure(var x:complex);
34 ComplexFunction2=procedure(var x,y:complex);
35
36 type
37 TUnaryOpOrdinal=class(TNExpression)
38 exp:TPrincipal;
39 opC:ComplexFunction1;
40 name:ansistring;
41 constructor create(e:TPrincipal; op1:FloatFunction1;
42 op2:extendedfunction1;op3:ComplexFunction1;
43 er1,er2:smallint;const n:ansistring);virtual;
44 procedure evalC(var x:complex);override;
45 function Code:Ansistring;override;
46 destructor destroy;override;
47 function QueryInteger:TSubstanceList;override;
48 function QueryDouble:TSubstanceList;override; // double������������������������������nil���������double���������
49 end;
50
51 TBinaryOpOrdinal=class(TNExpression)
52 exp1,exp2:TPrincipal;
53 opC:ComplexFunction2;
54 name:ansistring;
55 constructor create(e1,e2:TPrincipal;op1:FloatFunction2;
56 op2:extendedfunction2; op3:ComplexFunction2;
57 er1,er2:smallint;const n:ansistring);virtual;
58 procedure evalC(var x:complex);override;
59 function Code:Ansistring;override;
60 destructor destroy;override;
61 function QueryInteger:TSubstanceList;override;
62 function QueryDouble:TSubstanceList;override; // double������������������������������nil���������double���������
63 end;
64
65
66 type
67 TUnaryOp=class(TUnaryOpOrdinal)
68 opF:FloatFunction1;
69 opX:ExtendedFunction1;
70 overflowcode:smallint;
71 invalidcode:smallint;
72 constructor create(e:TPrincipal; op1:FloatFunction1;
73 op2:extendedfunction1;op3:ComplexFunction1;
74 er1,er2:smallint;const n:ansistring);override;
75 procedure evalC(var x:complex);override;
76 function OverflowErCode:integer;override;
77 function InvalidErCode:integer;override;
78 function OpName:string;override;
79 function QueryDouble:TSubstanceList;override; // double������������������������������nil���������double���������
80 end;
81
82 TBinaryOp=class(TBinaryOpOrdinal)
83 opF:FloatFunction2;
84 opX:ExtendedFunction2;
85 overflowcode:smallint;
86 invalidcode:smallint;
87 constructor create(e1,e2:TPrincipal;op1:FloatFunction2;
88 op2:extendedfunction2; op3:ComplexFunction2;
89 er1,er2:smallint;const n:ansistring);override;
90 procedure evalC(var x:complex);override;
91 function OverflowErCode:integer;override;
92 function InvalidErCode:integer;override;
93 function OpName:string;override;
94 function QueryDouble:TSubstanceList;override; // double������������������������������nil���������double���������
95 end;
96
97
98 function UnaryCOrdinal(op2:complexfunction1;er2:smallint;const name:ansistring):TPrincipal;
99 function BinaryCOrdinal(op2:complexfunction2; er2:smallint;const name:ansistring):TPrincipal;
100 function UnaryC(op2:complexfunction1;er2:smallint;const name:ansistring):TPrincipal;
101 function BinaryC(op2:complexfunction2; er2:smallint;const name:ansistring):TPrincipal;
102
103 function ComplexExp(const c:complex):complex;
104
105 implementation
106
107 uses SysUtils,
108 math,base,base0,objlist,texthand,helpctex,moddlg,optina,sconsts,suppliedc;
109
110
111 procedure CInit(var x:complex; a,b:double);
112 begin
113 x.x:=a; x.y:=b
114 end;
115
116 procedure CAdd(var x,y:complex);
117 begin
118 x.x:=x.x+y.x;
119 x.y:=x.y+y.y;
120 end;
121
122 procedure CSub(var x,y:complex);
123 begin
124 x.x:=x.x-y.x;
125 x.y:=x.y-y.y;
126 end;
127
128 procedure CMultiply(var x,y:complex);assembler;
129 asm
130 fld qword ptr [eax] //x.x
131 fld qword ptr [eax+$08] //x.y
132 fld qword ptr [edx] //y.x
133 fld qword ptr [edx+$08] //y.y
134 fld st(3) // x.x
135 fmul st,st(1) // x.x*y.y
136 fld st(3) // x.y
137 fmul st,st(3) // x.y*y.x
138 fadd // x.x*y.y+x.y*y.x
139 fstp qword ptr [eax+$08]
140 fmulp st(2),st // x.y*y.y
141 fmulp st(2),st // x.x*y.x
142 fsub // x.x*y.x-x.y*y.y
143 fstp qword ptr [eax]
144 wait
145 end;
146
147
148 (*
149 procedure CMultiply(var x,y:complex);
150 var
151 z:complex;
152 begin
153 z.x:=x.x * y.x - x.y * y.y;
154 z.y:=x.x * y.y + x.y * y.x;
155 x:=z;
156 end;
157 *)
158
159 (*
160 procedure CDiv (var x,y:complex);assembler;
161 asm
162 fld qword ptr [eax] //x.x
163 fld qword ptr [eax+$08] //x.y
164 fld qword ptr [edx] //y.x
165 fld qword ptr [edx+$08] //y.y
166 fld st(1) //y.x
167 fmul st,st(0) //y.x^2
168 fld st(1) //y.y
169 fmul st,st(0) //y.y^2
170 fadd //y.x^2+y.y^2
171 fdiv st(2),st // y.x���y.x/(y.x^2+y.y^2)
172 fdivp st(1),st // y.y���y.y/(y.x^2+y.y^2)
173 fld st(2) // x.y
174 fmul st,st(2) // x.y*y.x
175 fld st(4) // x.x
176 fmul st,st(2) // x.x*y.y
177 fsub // x.y*y.x-x.x*y.y
178 fstp qword ptr [eax+$08]
179 fmulp st(2),st // x.y*y.y
180 fmulp st(2),st // x.x*y.x
181 fadd // x.x*y.x+x.y*y.y
182 fstp qword ptr [eax]
183 wait
184 end;
185 *)
186
187
188 procedure CDiv (var x,y:complex);
189 {$MAXFPUREGISTERS 0}
190 var
191 z:complex;
192 n:extended;
193 begin
194 n:= sqr(y.x) + sqr(y.y);
195 if n=0 then begin setexception(3001); exit end;
196 z.x:=(x.x * y.x + x.y * y.y)/n;
197 z.y:=(x.y * y.x - x.x * y.y)/n;
198 x:=z;
199 end;
200
201
202
203
204 {**********}
205 {TNConstant}
206 {**********}
207
208
209 type
210 TNConstant=class(TNExpression)
211 valueC:complex;
212 constructor create(var n:number);
213 constructor create2(x:complex);
214 procedure evalC(var x:complex);override;
215 destructor destroy;override;
216 function isConstant:boolean;override;
217 function Code:AnsiString;override;
218 function QueryInteger:TSubstanceList;override;
219 function QueryDouble:TSubstanceList;override;
220 end;
221
222 type
223 TNFunction=class(TNExpression)
224 exe :TCALL;
225 constructor create(idr:TIdrec);
226 //procedure evalC(var x:complex);override;
227 function Code:Ansistring;override;
228 destructor destroy;override;
229 end;
230
231 type
232 TUnaryOpClass = class of TUnaryOpOrdinal;
233 TBinaryOpClass = class of TBinaryOpOrdinal;
234 {******************}
235 {numeric expresion}
236 {*****************}
237
238 constructor TNExpression.create;
239 begin
240 inherited create;
241 end;
242
243 function TNexpression.kind:char;
244 begin
245 kind:='n'
246 end;
247
248
249 constructor TNFunction.create(idr:TIdrec);
250 begin
251 inherited Create;
252 exe:=TCALL.createF(idr) ;
253 end;
254
255 destructor TNFunction.destroy;
256 begin
257 exe.free;
258 inherited destroy
259 end;
260 (*
261 procedure TNFunction.evalC(var x:complex);
262 begin
263 exe.evalC(x)
264 end;
265 *)
266
267 {*********}
268 {TNConstant}
269 {*********}
270
271
272 constructor TNConstant.create(var n:number);
273 begin
274 inherited create;
275 try
276 CInit(valueC,extendedval(N),0);
277 except
278 seterr(s_TooLargeConstant,IDH_JIS_5);
279 end;
280 end;
281
282 constructor TNConstant.create2(x:complex);
283 begin
284 inherited create;
285 valueC:=x;
286 end;
287
288 destructor TNConstant.destroy;
289 begin
290 inherited destroy;
291 end;
292
293 function TNConstant.isConstant:boolean;
294 begin
295 isConstant:=true
296 end;
297
298
299
300
301 {*****************}
302 {numeric operation}
303 {*****************}
304
305
306 constructor TunaryOpOrdinal.create(e:TPrincipal;op1:FloatFunction1;
307 op2:extendedfunction1;op3:ComplexFunction1;
308 er1,er2:smallint;const n:ansistring);
309 begin
310 inherited create;
311 exp:=e;
312 opC:=op3;
313 name:=n;
314 end;
315
316 constructor TunaryOp.create(e:TPrincipal;op1:FloatFunction1;
317 op2:extendedfunction1;op3:ComplexFunction1;
318 er1,er2:smallint;const n:ansistring);
319 begin
320 inherited create(e,op1,op2,op3,er1,er2,n);
321 opF:=op1;
322 opX:=op2;
323 overflowcode:=er1;
324 invalidcode:=er2;
325 //name:=n;
326 end;
327
328 destructor TunaryOpOrdinal.destroy;
329 begin
330 exp.free;
331 inherited destroy;
332 end;
333
334 constructor TBinaryOpOrdinal.create(e1,e2:TPrincipal; op1:FloatFunction2;
335 op2:extendedfunction2; op3:ComplexFunction2;
336 er1,er2:smallint;const n:ansistring );
337 begin
338 inherited create;
339 exp1:=e1;
340 exp2:=e2;
341 opC:=op3;
342 name:=n;
343 end;
344
345 constructor TBinaryOp.create(e1,e2:TPrincipal; op1:FloatFunction2;
346 op2:extendedfunction2; op3:ComplexFunction2;
347 er1,er2:smallint;const n:ansistring );
348 begin
349 inherited create(e1,e2,op1,op2,op3,er1,er2,n);
350 opF:=op1;
351 opX:=op2;
352 overflowcode:=er1;
353 invalidcode:=er2;
354 //name:=n;
355 end;
356
357 destructor TBinaryOpOrdinal.destroy;
358 begin
359 exp1.free;
360 exp2.free;
361 inherited destroy;
362 end;
363
364
365
366 function UnaryOp( e:TPrincipal;op1:FloatFunction1;op2:extendedfunction1;
367 op3:ComplexFunction1;er1,er2:smallint;
368 opclass:TUnaryOpClass;const name:ansistring):TPrincipal;
369 var
370 p:TPrincipal;
371 n:number;
372 x:complex;
373 flag:boolean;
374 begin
375 p:=opClass.create(e,op1,op2,op3,er1,er2,name);
376 if e.isConstant then
377 begin
378 flag:=true;
379 set8087cw($1372);
380 try
381 p.evalC(x);
382 except
383 {$IFNDEF Windows}
384 asm finit end;
385 {$ENDIF}
386 extype:=0;
387 flag:=false;
388 end;
389 set8087cw(OriginalCW);
390 if flag then
391 begin
392 p.free;
393 p:=TNConstant.create2(x);
394 end;
395 end;
396 UnaryOp:=p
397 end;
398
399
400 function BinaryOp( e1,e2:TPrincipal;
401 op1:FloatFunction2;op2:extendedfunction2; op3:ComplexFunction2;
402 er1,er2:smallint; opclass:TBinaryOpClass;const name:ansistring):TPrincipal;
403 var
404 p:TPrincipal;
405 n:number;
406 x:complex;
407 flag:boolean;
408 begin
409 p:=opClass.create(e1,e2,op1,op2,op3,er1,er2,name);
410 if e1.isConstant and e2.isConstant then
411 begin
412 flag:=true;
413 set8087cw($1372);
414 try
415 p.evalC(x)
416 except
417 {$IFNDEF Windows}
418 asm finit end;
419 {$ENDIF}
420 flag:=false;
421 extype:=0;
422 end;
423 set8087cw(OriginalCW);
424 if flag then
425 begin
426 p.free;
427 p:=TNConstant.create2(x);
428 end;
429 end;
430 BinaryOp:=p
431 end;
432
433
434 {************}
435 {Unary Binary}
436 {************}
437
438 type
439 TUnaryF=class(TUnaryOP)
440 procedure evalC(var c:complex);override;
441 end;
442
443 TBinaryF=class(TBinaryOP)
444 procedure evalC(var c:complex);override;
445 end;
446
447 type
448 TUnaryX=class(TUnaryOp)
449 procedure evalC(var x:complex); override;
450 end;
451
452 TBinaryX=class(TBinaryOp)
453 procedure evalC(var x:complex);override;
454 end;
455
456
457
458
459
460 function Unary({op1:unaryoperation;} op2:floatfunction1;er2:smallint;const name:ansistring):TPrincipal;
461 begin
462 Unary:=UnaryOp(argumentN1,op2,nil,nil,1003,er2,TUnaryF,name)
463 end;
464
465 function Binary({op1:binaryoperation;} op2:floatfunction2; er2:smallint;const name:ansistring):TPrincipal;
466 var
467 a1:TPrincipal;
468 begin
469 a1:=argumentN2a;
470 Binary:=BinaryOp(a1,ArgumentN2b,op2,nil,nil,1003,er2,TBinaryF,name)
471 end;
472
473 function UnaryX(op2:extendedfunction1;er2:smallint;const name:ansistring):TPrincipal;
474 begin
475 UnaryX:=UnaryOp(argumentN1,nil,op2,nil,1003,er2,TUnaryX,name)
476 end;
477
478 function BinaryX(op2:extendedfunction2; er2:smallint;const name:ansistring):TPrincipal;
479 var
480 a1:TPrincipal;
481 begin
482 a1:=argumentN2a;
483 BinaryX:=BinaryOp(a1,ArgumentN2b,nil,op2,nil,1003,er2,TBinaryX,name)
484 end;
485
486 function UnaryCOrdinal(op2:complexfunction1;er2:smallint;const name:ansistring):TPrincipal;
487 begin
488 UnaryCOrdinal:=
489 ExpressC.UnaryOp(argumentN1,nil,nil,op2,1003,er2,ExpressC.TUnaryOpOrdinal,name)
490 end;
491
492 function BinaryCOrdinal(op2:complexfunction2; er2:smallint;const name:ansistring):TPrincipal;
493 var
494 a1:TPrincipal;
495 begin
496 a1:=argumentN2a;
497 BinaryCOrdinal:=
498 ExpressC.BinaryOp(a1,ArgumentN2b,nil,nil,op2,1003,er2,ExpressC.TBinaryOpOrdinal,name)
499
500 end;
501
502 function UnaryC(op2:complexfunction1;er2:smallint;const name:ansistring):TPrincipal;
503 begin
504 UnaryC:=ExpressC.UnaryOp(argumentN1,nil,nil,op2,1003,er2,ExpressC.TUnaryOp,name)
505 end;
506
507 function BinaryC(op2:complexfunction2; er2:smallint;const name:ansistring):TPrincipal;
508 var
509 a1:TPrincipal;
510 begin
511 a1:=argumentN2a;
512 BinaryC:=ExpressC.BinaryOp(a1,ArgumentN2b,nil,nil,op2,1003,er2,ExpressC.TBinaryOp,name)
513
514 end;
515
516 {**********}
517 {NOperation}
518 {**********}
519 type
520 TNOperation=class(TNExpression)
521 Op:TPrincipal;
522 constructor Create(e1:TPrincipal);
523 procedure evalC(var x:complex); override;
524 function code:AnsiString;override;
525 function QueryInteger:TSubstanceList;override; // Integer������������������������������nil������������������
526 function QueryDouble:TSubstanceList;override; // double���������������������������������������������������
527 destructor destroy;override;
528 end;
529
530 constructor TNOperation.Create(e1:TPrincipal);
531 begin
532 inherited create;
533 op:=e1;
534 end;
535
536 destructor TNOperation.destroy;
537 begin
538 op.free;
539 inherited destroy;
540 end;
541
542 function NOperation(op:TPrincipal):TPrincipal ;
543 begin
544 result:=TNOperation.create(op);
545 end;
546
547 {****************}
548 {Execute Routines}
549 {****************}
550 function TNExpression.evalX:extended;
551 var
552 c:complex;
553 begin
554 evalC(c) ;
555 if c.y<>0 then setExceptionNonReal;
556 result:=c.x
557 end;
558
559 function TNExpression.evalLongint:longint;
560 begin
561 result:={$IFDEF ver100}system.round{$ELSE}LongIntRound{$ENDIF}(evalX);
562 end;
563
564 procedure TNConstant.evalC(var x:complex);
565 begin
566 x:=valueC;
567 end;
568
569
570 procedure TUnaryOpOrdinal.evalC(var x:complex);
571 begin
572 exp.evalC(x);
573 opC(x);
574 end;
575
576 procedure TUnaryOp.evalC(var x:complex);
577 begin
578 exp.evalC(x);
579 CurrentOperation:=self;
580 opC(x);
581 CurrentOperation:=nil;
582 end;
583
584 function TUnaryOp.OverflowErCode:integer;
585 begin
586 result:=OverFlowCode
587 end;
588
589 function TUnaryOp.InvalidErCode:integer;
590 begin
591 result:=InvalidCode;
592 end;
593
594 function TUnaryOp.OpName:string;
595 begin
596 result:=name;
597 end;
598
599 procedure TBinaryOpOrdinal.evalC(var x:complex);
600 var
601 m:complex;
602 begin
603 exp1.evalC(x);
604 exp2.evalC(m);
605 opC(x,m);
606 end;
607
608 procedure TBinaryOp.evalC(var x:complex);
609 var
610 m:complex;
611 begin
612 exp1.evalC(x);
613 exp2.evalC(m);
614 CurrentOperation:=self;
615 opC(x,m);
616 CurrentOperation:=nil;
617 end;
618
619 function TBinaryOp.OverflowErCode:integer;
620 begin
621 result:=OverFlowCode
622 end;
623
624 function TBinaryOp.InvalidErCode:integer;
625 begin
626 result:=InvalidCode;
627 end;
628
629 function TBinaryOp.OpName:string;
630 begin
631 result:=name;
632 end;
633
634
635 function IntPower(const c:complex; i: longint): complex;
636 var
637 x,t:ExtComplex;
638 begin
639 x.initC(c);
640 if i<0 then
641 begin
642 i:=-i;
643 x.inverse;
644 end;
645 t.init(1,0); //Result := 1.0;
646 while i > 0 do
647 begin
648 while not Odd(i) do
649 begin
650 i := i shr 1;
651 x.square; // X := X * X
652 end;
653 Dec(i);
654 t.multiply(@x); //Result := Result * X
655 end;
656 result.x:=t.x; result.y:=t.y
657 end;
658
659
660
661 function PowerSub(Base,Exponent:extended):extended;
662 begin
663 if ABS(BASE-1)>0.125 then
664 Result :=NPXPower(Base,Exponent) {Exp(Exponent * Ln(Base)) }
665 else
666 Result:=NPXPower1Plus(Base-1,Exponent);
667 end;
668
669 function ComplexExp(const c:complex):complex;
670 var
671 e:extended;
672 begin
673 e:=system.exp(c.x);
674 result.x:=e*cos(c.y);
675 result.y:=e*sin(c.y);
676 end;
677
678 function ComplexPower(Base:extended; Exponent: complex): complex;
679 var
680 t:extended;
681 y:Complex;
682 begin
683 if Exponent.y=0.0 then
684 begin
685 result.x:=PowerSub(base,Exponent.x);
686 result.y:=0;
687 end
688 else
689 begin
690 t:=ln(Base);
691 y.x:=t*Exponent.x;
692 y.y:=t*Exponent.y;
693 result:=ComplexExp(y)
694 end;
695 end;
696
697 function Power(const Base, Exponent: complex): complex;
698 begin
699 if (Exponent.x=0) and (exponent.y=0) then
700 CInit(result,1.0,0) //Result := 1.0
701 else if (Base.x=0)and (Base.y=0) and ((Exponent.y<>0) or (exponent.x<0)) then
702 setexception(3003)
703 else if (Exponent.y=0) and (frac(exponent.x)=0.0) and
704 (Exponent.x > -Maxint) and (Exponent.x < MaxInt) then
705 Result := IntPower(Base, Trunc(Exponent.x))
706 else if (Base.y=0.0) and (Base.x>0.0) then
707 result:=ComplexPower(base.x, Exponent)
708 else if (Base.x=0)and (Base.y=0) and (Exponent.y=0.0) and (Exponent.x>0) then
709 CInit(result,0,0)
710 else
711 begin
712 CInit(result,0,0);
713 if (Base.x=0)and (Base.y=0) then
714 setexception(3003)
715 else
716 setexception(3002) ;
717 end;
718 end;
719
720 procedure CPower( var x,y:complex);
721 begin
722 x:=Power(x,y)
723 end;
724
725 procedure CSquare(var x:complex);assembler;
726 asm
727 fld qword ptr [eax] //x.x
728 fld qword ptr [eax+$08] //x.y
729 fld st(1) // x.x
730 fmul st,st(0) // x.x^2
731 fld st(1) // x.y
732 fmul st,st(0) // x.y^2
733 fsub // x.x^2-x.y^2
734 fstp qword ptr [eax]
735 fmulp st(1),st // x.x*x.y
736 fadd st,st(0) // 2*x.x*x.y
737 fstp qword ptr [eax+$08]
738 wait
739 end;
740
741 (*
742 procedure CSquare(var x:complex);
743 var
744 z:complex;
745 begin
746 z.x:= sqr(x.x)-sqr(x.y);
747 z.y:=2*x.x * x.y;
748 x:=z;
749 end;
750 *)
751
752 procedure COppose(var x:complex);
753 begin
754 x.x:=-x.x; x.y:=-x.y
755 end;
756
757
758 function OpPower(e1,e2:TPrincipal):TPrincipal;
759 begin
760 result:=BinaryOp(e1,e2,nil,nil,CPower,1002,3002,TBinaryOpOrdinal,'power')
761 end;
762
763 function OpSquare(e1:TPrincipal):TPrincipal;
764 begin
765 result:=UnaryOp(e1,nil,nil,CSquare,1002,1002,TUnaryOpOrdinal,'CSqr')
766 end;
767
768 function OpUnaryMinus(e1:TPrincipal):TPrincipal;
769 begin
770 result:=UnaryOp(e1,nil,nil, COppose,1002,1002,TUnaryOpOrdinal,'COpo');
771 end;
772
773 function OpTimes(e1,e2:TPrincipal):TPrincipal;
774 begin
775 result:=BinaryOp(e1,e2,nil,nil,CMultiply, 1002,1002,TBinaryOpOrdinal,'CMul');
776 end;
777
778 function OpDivide(e1,e2:TPrincipal):TPrincipal;
779 begin
780 result:=BinaryOp(e1,e2,nil,nil,CDiv , 1002,3001,TBinaryOpOrdinal,'CDiv');
781 end;
782
783 function OpPlus(e1,e2:TPrincipal):TPrincipal;
784 begin
785 result:=BinaryOp(e1,e2, nil,nil,CAdd, 1002,1002,TBinaryOpOrdinal,'CAdd');
786 end;
787
788 function OpMinus(e1,e2:TPrincipal):TPrincipal;
789 begin
790 result:=BinaryOp(e1,e2, nil,nil,CSub, 1002,1002,TBinaryOpOrdinal,'CSub');
791 end;
792
793 function OpMSYen(e1,e2:TPrincipal):TPrincipal;
794 begin
795 setErr('',COMPILE_OPTION_SYNTAX);
796 end;
797
798 function OpMSMod(e1,e2:TPrincipal):TPrincipal;
799 begin
800 setErr('',COMPILE_OPTION_SYNTAX);
801 end;
802
803
804 function NConst(var n:number):TPrincipal;
805 begin
806 NConst:=TNConstant.create(n)
807 end;
808
809
810 function NFunction(idr:TIdrec):TPrincipal;
811 begin
812 NFunction:=TNFunction.create(idr)
813 end;
814
815
816
817 procedure TUnaryF.evalC(var c:complex);
818 begin
819 exp.evalC(c);
820 if (c.y=0) then
821 try
822 opF(c.x);
823 except
824 on EOverflow do
825 setexceptionwith(name,overflowcode);
826 on EMathError do
827 setexceptionwith(name,invalidcode);
828 on EDivByZero do
829 setexceptionwith(name,invalidcode);
830 end
831 else
832 setexceptionwith(name + '('+CStr(c)+')',3000) ;
833 end;
834
835 procedure TBinaryF.evalC(var c:complex);
836 var
837 m:complex;
838 begin
839 exp1.evalC(c);
840 exp2.evalC(m);
841 if (c.y=0) and (m.y=0) then
842 try
843 opF(c.x,m.x);
844 except
845 on EOverflow do
846 setexceptionwith(name,overflowcode);
847 on EMathError do
848 setexceptionwith(name,invalidcode);
849 on EDivByZero do
850 setexceptionwith(name,invalidcode);
851 end
852 else
853 setexceptionwith(name + '('+CStr(c)+','+CStr(m)+')',3000) ;
854 end;
855
856 procedure TUnaryX.evalC(var x:complex);
857 var
858 y:complex;
859 b:bytebool;
860 begin
861 exp.evalC(y);
862 if y.y=0.0 then
863 begin
864 x.y:=0.0;
865 try
866 x.x:=opX(y.x);
867 except
868 on EOverflow do
869 setexceptionwith(name+'('+CStr(y)+')',overflowcode);
870 on EMathError do
871 setexceptionwith(name+'('+CStr(y)+')',invalidcode);
872 on EDivByZero do
873 setexceptionwith(name+'('+CStr(y)+')',invalidcode);
874 end;
875 end
876 else
877 setexceptionwith(name+'('+CStr(y)+')',3000);
878 end;
879
880 procedure TBinaryX.evalC(var x:complex);
881 var
882 y,z:complex;
883 b:bytebool;
884 begin
885 exp1.evalC(y);
886 exp2.evalC(z);
887 if (y.y=0.0) and (z.y=0.0) then
888 begin
889 x.y:=0.0;
890 try
891 x.x:=opX(y.x,z.x);
892 except
893 on EOverflow do
894 setexceptionwith(name+'('+CStr(y)+','+CStr(z)+')',overflowcode);
895 on EMathError do
896 setexceptionwith(name+'('+CStr(y)+','+CStr(z)+')',invalidcode);
897 on EDivByZero do
898 setexceptionwith(name+'('+CStr(y)+','+CStr(z)+')',invalidcode);
899 end;
900 end
901 else
902 setexceptionwith(name+'('+CStr(y)+','+CStr(z)+')',3000);
903 end;
904
905 procedure TNOperation.evalC(var x:complex);
906 begin
907 op.EvalC(x)
908 end;
909
910
911 {************}
912 {NSubscripted}
913 {************}
914 type
915 TNSubscripted=class(TSubscripted)
916 end;
917
918 TNSubscripted1=class(TNSubscripted)
919 end;
920
921 TNSubscripted2=class(TNSubscripted)
922 end;
923
924 TNSubscripted3=class(TNSubscripted)
925 end;
926
927 TNSubscripted4=class(TNSubscripted)
928 end;
929
930
931 function NSubscripted1(idr:TIdrec; p:Subscriptarray):TVariable;
932 begin
933 result:=TNSubscripted1.create(idr,p);
934 end;
935
936 function NSubscripted2(idr:TIdrec; p:Subscriptarray):TVariable;
937 begin
938 result:=TNSubscripted2.create(idr,p);
939 end;
940
941 function NSubscripted3(idr:TIdrec; p:Subscriptarray):TVariable;
942 begin
943 result:=TNSubscripted3.create(idr,p);
944 end;
945
946 function NSubscripted4(idr:TIdrec; p:Subscriptarray):TVariable;
947 begin
948 result:=TNSubscripted4.create(idr,p);
949 end;
950
951 {***********}
952 {NComparison}
953 {***********}
954
955 type
956 TEqual=class(TLogicalBiOp)
957 function Code:Ansistring;override;
958 end;
959
960 TNotEqual=class(TLogicalBiOp)
961 function Code:Ansistring;override;
962 end;
963
964 TGreater=class(TLogicalBiOp)
965 function Code:Ansistring;override;
966 end;
967
968 TGreaterOrEq=class(TLogicalBiOp)
969 function Code:Ansistring;override;
970 end;
971
972 TSmaller=class(TLogicalBiOp)
973 function Code:Ansistring;override;
974 end;
975
976 TSmallerOrEq=class(TLogicalBiOp)
977 function Code:Ansistring;override;
978 end;
979
980
981
982
983
984 function NComparison(f:comparefunction; e1,e2:TPrincipal):TLogical;
985 begin
986 if (@f=@Equals) then
987 NComparison:=TEqual.create(e1,e2)
988 else if (@f=@NotEquals) then
989 NComparison:=TNotEqual.create(e1,e2)
990 else if (@f=@Greater) then
991 NComparison:=TGreater.create(e1,e2)
992 else if (@f=@NotLess) then
993 NComparison:=TGreaterOrEq.create(e1,e2)
994 else if (@f=@Less) then
995 NComparison:=TSmaller.create(e1,e2)
996 else if (@f=@NotGreater) then
997 Ncomparison:=TSmallerOrEq.create(e1,e2);
998 end;
999
1000 {***********}
1001 {Code Gen. }
1002 {***********}
1003
1004 function TNOperation.code:AnsiString;
1005 begin
1006 result:=Op.Code
1007 end;
1008
1009 function TNOperation.QueryInteger:TSubstanceList; // integer������������������������������nil������������������
1010 begin
1011 result:=Op.QueryInteger
1012 end;
1013
1014 function TNOperation.QueryDouble:TSubstanceList; // double���������������������������������������������������
1015 begin
1016 result:=TSubstanceList.create
1017 end;
1018
1019 function TNConstant.Code:AnsiString;
1020 begin
1021 if valueC.y=0 then
1022 result:=Format17(valueC.x)
1023 else
1024 result:='CMPLX(' + Format17(valueC.x) + ',' + Format17(valueC.y) +')' ;
1025 end;
1026
1027 function TNConstant.QueryInteger:TSubstanceList;
1028 begin
1029 with ValueC do
1030 if (y=0) and (Abs(x)<=maxint div 16) and (System.Frac(x)=0) then
1031 result:=TSubstanceList.create
1032 else
1033 result:=nil
1034 end;
1035
1036 function TNConstant.QueryDouble:TSubstanceList;
1037 begin
1038 if ValueC.y=0 then
1039 result:=TSubstanceList.create
1040 else
1041 result:=nil
1042 end;
1043
1044 function TUnaryOpOrdinal.Code:Ansistring;
1045 begin
1046 if @opC=@COppose then
1047 result := ' - (' + exp.code + ')'
1048 else
1049 result:= name + '('+ exp.code + ')'
1050 end;
1051
1052 function TBinaryOpOrdinal.Code:Ansistring;
1053 begin
1054 if @opC=@CAdd then
1055 result:= exp1.code + '+' + exp2.code
1056 else if @opC=@Csub then
1057 result:= exp1.code + '-' + exp2.code
1058 else if @opC=@Cmultiply then
1059 result:= '(' + exp1.code + ')*(' + exp2.code +')'
1060 else if @opC=@Cdiv then
1061 result:= '(' + exp1.code + ')/(' + exp2.code +')'
1062 else
1063 result:= name + '('+ exp1.code + ' , ' + exp2.code + ')'
1064 end;
1065
1066 function TUnaryOpOrdinal.QueryDouble:TSubstanceList; // double������������������������������nil���������double���������
1067 begin
1068 if (@opC=@CSQRT) or (@opC=@CSquare) or (@opC=@CConj) then
1069 result:=nil
1070 else
1071 result:=TSubstanceList.create;
1072 end;
1073
1074 function TUnaryOp.QueryDouble:TSubstanceList; // double������������������������������nil���������double���������
1075 begin
1076 if @opC=@CLOG then result:=nil
1077 else if @opC=@CEXP then
1078 result:=exp.QueryDouble
1079 else
1080 result:=TSubstanceList.create;
1081 end;
1082
1083 function TBinaryOpOrdinal.QueryDouble:TSubstanceList; // double������������������������������nil���������double���������
1084 begin
1085 if (@opC=@CCOMPLEX) or (@opC=@opPower) then
1086 result:=nil
1087 else
1088 result:=mergedList(exp1.QueryDouble, exp2.QueryDouble);
1089 end;
1090
1091
1092 function TBinaryOp.QueryDouble:TSubstanceList; // double������������������������������nil���������double���������
1093 begin
1094 result:=TSubstanceList.create;
1095 end;
1096
1097 function TUnaryOpOrdinal.QueryInteger:TSubstanceList; // Integer������������������������������nil������������������
1098 begin
1099 if (@opC=@COppose) then
1100 result:=exp.QueryInteger
1101 else
1102 result:=nil
1103 end;
1104
1105 function TBinaryOpOrdinal.QueryInteger:TSubstanceList; // Integer������������������������������nil������������������
1106 begin
1107 if (@opC=@CAdd) or (@opC=@CSub) then
1108 result:=mergedList(exp1.QueryInteger, exp2.QueryInteger)
1109 else
1110 result:=nil
1111 end;
1112
1113
1114
1115 function TNFunction.Code:AnsiString;
1116 begin
1117 result:= exe.Code;
1118 end;
1119
1120 function TEqual.Code:Ansistring;
1121 begin
1122 result:= exp1.code + '=' + exp2.code
1123 end;
1124
1125 function TNotEqual.Code:Ansistring;
1126 begin
1127 result:=exp1.code + '<>' + exp2.code
1128 end;
1129
1130 function TGreater.Code:Ansistring;
1131 begin
1132 result:= exp1.code + '>' + exp2.code
1133 end;
1134
1135 function TGreaterOrEq.Code:Ansistring;
1136 begin
1137 result:= exp1.code + '>=' + exp2.code
1138 end;
1139
1140 function TSmaller.Code:Ansistring;
1141 begin
1142 result:= exp1.code + '<' + exp2.code
1143 end;
1144
1145 function TSmallerOrEq.Code:Ansistring;
1146 begin
1147 result:= exp1.code + '<=' + exp2.code
1148 end;
1149
1150
1151
1152 {***********}
1153 {Mode Switch}
1154 {***********}
1155 procedure SwitchToComplexMode;
1156 begin
1157 Express.NConst:=NConst;
1158 EXpress.OpPower:=OpPower;
1159 EXpress.OpUnaryMinus:=OpUNaryMinus;
1160 EXpress.OpSquare:=OpSquare;
1161 Express.OpTimes:=OpTimes;
1162 Express.OpDivide:=OpDivide;
1163 Express.OpPlus:=OpPlus;
1164 Express.OpMinus:=OpMinus;
1165 Express.OpMSYen:=OpMsYen;
1166 Express.OpMsMod:=OpMsMod;
1167 Express.NFunction:=NFunction;
1168 Express.Unary:=Unary;
1169 Express.Binary:=Binary;
1170 Express.UnaryX:=UnaryX;
1171 Express.BinaryX:=BinaryX;
1172 Express.NOperation:=NOperation;
1173
1174 Express.NSubscripted1:=Nsubscripted1;
1175 Express.NSubscripted2:=Nsubscripted2;
1176 Express.NSubscripted3:=Nsubscripted3;
1177 Express.NSubscripted4:=Nsubscripted4;
1178
1179 EXpress.NComparison:=NComparison;
1180 end;
1181
1182 {******************}
1183 {supplied functions}
1184 {******************}
1185
1186 {**************}
1187 {reserved words}
1188 {**************}
1189
1190 function MAXNUMfnc:TPrincipal;far;
1191 var
1192 c:complex;
1193 begin
1194 c.x:=maxnumberDouble; c.y:=0;
1195 MAXNUMfnc:=expressC.TNConstant.create2(c)
1196 end;
1197
1198 function PIfnc:TPrincipal;far;
1199 var
1200 c:complex;
1201 begin
1202 c.x:=pi; c.y:=0;
1203 PIfnc:=TNConstant.create2(c) ;
1204 end;
1205
1206 {**********}
1207 {initialize}
1208 {**********}
1209
1210 procedure FunctionTableInit;far;
1211 begin
1212 if precisionMode=PrecisionComplex then
1213 begin
1214 ReservedWordTableInit('MAXNUM' , MAXNUMfnc );
1215 ReservedWordTableInit( 'PI' , PIfnc);
1216 end;
1217 end;
1218
1219 begin
1220 tableInitProcs.accept(FunctionTableInit);
1221 end.
1222

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26