Develop and Download Open Source Software

Browse Subversion Repository

Contents of /express.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: 56890 byte(s)


1 unit express;
2 {$IFDEF FPC}
3 {$MODE DELPHI}{$H+}
4 {$ENDIF}
5 (***************************************)
6 (* Copyright (C) 2009, SHIRAISHI Kazuo *)
7 (***************************************)
8
9
10
11 {********}
12 interface
13 {********}
14 uses Classes,
15 base,objlist,arithmet,float,texthand,variabl,struct;
16
17 type
18 extendedFunction1=function (x:extended):extended;
19 extendedFunction2=function (x,y:extended):extended;
20
21 {********}
22 {compiler}
23 {********}
24
25 {******}
26 {matrix}
27 {******}
28 type
29 TMatrix=class(TSubstance)
30 end;
31
32 {******************}
33 {logical expression}
34 {******************}
35 type
36 comparefunction=function(i:integer):boolean;
37
38 type
39 TLogical=class(TPrincipal)
40 end;
41
42 TLogicalBiOp=class(TLogical)
43 exp1,exp2:TPrincipal;
44 constructor create(e1,e2:TPrincipal);
45 destructor destroy;override;
46 end;
47
48 TDisjunction=class(TLogicalBiOp)
49 function Code:Ansistring;override;
50 end;
51
52 TConjunction=class(TLogicalBiOp)
53 function Code:Ansistring;override;
54 end;
55
56 TNegation=class(TLogical)
57 exp:TPrincipal;
58 constructor create(e:TPrincipal);
59 function Code:Ansistring;override;
60 destructor destroy;override;
61 end;
62
63 TComparison=class(TLogicalBiOp)
64 op:comparefunction;
65 constructor create(e1,e2:TPrincipal; f:comparefunction);
66 function Code:Ansistring;override;
67 end;
68
69 TComparisonN= class(TComparison)
70 end;
71
72 TComparisonS= class(TComparison)
73 end;
74
75
76
77 function Equals(i:integer):boolean;
78 function NotEquals(i:integer):boolean;
79 function Less(i:integer):boolean;
80 function Greater(i:integer):boolean;
81 function NotGreater(i:integer):boolean;
82 function NotLess(i:integer):boolean;
83
84 procedure findcomparefunction(const r:string; var f:comparefunction);
85
86 function primary:TPrincipal ;
87 function StringPrimary:TPrincipal ;
88 function NExpression:TPrincipal;
89 function NConstant:TPrincipal;
90 var NFunction:function(idr:TIdrec):TPrincipal;
91 function ChExpression:TPrincipal;
92 function ChannelExpression:TPrincipal;
93 function SExpression:TPrincipal;
94 function NSExpression:TPrincipal;
95 function SConstant:TPrincipal;
96 function matrix:TMatrix;
97 function Nmatrix:TMatrix;
98 function Smatrix:TMatrix;
99 function SMatrixDim(n:shortint):TMatrix;
100 function NMatrixDim(n:shortint):TMatrix;
101 function article:TPrincipal;
102 function principal(idrec:TIdRec):TPrincipal;
103 function simpleVariable:TSubstance;
104 function variable:TVariable;
105 function NVariable:TVariable;
106 function VariableOrFunctionRef:TPrincipal;
107 function relationalExpression:TLogical;
108 function IdRecord(CanInsert:boolean):TIdRec;
109
110 function reservedword(name:ShortString):boolean;
111
112
113 function tryLETst(prev,eld:TStatement):TStatement;far;
114
115
116 {**************}
117 {CALL statement}
118 {**************}
119
120 type
121 TCALL=class(TStatement)
122 params:TObjectList;
123 Routine:TRoutine;
124 constructor createF(idr:TIdrec); // for function,def
125 constructor Create(prev,eld:TStatement; kind:char); // for sub,picture
126 destructor destroy;override;
127 function Code:Ansistring;override;
128
129 private
130 procedure init(routine1:TRoutine);virtual;
131 procedure TestArithmetic;
132 end;
133
134
135 {*****************}
136 {string expression}
137 {*****************}
138
139 type
140 TStrExpression=class(TPrincipal)
141 function kind:char;override;
142 end;
143
144 type
145 TStrConstant=class(TStrExpression)
146 value:ansistring;
147 constructor create(const s:ansistring);
148 function evalS:ansistring;override;
149 function Code:AnsiString;override;
150 destructor destroy;override;
151 function isConstant:boolean;override;
152 end;
153
154
155 {**********}
156 {TInputVari}
157 {**********}
158
159 type
160 TInputVari=class
161 vari:TVariable;
162 constructor create(vari1:TVariable);
163 destructor destroy;override;
164 end;
165
166 TStrVari=class(TInputVari)
167 index1,index2:TPrincipal;
168 CharacterByte:boolean;
169 constructor create(vari1:TVariable);
170 destructor destroy;override;
171 function Code:ansistring;
172 end;
173 function InputVari(StrOnly:boolean):TInputVari;
174 function StrVari:TStrVari;
175
176 {*********}
177 {Arguments}
178 {*********}
179 function argumentN1:TPrincipal;
180 function argumentN2a:TPrincipal;
181 function argumentN2b:TPrincipal;
182
183 var Unary:function({op1:unaryoperation;} op2:floatfunction1;er2:smallint;const name:ansistring):TPrincipal;
184 var Binary:function({op1:binaryoperation;} op2:floatfunction2; er2:smallint;const name:ansistring):TPrincipal;
185 var UnaryX:function(op2:extendedfunction1;er2:smallint;const name:ansistring):TPrincipal;
186 var BinaryX:function(op2:extendedfunction2; er2:smallint;const name:ansistring):TPrincipal;
187 var NOperation:function(op:TPrincipal):TPrincipal;
188
189 var NConst:function(var n:number):TPrincipal;
190 var OpPower:function(e1,e2:TPrincipal):TPrincipal;
191 var OpUnaryMinus:function(e1:TPrincipal):TPrincipal;
192 var OpSquare:function(e1:TPrincipal):TPrincipal;
193 var OpTimes:function(e1,e2:TPrincipal):TPrincipal;
194 var OpDivide:function(e1,e2:TPrincipal):TPrincipal;
195 var OpPlus:function(e1,e2:TPrincipal):TPrincipal;
196 var OpMinus:function(e1,e2:TPrincipal):TPrincipal;
197 var OpMSYen:function(e1,e2:TPrincipal):TPrincipal;
198 var OpMSMod:function(e1,e2:TPrincipal):TPrincipal;
199
200 type
201 Subscriptarray=Array[1..4]of TPrincipal;
202
203 var NSubscripted1: function(idr:TIdrec; p:Subscriptarray):TVariable;
204 var NSubscripted2: function(idr:TIdrec; p:Subscriptarray):TVariable;
205 var NSubscripted3: function(idr:TIdrec; p:Subscriptarray):TVariable;
206 var NSubscripted4: function(idr:TIdrec; p:Subscriptarray):TVariable;
207
208 var NComparison: function(f:comparefunction; exp1,exp2:TPrincipal):TLogical;
209 type
210 TLogicalNumeric=Class(TLogical)
211 exp:TPrincipal;
212 constructor create;
213 destructor destroy;override;
214 end;
215 function JISNExpression:TPrincipal;
216
217 procedure SubstringQualifier(var exp1,exp2:tPrincipal);
218 function GetRoutine(idr:TIdrec; kind:char):TRoutine;
219
220 type
221 TSubscripted=class(TPointingVariable)
222 subs:TSubstance;
223 dim:integer;
224 subscript:Subscriptarray;
225 constructor create(idr:TIdrec; p:Subscriptarray); //2011.3.8������
226 destructor destroy;override; //2011.3.8
227 function kind:char;override;
228 function Code:AnsiString;override;
229 end;
230
231 TSubscripted1=class(TSubscripted)
232 end;
233 TSubscripted2=class(TSubscripted)
234 end;
235 TSubscripted3=class(TSubscripted)
236 end;
237 TSubscripted4=class(TSubscripted)
238 end;
239
240 //For Code Generate
241 function ArgNLiteral(i:integer):Ansistring;
242 function ArgSLiteral(i:integer):Ansistring;
243
244 implementation
245
246 uses SysUtils,Forms,
247 base0,myutils,helpctex,optina,moddlg ,expressf,sconsts ;
248
249 {************}
250 {TSubscripted}
251 {************}
252
253 constructor TSubscripted.create(idr:TIdRec; p:Subscriptarray);
254 var
255 i:integer;
256 begin
257 inherited create;
258 subs:=idr.subs;
259 dim:=idr.dim;
260 subscript:=p
261 end;
262
263 destructor TSubscripted.destroy;
264 var
265 i:integer;
266 begin
267 for i:=1 to dim do subscript[i].free;
268 inherited destroy;
269 end;
270
271 function TSubscripted.kind:char;
272 begin
273 kind:=subs.kind
274 end;
275
276
277
278
279 {**************************}
280 {function referece and CALL}
281 {**************************}
282
283 type
284 TConcat=class(TStrExpression)
285 exp1,exp2:TPrincipal;
286 constructor create(e1,e2:TPrincipal);
287 destructor destroy;override;
288 function Code:AnsiString;override;
289 end;
290
291 type
292 TConstVariable=class(TVariable)
293 vari:TVariable;
294 constructor create(exp:TVariable);
295 destructor destroy;override;
296 function Kind:char;override;
297 function Code:AnsiString;override;
298 end;
299
300
301 constructor TConstVariable.create(exp:TVariable);
302 begin
303 inherited create;
304 vari:=exp;
305
306 end;
307
308 destructor TConstVariable.destroy;
309 begin
310 vari.free;
311 inherited destroy;
312 end;
313
314
315 procedure TestSubscripted;forward;
316
317 procedure TCall.TestArithmetic;
318 begin
319 if (routine is TProgramUnit)
320 and (punit.arithmetic<>(routine as TProgramUnit).arithmetic) then
321 seterr(Format(s_IsNotAgreeArithmetic,[routine.name]),IDH_OPTION_ARITHMETIC)
322 end;
323
324 function GetRoutine(idr:TIdrec; kind:char):TRoutine;
325 var
326 routine:TRoutine;
327 nam:AnsiString;
328 begin
329 GetRoutine:=nil;
330 with idr do
331 if modulename<>'' then
332 nam:=modulename + '.' + name
333 else
334 nam:=name;
335 if CurrentProgram.inquire(nam,routine)
336 and ((routine.isfunction and (kind='F')) or(routine.kind=kind)) then
337 GetRoutine:=routine
338 else if pass=2 then
339 begin
340 statusmes.add(Format(s_BodyIsNotFound,[token]));
341 if (kind='F') and
342 (token<>'SHIFT') and (token<>'SCALE') and (token<>'ROTATE')
343 and (token<>'SHEAR') and (nexttoken='(') then
344 TestSubscripted
345 else
346 seterr('',IDH_FUNCTION);
347 end;
348 end;
349
350 function lastChar(const s:string):char;
351 begin
352 if s<>'' then
353 result:=s[length(s)]
354 else
355 result:=#0;
356 end;
357
358 procedure TCALL.init(routine1:TRoutine);
359 var
360 i:integer;
361 table:TIdTable;
362 exp:TPrincipal;
363 svtoken:string;
364 begin
365 case pass of
366 1:
367 begin
368 gettoken;
369 if token='(' then
370 begin
371 gettoken;
372 repeat
373 exp:=article;
374 exp.free;
375 until test(',')=false;
376 check(')',IDH_FUNCTION);
377 end;
378 end;
379 2: begin
380 routine:=routine1;
381 if routine<>nil then
382 begin
383 gettoken;
384 table:=routine.VarTable;
385 params:=TObjectList.create(table.count);
386 if routine.isfunction then
387 if lastChar(routine.name)<>'$' then
388 TestArithmetic;
389 i:=0;
390 with table do
391 while (i<count) and TIdRec(items[i]).prm do
392 begin
393 if i=0 then check('(',IDH_FUNCTION)
394 else check(',',IDH_FUNCTION);
395 svtoken:=token;
396 exp:=principal(TIdRec(items[i]));
397 if (TIdRec(items[i]).kindchar='n') then TestArithmetic;
398 if (not routine.isfunction) and (svtoken='(')
399 and (exp is TVariable) then
400 exp:=TConstVariable.create(TVariable(exp));
401 params.add(exp);
402 if (not routine.isfunction) and (exp is TFVari) then //������������
403 TFvari(exp).addQueryInteger(nil);
404 if (not routine.isfunction) and (exp is TCVari) then //������������
405 TCvari(exp).addQueryDouble(nil);
406 inc(i);
407 end;
408 if i>0 then check(')',IDH_FUNCTION);
409 end
410 end;
411 end;
412 end;
413
414 constructor TCall.createF(idr:TIdrec);
415 begin
416 inherited create(nil,nil);
417 init(GetRoutine(idr,'F'))
418 end;
419
420 constructor TCall.Create(prev,eld:TStatement; kind:char);
421 var
422 idr:TIdrec;
423 index:integer;
424 mnam,nam:ansistring;
425 begin
426 inherited create(prev,eld);
427 mnam:=Modifier(token);
428 nam:=Identifier(token);
429 if mnam<>'' then
430 begin
431 idr:=TIdrec.InitF(mnam,nam,extern);
432 try
433 init(GetRoutine(idr,kind));
434 finally
435 idr.free;
436 end;
437 end
438 else if ProgramUnit.ExternalSubTable.search(nam,index) then
439 begin
440 idr:=TIdrec(ProgramUnit.ExternalSubTable.items[index]);
441 init(GetRoutine(idr,kind))
442 end
443 else
444 begin
445 idr:=TIdrec.initF(mnam,token,intern);
446 try
447 init(GetRoutine(idr,kind));
448 finally
449 idr.free;
450 end;
451 end;
452 end;
453
454 destructor TCALL.destroy;
455 begin
456 params.free;
457 inherited destroy
458 end;
459
460
461 {*********************}
462 {Numerical Expressions}
463 {*********************}
464
465 function NConstant:TPrincipal;
466 var
467 n:number;
468 begin
469 numericconstant(n);
470 NConstant:=NConst(n)
471 end;
472
473 function primary:TPrincipal ;
474 var
475 x:number;
476 begin
477 if test('(') then
478 begin
479 primary:=NExpression;
480 checktoken(')',IDH_NUMBER);
481 end
482 else if tokenspec=Nrep then
483 begin
484 x:=tokenValue;
485 getToken;
486 primary:=NConst(x);
487 end
488 else if tokenspec=NIdf then
489 begin
490 result:=VariableOrFunctionRef;
491 if (result=nil) or (result.kind<>'n') then
492 seterr(token+s_CantBelongHere + EOL + s_ExpressionIncorrect,IDH_NUMBER);
493 end
494 else
495 seterr(s_ExpressionIncorrect +EOL + token + s_CantBelongHere , IDH_NUMBER) ;
496
497
498 end;
499
500 function Negation:TPrincipal;forward;
501
502 function factor:TPrincipal ;
503 var
504 exp:TPrincipal;
505 begin
506 exp:=primary;
507 while (Token='^') and (exp<>nil) do
508 begin
509 gettoken;
510 if token='-' then
511 exp:=OpPower(exp,negation)
512 else if token='2' then
513 begin
514 gettoken;
515 exp:=OpSquare(exp)
516 end
517 else
518 exp:=OpPower(exp,primary);
519 end;
520 factor:=exp;
521 end;
522
523 procedure insertParenthesis;
524 var
525 svcp:tokensave;
526 exp:TPrincipal;
527 begin
528 savetoken(svcp);
529 gettoken;
530 exp:=factor;
531 exp.free;
532 if NoContinuation and (AutoCorrect[ac_exp] or
533 confirmFrom(svcp,
534 extract(svcp)+s_CanBeParenthesized,IDH_MICROSOFT_OP)) then
535 begin
536 insertkeyword('(',svcp);
537 inserttext(')');
538 raise ERecompile.create('');
539 end
540 else
541 restoreToken(svcp);
542 end;
543
544 function Negation:TPrincipal;
545 begin
546 Negation:=nil;
547 if token='-' then
548 if permitMicrosoft then
549 begin
550 gettoken;
551 Negation:=OpUnaryMinus(factor);
552 end
553 else
554 begin
555 insertParenthesis;
556 Negation:=factor;
557 end
558 else
559 Negation:=factor;
560 end;
561
562
563 function term:TPrincipal;
564 var
565 exp:TPrincipal ;
566 op:char;
567 begin
568 exp:=factor;
569 while ((token='*') or (token='/')) and (exp<>nil) do
570 begin
571 op:=token[1];
572 gettoken;
573 case op of
574 '*': exp:=OpTimes(exp, negation);
575 '/': exp:=OpDivide(exp, negation);
576 end;
577 end;
578 term:=exp
579 end;
580
581 function YenTerm:TPrincipal;
582 var
583 svcp1,svcp2:tokensave;
584
585 exp,exp2:TPrincipal;
586 begin
587 savetoken(svcp1);
588 exp:=Term;
589 Result:=exp;
590
591 if permitMicrosoft then
592 while (token='\') do
593 begin
594 gettoken;
595 Result:=OpMSYen(result,Term);
596 end
597 else if (token='\') and NoContinuation then
598 case confirmMod of
599 0:begin
600 savetoken(svcp2);
601 gettoken;
602 exp2:=Term;
603 exp.free;
604 exp2.free;
605 inserttext('))');
606 replaceKeyword('/(',svcp2);
607 insertkeyword('INT(',svcp1);
608 raise ERecompile.create('');
609 end;
610 1:begin
611 savetoken(svcp2);
612 gettoken;
613 exp2:=Term;
614 exp.free;
615 exp2.free;
616 inserttext('))');
617 replaceKeyword('/(',svcp2);
618 insertkeyword('IP(',svcp1);
619 raise ERecompile.create('');
620 end;
621 2:begin
622 savetoken(svcp2);
623 gettoken;
624 exp2:=Term;
625 exp.free;
626 exp2.free;
627 inserttext('))');
628 replaceKeyword(')/ROUND(',svcp2);
629 insertkeyword('IP(ROUND(',svcp1);
630 raise ERecompile.create('');
631 end;
632 end
633 end;
634
635
636 function ModTerm:TPrincipal;
637 var
638 svcp1,svcp2:tokensave;
639
640 exp,exp2:TPrincipal;
641 begin
642 savetoken(svcp1);
643 exp:=YenTerm;
644 result:=exp;
645
646 if permitMicrosoft then
647 while (token='MOD') do
648 begin
649 gettoken;
650 Result:=OpMSMod(result,YenTerm);
651 end
652 else if (token='MOD') and NoContinuation then
653 case confirmMod of
654 0:begin
655 savetoken(svcp2);
656 gettoken;
657 exp2:=YenTerm;
658 exp.free;
659 exp2.free;
660 inserttext(')');
661 replaceKeyword(',',svcp2);
662 insertkeyword('MOD(',svcp1);
663 raise ERecompile.create('');
664 end;
665 1:begin
666 savetoken(svcp2);
667 gettoken;
668 exp2:=YenTerm;
669 exp.free;
670 exp2.free;
671 inserttext(')');
672 replaceKeyword(',',svcp2);
673 insertkeyword('REMAINDER(',svcp1);
674 raise ERecompile.create('');
675 end;
676 2:begin
677 savetoken(svcp2);
678 gettoken;
679 exp2:=YenTerm;
680 exp.free;
681 exp2.free;
682 inserttext('))');
683 replaceKeyword('),ROUND(',svcp2);
684 insertkeyword('REMAINDER(ROUND(',svcp1);
685 raise ERecompile.create('');
686 end;
687 end
688 else
689 ModTerm:=exp
690 end;
691
692 function JISNExpression:TPrincipal;
693 var
694 exp:TPrincipal;
695 op:char;
696 begin
697 if token='+' then
698 begin
699 gettoken;
700 exp:=ModTerm
701 end
702 else if token='-' then
703 begin
704 gettoken;
705 exp:=OpUnaryMinus(term);
706 end
707 else
708 exp:=ModTerm;
709
710 while ((token='+') or (token='-')) and (exp<>nil) do
711 begin
712 op:=token[1];
713 gettoken;
714 case op of
715 '+': exp:=OpPlus(exp,ModTerm);
716 '-': exp:=OpMinus(exp,ModTerm);
717 end;
718 end;
719
720 JISNExpression:=exp
721 end;
722
723 //function MicrosoftNExpression:TPrincipal;forward;
724
725 function NExpression:TPrincipal;
726 begin
727 if permitMicrosoft then
728 result:=MicrosoftNExpression
729 else
730 result:=JISNExpression
731 end;
732
733 {******************}
734 {string expression }
735 {******************}
736
737 type
738 TStrFunction=class(TStrExpression)
739 exe :TCALL;
740 constructor create(idr:TIdrec);
741 destructor destroy;override;
742 function Code:ansistring;override;
743 end;
744
745
746
747
748 {*****************}
749 {string expression}
750 {*****************}
751
752
753
754
755 function TStrExpression.kind:char;
756 begin
757 kind:='s'
758 end;
759
760
761 constructor TStrFunction.create(idr:TIdrec);
762 begin
763 inherited create;
764 exe:=TCALL.createF(idr) ;
765 end;
766
767 destructor TStrFunction.destroy;
768 begin
769 exe.free;
770 inherited destroy
771 end;
772
773 constructor TStrConstant.create(const s:ansistring);
774 begin
775 inherited create;
776 value:=s
777 end;
778
779 destructor TStrConstant.destroy;
780 begin
781 inherited destroy
782 end;
783
784 function TStrConstant.isConstant:boolean;
785 begin
786 isConstant:=true
787 end;
788
789
790 function TStrConstant.evalS:ansistring;
791 begin
792 result:=value;
793 end;
794
795
796 {******************}
797 {logical expression}
798 {******************}
799
800
801 constructor TLogicalBiOp.create(e1,e2:TPrincipal);
802 begin
803 inherited create;
804 exp1:=e1;
805 exp2:=e2;
806 end;
807
808
809 destructor TLogicalBiOp.destroy;
810 begin
811 exp1.free;
812 exp2.free;
813 inherited destroy
814 end;
815
816 {*****************}
817 {logical operation}
818 {*****************}
819
820
821 constructor TComparison.create(e1,e2:TPrincipal; f:comparefunction);
822 begin
823 inherited create(e1,e2);
824 op:=f
825 end;
826
827
828
829 {*****************}
830 {logical operation}
831 {*****************}
832
833 constructor TNegation.create(e:TPrincipal);
834 begin
835 inherited create;
836 exp:=e ;
837 end;
838
839 destructor TNegation.destroy;
840 begin
841 exp.free;
842 inherited destroy;
843 end;
844
845 {********}
846 {compiler}
847 {********}
848
849 function subscript(idr:TIdRec):Subscriptarray; //2011.3.8������
850 var
851 i:integer;
852 exp:TPrincipal;
853 d:integer;
854 begin
855 for i:=1 to 4 do result[i]:=nil;
856 check('(',IDH_ARRAY);
857 with idr do
858 if tag=undeterm then
859 begin
860 d:=0;
861 repeat
862 inc(d);
863 result[d]:=NExpression;
864 until (d=4) or (test(',')=false) ;
865 check(')',IDH_ARRAY);
866 tag:=intern;
867 setdim1(d);
868 end
869 else
870 begin
871 for i:=1 to dim do
872 begin
873 exp:=NExpression;
874 if exp is TFVari then
875 TFVari(exp).usedAsASubscript:=true;
876 result[i]:=exp;
877 if i<dim then check(',',IDH_ARRAY);
878 end;
879 check(')',IDH_ARRAY);
880 end;
881 end;
882
883
884 procedure TestSubscripted; //2011.3.8 ������
885 var
886 idr:TIdRec;
887 p:SubscriptArray;
888 s:ansistring;
889 i:integer;
890 begin
891 if insertDimst and not OptionExplicit then
892 begin
893 idr:=TIdrec.InitA(token,1,Undeterm);
894 try
895 gettoken;
896 p:=subscript(idr);
897 s:='10';
898 i:=idr.dim;
899 while i>1 do begin s:=s+',10'; dec(i) end;
900 insertLine(linenumber,'DIM '+idr.name+'('+s+')');
901 raise EReCompile.create('');
902 finally
903 idr.free;
904 end;
905 end
906 else
907 gettoken;
908 end;
909
910
911 function reservedword(name:ShortString):boolean;
912 var
913 index:integer;
914 s:boolean;
915 begin
916 s:=ReservedwordTable.search(@name,index);
917 if s then seterr(name+s_IsReserved,IDH_RESERVED);
918 reservedword:=s;
919 end;
920
921 function ColonIncluded:boolean;
922 var
923 svcp:tokensave;
924 begin
925 savetoken(svcp);
926 gettoken;
927 repeat
928 gettoken;
929 while token='(' do
930 FindCorrespondingParenthesis;
931 until (token=':') or (token=')') or (tokenspec=tail);
932 result:=(token=':');
933 restoretoken(svcp);
934 end;
935
936 function IdRecord(CanInsert:boolean):TIdRec;
937 var
938 index,index1: integer;
939 idr:TIdRec;
940 func: SimpleFunction;
941 module1:TModule;
942 mnam:AnsiString;
943 nam:ansistring;
944 begin
945 IdRecord:=nil;
946 mnam:=modifier(token);
947 nam:=identifier(token);
948 if mnam<>'' then
949 begin
950 if ForceFunctionDeclare
951 and not ProgramUnit.ExternalVarTable.search2(mnam,nam,index1) then
952 seterr(token+s_IsNotExternalDeclared,IDH_MODULE);
953
954 module1:=nil;
955 if pass=2 then module1:=module(mnam);
956 if (module1<>nil) and module1.ShareVarTable.search(nam,index1) then
957 begin
958 Idr:=TIdRec(module1.ShareVartable.items[index1]);
959 Idrecord:=idr;
960 if (idr.tag<>idPublic) then
961 seterr(Format(s_NotPublicDeclaredIn,[mnam,nam]),IDH_MODULE);
962 if (tokenspec=NIdf) and (module1.Arithmetic<>programunit.Arithmetic) then
963 seterr(s_DisAgreeArithmetic,IDH_MODULE);
964
965 end
966 else if ProgramUnit.ExternalVarTable.search2(mnam,nam,index1) then
967 idrecord:=TIdRec(ProgramUnit.ExternalVarTable.items[index1]);
968 end
969 else if (LocalRoutine<>nil)
970 and LocalRoutine.isFunction and (LocalRoutine.ResultVar.name=token) then
971 IdRecord:=LocalRoutine.ResultVar
972 else if (LocalRoutine<>nil) and LocalRoutine.VarTable.search(token,index1) then
973 IdRecord:=TIdRec(LocalRoutine.VarTable.items[index1])
974 else if ProgramUnit.isFunction and (ProgramUnit.ResultVar.name=token) then
975 IdRecord:=ProgramUnit.ResultVar
976 else if ProgramUnit.VarTable.search(token,index) then
977 IdRecord:=TIdRec(ProgramUnit.VarTable.items[index])
978 else if (CurModule<>nil) and CurModule.ShareVarTable.search(token,index1) then
979 begin
980 IdRecord:=TIdRec(CurModule.ShareVarTable.items[index1]);
981 if (tokenspec=NIdf) and (CurModule.Arithmetic<>programunit.Arithmetic) then
982 seterr(s_DisAgreeArithmetic,IDH_MODULE);
983 end
984 else if ProgramUnit.ExternalVarTable.search(token,index1) then
985 begin
986 idr:=TIdRec(ProgramUnit.ExternalVarTable.items[index1]);
987 if (pass=1) or (idr.dim<0) then
988 IdRecord:=idr
989 else
990 begin
991 module1:=module(idr.moduleName);
992 if (module1<>nil) and module1.ShareVarTable.search(token,index1) then
993 IdRecord:=TIdRec(module1.ShareVartable.items[index1])
994 end
995 end
996 else if CanInsert then
997 begin
998 if (nexttoken='(') then
999 if MinimalBasic and not SuppliedFunctionTable.find(token,func) then
1000 ProgramUnit.VarTable.insert(index,TIdRec.initA(token,1,Undeterm))
1001 else if (tokenSpec=Sidf) and ColonIncluded then
1002 ProgramUnit.VarTable.insert(index,TIdRec.initSimple(token,intern,maxint))
1003 else
1004 exit
1005 else if not OptionExplicit then
1006 ProgramUnit.VarTable.insert(index,TIdRec.initSimple(token,intern,maxint))
1007 else
1008 setErr(token+s_IsNotDeclared,IDH_DECLARE) ;
1009 IdRecord:=TIdRec(ProgramUnit.VarTable.items[index]);
1010 end;
1011 end;
1012
1013
1014
1015
1016 function Variablesub(var k:integer):TVariable;
1017 var
1018 IdRec:TIdRec;
1019 begin
1020 Variablesub:=nil;
1021 if reservedword(token) then exit;
1022
1023 idrec:=IdRecord(true);
1024 if IdRec=nil then exit;
1025
1026 gettoken;
1027 with IdRec do
1028 if kindchar='n' then
1029 begin
1030 k:=dim;
1031 case k of
1032 0: Variablesub:=IdRec.subs;
1033 1: Variablesub:=NSubScripted1(IdRec,Subscript(IdRec));
1034 2: Variablesub:=NSubScripted2(IdRec,Subscript(IdRec));
1035 3: Variablesub:=NSubScripted3(IdRec,Subscript(IdRec));
1036 4: Variablesub:=NSubScripted4(IdRec,Subscript(IdRec));
1037 -1: if prm then
1038 Variablesub:=IdRec.subs
1039 else
1040 seterr(prevtoken +s_IsFunctionName,IDH_RESERVED);
1041 end;
1042 end
1043 else
1044 begin
1045 k:=dim;
1046 case k of
1047 0: Variablesub:=IdRec.subs;
1048 1: Variablesub:=TSubScripted1.create(IdRec,Subscript(IdRec));
1049 2: Variablesub:=TSubScripted2.create(IdRec,Subscript(IdRec));
1050 3: Variablesub:=TSubScripted3.create(IdRec,Subscript(IdRec));
1051 4: Variablesub:=TSubScripted4.create(IdRec,Subscript(IdRec));
1052 -1: if prm then
1053 Variablesub:=IdRec.subs
1054 else
1055 seterr(prevtoken +s_IsFunctionName,IDH_RESERVED);
1056 end;
1057 end;
1058 end;
1059
1060 function variable:TVariable;
1061 var
1062 p:TVariable;
1063 k:integer;
1064 begin
1065 variable:=nil;
1066 p:=variablesub(k);
1067 if (p<>nil) and (k>=0) then
1068 variable:=p
1069 else {function reference}
1070 begin
1071 seterrExpected(s_VarName,IDH_RESERVED) ;
1072 p.free
1073 end;
1074 end;
1075
1076 function NVariable:TVariable;
1077 begin
1078 result:=Variable;
1079 if (result<>nil) and (result.kind<>'n') then
1080 seterrExpected(s_NumVar,IDH_RESERVED);
1081 end;
1082
1083
1084 function simpleVariable:TSubstance;
1085 var
1086 p:TPrincipal;
1087 k:integer;
1088 begin
1089 p:=nil;
1090 if tokenspec=NIdf then
1091 begin
1092 p:=variablesub(k);
1093 if (p<>nil) and (k<>0) then
1094 begin
1095 p.free;
1096 p:=nil
1097 end;
1098 end;
1099 if p=nil then
1100 seterrRestricted(s_SimpleVar,IDH_RESERVED);
1101 simplevariable:=p as TSubstance
1102 end;
1103
1104
1105 {********}
1106 {compiler}
1107 {********}
1108 function NSExpression1:TPrincipal;
1109 var
1110 svcp:^tokensave;
1111 begin
1112 new(svcp);
1113 savetoken(svcp^);
1114 try
1115 try
1116 inc(trying);
1117 result:=NExpression;
1118 except
1119 on SyntaxError do
1120 begin
1121 restoreToken(svcp^);
1122 result:=SExpression;
1123 statusmes.clear;
1124 HelpContext:=0;
1125 end;
1126 end;
1127 finally
1128 dispose(svcp);
1129 dec(trying);
1130 end;
1131 end;
1132
1133 function NSExpression:TPrincipal;
1134 var
1135 sp:tokenspecification;
1136 begin
1137 sp:=tokenspec;
1138 if token='(' then sp:=NextTokenspecWithinParenthesis; // sp:=nexttokenspec;//2006.1.15
1139 case sp of
1140 SCon,Sidf:NSExpression:=SExpression;
1141 NRep,NIdf:NSExpression:=NExpression;
1142 else NSExpression:=NSExpression1;
1143 end;
1144 end;
1145
1146
1147
1148 function article:TPrincipal;
1149 var
1150 svcp:^tokensave;
1151 begin
1152 if token='#' then
1153 article:=ChExpression
1154 else
1155 begin
1156 new(svcp);
1157 inc(trying);
1158 try
1159 savetoken(svcp^);
1160 try
1161 article:=NSExpression;
1162 except
1163 on SyntaxError do
1164 begin
1165 restoreToken(svcp^);
1166 article:=matrix;
1167 statusmes.clear;
1168 HelpContext:=0;
1169 end;
1170 end;
1171 finally
1172 dispose(svcp);
1173 dec(trying);
1174 end;
1175 end;
1176 end;
1177
1178
1179
1180 {********************}
1181 {numerical Expression}
1182 {********************}
1183
1184 function NMatrixDim(n:shortint):TMatrix;
1185 begin
1186 result:=NMatrix;
1187 if result.idr.dim<>n then SeterrDimension(IDH_Array_Parameter);
1188 end;
1189
1190 function SMatrixDim(n:shortint):TMatrix;
1191 begin
1192 result:=SMatrix;
1193 if result.idr.dim<>n then SeterrDimension(IDH_Array_Parameter);
1194 end;
1195
1196
1197 function principal(idrec:TIdRec):TPrincipal;
1198 begin
1199 principal:=nil;
1200 case idrec.kindchar of
1201 'n': if idrec.dim =0 then
1202 principal:=NExpression
1203 else if idrec.dim>0 then
1204 principal:=NMatrixDim(idrec.dim) ;
1205 's':if idrec.dim =0 then
1206 principal:=sexpression
1207 else if idrec.dim>0 then
1208 principal:=SMatrixDim(idrec.dim) ;
1209 'c': principal:=ChExpression;
1210 end;
1211 end;
1212
1213
1214
1215 function VariableOrFunctionRef:TPrincipal; {numeric variable | function reference}
1216 var
1217 func: SimpleFunction;
1218 idr:TIdRec;
1219
1220 begin
1221 VariableOrFunctionRef:=nil;
1222
1223 if ReservedWordTable.find(token,func) then
1224 begin
1225 gettoken;
1226 VariableOrFunctionRef:=func
1227 end
1228 else
1229 begin
1230 idr:=IdRecord(true);
1231 if idr<>nil then
1232 with idr do
1233 case dim of
1234 0: begin
1235 gettoken;
1236 VariableOrFunctionRef:=idr.subs;
1237 end;
1238 1: begin
1239 gettoken;
1240 VariableOrFunctionRef:=
1241 NSubscripted1(idr,Subscript(idr));
1242 end;
1243 2: begin
1244 gettoken;
1245 VariableOrFunctionRef:=
1246 NSubscripted2(idr,Subscript(idr));
1247 end;
1248 3: begin
1249 gettoken;
1250 VariableOrFunctionRef:=
1251 NSubscripted3(idr,Subscript(idr));
1252 end;
1253 4: begin
1254 gettoken;
1255 VariableOrFunctionRef:=
1256 NSubscripted4(idr,Subscript(idr));
1257 end;
1258 -1 : if idr.kindchar='n' then
1259 VariableOrFunctionRef:=NFunction(idr)
1260 else
1261 VariableOrFunctionRef:=TStrFunction.create(idr);
1262 end
1263 else if SuppliedFunctionTable.find(token,func) then
1264 begin
1265 gettoken;
1266 VariableOrFunctionRef:=func
1267 end
1268 else if not (ForceFunctionDeclare or OptionExplicit) then
1269 try
1270 idr:=TIdrec.initF(modifier(token),identifier(token),intern);
1271 if tokenspec=NIdf then
1272 VariableOrFunctionRef:=NFunction(idr)
1273 else if tokenspec=SIDf then
1274 VariableOrFunctionRef:=TStrFunction.create(idr);
1275 finally
1276 idr.free;
1277 end ;
1278 end;
1279 end;
1280
1281
1282
1283 {**********}
1284 { string }
1285 {**********}
1286
1287 type
1288 TSubstring=class(TStrExpression)
1289 exp:TPrincipal;
1290 exp1,exp2:TPrincipal;
1291 CharacterByte:boolean;
1292 constructor create(e:TPrincipal);
1293 destructor destroy;override;
1294 function Code:AnsiString;override;
1295 end;
1296
1297 procedure SubstringQualifier(var exp1,exp2:tPrincipal);
1298 begin
1299 check('(',IDH_SUBSTRING);
1300 exp1:=NExpression;
1301 check(':',IDH_SUBSTRING);
1302 exp2:=NExpression;
1303 check(')',IDH_SUBSTRING);
1304 end;
1305
1306 constructor TSubString.create(e:TPrincipal);
1307 begin
1308 inherited create;
1309 CharacterByte:=ProgramUnit.CharacterByte;
1310 exp:=e;
1311 SubstringQualiFier(exp1,exp2);
1312 end;
1313
1314 destructor TSubString.destroy;
1315 begin
1316 exp.free;
1317 exp1.free;
1318 exp2.free;
1319 inherited destroy;
1320 end;
1321
1322 function StringPrimary:TPrincipal ;
1323 var
1324 exp:TPrincipal;
1325 begin
1326 if token='(' then
1327 begin
1328 check('(',IDH_STRING);
1329 stringprimary:=SExpression;
1330 checktoken(')',IDH_STRING);
1331 end
1332 else if tokenspec=Scon then
1333 begin
1334 StringPrimary:=TStrConstant.create(tokenstring);
1335 gettoken;
1336 end
1337 else if tokenspec=SIdf then
1338 begin
1339 exp:=VariableOrFunctionRef;
1340 if (exp=nil) or (exp.kind<>'s') then
1341 seterr( token + s_CantBelongHere + EOL +s_IllegalStringVar,IDH_String);
1342 if (token='(') and (exp is TVariable) then
1343 StringPrimary:=TSubString.create(exp)
1344 else
1345 StringPrimary:=exp ;
1346 end
1347 else
1348 seterr(s_IllegalStringVar + EOL+ token + s_CantBelongHere ,IDH_STRING);
1349 end;
1350
1351 constructor TConcat.create(e1,e2:TPrincipal);
1352 begin
1353 inherited create;
1354 exp1:=e1;
1355 exp2:=e2;
1356 end;
1357
1358 destructor TConcat.destroy;
1359 begin
1360 exp1.free;
1361 exp2.free;
1362 inherited destroy;
1363 end;
1364
1365 var
1366 confirmedA:boolean=false;
1367
1368 function confirmA:boolean;
1369 begin
1370 confirmA:=false;
1371 if permitMicrosoft then
1372 confirmA:=true
1373 else if autocorrect[ac_string] or confirmedA or
1374 confirm(s_ConfirmPlusSignToAnpersand,IDH_MICROSOFT_OP) then
1375 begin
1376 replacetoken('&');
1377 confirmedA:=true;
1378 confirmA:=true;
1379 end;
1380 end;
1381
1382
1383 function SExpression:TPrincipal;
1384 var
1385 exp:TPrincipal;
1386 begin
1387 exp:=stringprimary;
1388 while ((Token='&') or (token='+') and confirmA) and (exp<>nil) do
1389 begin
1390 gettoken;
1391 exp:=TConcat.create(exp,stringprimary);
1392 end;
1393 SExpression:=exp;
1394 end;
1395
1396 {**************}
1397 {constant term }
1398 {**************}
1399
1400 function SConstant:TPrincipal;
1401 begin
1402 if tokenspec=SCon then
1403 SConstant:=stringprimary
1404 else
1405 begin
1406 seterrrestricted(s_Constant,IDH_STRING);
1407 SConstant:=nil
1408 end
1409 end;
1410
1411
1412 {******}
1413 {matrix}
1414 {******}
1415
1416 function Matrix:TMatrix;
1417 var
1418 idr:TidRec;
1419 begin
1420 matrix:=nil;
1421 idr:=Idrecord(false);
1422 if (idr<>nil) and (idr.dim>0) then
1423 begin
1424 matrix:=TMatrix(idr.subs);
1425 gettoken;
1426 end
1427 else
1428 seterr(token+s_IsNotArrayName,IDH_MAT);
1429 end;
1430
1431
1432 function Nmatrix:TMatrix;
1433 begin
1434 result:=matrix;
1435 if (result<>nil) and (result.kind<>'n') then
1436 begin
1437 result.Free;
1438 result:=nil;
1439 seterrExpected(s_NumArrayName,IDH_MAT);
1440 end;
1441 end;
1442
1443 function Smatrix:TMatrix;
1444 begin
1445 result:=matrix;
1446 if (result<>nil) and (result.kind<>'s') then
1447 begin
1448 result.Free;
1449 seterrExpected(s_StringArrayName,IDH_MAT_STRING);
1450 end;
1451 end;
1452
1453
1454 {*******************}
1455 { logical expression}
1456 {*******************}
1457
1458
1459 procedure findcomparefunction(const r:string; var f:comparefunction);
1460 begin
1461 if r='=' then f:=Equals
1462 else if r='<' then f:=Less
1463 else if (r='<=') or (r='=<') then f:=NotGreater
1464 else if r='>' then f:=Greater
1465 else if (r='>=') or (r='=>') then f:=NotLess
1466 else if (r='<>') or (r='><') then f:=NotEquals
1467 else if r='' then seterrExpected(s_ComparisonExp,IDH_LOGICAL)
1468 else seterrIllegal(r,IDH_LOGICAL) ;
1469 end;
1470
1471
1472
1473 function comparison:TLogical; //TComparison;
1474 var
1475 e1,e2:TPrincipal ;
1476 f:comparefunction;
1477 begin
1478 comparison:=nil;
1479 e1:=NSExpression;
1480 if e1=nil then exit;
1481 findcomparefunction(token,f);
1482 gettoken;
1483 if e1.kind='n' then
1484 begin
1485 e2:=NExpression;
1486 Comparison:=NComparison(f,e1,e2)
1487 end
1488 else
1489 comparison:=tComparisonS.create(e1,SExpression,f) ;
1490 end;
1491
1492 function Disjunction :TLogical;forward;
1493
1494 function relationalPrimary:TLogical;
1495 var
1496 svcp:^tokensave;
1497 begin
1498 if Token= '(' then
1499 begin
1500 new(svcp);
1501 inc(trying);
1502 try
1503 saveToken(svcp^);
1504 try //���������������������������������������
1505 relationalprimary:=comparison;
1506 except
1507 On SyntaxError do
1508 begin
1509 restoretoken(svcp^);
1510 gettoken; //������������������������������������
1511 relationalprimary:=disjunction;
1512 checktoken(')',IDH_LOGICAL);
1513 statusmes.clear;
1514 HelpContext:=0;
1515 end;
1516 end;
1517 finally
1518 dispose(svcp);
1519 dec(trying);
1520 end;
1521 end
1522 else
1523 relationalprimary:=comparison;
1524 end;
1525
1526 function relationalTerm:TLogical;
1527 begin
1528 if token='NOT' then
1529 begin
1530 gettoken;
1531 relationalTerm:=TNegation.create(relationalPrimary)
1532 end
1533 else
1534 begin
1535 relationalTerm:=relationalprimary;
1536 end;
1537 end;
1538
1539 function conjunction :TLogical;
1540 var
1541 b:TLogical;
1542 begin
1543 b:=relationalTerm;
1544 while token='AND' do
1545 begin
1546 gettoken;
1547 b:=TConjunction.create(b,relationalTerm)
1548 end;
1549 conjunction:=b
1550 end;
1551
1552 function Disjunction :TLogical;
1553 var
1554 b:Tlogical;
1555 begin
1556 b:=conjunction;
1557 while token='OR' do
1558 begin
1559 gettoken;
1560 b:=TDisjunction.create(b,conjunction)
1561 end ;
1562 disjunction:=b
1563 end;
1564
1565 function relationalExpression :TLogical;
1566 begin
1567 if permitMicrosoft then
1568 relationalExpression:=TLogicalNumeric.create
1569 else
1570 relationalExpression:=Disjunction
1571 end;
1572
1573
1574 {************}
1575 {LET statement}
1576 {************}
1577 type
1578 TLet=class(TStatement)
1579 vari:TVariable;
1580 exp :TPrincipal;
1581 constructor create(prev,eld:TStatement; vari1:Tvariable; exp1:Tprincipal);
1582 destructor destroy;override;
1583 function Code:AnsiString;override;
1584 end;
1585
1586 TLetWithNoRound=class(TLet)
1587 function Code:AnsiString;override;
1588 end;
1589
1590 constructor TLet.create(prev,eld:TStatement; vari1:Tvariable; exp1:Tprincipal);
1591 begin
1592 inherited create(prev,eld);
1593 vari:=vari1;
1594 exp:=exp1;
1595 if vari is TFVari then
1596 TFVari(vari).AddQueryInteger(exp.QueryInteger);
1597 if vari is TCVari then
1598 TCVari(vari).AddQueryDouble(exp.QueryDouble);
1599 end;
1600
1601 destructor TLet.destroy;
1602 begin
1603 vari.free;
1604 exp.free;
1605 inherited destroy
1606 end;
1607
1608
1609 type
1610 TLetMulti0=class(TStatement)
1611 varis:TObjectList; {collection of TVariable}
1612 exp :TPrincipal;
1613 constructor create(prev,eld:TStatement);
1614 destructor destroy;override;
1615 end;
1616
1617 type
1618 TLetMultiN=class(TLetMulti0)
1619 arith:tpPrecision;
1620 constructor create(prev,eld:TStatement);
1621 function Code:ansistring;override;
1622 end;
1623
1624 constructor TLetMulti0.create(prev,eld:TStatement);
1625 begin
1626 inherited create(prev,eld);
1627 varis:=TObjectList.create(4);
1628 end;
1629
1630 constructor TLetMultiN.create(prev,eld:TStatement);
1631 var
1632 k:integer;
1633 p:TPrincipal;
1634 i:integer;
1635 begin
1636 inherited create(prev,eld);
1637 arith:=programunit.arithmetic;
1638 repeat
1639 p:=Variablesub(k);
1640 varis.add(p);
1641 if (p=nil) or (p.kind<>'n') then seterr('',IDH_LET);
1642 if k<0 then seterrillegal(s_FunctionName,IDH_LET);
1643 until not test(',');
1644 check('=',IDH_LET);
1645 exp:=NExpression;
1646
1647 with varis do
1648 for i:=0 to count-1 do
1649 begin
1650 p:=TPrincipal(items[i]);
1651 if p is TFVari then
1652 TFVari(p).AddQueryInteger(nil); //Integer���������
1653 if p is TCVari then
1654 TCVari(p).AddQueryDouble(nil); //Double���������
1655 end;
1656
1657 end;
1658
1659 destructor TLetMulti0.destroy;
1660 begin
1661 varis.free;
1662 exp.free;
1663 inherited destroy
1664 end;
1665
1666 {**********}
1667 {TInputVari}
1668 {**********}
1669
1670 function InputVari(StrOnly:Boolean):TInputVari;
1671 var
1672 vari:TVariable;
1673 k:integer;
1674 begin
1675 vari:=Variablesub(k);
1676 if(vari=nil) or (k<0) then
1677 begin
1678 vari.Free;
1679 seterrillegal(s_FunctionName,IDH_LET);
1680 end;
1681 if StrOnly and (vari.Kind<>'s') then
1682 begin
1683 vari.Free;
1684 SetErr(s_OnlyStringVar,IDH_LINE_INPUT);
1685 end;
1686 if vari.kind='n' then
1687 result:=TInputVari.create(vari)
1688 else if vari.kind='s' then
1689 result:=TStrVari.create(vari);
1690 end;
1691
1692 constructor TInputVari.create(vari1:TVariable);
1693 begin
1694 inherited create;
1695 vari:=vari1;
1696 if vari is TFVari then
1697 TFVari(vari).AddQueryInteger(nil); //Integer���������
1698
1699 end;
1700
1701 function StrVari:TStrVari;
1702 var
1703 vari:TVariable;
1704 k:integer;
1705 begin
1706 vari:=Variablesub(k);
1707 if k<0 then
1708 begin
1709 vari.Free;
1710 seterrillegal(s_FunctionName,IDH_LET);
1711 end;
1712 result:=TStrVari.create(vari)
1713 end;
1714
1715 constructor TStrVari.create(vari1:TVariable);
1716 begin
1717 inherited create(vari1);
1718 if (vari1=nil) or (vari1.kind<>'s') then
1719 seterrexpected(s_StringIdentifier,IDH_String);
1720 if token='(' then
1721 SubstringQualifier(index1,index2);
1722 CharacterByte:=ProgramUnit.CharacterByte;
1723 end;
1724
1725 destructor TInputVari.destroy;
1726 begin
1727 vari.free;
1728 inherited destroy;
1729 end;
1730
1731 destructor TStrVari.destroy;
1732 begin
1733 index1.free;
1734 index2.free;
1735 inherited destroy;
1736 end;
1737
1738 type
1739 TLetMultiS=class(TLetMulti0)
1740 constructor create(prev,eld:TStatement);
1741 function code:ansistring;override;
1742 end;
1743
1744 constructor TLetMultiS.create(prev,eld:TStatement);
1745 begin
1746 inherited Create(prev,eld);
1747 repeat
1748 varis.add(StrVari);
1749 until not test(',');
1750 trying:=0;
1751 check('=',IDH_LET);
1752 exp:=SExpression;
1753 end;
1754
1755 function LETst(prev,eld:TStatement):TStatement;
1756 var
1757 vari:Tvariable;
1758 svcp:TokenSave;
1759 sp:char;
1760 k:integer;
1761 begin
1762 LETst:=nil;
1763 savetoken(svcp);
1764 vari:=Variablesub(k);
1765 if (vari<>nil) then
1766 begin
1767 sp:=vari.kind;
1768 if (k<0) then
1769 begin
1770 check('=',IDH_LET);
1771 trying:=0;
1772 case sp of
1773 'n': Letst:=TLetwithNoRound.create(prev,eld,vari,NExpression);
1774 's': Letst:=TLetwithNoRound.create(prev,eld,vari,SExpression);
1775 end;
1776 end
1777 else if sp='n' then
1778 if token=',' then
1779 begin
1780 vari.Free;
1781 restoretoken(svcp);
1782 Letst:=TLetMultiN.create(prev,eld);
1783 end
1784 else
1785 begin
1786 check('=',IDH_LET);
1787 trying:=0;
1788 Letst:=Tlet.create(prev,eld,vari,NExpression);
1789 end
1790 else if sp='s' then
1791 begin
1792 vari.Free;
1793 restoretoken(svcp);
1794 Letst:=TLetMultiS.create(prev,eld);
1795 end;
1796 end
1797 else
1798 if ((tokenspec=NIdf) or (tokenspec=SIdf)) and (nexttoken='(') then
1799 begin
1800 vari.Free;
1801 TestSubscripted;
1802 seterr(s_ArrayShouldBeDeclared,IDH_ARRAY);
1803 end ;
1804 end;
1805
1806
1807
1808 function tryLETst(prev,eld:TStatement):TStatement;far;
1809 {���������������������������nil���������}
1810 var
1811 p:TStatement;
1812 svcp:^TokenSave;
1813 begin
1814 tryLETst:=nil;
1815 if (token='ELSEIF') or (token='ELSE') or (token='USE')
1816 or (token='CASE') then exit;
1817 if NextTokenBeyondParenthesis2<>'=' then exit;
1818
1819 if permitMicroSoft then
1820 begin TryLETst:=LETst(prev,eld);exit end;
1821
1822 p:=nil;
1823 new(svcp);
1824 try
1825 savetoken(svcp^);
1826 try
1827 inc(trying);
1828 p:=LETst(prev,eld);
1829 if AutoCorrect[ac_let] or
1830 confirm(s_ConfirmInsertLET,IDH_MICROSOFT_OP) then
1831 begin
1832 TryLETst:=p;
1833 insertKeyWord('LET ',svcp^) ;
1834 end
1835 else
1836 begin
1837 p.Free;
1838 restoretoken(svcp^);
1839 end;
1840 except
1841 On SyntaxError do
1842 restoretoken(svcp^);
1843 end;
1844 finally
1845 dispose(svcp);
1846 dec(trying);
1847 end;
1848 end;
1849
1850 {*************}
1851 {DEFst }
1852 {*************}
1853 type
1854 TDefN = class(TLetwithNoRound)
1855 constructor create(prev,eld:TStatement; routine:TRoutine);
1856 end;
1857
1858 TDefS = class(TLetwithNoRound)
1859 constructor create(prev,eld:TStatement; routine:TRoutine);
1860 end;
1861
1862 constructor TDefN.create(prev,eld:TStatement; routine:TRoutine);
1863 begin
1864 inherited TStatementcreate(prev,eld);
1865 vari:=routine.ResultVar.subs;
1866 check('=',IDH_DEF);
1867 exp:=NExpression ;
1868 end;
1869
1870 constructor TDefS.create(prev,eld:TStatement; routine:TRoutine);
1871 begin
1872 inherited TStatementcreate(prev,eld);
1873 vari:=routine.ResultVar.subs;
1874 check('=',IDH_DEF);
1875 exp:=SExpression ;
1876 end;
1877
1878
1879
1880
1881 function DEFst(prev,eld:TStatement):TStatement;far;
1882 var
1883 sp:tokenspecification;
1884 begin
1885 if (LocalRoutine<>nil)
1886 or (indent>0) and (CurModule=MainProgram)
1887 or (indent>1)
1888 then seterrillegal(prevtoken,IDH_DEF) ;
1889 if (ProgramUnit=CurModule) and (ProgramUnit<>MainProgram) then
1890 seterr(s_InternalRoutineCanntotbeInProcedure,IDH_MODULE);
1891 DEFst:=TStatementNoTrace.create(prev,eld) ;
1892 sp:=tokenspec;
1893 LocalRoutine:=routineHeadLocal;
1894 LocalRoutine.MakeParameter;
1895 case sp of
1896 NIdf: LocalRoutine.block:=TDefN.create(prev,eld,LocalRoutine);
1897 SIdf: LocalRoutine.block:=TDefS.create(prev,eld,LocalRoutine);
1898 end;
1899 localRoutine:=nil;
1900 end;
1901
1902 {*********}
1903 {Arguments}
1904 {*********}
1905
1906 function argumentN1:TPrincipal;
1907 begin
1908 check('(',IDH_FUNCTIONS);
1909 argumentN1:=Nexpression;
1910 checktoken(')',IDH_FUNCTIONS);
1911 end;
1912
1913 function argumentN2a:TPrincipal;
1914 begin
1915 check('(',IDH_FUNCTIONS);
1916 argumentN2a:=Nexpression;
1917 check(',',IDH_FUNCTIONS);
1918 end;
1919
1920 function argumentN2b:TPrincipal;
1921 begin
1922 argumentN2b:=Nexpression;
1923 checktoken(')',IDH_FUNCTIONS);
1924 end;
1925
1926 {*********}
1927 {Micorsoft}
1928 {*********}
1929
1930 constructor TLogicalNumeric.create;
1931 begin
1932 inherited create;
1933 exp:=NExpression;
1934 end;
1935
1936 destructor TLogicalNumeric.destroy;
1937 begin
1938 exp.free;
1939 inherited destroy
1940 end;
1941
1942 {********}
1943 {TChannel}
1944 {********}
1945 type
1946 TChannel=class(TPrincipal)
1947 exp:TPrincipal;
1948 PUnit:TProgramUnit;
1949 constructor create;
1950 destructor destroy;override;
1951 function kind:char;override;
1952 function InvalidErCode:integer;override;
1953 function Code:ansistring;override;
1954 end;
1955
1956 constructor TChannel.create;
1957 begin
1958 inherited create;
1959 checkToken('#',IDH_FILE);
1960 exp:=NExpression;
1961 Punit:=programUnit;
1962 PUnit.haveChannelExpression:=true;
1963 end;
1964
1965 destructor TChannel.destroy;
1966 begin
1967 exp.free;
1968 inherited destroy;
1969 end;
1970
1971 function ChExpression:TPrincipal;
1972 begin
1973 chExpression:=TChannel.create;
1974 end;
1975
1976
1977 function ChannelExpression:TPrincipal;
1978 begin
1979 if token='#' then
1980 begin
1981 gettoken;
1982 ChannelExpression:=NExpression;
1983 programunit.HaveChannelExpression:=true;
1984 end
1985 else
1986 ChannelExpression:=nil;
1987 end;
1988
1989
1990
1991 function Equals(i:integer):boolean;
1992 begin
1993 Equals:=(i=0)
1994 end;
1995
1996 function NotEquals(i:integer):boolean;far;
1997 begin
1998 NotEquals:=(i<>0)
1999 end;
2000
2001 function Less(i:integer):boolean;far;
2002 begin
2003 Less:=(i<0)
2004 end;
2005
2006 function Greater(i:integer):boolean;far;
2007 begin
2008 Greater:=(i>0)
2009 end;
2010
2011 function NotGreater(i:integer):boolean;
2012 begin
2013 NotGreater:=(i<=0)
2014 end;
2015
2016 function NotLess(i:integer):boolean;far;
2017 begin
2018 NotLess:=(i>=0)
2019 end;
2020
2021
2022 function TChannel.InvalidErCode:integer;
2023 begin
2024 result:=7001
2025 end;
2026
2027
2028 function TChannel.kind:char;
2029 begin
2030 result:='c'
2031 end;
2032
2033 {*************}
2034 {Generate Code}
2035 {*************}
2036
2037 function ArgNLiteral(i:integer):Ansistring;
2038 begin
2039 result:='arg_n'+Format('%5.5u',[i]);
2040 end;
2041
2042 function ArgSLiteral(i:integer):Ansistring;
2043 begin
2044 result:='arg_s'+Format('%5.5u',[i]);
2045 end;
2046
2047 var
2048 SeqCounterN:cardinal;
2049 SeqCounterS:cardinal;
2050
2051 function ArgVarNameN:string;
2052 begin
2053 inc(SeqCounterN);
2054 result:=ArgNLiteral(SeqCounterN);
2055 end;
2056 function ArgVarNameS:string;
2057 begin
2058 inc(SeqCounterS);
2059 result:=ArgSLiteral(SeqCounterS);
2060 end;
2061
2062 function TCall.Code:AnsiString;
2063 var
2064 i:integer;
2065 s:Ansistring;
2066 FinalizeCode:AnsiString;
2067 a:tArticle;
2068 begin
2069 case Routine.kind of
2070 'D','F':
2071 begin
2072 s:='';
2073 for i:=0 to params.count -1 do
2074 begin
2075 if i>0 then s:=s+',';
2076 a:=TArticle(params.items[i]);
2077 s:=s+a.code;
2078 //if (Routine.Kind='F') and (a is TFAVari) or (a is TCAVari) or (a is TSAVari) then
2079 if (Routine.Kind='F') and ((a is TSubstance) and (TSubstance(a).idr.dim>0)) then
2080 s:=s+'.NewCopy ';
2081 end;
2082 if s<>'' then s:='('+s+')';
2083 result := routine.NameCode + s;
2084 end;
2085 'S','P':
2086 begin
2087 SeqCounterN:=0;
2088 SeqCounterS:=0;
2089 s:='';
2090 for i:=0 to params.count -1 do
2091 begin
2092 if i>0 then s:=s+',';
2093 a:=TArticle(params.items[i]);
2094 if (a is TVariable) and not (a is TConstVariable) then
2095 s:=s+a.code
2096 else if (a is TPrincipal) then
2097 case TPrincipal(a).kind of
2098 'n': s:=s+ 'NumericVariable('+ ArgVarNameN + ',' + a.code + ')^';
2099 's': s:=s+ 'StringVariable('+ ArgVarNameS + ',' + a.code + ')^';
2100 'c': s:=s+ 'TDeviceRef.create(ChannelList,'+a.code+')';
2101 end;
2102 end;
2103 if s<>'' then s:='('+s+')';
2104 result := routine.nameCode + s +';';
2105 with proc do
2106 begin
2107 if PUnit.Arithmetic=precisionNative then
2108 MaxNumArgDouble:=base.max(MaxNumArgDouble,SeqCounterN)
2109 else if Punit.Arithmetic=precisionComplex then
2110 MaxNumArgComplex:=base.max(MaxNumArgComplex,SeqCounterN);
2111 MaxNumArgString :=base.max(MaxNumArgString,SeqCounterS);
2112 end;
2113 end;
2114 end;
2115 end;
2116
2117 function TDisjunction.Code:AnsiString;
2118 begin
2119 result:= '(' + exp1.Code + ') or (' + exp2.Code + ')'
2120 end;
2121
2122 function TConjunction.Code:AnsiString;
2123 begin
2124 result:= '(' + exp1.Code + ') and (' + exp2.Code + ')'
2125 end;
2126
2127 function TNegation.Code:AnsiString;
2128 begin
2129 result:= ' not(' + exp.Code + ') '
2130 end;
2131
2132 function TComparison.Code:AnsiString;
2133 var
2134 opCode:String[2];
2135 begin
2136 if @op=@Express.Equals then
2137 opCode:='='
2138 else if @op=@NotEquals then
2139 opCode:='<>'
2140 else if @op=@Greater then
2141 opCode:='>'
2142 else if @op=@Less then
2143 opCode:='<'
2144 else if @op=@NotGreater then
2145 opCode:='<='
2146 else if @op=@NotLess then
2147 opCode:='>=';
2148
2149 result := exp1.Code + opCode + exp2.Code
2150 end;
2151
2152 function TLetWithNoRound.Code:AnsiString;
2153 begin
2154 result:=Vari.Code + ' := ' + exp.Code + ';'
2155 end;
2156
2157
2158 function TLet.Code:AnsiString;
2159 var
2160 channel:ansistring;
2161 begin
2162 result:=Vari.Code + ' := ' + exp.Code + ';';
2163 // TRACE
2164 if PUnit.haveTraceSt then
2165 begin
2166 channel:='Trace' + IntToStr(PUNIT.LineNumb+1);
2167 if Vari is TSubstance then
2168 begin
2169 result:=result + EOL +
2170 'if ' + channel + '<>nil then '+
2171 channel + '.PRINT([],rsNone, false ,['' ' +
2172 TSubstance(Vari).idr.name + '='' ,' ;
2173 if (vari.kind='n') and (PUnit.Arithmetic=precisionComplex) then
2174 result := result+ 'TComplex.create('+vari.Code+')'
2175 else
2176 result := result + vari.Code;
2177 result := result + ', TNewLine.create ]);' + EOL
2178 end
2179 else if Vari is TSubscripted then
2180 with TSubscripted(Vari) do
2181 begin
2182 result:=subs.idr.Literal+'.LetWithTrace(' + channel + ',''' + subs.idr.name + ''',';
2183 case dim of
2184 1: result:=result + subscript[1].code +',';
2185 2: result:=result + subscript[1].code +','+ subscript[2].code +',';
2186 3: result:=result + subscript[1].code +','+ subscript[2].code +','+ subscript[3].code +',';
2187 4: result:=result + subscript[1].code +','+ subscript[2].code +','+ subscript[3].code +','+ subscript[4].code +',';
2188 end;
2189 result:=result + exp.code + ');' +EOL;
2190 end;
2191 end;
2192 end;
2193
2194
2195 function TConcat.Code:ansistring;
2196 begin
2197 result:=exp1.code + '+' + exp2.code
2198 end;
2199 function TSubscripted.Code:AnsiString;
2200 begin
2201 result:= subs.Code + '.elements^['+subs.Code +'.index(' + subscript[1].Code;
2202 if dim>=2 then result:= result + ',' + subscript[2].Code;
2203 if dim>=3 then result:= result + ',' + subscript[3].Code;
2204 if dim>=4 then result:= result + ',' + subscript[4].Code;
2205 result:= result + ')]';
2206 end;
2207
2208 function TSubstring.Code:Ansistring;
2209 begin
2210 if CharacterByte then
2211 result:='SubStringByte('
2212 else
2213 result:='SubString(';
2214 result:=result+exp.Code+','+exp1.Code+','+exp2.code+')'
2215 end;
2216
2217 function TStrConstant.Code:AnsiString;
2218 begin
2219 result:=AnsiQuotedStr(value,'''')
2220 end;
2221
2222 function TletMultiN.code:ansistring;
2223 var
2224 i:integer;
2225 begin
2226 if arith=PrecisionComplex then
2227 result:='LETC(['
2228 else // PrecisionNative
2229 result:='LET([' ;
2230 with varis do
2231 for i:=0 to count-1 do
2232 begin
2233 with (items[i] as TPrincipal) do
2234 result:=result + '@' + code;
2235 if i<count-1 then
2236 result:=result+',';
2237 end;
2238 result:=result+'],'+exp.code+');'
2239 end;
2240
2241 function TStrVari.Code:ansistring;
2242 begin
2243 if index1=nil then
2244 result:='TStrvar.create(@' + vari.code +')'
2245 else if characterbyte then
2246 result:='TStrvarByte.create(@' + vari.code +',' + index1.code +','+ index2.code +')'
2247 else
2248 result:='TStrvar2.create(@' + vari.code +',' + index1.code +','+ index2.code +')';
2249 end;
2250
2251
2252 function TletMultiS.code:ansistring;
2253 var
2254 i:integer;
2255 begin
2256 result:='LETS([';
2257 with varis do
2258 for i:=0 to count-1 do
2259 begin
2260 if i>0 then
2261 result:=result+',';
2262 result:=result+(items[i] as TStrVari).code;
2263 end;
2264 result:=result+'],'+exp.code+');'
2265 end;
2266
2267 function TChannel.code:ansistring;
2268 begin
2269 result:=exp.code
2270 end;
2271
2272 function TStrFunction.code:ansistring;
2273 begin
2274 result:=exe.code
2275 end;
2276
2277 function TConstVariable.Kind:Char;
2278 begin
2279 result:=vari.kind
2280 end;
2281
2282 function TConstVariable.Code:AnsiString;
2283 begin
2284 result:=vari.Code
2285 end;
2286
2287 {**********}
2288 {Initialize}
2289 {**********}
2290 procedure statementTableinit;far;
2291 begin
2292 statementTableinitImperative('LET',LETst);
2293 statementTableinitStructural('DEF',DEFst);
2294 end;
2295
2296
2297 initialization
2298 suppliedFunctionTable:=TFncSelection.create;
2299 suppliedFunctionTable.capacity:=96;
2300 reservedwordTable:=TFncSelection.create;
2301 if TableInitProcs=nil then
2302 TableInitProcs:=TProcsCollection.create; //97.10.12 ������������������������������struct.pas������������
2303 tableInitProcs.accept(statementTableinit);
2304
2305 finalization
2306 suppliedFunctionTable.free;
2307 reservedwordTable.free;
2308
2309 end.

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