В оптимизацию foreach добавлен IList
This commit is contained in:
parent
17339ade0c
commit
5aa72fac74
6
InstallerSamples/LanguageFeatures/IfThenElseExpr.pas
Normal file
6
InstallerSamples/LanguageFeatures/IfThenElseExpr.pas
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
begin
|
||||
var (a,b) := (2,3);
|
||||
var min: integer;
|
||||
min := if a<b then a else b;
|
||||
Print(min)
|
||||
end.
|
||||
14
InstallerSamples/LanguageFeatures/IfThenElseExpr2.pas
Normal file
14
InstallerSamples/LanguageFeatures/IfThenElseExpr2.pas
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
begin
|
||||
var (x,y) := (5,-3);
|
||||
var q :=
|
||||
if x>0 then
|
||||
if y>0 then
|
||||
1
|
||||
else 4
|
||||
else
|
||||
if y>0 then
|
||||
2
|
||||
else 3;
|
||||
|
||||
Print(q)
|
||||
end.
|
||||
|
|
@ -9,6 +9,7 @@ using PascalABCCompiler.SyntaxTree;
|
|||
|
||||
namespace SyntaxVisitors.SugarVisitors
|
||||
{
|
||||
|
||||
public class NewRangeDesugarVisitor : BaseChangeVisitor
|
||||
{
|
||||
public static NewRangeDesugarVisitor New
|
||||
|
|
@ -83,10 +84,11 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
var cr = fe.type_name is no_type_foreach;
|
||||
|
||||
var left = new int32_const(0, fe.identifier.source_context);
|
||||
var right = dn.left.dot_node("Count").Minus(1);
|
||||
var right = dn.left.dot_node("Count").Minus(1); // Строки таким образом сделать не получится. Разве что в семантическом контроле чуть довернуть этот узел ))
|
||||
|
||||
var fn = new for_node(fe.identifier, left, right, fe.stmt, for_cycle_type.to, null, typ, cr);
|
||||
var sl = new List<statement>();
|
||||
sl.Add(new semantic_check_sugared_statement_node(typeof(foreach_stmt), new List<syntax_tree_node> { dn.right }, fe.source_context));
|
||||
sl.Add(fn);
|
||||
|
||||
ReplaceStatementUsingParent(fe, sl);
|
||||
|
|
|
|||
|
|
@ -165,14 +165,7 @@ namespace PascalABCCompiler.TreeConverter
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Преобразует foreach в for, если коллекция это одномерный массив.
|
||||
/// </summary>
|
||||
/// <param name="_foreach_stmt"></param>
|
||||
/// <param name="in_what"></param>
|
||||
/// <returns>True - если преобразование удалось, иначе False</returns>
|
||||
private bool OptimizeForeachInCase1DArray(foreach_stmt _foreach_stmt, expression_node in_what)
|
||||
private bool Is1DArray(expression_node in_what)
|
||||
{
|
||||
var is1dimdynarr = false;
|
||||
var comptn = in_what.type as compiled_type_node;
|
||||
|
|
@ -186,15 +179,28 @@ namespace PascalABCCompiler.TreeConverter
|
|||
if (comtn != null && comtn.internal_type_special_kind == type_special_kind.array_kind &&
|
||||
comtn.rank == 1)
|
||||
{
|
||||
is1dimdynarr = true;
|
||||
is1dimdynarr = true;
|
||||
}
|
||||
}
|
||||
return is1dimdynarr;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Преобразует foreach в for, если коллекция это одномерный массив.
|
||||
/// </summary>
|
||||
/// <param name="_foreach_stmt"></param>
|
||||
/// <param name="in_what"></param>
|
||||
/// <returns>True - если преобразование удалось, иначе False</returns>
|
||||
private bool OptimizeForeachInCase1DArray(foreach_stmt _foreach_stmt, expression_node in_what)
|
||||
{
|
||||
var is1dimdynarr = Is1DArray(in_what);
|
||||
|
||||
var il = IsIList(in_what);
|
||||
|
||||
// SSM 23.08.16 Закомментировал оптимизацию. Не работает с лямбдами. Лямбды обходят старое дерево. А заменить foreach на for на этом этапе пока не получается - не развита инфраструктура
|
||||
// SSM 24.12.19 Раскомментировал оптимизацию, но только если foreach не вложен в лямбду
|
||||
if (is1dimdynarr) // Замена foreach на for для массива
|
||||
if (is1dimdynarr || il) // Замена foreach на for для массива
|
||||
{
|
||||
// сгенерировать код для for и вызвать соответствующий visit
|
||||
var arrid = GenIdentName();
|
||||
|
|
|
|||
|
|
@ -244,6 +244,11 @@ namespace PascalABCCompiler.TreeConverter
|
|||
}
|
||||
}
|
||||
|
||||
void semantic_check_for_indices(SyntaxTree.expression expr)
|
||||
{
|
||||
// Надо проверить, что expr - это одноразмерный массив или список. Эта проверка была в visit(foreach)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20305,12 +20305,17 @@ namespace PascalABCCompiler.TreeConverter
|
|||
var expr = st.lst[0] as SyntaxTree.expression;
|
||||
semantic_check_loop_stmt(expr);
|
||||
}
|
||||
else if (st.typ as System.Type == typeof(SyntaxTree.foreach_stmt)) // для NewRange Visitorа. Если будет перекрытие, то надоделать новые типы-маркеры
|
||||
else if (st.typ as System.Type == typeof(SyntaxTree.foreach_stmt) && st.lst.Count == 3) // для NewRange Visitorа. Если будет перекрытие, то надоделать новые типы-маркеры
|
||||
{
|
||||
var expr = st.lst[0] as SyntaxTree.diapason_expr_new;
|
||||
var td = st.lst[1] as SyntaxTree.type_definition;
|
||||
var id = st.lst[2] as SyntaxTree.ident;
|
||||
semantic_check_for_new_range(expr,td,id);
|
||||
semantic_check_for_new_range(expr, td, id);
|
||||
}
|
||||
else if (st.typ as System.Type == typeof(SyntaxTree.foreach_stmt) && st.lst.Count == 3) // для a.Indices. Пока непонятно, где описывать тип-маркер
|
||||
{
|
||||
var expr = st.lst[0] as SyntaxTree.expression;
|
||||
semantic_check_for_indices(expr);
|
||||
}
|
||||
// Patterns
|
||||
else if (st.typ is SemanticCheckType.MatchedExpression)
|
||||
|
|
|
|||
Loading…
Reference in a new issue