From 5aa72fac7425d4440af4e75ab08e75c3714a2142 Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Mon, 6 Jan 2020 11:23:55 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=20=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8E=20foreach=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20IList?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LanguageFeatures/IfThenElseExpr.pas | 6 +++++ .../LanguageFeatures/IfThenElseExpr2.pas | 14 ++++++++++ .../SugarVisitors/NewRangeDesugarVisitor.cs | 4 ++- .../SyntaxTreeVisitorNodes/Foreach.cs | 26 ++++++++++++------- .../semantic_checks_for_sugar.cs | 5 ++++ .../TreeConversion/syntax_tree_visitor.cs | 9 +++++-- 6 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 InstallerSamples/LanguageFeatures/IfThenElseExpr.pas create mode 100644 InstallerSamples/LanguageFeatures/IfThenElseExpr2.pas diff --git a/InstallerSamples/LanguageFeatures/IfThenElseExpr.pas b/InstallerSamples/LanguageFeatures/IfThenElseExpr.pas new file mode 100644 index 000000000..8b64f17d9 --- /dev/null +++ b/InstallerSamples/LanguageFeatures/IfThenElseExpr.pas @@ -0,0 +1,6 @@ +begin + var (a,b) := (2,3); + var min: integer; + min := if a0 then + if y>0 then + 1 + else 4 + else + if y>0 then + 2 + else 3; + + Print(q) +end. \ No newline at end of file diff --git a/SyntaxVisitors/SugarVisitors/NewRangeDesugarVisitor.cs b/SyntaxVisitors/SugarVisitors/NewRangeDesugarVisitor.cs index 748b2cb6d..a17cf66d0 100644 --- a/SyntaxVisitors/SugarVisitors/NewRangeDesugarVisitor.cs +++ b/SyntaxVisitors/SugarVisitors/NewRangeDesugarVisitor.cs @@ -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(); + sl.Add(new semantic_check_sugared_statement_node(typeof(foreach_stmt), new List { dn.right }, fe.source_context)); sl.Add(fn); ReplaceStatementUsingParent(fe, sl); diff --git a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs index 837035729..0d5d6fc61 100644 --- a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs +++ b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Foreach.cs @@ -165,14 +165,7 @@ namespace PascalABCCompiler.TreeConverter return false; } - - /// - /// Преобразует foreach в for, если коллекция это одномерный массив. - /// - /// - /// - /// True - если преобразование удалось, иначе False - 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; + } + + + /// + /// Преобразует foreach в for, если коллекция это одномерный массив. + /// + /// + /// + /// True - если преобразование удалось, иначе False + 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(); diff --git a/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs b/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs index 2e55c3d28..ece286d99 100644 --- a/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs +++ b/TreeConverter/TreeConversion/semantic_checks_for_sugar.cs @@ -244,6 +244,11 @@ namespace PascalABCCompiler.TreeConverter } } + void semantic_check_for_indices(SyntaxTree.expression expr) + { + // Надо проверить, что expr - это одноразмерный массив или список. Эта проверка была в visit(foreach) + } + } } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 26b34c686..e2c191e1f 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -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)