diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index c7ece9551..f4ad00cc3 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "1"; public const string Build = "0"; - public const string Revision = "1284"; + public const string Revision = "1286"; 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 78b304ba2..6ff2fb5da 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=1 -%REVISION%=1284 +%REVISION%=1286 %COREVERSION%=0 %MAJOR%=3 diff --git a/PascalABCNET.axml b/PascalABCNET.axml index 0953801e0..451b2e884 100644 --- a/PascalABCNET.axml +++ b/PascalABCNET.axml @@ -1154,15 +1154,6 @@ - \TreeConverter\TreeConversion\syntax_tree_visitor.cs - return; - - internal void visit_method_call ( SyntaxTree . method_call _method_call ) - public class syntax_tree_visitor : SyntaxTree . AbstractVisitor - namespace PascalABCCompiler . TreeConverter - - - \TreeConverter\TreeConversion\syntax_tree_visitor.cs @@ -1177,6 +1168,32 @@ + + + + \TreeConverter\TreeConversion\syntax_tree_visitor.cs + public override void visit(SyntaxTree.foreach_stmt _foreach_stmt) + + public override void visit ( SyntaxTree . foreach_stmt _foreach_stmt ) + public class syntax_tree_visitor : SyntaxTree . AbstractVisitor + namespace PascalABCCompiler . TreeConverter + + + + + + \TreeConverter\TreeConversion\syntax_tree_visitor.cs + public override void visit(SyntaxTree.semantic_type_node stn) + + public override void visit ( SyntaxTree . semantic_type_node stn ) + public class syntax_tree_visitor : SyntaxTree . AbstractVisitor + namespace PascalABCCompiler . TreeConverter + + + + + + \ No newline at end of file diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 516d10103..b9df37f5b 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.1.0.1284' +!define VERSION '3.1.0.1286' diff --git a/SyntaxTree/tree/NodesBuilder.cs b/SyntaxTree/tree/NodesBuilder.cs index f6fa84a42..a7ef30f05 100644 --- a/SyntaxTree/tree/NodesBuilder.cs +++ b/SyntaxTree/tree/NodesBuilder.cs @@ -9,6 +9,13 @@ namespace PascalABCCompiler.SyntaxTree { public static SourceContext BuildGenSC = new SourceContext(0, 777777, 0, 0, 0, 0); + private static int GenIdNum = 0; + public static ident GenIdentName() + { + GenIdNum++; + return new ident("$GenId" + GenIdNum.ToString()); + } + public static type_definition BuildSimpleType(string name) { return new named_type_reference(name, null); diff --git a/SyntaxTree/tree/tree.nin b/SyntaxTree/tree/tree.nin index 929806bea..3a6583ca1 100644 Binary files a/SyntaxTree/tree/tree.nin and b/SyntaxTree/tree/tree.nin differ diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index 0a56557be..ba0e067c6 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -8452,7 +8452,7 @@ end; // Дополнения февраль 2016: Shuffle, AdjacentFind, IndexMin, IndexMax, Replace, Transform // Статические методы - в методы расширения: BinarySearch, ConvertAll, Find, FindIndex, FindAll, -// FindLast, FindLastIndex, IndexOf, Contains, LastIndexOf, Reverse, Resize, Sort +// FindLast, FindLastIndex, IndexOf, Contains, LastIndexOf, Reverse, Sort /// Перемешивает элементы массива случайным образом function Shuffle(Self: array of T): array of T; extensionmethod; @@ -8645,12 +8645,6 @@ begin Result := System.Array.LastIndexOf(self,x,start); end; -/// Меняет размер массива -procedure Resize(self: array of T; x: integer); extensionmethod; -begin - System.Array.Resize(self,x); -end; - /// Сортирует массив по возрастанию procedure Sort(self: array of T); extensionmethod; begin diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 1f7d71d5c..9daac03e8 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -16524,13 +16524,68 @@ namespace PascalABCCompiler.TreeConverter AddError(new LambdasNotAllowedInForeachInWhatSatetement(get_location(lambdaSearcher.FoundLambda))); } + expression_node in_what = convert_strong(_foreach_stmt.in_what); + + // SSM 29.07.16 - если in_what - одномерный массив, то заменить код foreach на for + var is1dimdynarr = false; + var comptn = in_what.type as compiled_type_node; + if (comptn != null && comptn.type_special_kind == SemanticTree.type_special_kind.array_kind && comptn.rank == 1) + { + is1dimdynarr = true; + } + if (!is1dimdynarr) + { + var comtn = in_what.type as common_type_node; + if (comtn != null && comtn.internal_type_special_kind == SemanticTree.type_special_kind.array_kind && comtn.rank == 1) + { + is1dimdynarr = true; + } + } + + if (is1dimdynarr) // Замена foreach на for для массива + { + // сгенерировать код для for и вызвать соответствующий visit + var sem_expr = new semantic_addr_value(in_what); // перевод в синтаксис для мгновенного вычисления семантического выражения, которое уже вычислено в in_what + var arrid = SyntaxTreeBuilder.GenIdentName(); + var vdarr = new var_def_statement(arrid, null, sem_expr); + visit(vdarr); + + statement_list newbody; + if (_foreach_stmt.stmt is statement_list) + newbody = _foreach_stmt.stmt as statement_list; + else newbody = new statement_list(_foreach_stmt.stmt); + var i = SyntaxTreeBuilder.GenIdentName(); + + var x = _foreach_stmt.identifier; + + // Возможны 3 случая: + // 1. _foreach_stmt.type_name = null - значит, переменная определена в другом месте + // 2. _foreach_stmt.type_name = no_type_foreach - значит, это for var x in a + // 3. _foreach_stmt.type_name = T - значит, это for var x: T in a + + statement vd; + if (_foreach_stmt.type_name == null) + vd = new assign(x, new indexer(arrid,new expression_list(i))); + else if (_foreach_stmt.type_name is no_type_foreach) + vd = new var_statement(x, new indexer(arrid,new expression_list(i))); + else vd = new var_statement(x,_foreach_stmt.type_name, new indexer(arrid,new expression_list(i))); + + newbody.AddFirst(vd); + + var high = new bin_expr(new dot_node(arrid, new ident("Length")),new int32_const(1),Operators.Minus); + + var fornode = new SyntaxTree.for_node(i, new int32_const(0), high, newbody, for_cycle_type.to, null, null, true); + visit(fornode); + return; + } + /// SSM 29.07.16 + //throw new NotSupportedError(get_location(_foreach_stmt)); definition_node dn = null; var_definition_node vdn = null; statements_list sl2 = new statements_list(get_location(_foreach_stmt)); convertion_data_and_alghoritms.statement_list_stack_push(sl2); - expression_node in_what = convert_strong(_foreach_stmt.in_what); expression_node tmp = in_what; if (in_what is typed_expression) in_what = convert_typed_expression_to_function_call(in_what as typed_expression); type_node elem_type = null; @@ -16538,6 +16593,9 @@ namespace PascalABCCompiler.TreeConverter in_what = tmp; //if (in_what.type.find_in_type("GetEnumerator") == null) + //(in_what.type as common_type_node).internal_type_special_kind == SemanticTree.type_special_kind.array_kind + //in_what.type as compiled_type_node + if (!FindIEnumerableElementType(/*_foreach_stmt, */in_what.type, ref elem_type)) //if (!IsGetEnumerator(in_what.type, ref elem_type)) AddError(in_what.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", in_what.type.name); diff --git a/bin/Lib/PABCRtl.dll b/bin/Lib/PABCRtl.dll index ecabb664e..6e1cc3e6e 100644 Binary files a/bin/Lib/PABCRtl.dll and b/bin/Lib/PABCRtl.dll differ diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index 0a56557be..ba0e067c6 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -8452,7 +8452,7 @@ end; // Дополнения февраль 2016: Shuffle, AdjacentFind, IndexMin, IndexMax, Replace, Transform // Статические методы - в методы расширения: BinarySearch, ConvertAll, Find, FindIndex, FindAll, -// FindLast, FindLastIndex, IndexOf, Contains, LastIndexOf, Reverse, Resize, Sort +// FindLast, FindLastIndex, IndexOf, Contains, LastIndexOf, Reverse, Sort /// Перемешивает элементы массива случайным образом function Shuffle(Self: array of T): array of T; extensionmethod; @@ -8645,12 +8645,6 @@ begin Result := System.Array.LastIndexOf(self,x,start); end; -/// Меняет размер массива -procedure Resize(self: array of T; x: integer); extensionmethod; -begin - System.Array.Resize(self,x); -end; - /// Сортирует массив по возрастанию procedure Sort(self: array of T); extensionmethod; begin