diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 3ab17836c..c50dccdcb 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -14,8 +14,8 @@ internal static class RevisionClass { public const string Major = "3"; public const string Minor = "7"; - public const string Build = "0"; - public const string Revision = "2671"; + public const string Build = "1"; + public const string Revision = "2677"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 159a11642..a96da6604 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=7 -%REVISION%=2671 -%COREVERSION%=0 +%REVISION%=2677 +%COREVERSION%=1 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index a49483d09..10e82db34 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.7.0.2671 +3.7.1.2677 diff --git a/ReleaseGenerators/License.rtf b/ReleaseGenerators/License.rtf index ef7c268d7..40e631bb7 100644 --- a/ReleaseGenerators/License.rtf +++ b/ReleaseGenerators/License.rtf @@ -37,17 +37,18 @@ \fs22\lang1049\langfe1049\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1 \widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 \snext11 \ssemihidden \sunhideused -Normal Table;}}{\*\rsidtbl \rsid1983975\rsid2307793\rsid2756858\rsid5121612\rsid9338748\rsid9583613\rsid12019863\rsid14836557}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1} -{\info{\operator \'d1\'f2\'e0\'ed\'e8\'f1\'eb\'e0\'e2 \'cc\'e8\'f5\'e0\'eb\'ea\'ee\'e2\'e8\'f7}{\creatim\yr2018\mo8\dy29\hr21\min57}{\revtim\yr2020\mo8\dy24\hr15\min4}{\version8}{\edmins9}{\nofpages4}{\nofwords1386}{\nofchars7904}{\nofcharsws9272} -{\vern7}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1701\margr850\margt1134\margb1134\gutter0\ltrsect +Normal Table;}}{\*\rsidtbl \rsid1983975\rsid2307793\rsid2756858\rsid5121612\rsid9338748\rsid9583613\rsid12019863\rsid14836557\rsid14959605}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440 +\mintLim0\mnaryLim1}{\info{\operator \'d1\'f2\'e0\'ed\'e8\'f1\'eb\'e0\'e2 \'cc\'e8\'f5\'e0\'eb\'ea\'ee\'e2\'e8\'f7}{\creatim\yr2018\mo8\dy29\hr21\min57}{\revtim\yr2020\mo9\dy5\hr20\min24}{\version9}{\edmins9}{\nofpages4}{\nofwords1386}{\nofchars7906} +{\nofcharsws9274}{\vern7}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1701\margr850\margt1134\margb1134\gutter0\ltrsect \widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701 -\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot9338748 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2 +\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale110\rsidroot9338748 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2 \pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6 \pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid14836557 \loch\af37\dbch\af31505\hich\f37 \'c4\'e0\'ed\'ed\'fb\'e9\loch\f37 \hich\f37 \'e4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\loch\f37 \hich\f37 \'ee\'ef\'e8\'f1\'fb\'e2\'e0\'e5\'f2\loch\f37 \hich\f37 \'f3\'f1\'eb\'ee\'e2\'e8\'ff \loch\f37 \hich\f37 \'f0\'e0\'f1\'ef\'f0\'ee\'f1\'f2\'f0\'e0\'ed\'e5\'ed\'e8\'ff\loch\f37 \hich\f37 \'ef\'f0\'ee\'e4\'f3\'ea\'f2\'e0\loch\f37 \hich\f37 PascalABC.NET (\'e2\'e5\'f0\'f1\'e8\'ff\loch\f37 3.}{\rtlch\fcs1 \af37 \ltrch\fcs0 -\f37\lang1033\langfe1049\langnp1033\insrsid2307793 \hich\af37\dbch\af31505\loch\f37 7}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 ). +\f37\insrsid2307793\charrsid14959605 \hich\af37\dbch\af31505\loch\f37 7}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid14959605 \hich\af37\dbch\af31505\loch\f37 .1}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 +\hich\af37\dbch\af31505\loch\f37 ). \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid14836557 \loch\af37\dbch\af31505\hich\f37 \'ca\'ee\'ef\'e8\'ff\loch\f37 \hich\f37 \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'e8\loch\f37 \hich\f37 GNU LGPL \'ef\'f0\'e8\'eb\'e0\'e3\'e0\'e5\'f2\'f1\'ff\loch\f37 \hich\f37 \'e2\loch\f37 \hich\f37 \'ea\'ee\'ed\'f6\'e5\loch\f37 \hich\f37 \'fd\'f2\'ee\'e3\'ee\loch\f37 \hich\f37 \'f4\'e0\'e9\'eb\'e0. \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 @@ -104,10 +105,10 @@ Normal Table;}}{\*\rsidtbl \rsid1983975\rsid2307793\rsid2756858\rsid5121612\rsid \par \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 Copyright (C) 2007 Free Software Foundation, Inc. <}{\field{\*\fldinst {\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 HYPERLINK "http://fsf.org/"}{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid9338748 {\*\datafield -00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b3800000068007400740070003a002f002f006600730066002e006f00720067002f000000795881f43b1d7f48af2c825dc485276300000000a5ab0003006500000c}}}{\fldrslt {\rtlch\fcs1 \af37 +00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b3800000068007400740070003a002f002f006600730066002e006f00720067002f000000795881f43b1d7f48af2c825dc485276300000000a5ab0003006500000c00}}}{\fldrslt {\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\ul\cf2\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 http://fsf.org/}}}\sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 > -\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 Everyone is permitted to copy and distribute verbatim copies}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 +\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 Ev\hich\af37\dbch\af31505\loch\f37 eryone is permitted to copy and distribute verbatim copies}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 of this license document, but changing it is not allowed.}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 @@ -117,7 +118,7 @@ Normal Table;}}{\*\rsidtbl \rsid1983975\rsid2307793\rsid2756858\rsid5121612\rsid \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 the terms and conditions of version 3 of the GNU General Public}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 -\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 License, supplemented by the additional permissions listed below.}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 +\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 Lic\hich\af37\dbch\af31505\loch\f37 ense, supplemented by the additional permissions listed below.}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 \par \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 0. Additional Definitions.}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 @@ -178,9 +179,9 @@ Normal Table;}}{\*\rsidtbl \rsid1983975\rsid2307793\rsid2756858\rsid5121612\rsid \par \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 2. Conveying Modified Versions.}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 \par -\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 If you modify a copy of the Library, and, in your mod\hich\af37\dbch\af31505\loch\f37 ifications, a}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 +\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 If you modify a copy of the Library, and, in your modifications, a}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 -\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 facility refers to a function or data to be supplied by an Application}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 +\par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 facility refers to a function o\hich\af37\dbch\af31505\loch\f37 r data to be supplied by an Application}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 \par }{\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\lang7\langfe1049\langnp7\insrsid14836557 \hich\af37\dbch\af31505\loch\f37 that uses the facility (other than as an argument passed when the}{\rtlch\fcs1 \af37\afs24 \ltrch\fcs0 \f37\fs24\lang1033\langfe1049\langnp1033\insrsid14836557 @@ -518,8 +519,8 @@ fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000e041 -e0ab0e7ad601feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000205e +2269a983d601feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/ReleaseGenerators/License.txt b/ReleaseGenerators/License.txt index 917643ba8..87690baad 100644 --- a/ReleaseGenerators/License.txt +++ b/ReleaseGenerators/License.txt @@ -1,4 +1,4 @@ -Данный документ описывает условия распространения продукта PascalABC.NET (версия 3.7). +Данный документ описывает условия распространения продукта PascalABC.NET (версия 3.7.1). Копия лицензии GNU LGPL прилагается в конце этого файла. ВАЖНЕЙШИЕ УСЛОВИЯ РАСПРОСТРАНЕНИЯ ПРОДУКТА PascalABC.NET или любого производного продукта diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 20aad5e2b..c94fa27bd 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.7.0.2671' +!define VERSION '3.7.1.2677' diff --git a/SyntaxVisitors/UniversalVisitors/ABCStatisticsVisitors.cs b/SyntaxVisitors/UniversalVisitors/ABCStatisticsVisitors.cs index 64ad58654..5e106efba 100644 --- a/SyntaxVisitors/UniversalVisitors/ABCStatisticsVisitors.cs +++ b/SyntaxVisitors/UniversalVisitors/ABCStatisticsVisitors.cs @@ -17,29 +17,125 @@ namespace SyntaxVisitors public int InBlockVarDefs { get; set; } public int OutBlockVarDefs { get; set; } public int ForsWithoutVar { get; set; } + public int ForsWithVar { get; set; } public bool ProgramKeyword { get; set; } - public bool OldStrings { get; set; } - public bool StaticArrays { get; set; } - public bool ReadProc { get; set; } - public bool WriteProcWithSpace { get; set; } + public int OldStrings { get; set; } + public int StaticArrays { get; set; } + public int DynamicArrays { get; set; } + public int ReadProc { get; set; } + public int WriteProcWithSpace { get; set; } + public int TuplesCount { get; set; } + public int InitVarInDef { get; set; } + public int UnpackingAssign { get; set; } + public int LoopsCount { get; set; } + public int ForeachCount { get; set; } + public int LambdasCount { get; set; } + public int ExtAssignCount { get; set; } + public int BigIntegerTypeCount { get; set; } + public int ReadFuncCount { get; set; } + public int PrintCount { get; set; } + public ABCStatisticsVisitor() { } + public override void visit(ident id) + { + var name = id.name.ToLower(); + if (name.StartsWith("readinteger") || name.StartsWith("readreal") || name.StartsWith("readstring") || + name.StartsWith("readlninteger") || name.StartsWith("readlnreal") || name.StartsWith("readlnstring")) + ReadFuncCount++; + if (name.StartsWith("print")) + PrintCount++; + } + + public override void visit(named_type_reference ntr) + { + var name = ntr.names[0].name.ToLower(); + if (name == "biginteger") + BigIntegerTypeCount++; + base.visit(ntr); + } + public override void visit(assign an) + { + if (an.operator_type == Operators.AssignmentAddition || an.operator_type == Operators.AssignmentMultiplication || an.operator_type == Operators.AssignmentDivision) + ExtAssignCount++; + base.visit(an); + } + public override void visit(function_lambda_definition fld) + { + LambdasCount++; + base.visit(fld); + } + public override void visit(loop_stmt ln) + { + LoopsCount++; + base.visit(ln); + } + public override void visit(foreach_stmt fn) + { + ForeachCount++; + base.visit(fn); + } + public override void visit(tuple_node tn) + { + TuplesCount++; + base.visit(tn); + } + public override void visit(assign_var_tuple at) + { + UnpackingAssign++; + base.visit(at); + } + public override void visit(assign_tuple at) + { + UnpackingAssign++; + base.visit(at); + } + + public override void visit(for_node fn) + { + if (fn.create_loop_variable == false) + ForsWithoutVar++; + if (fn.create_loop_variable == true) + ForsWithVar++; + base.visit(fn); + } + public override void visit(var_def_statement vds) { if (vds.Parent is var_statement) - InBlockVarDefs += 1; - else OutBlockVarDefs += 1; + { + InBlockVarDefs += vds.vars.Count; + } + else + { + OutBlockVarDefs += vds.vars.Count; + } if (vds.vars_type != null && vds.vars_type is string_num_definition) { - OldStrings = true; + OldStrings += 1; } if (vds.vars_type != null && vds.vars_type is array_type at && at.indexers != null && at.indexers.Count > 0 && at.indexers.indexers[0] != null) { - StaticArrays = true; + StaticArrays += 1; } + if (vds.vars_type != null && vds.vars_type is array_type at1 && at1.indexers == null) + { + DynamicArrays += 1; + } + if (vds.inital_value != null) + InitVarInDef++; + /*if (vds.inital_value != null) + { + if (vds.inital_value is ident id && + (id.name.ToLower().StartsWith("readinteger") || id.name.ToLower().StartsWith("readreal") || id.name.ToLower().StartsWith("readstring") || + id.name.ToLower().StartsWith("readlninteger") || id.name.ToLower().StartsWith("readlnreal") || id.name.ToLower().StartsWith("readlnstring"))) + ReadFuncCount++; + }*/ + + base.visit(vds); } public override void visit(program_name pn) @@ -50,7 +146,7 @@ namespace SyntaxVisitors public override void visit(method_call mc) { - if (mc.dereferencing_value is ident id && (id.name.ToLower() == "read" || id.name.ToLower() == "readln")) + /*if (mc.dereferencing_value is ident id && (id.name.ToLower() == "read" || id.name.ToLower() == "readln")) { syntax_tree_node n = mc; do @@ -58,15 +154,25 @@ namespace SyntaxVisitors n = n.Parent; } while (n != null && !(n is class_members)); if (n != null) - ReadProc = false; + ; + //ReadProc = false; else - ReadProc = true; - } + ReadProc += 1; + }*/ + /*if (mc.dereferencing_value is ident id2) + { + var name = id2.name.ToLower(); + var h = new HashSet { "readinteger", "readlninteger", "readreal", "readlnreal", "readstring", "readlnstring", "readchar", "readlnchar" }; + if (h.Contains(name)) + ReadFuncCount++; + }*/ + if (mc.dereferencing_value is ident id1 && (id1.name.ToLower() == "write" || id1.name.ToLower() == "writeln") && mc.parameters != null && mc.parameters.expressions.Any(ex => ex is char_const cc && cc.cconst == ' ')) { - WriteProcWithSpace = true; + WriteProcWithSpace += 1; } + base.visit(mc); } public override void visit(procedure_call pc) { @@ -78,15 +184,17 @@ namespace SyntaxVisitors n = n.Parent; } while (n != null && !(n is class_members)); if (n != null) - ReadProc = false; + //ReadProc = false + ; else - ReadProc = true; + ReadProc += 1; } if (pc.func_name is method_call mc1 && mc1.dereferencing_value is ident id1 && (id1.name.ToLower() == "write" || id1.name.ToLower() == "writeln") && mc1.parameters != null && mc1.parameters.expressions.Any(ex => ex is char_const cc && cc.cconst == ' ')) { - WriteProcWithSpace = true; + WriteProcWithSpace += 1; } + base.visit(pc); } /*public override void visit(dot_node dn) diff --git a/TestSuite/CompilationSamples/School.pas b/TestSuite/CompilationSamples/School.pas index 469d4fed6..11696eaa7 100644 --- a/TestSuite/CompilationSamples/School.pas +++ b/TestSuite/CompilationSamples/School.pas @@ -80,24 +80,29 @@ function SeqRandomReal(n: integer; a, b: real; t: integer): sequence of real; /// на интервале [a; b) с t знаками в дробной части function MatrRandomReal(m: integer; n: integer; a, b: real; t: integer): array [,] of real; -/// Возвращает логическое значение операции импликации a -> b -function Imp(a, b: boolean) : boolean; +/// Возвращает таблицу истинности для двух переменных +function TrueTable(f: function(a, b: boolean): boolean): + array[,] of boolean; -/// Выводит на монитор таблицу истинности для двух переменных -procedure TrueTable(f: function(a, b: boolean): boolean; - vars: string := 'x1.x2'); - -/// Выводит на монитор таблицу истинности для трех переменных -procedure TrueTable(f: function(a, b, c: boolean): boolean; - vars: string := 'x1.x2.x3'); +/// Возвращает таблицу истинности для трех переменных +function TrueTable(f: function(a, b, c: boolean): boolean): + array[,] of boolean; -/// Выводит на монитор таблицу истинности для четырех переменных -procedure TrueTable(f: function(a, b, c, d: boolean): boolean; - vars: string := 'x1.x2.x3.x4'); +/// Возвращает таблицу истинности для четырех переменных +function TrueTable(f: function(a, b, c, d: boolean): boolean): + array[,] of boolean; -/// Выводит на монитор таблицу истинности для пяти переменных -procedure TrueTable(f: function(a, b, c, d, e: boolean): boolean; - vars: string := 'x1.x2.x3.x4.x5'); +/// Возвращает таблицу истинности для пяти переменных +function TrueTable(f: function(a, b, c, d, e: boolean): boolean): + array[,] of boolean; + +/// Выводит на монитор таблицу истинности +/// f = 0 - только для значения функции False +/// f = 1 - только для значения функции True +procedure TrueTablePrint(a: array[,] of boolean; f: integer := -1); + +/// Заменяет последнее вхождение подстроки в строку +procedure ReplaceLast(var Строка: string; ЧтоЗаменить, ЧемЗаменить: string); implementation @@ -219,6 +224,21 @@ begin end end; +/// Перевод десятичного числа в систему счисления по основанию base (2..32) +function ToBase(Self: string; base: integer): string; extensionmethod; +begin + var n: BigInteger; + if not BigInteger.TryParse(Self, n) then exit; + var s := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + Result := ''; + while n > 0 do + begin + Result := s[integer(n mod base) + 1] + Result; + n := n div base + end; + if Result = '' then Result := '0' +end; + {$endregion} {$region MinMax} @@ -232,7 +252,7 @@ begin min := m else if m > max then max := m; - Result := (min, max) + Result := (min, max) end; /// Возвращает кортеж из минимума и максимума последовательности s @@ -244,16 +264,17 @@ begin min := m else if m > max then max := m; - Result := (min, max) + Result := (min, max) end; /// Возвращает кортеж из минимума и максимума последовательности function MinMax(Self: sequence of int64): (int64, int64); extensionmethod := - MinMax(Self); - +MinMax(Self); + /// Возвращает кортеж из минимума и максимума последовательности function MinMax(Self: sequence of integer): (integer, integer); - extensionmethod := MinMax(Self); + extensionmethod := +MinMax(Self); {$endregion} @@ -336,11 +357,11 @@ end; /// разложение числа на простые множители function Factorize(Self: int64): List; extensionmethod := - Factorize(Self); - +Factorize(Self); + /// Разложение числа на простые множители function Factorize(Self: integer): List; extensionmethod := - Factorize(Self); +Factorize(Self); {$endregion} @@ -349,21 +370,21 @@ function Factorize(Self: integer): List; extensionmethod := /// Простые числа на интервале [2;n] function Primes(n: integer): List; // Модифицированное решето Эратосфена на [2;n] -begin +begin var Mas := ArrFill(n, True); var i := 2; while i * i <= n do - begin - if Mas[i-1] then - begin - var k := i*i; + begin + if Mas[i - 1] then + begin + var k := i * i; while k <= n do - begin - Mas[k-1] := False; + begin + Mas[k - 1] := False; k += i end end; - Inc(i) + Inc(i) end; n := Mas.Count(t -> t); Result := new List; @@ -375,21 +396,21 @@ end; function FirstPrimes(n: integer): List; // Модифицированное решето Эратосфена begin - var n1 := Trunc(Exp((Ln(n)+1.088)/0.8832)); + var n1 := Trunc(Exp((Ln(n) + 1.088) / 0.8832)); var Mas := ArrFill(n1, True); var i := 2; while i * i <= n1 do - begin - if Mas[i-1] then - begin - var k := i*i; + begin + if Mas[i - 1] then + begin + var k := i * i; while k <= n1 do - begin - Mas[k-1] := False; + begin + Mas[k - 1] := False; k += i end end; - Inc(i) + Inc(i) end; //n := Mas.Count(t -> t); Result := new List; @@ -466,12 +487,14 @@ end; /// Возвращает список, содержащий цифры числа function Digits(Self: integer): List; - extensionmethod := Digits(Self); + extensionmethod := +Digits(Self); /// возвращает список, содержащий цифры числа function Digits(Self: int64): List; - extensionmethod := Digits(Self); - + extensionmethod := +Digits(Self); + {$endregion} {$region Divisors} @@ -484,7 +507,7 @@ begin L.Add(1); L.Add(n); if n > 3 then - begin + begin var k := 2; while (k * k <= n) and (k < 46341) do begin @@ -510,7 +533,7 @@ begin L.Add(1); L.Add(n); if n > 3 then - begin + begin var k := int64(2); while (k * k <= n) and (k < 3037000500) do begin @@ -530,11 +553,11 @@ end; /// возвращает список делителей натурального числа function Divizors(Self: integer): List; extensionmethod := - Divizors(Self); - +Divizors(Self); + /// возвращает список делителей натурального числа function Divizors(Self: int64): List; extensionmethod := - Divizors(Self); +Divizors(Self); {$endregion} @@ -545,7 +568,7 @@ function SinDegrees(x: real): real := Sin(DegToRad(x)); function CosDegrees(x: real): real := Cos(DegToRad(x)); function TanDegrees(x: real): real := Tan(DegToRad(x)); - + {$endregion} {$region Random} @@ -581,79 +604,121 @@ end; {$region BooleanLogic} -function BoolToStr(Self: boolean): string; extensionmethod := - if Self then '1' else '0'; - /// Возвращает логическое значение операции импликации a -> b -function Imp(a, b: boolean) : boolean := not a or b; +function Imp(Self, b: boolean): boolean; extensionmethod := not Self or b; -/// Выводит на монитор таблицу истинности для двух переменных -procedure TrueTable(f: function(a, b: boolean): boolean; - vars: string); +/// Возвращает таблицу истинности для двух переменных +function TrueTable(f: function(a, b: boolean): boolean): + array[,] of boolean; begin - var names := vars.ToWords('.'); - var lengths := names.Select(Имя -> Имя.Length + 1).ToArray; - Write(' '); - names.Print; - Writeln(' F'); + Result := new boolean[4, 3]; + var i := 0; for var a := False to True do for var b := False to True do - Writeln(a.BoolToStr:lengths[0], b.BoolToStr:lengths[1], - f(a, b).BoolToStr:2) + begin + Result[i, 0] := a; + Result[i, 1] := b; + Result[i, 2] := f(a, b); + i += 1 + end; end; - -/// Выводит на монитор таблицу истинности для трех переменных -procedure TrueTable(f: function(a, b, c: boolean): boolean; - vars: string); + +/// Возвращает таблицу истинности для трех переменных +function TrueTable(f: function(a, b, c: boolean): boolean): + array[,] of boolean; begin - var names := vars.ToWords('.'); - var lengths := names.Select(Имя -> Имя.Length + 1).ToArray; - Write(' '); - names.Print; - Writeln(' F'); + Result := new boolean[8, 4]; + var i := 0; for var a := False to True do for var b := False to True do for var c := False to True do - Writeln(a.BoolToStr:lengths[0], b.BoolToStr:lengths[1], - c.BoolToStr:lengths[2], f(a, b, c).BoolToStr:2) + begin + Result[i, 0] := a; + Result[i, 1] := b; + Result[i, 2] := c; + Result[i, 3] := f(a, b, c); + i += 1 + end; end; -/// Выводит на монитор таблицу истинности для четырех переменных -procedure TrueTable(f: function(a, b, c, d: boolean): boolean; - vars: string); +/// Возвращает таблицу истинности для четырех переменных +function TrueTable(f: function(a, b, c, d: boolean): boolean): + array[,] of boolean; begin - var names := vars.ToWords('.'); - var lengths := names.Select(Имя -> Имя.Length + 1).ToArray; - Write(' '); - names.Print; - Writeln(' F'); + Result := new boolean[16, 5]; + var i := 0; for var a := False to True do for var b := False to True do for var c := False to True do for var d := False to True do - Writeln(a.BoolToStr:lengths[0], b.BoolToStr:lengths[1], - c.BoolToStr:lengths[2], d.BoolToStr:lengths[3], - f(a, b, c, d).BoolToStr:2) + begin + Result[i, 0] := a; + Result[i, 1] := b; + Result[i, 2] := c; + Result[i, 3] := d; + Result[i, 4] := f(a, b, c, d); + i += 1 + end; end; -/// Выводит на монитор таблицу истинности для пяти переменных -procedure TrueTable(f: function(a, b, c, d, e: boolean): boolean; - vars: string); +/// Возвращает таблицу истинности для пяти переменных +function TrueTable(f: function(a, b, c, d, e: boolean): boolean): + array[,] of boolean; begin - var names := vars.ToWords('.'); - var lengths := names.Select(Имя -> Имя.Length + 1).ToArray; - Write(' '); - names.Print; - Writeln(' F'); + Result := new boolean[32, 6]; + var i := 0; for var a := False to True do for var b := False to True do for var c := False to True do for var d := False to True do for var e := False to True do - Writeln(a.BoolToStr:lengths[0], b.BoolToStr:lengths[1], - c.BoolToStr:lengths[2], d.BoolToStr:lengths[3], - e.BoolToStr:lengths[4], f(a, b, c, d, e).BoolToStr:2) -end; + begin + Result[i, 0] := a; + Result[i, 1] := b; + Result[i, 2] := c; + Result[i, 3] := d; + Result[i, 4] := d; + Result[i, 5] := f(a, b, c, d, e); + i += 1 + end; +end; + +/// Выводит на монитор таблицу истинности +/// f = 0 - только для значения функции False +/// f = 1 - только для значения функции True +procedure TrueTablePrint(a: array[,] of boolean; f: integer); +begin + var (n, c) := (a.ColCount, 'a'); + for var i := 0 to n - 2 do + begin + Write(' ' + c); + Inc(c) + end; + Writeln(' F'); + Writeln(' ' + (2 * n - 1) * '-'); + for var i := 0 to a.RowCount - 1 do + if not (((f = 0) and a[i, n - 1]) or ((f = 1) and not a[i, n - 1])) then + begin + for var j := 0 to n - 1 do + Write(if a[i, j] then ' 1' else ' 0'); + Writeln + end +end; + +{$endregion} + +{$region String} + +/// Заменяет последнее вхождение подстроки в строку +procedure ReplaceLast(var Строка: string; ЧтоЗаменить, ЧемЗаменить: string); +begin + var Позиция := LastPos(ЧтоЗаменить, Строка); + if Позиция > 0 then + begin + Delete(Строка, Позиция, ЧтоЗаменить.Length); + Insert(ЧемЗаменить, Строка, Позиция) + end +end; {$endregion} diff --git a/VisualPascalABCNET/ABCHealth.Designer.cs b/VisualPascalABCNET/ABCHealth.Designer.cs new file mode 100644 index 000000000..3cfc7511f --- /dev/null +++ b/VisualPascalABCNET/ABCHealth.Designer.cs @@ -0,0 +1,48 @@ +namespace VisualPascalABC +{ + partial class ABCHealth + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ABCHealth)); + this.SuspendLayout(); + // + // ABCHealth + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(474, 331); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "ABCHealth"; + this.Text = "Здоровье PascalABC.NET программы"; + this.ResumeLayout(false); + + } + + #endregion + } +} \ No newline at end of file diff --git a/VisualPascalABCNET/ABCHealth.cs b/VisualPascalABCNET/ABCHealth.cs new file mode 100644 index 000000000..a6a8442e8 --- /dev/null +++ b/VisualPascalABCNET/ABCHealth.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace VisualPascalABC +{ + public partial class ABCHealth : Form + { + public ABCHealth() + { + InitializeComponent(); + this.Font = new Font(this.Font.FontFamily, 10); + this.Activated += OnActivated; + //this.Paint += OnPaint; + } + + private int i = 0; + private void OnActivated(object sender, EventArgs e) + { + } + } +} diff --git a/VisualPascalABCNET/ABCHealth.ico b/VisualPascalABCNET/ABCHealth.ico new file mode 100644 index 000000000..2d2e71bda Binary files /dev/null and b/VisualPascalABCNET/ABCHealth.ico differ diff --git a/VisualPascalABCNET/ABCHealth.resx b/VisualPascalABCNET/ABCHealth.resx new file mode 100644 index 000000000..42c814ccb --- /dev/null +++ b/VisualPascalABCNET/ABCHealth.resx @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA + AAD///////////////////////////////////////////////////////////////////////////// + //////////////////+tkYH/jHVj/4dvXP+CaVb/fWRR/3hfTP90Wkf/b1VC/2xRPf9oTTn/ZUs2/2VL + Nv9jSDP/////////////////sJWF///////////////////////////////////////+/v3//v39//79 + /f/+/f3/ZUs1/////////////////7OYif/+/v7//v7+/5NHI/+TRyP/k0cj//7+/v/+/v7/AAD///7+ + /v/+/v7//v7+/2lOOf////////////////+2nI3//v7+/5NHI//+/v7//v7+//7+/v/+/v7//v7+/wAA + ///+/v7//v7+//7+/v9sUT3/////////////////uaCS//7+/v+TRyP//v7+//7+/v/+/v7/AAD//wAA + //8AAP//AAD//wAA///+/v7/b1ZB/////////////////7yklv/+/v7/k0cj//7+/v/+/v7//v7+//7+ + /v/+/v7/AAD///7+/v/+/v7//v7+/3RaRv/////////////////Ap5v//v7+//7+/v+TRyP/k0cj/5NH + I//+/v7//v7+/wAA///+/v7//v7+//7+/v94X0z/////////////////wque//7+/v/+/v7//vv7//76 + +f/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/f3/fWRQ/////////////////8Wuo//+/v7/k0cj//7+ + /v/+/v7/k0cj//7+/v+TRyP/k0cj/5NHI//+/v7//v39/4JpV//////////////////Is6j//////5NH + I//9/f3//f39/5NHI//+/v7/k0cj//7+/v/+/v7/k0cj//79/f+Hblz/////////////////y7at//// + //+TRyP/k0cj/5NHI/+TRyP//v7+/5NHI/+TRyP/k0cj//7+/v/+/f3/jXRi/////////////////867 + sf//////k0cj////////////k0cj//7+/v+TRyP//v7+//7+/v+TRyP//v39/5J6af////////////// + ///SwLb///////////+TRyP/k0cj//7+/v/+/v7/k0cj/5NHI/+TRyP//v39//79/f+XgG////////// + ////////1cS8///////////////////////////////////////+/v3//v39//79/f/+/f3/nYZ1//// + /////////////9jJwf/VxLz/0sC2/8+8sv/MuK3/ybSo/8awpP/DrKD/wKmc/76mmf+7opT/u6KU/7if + kP//////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAA== + + + \ No newline at end of file diff --git a/VisualPascalABCNET/Form1.Designer.cs b/VisualPascalABCNET/Form1.Designer.cs index d07b76485..f301e396c 100644 --- a/VisualPascalABCNET/Form1.Designer.cs +++ b/VisualPascalABCNET/Form1.Designer.cs @@ -53,6 +53,7 @@ namespace VisualPascalABC this.tssRunStopSeparator = new System.Windows.Forms.ToolStripSeparator(); this.tsOutputWindow = new System.Windows.Forms.ToolStripButton(); this.tsAutoInsertCode = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator(); this.tsFormat = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); @@ -298,6 +299,7 @@ namespace VisualPascalABC this.tssRunStopSeparator, this.tsOutputWindow, this.tsAutoInsertCode, + this.toolStripButton1, this.toolStripSeparator13, this.tsFormat, this.toolStripSeparator4, @@ -535,6 +537,16 @@ namespace VisualPascalABC this.tsAutoInsertCode.ToolTipText = "M_AUTOINSERT_CODE"; this.tsAutoInsertCode.Click += new System.EventHandler(this.tsAutoInsertCode_Click); // + // toolStripButton1 + // + this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButton1.Image = global::VisualPascalABC.Properties.Resources.ABCHealth; + this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton1.Name = "toolStripButton1"; + this.toolStripButton1.Size = new System.Drawing.Size(23, 22); + this.toolStripButton1.Text = "Здоровье PascalABC.NET программы"; + this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click); + // // toolStripSeparator13 // this.toolStripSeparator13.Name = "toolStripSeparator13"; @@ -1391,7 +1403,7 @@ namespace VisualPascalABC // miShowGrid // this.miShowGrid.Name = "miShowGrid"; - this.miShowGrid.Size = new System.Drawing.Size(180, 22); + this.miShowGrid.Size = new System.Drawing.Size(165, 22); this.miShowGrid.Text = "M_SHOW_GRID"; this.miShowGrid.Visible = false; this.miShowGrid.Click += new System.EventHandler(this.miShowGrid_Click); @@ -1399,7 +1411,7 @@ namespace VisualPascalABC // miSnapToGrid // this.miSnapToGrid.Name = "miSnapToGrid"; - this.miSnapToGrid.Size = new System.Drawing.Size(180, 22); + this.miSnapToGrid.Size = new System.Drawing.Size(165, 22); this.miSnapToGrid.Text = "M_SNAP_TO_GRID"; this.miSnapToGrid.Visible = false; this.miSnapToGrid.Click += new System.EventHandler(this.miSnapToGrid_Click); @@ -1415,7 +1427,7 @@ namespace VisualPascalABC this.miAlignCenters, this.miAlignToGrid}); this.miAlign.Name = "miAlign"; - this.miAlign.Size = new System.Drawing.Size(180, 22); + this.miAlign.Size = new System.Drawing.Size(165, 22); this.miAlign.Text = "M_ALIGN"; // // miAlignLefts @@ -1473,7 +1485,7 @@ namespace VisualPascalABC this.miCenterHorizontally, this.miCenterVertically}); this.miCenter.Name = "miCenter"; - this.miCenter.Size = new System.Drawing.Size(180, 22); + this.miCenter.Size = new System.Drawing.Size(165, 22); this.miCenter.Text = "M_CENTER"; // // miCenterHorizontally @@ -1498,7 +1510,7 @@ namespace VisualPascalABC this.miSizeToControlHeight, this.miSizeToGrid}); this.miSizeTo.Name = "miSizeTo"; - this.miSizeTo.Size = new System.Drawing.Size(180, 22); + this.miSizeTo.Size = new System.Drawing.Size(165, 22); this.miSizeTo.Text = "M_SIZE_TO"; // // miSizeToControl @@ -1535,7 +1547,7 @@ namespace VisualPascalABC this.miBringToFront, this.miSendToBack}); this.miZOrder.Name = "miZOrder"; - this.miZOrder.Size = new System.Drawing.Size(180, 22); + this.miZOrder.Size = new System.Drawing.Size(165, 22); this.miZOrder.Text = "M_Z_ORDER"; // // miBringToFront @@ -1555,7 +1567,7 @@ namespace VisualPascalABC // miTabOrder // this.miTabOrder.Name = "miTabOrder"; - this.miTabOrder.Size = new System.Drawing.Size(180, 22); + this.miTabOrder.Size = new System.Drawing.Size(165, 22); this.miTabOrder.Text = "M_TAB_ORDER"; this.miTabOrder.Click += new System.EventHandler(this.miTabOrder_Click); // @@ -2615,6 +2627,7 @@ namespace VisualPascalABC private System.Windows.Forms.ToolStripButton tsAutoInsertCode; private System.Windows.Forms.ToolStripMenuItem mAUTOINSERTToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem mUNITTESTSToolStripMenuItem; + private System.Windows.Forms.ToolStripButton toolStripButton1; } } diff --git a/VisualPascalABCNET/Form1.cs b/VisualPascalABCNET/Form1.cs index fd55cba34..1d54ada13 100644 --- a/VisualPascalABCNET/Form1.cs +++ b/VisualPascalABCNET/Form1.cs @@ -1570,6 +1570,383 @@ namespace VisualPascalABC } } + public ABCHealth ABCHealthForm = null; + + private Label AddString(double x, double y, string s, bool link = false, bool goodfeatures = false) + { + Label l; + if (link) + l = new LinkLabel(); + else l = new Label(); + l.Text = s; + l.Left = (int)Math.Round(x); + l.Top = (int)Math.Round(y); + //if (link) + if (!goodfeatures) + l.ForeColor = System.Drawing.Color.Red; + else l.ForeColor = System.Drawing.Color.Green; + l.AutoSize = true; + ABCHealthForm.Controls.Add(l); + return l; + } + + private string Raz(int n) + { + if ((n % 10 == 2 || n % 10 == 3 || n % 10 == 4) && (n / 10 % 10 != 1)) + return n + " раза"; + else return n + " раз"; + } + private void toolStripButton1_Click(object sender, EventArgs e) + { + if (ABCHealthForm == null) + { + ABCHealthForm = new ABCHealth(); + ABCHealthForm.FormBorderStyle = FormBorderStyle.Fixed3D; + } + try + { + var gr = Graphics.FromHwnd(Handle); + var scale = gr.DpiX / 96; + + var aw = ABCHealthForm.Width; + var ah = ABCHealthForm.Height; + var c = new PascalABCCompiler.Compiler(); + c.Reload(); + var errors = new List(); + var warnings = new List(); + + var text = CurrentSyntaxEditor.TextEditor.ActiveTextAreaControl.TextArea.Document.TextContent; + + WorkbenchServiceFactory.Workbench.ErrorsListWindow.ClearErrorList(); + var res = c.ParseText(CurrentSourceFileName, text, errors, warnings); + WorkbenchServiceFactory.Workbench.ErrorsListWindow.ShowErrorsSync(c.ErrorsList, c.ErrorsList.Count != 0); + if (res != null) + { + var y = 30/2*scale; + var stat = new SyntaxVisitors.ABCStatisticsVisitor(); + stat.ProcessNode(res); + //stat. + var h = 40 / 2 * scale; + var x = 50 / 2 * scale; + ABCHealthForm.Controls.Clear(); + + var pp = new Panel(); + + ToolTip ToolTip1 = new ToolTip(); + ToolTip1.SetToolTip(pp, "Здоровье PascalABC.NET программы"); + + pp.Width = (int)Math.Round(220 / 2 * scale); + pp.Height = (int)Math.Round(100 / 2 * scale); + pp.Left = ABCHealthForm.ClientSize.Width - pp.Width - (int)Math.Round(24 / 2 * scale); + pp.Top = (int)Math.Round(24 / 2 * scale); + pp.BackColor = Color.Gray; + + ABCHealthForm.Controls.Add(pp); + + + var l0 = AddString(x, y, "О здоровье кода",true) as LinkLabel; + l0.LinkClicked += (o, e1) => + { + System.Diagnostics.Process.Start("https://pascalabcnet.github.io/program_health.html"); + }; + y += 48 / 2 * scale; + + var l1 = AddString(x, y, "В программе найдены следующие конструкции базового Паскаля,"); + y += 36 / 2 * scale; + var l2 = AddString(x, y, "считающиеся устаревшими в PascalABC.NET:"); + l1.ForeColor = Color.Black; + l2.ForeColor = Color.Black; + y += h; + y += 8 / 2 * scale; + x += 24 / 2 * scale; + + // Проценты в минус + // 1. Количество var вне - количество var внутри. За первую - -10%, за остальные - -2% пока не достигнет 25% + // 2. Количество for i - за первую - -15%, за каждую следующую - -3% пока не достигнет 25% + // 3. Read(i,j) - за первую -15%, за последующие - -2% пока не достигнет -20% + // 4. program - -10% + // 5. Статические массивы - -10%, за каждый последующий - -2% пока не достигнет -15% + // 6. Write(a,' ',b) - за каждую - -1% пока не достгнет -5% + // 7. string[10] - за каждую - -1% . Если минусуется > 100%, то здоровье делать 0% + + var Percent = 100; + var NegativePercent = 0; + + var ShowNegativeInfo = false; + if (stat.OutBlockVarDefs > 0 && stat.OutBlockVarDefs > stat.InBlockVarDefs) + { + AddString(x, y, "Переменные описаны вне блоков begin-end: " + Raz(stat.OutBlockVarDefs), false); + y += h; + ShowNegativeInfo = true; + } + if (stat.ForsWithoutVar != 0) + { + AddString(x, y, "Переменная цикла for не описана в заголовке цикла: " + Raz(stat.ForsWithoutVar), false); + y += h; + ShowNegativeInfo = true; + } + if (stat.ReadProc > 0) + { + AddString(x, y, "Для ввода использована процедура Read: " + Raz(stat.ReadProc), false); + y += h; + ShowNegativeInfo = true; + } + if (stat.ProgramKeyword) + { + AddString(x, y, "Использовано ключевое слово program", false); + y += h; + ShowNegativeInfo = true; + } + if (stat.WriteProcWithSpace > 0) + { + AddString(x, y, "Использована процедура Write с пробелом в качестве разделителя: " + Raz(stat.WriteProcWithSpace), false); + y += h; + ShowNegativeInfo = true; + } + if (stat.StaticArrays > 0) + { + AddString(x, y, "Используются статические массивы вместо динамических: " + Raz(stat.StaticArrays), false); + y += h; + ShowNegativeInfo = true; + } + if (stat.OldStrings > 0) + { + AddString(x, y, "Используются устаревшие строки вида string[10]: " + Raz(stat.OldStrings), false); + y += h; + ShowNegativeInfo = true; + } + + ///---------------------------------------------------- + y += 12 / 2 * scale; + x -= 24 / 2 * scale; + var l3 = AddString(x, y, "В программе используются следующие рекомендованные конструкции"); + y += 36 / 2 * scale; + var l4 = AddString(x, y, "PascalABC.NET:"); + l3.ForeColor = Color.Black; + l4.ForeColor = Color.Black; + x += 24 / 2 * scale; + y += h; + y += 8 / 2 * scale; + if (stat.InBlockVarDefs > 0) + { + AddString(x, y, "Используются внутриблочные описания переменных: " + Raz(stat.InBlockVarDefs), false, true); + y += h; + } + if (stat.ForsWithVar != 0) + { + AddString(x, y, "Переменная цикла for описана в заголовке цикла: " + Raz(stat.ForsWithVar), false, true); + y += h; + } + if (stat.InitVarInDef > 0) + { + AddString(x, y, "Используется инициализация при описании: " + Raz(stat.InitVarInDef), false, true); + y += h; + } + if (stat.ReadFuncCount > 0) + { + AddString(x, y, "Для ввода используется функция вида ReadInteger, ReadReal: " + Raz(stat.ReadFuncCount), false, true); + y += h; + } + if (stat.ExtAssignCount > 0) + { + AddString(x, y, "Используется расширенное присваивание: " + Raz(stat.ExtAssignCount), false, true); + y += h; + } + if (stat.PrintCount > 0) + { + AddString(x, y, "Для вывода использована Print: " + Raz(stat.PrintCount), false, true); + y += h; + } + if (stat.TuplesCount > 0) + { + AddString(x, y, "Используются кортежи: " + Raz(stat.TuplesCount), false, true); + y += h; + } + if (stat.DynamicArrays > 0) + { + AddString(x, y, "Используются динамические массивы: " + Raz(stat.DynamicArrays), false, true); + y += h; + } + if (stat.UnpackingAssign > 0) + { + AddString(x, y, "Используется распаковка значения в переменные: " + Raz(stat.UnpackingAssign), false, true); + y += h; + } + if (stat.LoopsCount > 0) + { + AddString(x, y, "Используется цикл loop: " + Raz(stat.LoopsCount), false, true); + y += h; + } + if (stat.ForeachCount > 0) + { + AddString(x, y, "Используется цикл foreach: " + Raz(stat.ForeachCount), false, true); + y += h; + } + if (stat.LambdasCount > 0) + { + AddString(x, y, "Используются лямбда-выражения: " + Raz(stat.LambdasCount), false, true); + y += h; + } + + // Процент здоровья + // VarDefs + var diffBlockVarDefs = stat.OutBlockVarDefs; // - stat.InBlockVarDefs; + if (diffBlockVarDefs > 0) + { + NegativePercent += 10; // за первую + NegativePercent += (diffBlockVarDefs - 1) * 2; // за оставшиеся + if (NegativePercent > 25) + NegativePercent = 25; + } + // For i + if (stat.ForsWithoutVar > 0) + { + NegativePercent += Math.Min(15 + (stat.ForsWithoutVar - 1) * 3, 25); + } + if (stat.ReadProc > 0) + { + NegativePercent += Math.Min(15 + (stat.ReadProc - 1) * 2, 20); + } + if (stat.ProgramKeyword) + { + NegativePercent += 10; + } + if (stat.StaticArrays > 0) + { + NegativePercent += Math.Min(10 + (stat.StaticArrays - 1) * 2, 15); + } + if (stat.WriteProcWithSpace > 0) + { + NegativePercent += Math.Min(2 + (stat.StaticArrays - 1) * 1, 5); + } + if (stat.OldStrings > 0) + { + NegativePercent += stat.OldStrings; + } + if (NegativePercent < 0) + NegativePercent = 0; + + Percent -= NegativePercent; + + var PositivePercent = 0; + + // Проценты за положительное + if (stat.InBlockVarDefs > 0) + { + PositivePercent += 10; // за первую + PositivePercent += (stat.InBlockVarDefs - 1) * 2; // за оставшиеся + // этот алгоритм уравновешивает описания внутри и вне. За одинаковое количество дается 0 баллов + } + if (stat.ForsWithVar != 0) + { + PositivePercent += stat.ForsWithVar * 3; + } + if (stat.InitVarInDef > 0) + { + PositivePercent += stat.InitVarInDef * 4; + } + if (stat.ReadFuncCount > 0) + { + PositivePercent += stat.ReadFuncCount * 3; + } + if (stat.ExtAssignCount > 0) + { + PositivePercent += stat.ExtAssignCount * 3; + } + if (stat.PrintCount > 0) + { + PositivePercent += stat.PrintCount * 4; + } + if (stat.TuplesCount > 0) + { + PositivePercent += stat.PrintCount * 5; + } + if (stat.DynamicArrays > 0) + { + PositivePercent += stat.PrintCount * 5; + } + if (stat.UnpackingAssign > 0) + { + PositivePercent += stat.UnpackingAssign * 5; + } + if (stat.LoopsCount > 0) + { + PositivePercent += stat.LoopsCount * 4; + } + if (stat.ForeachCount > 0) + { + PositivePercent += stat.ForeachCount * 4; + } + if (stat.LambdasCount > 0) + { + PositivePercent += stat.LambdasCount * 8; + } + + Percent += PositivePercent; + if (Percent > 200) + Percent = 200; + + if (!ShowNegativeInfo) + { + l1.Text = "В программе отсутствуют устаревшие в PascalABC.NET конструкции"; + l2.Text = ""; + } + if (PositivePercent == 0) + { + l3.Text = "В программе отсутствуют рекомендованные в PascalABC.NET конструкции"; + l4.Text = ""; + } + + // Цвет панели + if (Percent < 25) + pp.BackColor = Color.FromArgb(255, 0, 0); + else if (Percent < 50) + pp.BackColor = Color.FromArgb(255, 64, 64); + else if (Percent < 75) + pp.BackColor = Color.FromArgb(128, 128, 128); + else if (Percent < 100) + pp.BackColor = Color.FromArgb(64+16, 128, 64 + 16); + else pp.BackColor = Color.FromArgb(0, 128, 0); + + pp.Paint += (o, ea) => + { + Font drawFont = new Font("Arial", 20); + SolidBrush drawBrush = new SolidBrush(Color.White); + StringFormat format = new StringFormat(StringFormatFlags.NoClip); + format.LineAlignment = StringAlignment.Center; + format.Alignment = StringAlignment.Center; + ea.Graphics.DrawString(Percent + "%", drawFont, drawBrush, new RectangleF(0, 0, pp.Width, pp.Height),format); + }; + + Button b = new Button(); + b.Text = "OK"; + b.Width = (int)Math.Round(156 / 2 * scale); + b.Height = (int)Math.Round(48 / 2 * scale); + y += h; + b.Top = (int)Math.Round(y); + b.Left = (int)Math.Round((double)(ABCHealthForm.Width - b.Width) / 2); + b.Click += (o, ee) => { ABCHealthForm.Close(); }; + ABCHealthForm.Controls.Add(b); + y += b.Height + h; + var hh = ABCHealthForm.Height - ABCHealthForm.ClientSize.Height; + ABCHealthForm.Height = (int)Math.Round(y+hh); + + ABCHealthForm.StartPosition = FormStartPosition.Manual; + ABCHealthForm.Left = this.Left + Width - aw; + ABCHealthForm.Top = this.Top; + b.PreviewKeyDown += (o, eee) => + { + if (eee.KeyCode == Keys.Escape) + ABCHealthForm.Close(); + }; + ABCHealthForm.ShowDialog(); + } + } + catch (System.Exception ee) + { + } + } + private void tsHelp_Click(object sender, EventArgs e) { __showhelpinqueue(); diff --git a/VisualPascalABCNET/Form1.resx b/VisualPascalABCNET/Form1.resx index 42168b08e..513fddec6 100644 --- a/VisualPascalABCNET/Form1.resx +++ b/VisualPascalABCNET/Form1.resx @@ -681,7 +681,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABK - FQAAAk1TRnQBSQFMAgEBEAEAARwBAQEcAQEBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + FQAAAk1TRnQBSQFMAgEBEAEAAaQBAQGkAQEBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAAVADAAEBAQABCAYAARQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/VisualPascalABCNET/Properties/Resources.Designer.cs b/VisualPascalABCNET/Properties/Resources.Designer.cs index 3336fd86d..852470651 100644 --- a/VisualPascalABCNET/Properties/Resources.Designer.cs +++ b/VisualPascalABCNET/Properties/Resources.Designer.cs @@ -60,6 +60,16 @@ namespace VisualPascalABC.Properties { } } + /// + /// Поиск локализованного ресурса типа System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ABCHealth { + get { + object obj = ResourceManager.GetObject("ABCHealth", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Поиск локализованного ресурса типа System.Drawing.Bitmap. /// diff --git a/VisualPascalABCNET/Properties/Resources.resx b/VisualPascalABCNET/Properties/Resources.resx index 955867f3a..9a76925d2 100644 --- a/VisualPascalABCNET/Properties/Resources.resx +++ b/VisualPascalABCNET/Properties/Resources.resx @@ -526,4 +526,7 @@ ..\Resources\format1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\format2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/VisualPascalABCNET/VisualPascalABCNET.csproj b/VisualPascalABCNET/VisualPascalABCNET.csproj index 817e014fe..dcd72eb67 100644 --- a/VisualPascalABCNET/VisualPascalABCNET.csproj +++ b/VisualPascalABCNET/VisualPascalABCNET.csproj @@ -119,6 +119,12 @@ + + Form + + + ABCHealth.cs + Form @@ -417,6 +423,9 @@ Form + + ABCHealth.cs + Designer AboutBox.cs @@ -672,6 +681,8 @@ + + diff --git a/VisualPascalABCNET/Workbench/BuildService.cs b/VisualPascalABCNET/Workbench/BuildService.cs index dc2ea2411..cc28a21a6 100644 --- a/VisualPascalABCNET/Workbench/BuildService.cs +++ b/VisualPascalABCNET/Workbench/BuildService.cs @@ -18,7 +18,7 @@ namespace VisualPascalABC bool __ForRun; string __RuntimeServicesModule; bool __savePCU; - List ErrorsList = new List(); + public List ErrorsList = new List(); IWorkbench Workbench; IWorkbenchProjectService ProjectService; diff --git a/bin/Lib/School.pas b/bin/Lib/School.pas index 469d4fed6..11696eaa7 100644 --- a/bin/Lib/School.pas +++ b/bin/Lib/School.pas @@ -80,24 +80,29 @@ function SeqRandomReal(n: integer; a, b: real; t: integer): sequence of real; /// на интервале [a; b) с t знаками в дробной части function MatrRandomReal(m: integer; n: integer; a, b: real; t: integer): array [,] of real; -/// Возвращает логическое значение операции импликации a -> b -function Imp(a, b: boolean) : boolean; +/// Возвращает таблицу истинности для двух переменных +function TrueTable(f: function(a, b: boolean): boolean): + array[,] of boolean; -/// Выводит на монитор таблицу истинности для двух переменных -procedure TrueTable(f: function(a, b: boolean): boolean; - vars: string := 'x1.x2'); - -/// Выводит на монитор таблицу истинности для трех переменных -procedure TrueTable(f: function(a, b, c: boolean): boolean; - vars: string := 'x1.x2.x3'); +/// Возвращает таблицу истинности для трех переменных +function TrueTable(f: function(a, b, c: boolean): boolean): + array[,] of boolean; -/// Выводит на монитор таблицу истинности для четырех переменных -procedure TrueTable(f: function(a, b, c, d: boolean): boolean; - vars: string := 'x1.x2.x3.x4'); +/// Возвращает таблицу истинности для четырех переменных +function TrueTable(f: function(a, b, c, d: boolean): boolean): + array[,] of boolean; -/// Выводит на монитор таблицу истинности для пяти переменных -procedure TrueTable(f: function(a, b, c, d, e: boolean): boolean; - vars: string := 'x1.x2.x3.x4.x5'); +/// Возвращает таблицу истинности для пяти переменных +function TrueTable(f: function(a, b, c, d, e: boolean): boolean): + array[,] of boolean; + +/// Выводит на монитор таблицу истинности +/// f = 0 - только для значения функции False +/// f = 1 - только для значения функции True +procedure TrueTablePrint(a: array[,] of boolean; f: integer := -1); + +/// Заменяет последнее вхождение подстроки в строку +procedure ReplaceLast(var Строка: string; ЧтоЗаменить, ЧемЗаменить: string); implementation @@ -219,6 +224,21 @@ begin end end; +/// Перевод десятичного числа в систему счисления по основанию base (2..32) +function ToBase(Self: string; base: integer): string; extensionmethod; +begin + var n: BigInteger; + if not BigInteger.TryParse(Self, n) then exit; + var s := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + Result := ''; + while n > 0 do + begin + Result := s[integer(n mod base) + 1] + Result; + n := n div base + end; + if Result = '' then Result := '0' +end; + {$endregion} {$region MinMax} @@ -232,7 +252,7 @@ begin min := m else if m > max then max := m; - Result := (min, max) + Result := (min, max) end; /// Возвращает кортеж из минимума и максимума последовательности s @@ -244,16 +264,17 @@ begin min := m else if m > max then max := m; - Result := (min, max) + Result := (min, max) end; /// Возвращает кортеж из минимума и максимума последовательности function MinMax(Self: sequence of int64): (int64, int64); extensionmethod := - MinMax(Self); - +MinMax(Self); + /// Возвращает кортеж из минимума и максимума последовательности function MinMax(Self: sequence of integer): (integer, integer); - extensionmethod := MinMax(Self); + extensionmethod := +MinMax(Self); {$endregion} @@ -336,11 +357,11 @@ end; /// разложение числа на простые множители function Factorize(Self: int64): List; extensionmethod := - Factorize(Self); - +Factorize(Self); + /// Разложение числа на простые множители function Factorize(Self: integer): List; extensionmethod := - Factorize(Self); +Factorize(Self); {$endregion} @@ -349,21 +370,21 @@ function Factorize(Self: integer): List; extensionmethod := /// Простые числа на интервале [2;n] function Primes(n: integer): List; // Модифицированное решето Эратосфена на [2;n] -begin +begin var Mas := ArrFill(n, True); var i := 2; while i * i <= n do - begin - if Mas[i-1] then - begin - var k := i*i; + begin + if Mas[i - 1] then + begin + var k := i * i; while k <= n do - begin - Mas[k-1] := False; + begin + Mas[k - 1] := False; k += i end end; - Inc(i) + Inc(i) end; n := Mas.Count(t -> t); Result := new List; @@ -375,21 +396,21 @@ end; function FirstPrimes(n: integer): List; // Модифицированное решето Эратосфена begin - var n1 := Trunc(Exp((Ln(n)+1.088)/0.8832)); + var n1 := Trunc(Exp((Ln(n) + 1.088) / 0.8832)); var Mas := ArrFill(n1, True); var i := 2; while i * i <= n1 do - begin - if Mas[i-1] then - begin - var k := i*i; + begin + if Mas[i - 1] then + begin + var k := i * i; while k <= n1 do - begin - Mas[k-1] := False; + begin + Mas[k - 1] := False; k += i end end; - Inc(i) + Inc(i) end; //n := Mas.Count(t -> t); Result := new List; @@ -466,12 +487,14 @@ end; /// Возвращает список, содержащий цифры числа function Digits(Self: integer): List; - extensionmethod := Digits(Self); + extensionmethod := +Digits(Self); /// возвращает список, содержащий цифры числа function Digits(Self: int64): List; - extensionmethod := Digits(Self); - + extensionmethod := +Digits(Self); + {$endregion} {$region Divisors} @@ -484,7 +507,7 @@ begin L.Add(1); L.Add(n); if n > 3 then - begin + begin var k := 2; while (k * k <= n) and (k < 46341) do begin @@ -510,7 +533,7 @@ begin L.Add(1); L.Add(n); if n > 3 then - begin + begin var k := int64(2); while (k * k <= n) and (k < 3037000500) do begin @@ -530,11 +553,11 @@ end; /// возвращает список делителей натурального числа function Divizors(Self: integer): List; extensionmethod := - Divizors(Self); - +Divizors(Self); + /// возвращает список делителей натурального числа function Divizors(Self: int64): List; extensionmethod := - Divizors(Self); +Divizors(Self); {$endregion} @@ -545,7 +568,7 @@ function SinDegrees(x: real): real := Sin(DegToRad(x)); function CosDegrees(x: real): real := Cos(DegToRad(x)); function TanDegrees(x: real): real := Tan(DegToRad(x)); - + {$endregion} {$region Random} @@ -581,79 +604,121 @@ end; {$region BooleanLogic} -function BoolToStr(Self: boolean): string; extensionmethod := - if Self then '1' else '0'; - /// Возвращает логическое значение операции импликации a -> b -function Imp(a, b: boolean) : boolean := not a or b; +function Imp(Self, b: boolean): boolean; extensionmethod := not Self or b; -/// Выводит на монитор таблицу истинности для двух переменных -procedure TrueTable(f: function(a, b: boolean): boolean; - vars: string); +/// Возвращает таблицу истинности для двух переменных +function TrueTable(f: function(a, b: boolean): boolean): + array[,] of boolean; begin - var names := vars.ToWords('.'); - var lengths := names.Select(Имя -> Имя.Length + 1).ToArray; - Write(' '); - names.Print; - Writeln(' F'); + Result := new boolean[4, 3]; + var i := 0; for var a := False to True do for var b := False to True do - Writeln(a.BoolToStr:lengths[0], b.BoolToStr:lengths[1], - f(a, b).BoolToStr:2) + begin + Result[i, 0] := a; + Result[i, 1] := b; + Result[i, 2] := f(a, b); + i += 1 + end; end; - -/// Выводит на монитор таблицу истинности для трех переменных -procedure TrueTable(f: function(a, b, c: boolean): boolean; - vars: string); + +/// Возвращает таблицу истинности для трех переменных +function TrueTable(f: function(a, b, c: boolean): boolean): + array[,] of boolean; begin - var names := vars.ToWords('.'); - var lengths := names.Select(Имя -> Имя.Length + 1).ToArray; - Write(' '); - names.Print; - Writeln(' F'); + Result := new boolean[8, 4]; + var i := 0; for var a := False to True do for var b := False to True do for var c := False to True do - Writeln(a.BoolToStr:lengths[0], b.BoolToStr:lengths[1], - c.BoolToStr:lengths[2], f(a, b, c).BoolToStr:2) + begin + Result[i, 0] := a; + Result[i, 1] := b; + Result[i, 2] := c; + Result[i, 3] := f(a, b, c); + i += 1 + end; end; -/// Выводит на монитор таблицу истинности для четырех переменных -procedure TrueTable(f: function(a, b, c, d: boolean): boolean; - vars: string); +/// Возвращает таблицу истинности для четырех переменных +function TrueTable(f: function(a, b, c, d: boolean): boolean): + array[,] of boolean; begin - var names := vars.ToWords('.'); - var lengths := names.Select(Имя -> Имя.Length + 1).ToArray; - Write(' '); - names.Print; - Writeln(' F'); + Result := new boolean[16, 5]; + var i := 0; for var a := False to True do for var b := False to True do for var c := False to True do for var d := False to True do - Writeln(a.BoolToStr:lengths[0], b.BoolToStr:lengths[1], - c.BoolToStr:lengths[2], d.BoolToStr:lengths[3], - f(a, b, c, d).BoolToStr:2) + begin + Result[i, 0] := a; + Result[i, 1] := b; + Result[i, 2] := c; + Result[i, 3] := d; + Result[i, 4] := f(a, b, c, d); + i += 1 + end; end; -/// Выводит на монитор таблицу истинности для пяти переменных -procedure TrueTable(f: function(a, b, c, d, e: boolean): boolean; - vars: string); +/// Возвращает таблицу истинности для пяти переменных +function TrueTable(f: function(a, b, c, d, e: boolean): boolean): + array[,] of boolean; begin - var names := vars.ToWords('.'); - var lengths := names.Select(Имя -> Имя.Length + 1).ToArray; - Write(' '); - names.Print; - Writeln(' F'); + Result := new boolean[32, 6]; + var i := 0; for var a := False to True do for var b := False to True do for var c := False to True do for var d := False to True do for var e := False to True do - Writeln(a.BoolToStr:lengths[0], b.BoolToStr:lengths[1], - c.BoolToStr:lengths[2], d.BoolToStr:lengths[3], - e.BoolToStr:lengths[4], f(a, b, c, d, e).BoolToStr:2) -end; + begin + Result[i, 0] := a; + Result[i, 1] := b; + Result[i, 2] := c; + Result[i, 3] := d; + Result[i, 4] := d; + Result[i, 5] := f(a, b, c, d, e); + i += 1 + end; +end; + +/// Выводит на монитор таблицу истинности +/// f = 0 - только для значения функции False +/// f = 1 - только для значения функции True +procedure TrueTablePrint(a: array[,] of boolean; f: integer); +begin + var (n, c) := (a.ColCount, 'a'); + for var i := 0 to n - 2 do + begin + Write(' ' + c); + Inc(c) + end; + Writeln(' F'); + Writeln(' ' + (2 * n - 1) * '-'); + for var i := 0 to a.RowCount - 1 do + if not (((f = 0) and a[i, n - 1]) or ((f = 1) and not a[i, n - 1])) then + begin + for var j := 0 to n - 1 do + Write(if a[i, j] then ' 1' else ' 0'); + Writeln + end +end; + +{$endregion} + +{$region String} + +/// Заменяет последнее вхождение подстроки в строку +procedure ReplaceLast(var Строка: string; ЧтоЗаменить, ЧемЗаменить: string); +begin + var Позиция := LastPos(ЧтоЗаменить, Строка); + if Позиция > 0 then + begin + Delete(Строка, Позиция, ЧтоЗаменить.Length); + Insert(ЧемЗаменить, Строка, Позиция) + end +end; {$endregion}