Оптимизирован foreach для массивов - для него генерируется цикл for
This commit is contained in:
parent
a73432abc3
commit
945b18a326
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%MINOR%=1
|
||||
%REVISION%=1284
|
||||
%REVISION%=1286
|
||||
%COREVERSION%=0
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
|
|
@ -1154,15 +1154,6 @@
|
|||
</Items>
|
||||
</Node>
|
||||
<Node Name="a.Sort((row1, row2) -> 1)">
|
||||
<FileName>\TreeConverter\TreeConversion\syntax_tree_visitor.cs</FileName>
|
||||
<Text>return;</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">internal void visit_method_call ( SyntaxTree . method_call _method_call )</i>
|
||||
<i Type="ClassOrNamespace">public class syntax_tree_visitor : SyntaxTree . AbstractVisitor</i>
|
||||
<i Type="ClassOrNamespace">namespace PascalABCCompiler . TreeConverter</i>
|
||||
<i Type="CS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
<Items>
|
||||
<Node Name="visit_method_call">
|
||||
<FileName>\TreeConverter\TreeConversion\syntax_tree_visitor.cs</FileName>
|
||||
|
|
@ -1177,6 +1168,32 @@
|
|||
</Node>
|
||||
</Items>
|
||||
</Node>
|
||||
<Node Name="foreach Arr -> for">
|
||||
<Items>
|
||||
<Node Name="visit(SyntaxTree.foreach_stmt">
|
||||
<FileName>\TreeConverter\TreeConversion\syntax_tree_visitor.cs</FileName>
|
||||
<Text>public override void visit(SyntaxTree.foreach_stmt _foreach_stmt)</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">public override void visit ( SyntaxTree . foreach_stmt _foreach_stmt )</i>
|
||||
<i Type="ClassOrNamespace">public class syntax_tree_visitor : SyntaxTree . AbstractVisitor</i>
|
||||
<i Type="ClassOrNamespace">namespace PascalABCCompiler . TreeConverter</i>
|
||||
<i Type="CS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
<Node Name="visit(SyntaxTree.semantic_type_node">
|
||||
<FileName>\TreeConverter\TreeConversion\syntax_tree_visitor.cs</FileName>
|
||||
<Text>public override void visit(SyntaxTree.semantic_type_node stn)</Text>
|
||||
<OCtx>
|
||||
<i Type="Method">public override void visit ( SyntaxTree . semantic_type_node stn )</i>
|
||||
<i Type="ClassOrNamespace">public class syntax_tree_visitor : SyntaxTree . AbstractVisitor</i>
|
||||
<i Type="ClassOrNamespace">namespace PascalABCCompiler . TreeConverter</i>
|
||||
<i Type="CS_TreeNode">
|
||||
</i>
|
||||
</OCtx>
|
||||
</Node>
|
||||
</Items>
|
||||
</Node>
|
||||
</Items>
|
||||
</Node>
|
||||
</AspectFile>
|
||||
|
|
@ -1 +1 @@
|
|||
!define VERSION '3.1.0.1284'
|
||||
!define VERSION '3.1.0.1286'
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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<T>(Self: array of T): array of T; extensionmethod;
|
||||
|
|
@ -8645,12 +8645,6 @@ begin
|
|||
Result := System.Array.LastIndexOf(self,x,start);
|
||||
end;
|
||||
|
||||
/// Меняет размер массива
|
||||
procedure Resize<T>(self: array of T; x: integer); extensionmethod;
|
||||
begin
|
||||
System.Array.Resize(self,x);
|
||||
end;
|
||||
|
||||
/// Сортирует массив по возрастанию
|
||||
procedure Sort<T>(self: array of T); extensionmethod;
|
||||
begin
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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<T>(Self: array of T): array of T; extensionmethod;
|
||||
|
|
@ -8645,12 +8645,6 @@ begin
|
|||
Result := System.Array.LastIndexOf(self,x,start);
|
||||
end;
|
||||
|
||||
/// Меняет размер массива
|
||||
procedure Resize<T>(self: array of T; x: integer); extensionmethod;
|
||||
begin
|
||||
System.Array.Resize(self,x);
|
||||
end;
|
||||
|
||||
/// Сортирует массив по возрастанию
|
||||
procedure Sort<T>(self: array of T); extensionmethod;
|
||||
begin
|
||||
|
|
|
|||
Loading…
Reference in a new issue