diff --git a/PascalABCNET.axml b/PascalABCNET.axml index dd94af723..6e34fd745 100644 --- a/PascalABCNET.axml +++ b/PascalABCNET.axml @@ -1181,6 +1181,32 @@ public override void visit ( formal_parameters fp ) + + + + \syntaxvisitors\yieldvisitors\processyieldscapturedvars.cs + private bool InsertGlobalIteratorMethodPredefinition(procedure_definition pd) + + private bool InsertGlobalIteratorMethodPredefinition ( procedure_definition pd ) + public class ProcessYieldCapturedVarsVisitor : BaseChangeVisitor + namespace SyntaxVisitors + + + + + + \TreeConverter\TreeConversion\compilation_context.cs + private bool check_unique_or_predefined(common_function_node fn) + + private bool check_unique_or_predefined ( common_function_node fn ) + public class compilation_context + namespace PascalABCCompiler . TreeConverter + + + + + + diff --git a/SyntaxTree/tree/tree.nin b/SyntaxTree/tree/tree.nin index 3a6583ca1..ae9780670 100644 Binary files a/SyntaxTree/tree/tree.nin and b/SyntaxTree/tree/tree.nin differ diff --git a/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs b/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs index a12be73bf..f1e85cba9 100644 --- a/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs +++ b/SyntaxVisitors/YieldVisitors/ProcessYieldsCapturedVars.cs @@ -832,6 +832,20 @@ namespace SyntaxVisitors return false; } + // SSM и еще нельзя генерировать если это функция, описанная в interface и implementation модуля + var un = UpperNode(2) as implementation_node; + if (un != null) + { + var cu = UpperNode(3) as unit_module; + if (cu != null) // а это всегда так + { + var fhh = cu.interface_part.interface_definitions.defs.OfType().Where(fh => fh.name.meth_name.name.ToLower()==pd.proc_header.name.meth_name.name.ToLower()); + if (fhh.Any()) // если еть в разделе интерфейса такие же имена, то не генерировать предописание + return false; + // вообще-то надо сравнивать заголовки - не только имена - но даже так устраняется основная масса ошибок + } + } + var pdPredefs = UpperTo().defs .OfType() .Where(lpd => lpd.proc_body == null @@ -877,6 +891,8 @@ namespace SyntaxVisitors return; // frninja 05/06/16 - вставляем предописание если метод-итератор описан не в классе (обычная функция) чтоб работали рекурсивные вызовы + // Нужен также для верной работы функции, проверяющей разные ошибки на этапе семантики + // Как только уберу -функцию, от этого тоже можно избавиться bool methodPredefCreated = InsertGlobalIteratorMethodPredefinition(pd); // frninja 24/05/16 - оборачиваем одиночные операторы в begin..end @@ -966,10 +982,10 @@ namespace SyntaxVisitors pd.has_yield = false; // frninja 05/06/16 - убираем where-секцию у описания метода. Они уже скопированы куда надо - if (methodPredefCreated) + /*if (methodPredefCreated) { pd.proc_header.where_defs = null; - } + }*/ //mids = null; // вдруг мы выйдем из процедуры, не зайдем в другую, а там - оператор! Такого конечно не может быть } diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index 7ddc068f1..a3a6d2b43 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -1562,6 +1562,8 @@ function ReadSeqReal(const prompt: string; n: integer): sequence of real; /// Выводит приглашение к вводу и возвращает последовательность из n строк, введенных с клавиатуры function ReadSeqString(const prompt: string; n: integer): sequence of string; +/// Возвращает последовательность целых, вводимых с клавиатуры пока выполняется определенное условие +//function ReadSeqIntegerWhile(cond: integer -> boolean): sequence of integer; // ----------------------------------------------------- //>> Подпрограммы для генерации динамических массивов # Subroutines for array of T generation @@ -4094,6 +4096,17 @@ begin Result := Range(1,n).Select(i->ReadInteger()); end; +function ReadSeqIntegerWhile(cond: integer -> boolean): sequence of integer; +begin + while True do + begin + var x := ReadInteger(); + if cond(x) then + break; + yield 1; + end; +end; + function ReadSeqInteger(const prompt: string; n: integer): sequence of integer; begin Print(prompt); @@ -8765,6 +8778,8 @@ begin yield c.TakeGroup(); end; +//ToDo Сделать AdjacentGroup с функцией сравнения + /// Возвращает минимальный элемент function Min(Self: array of T): T; extensionmethod; where T: System.IComparable; begin diff --git a/TreeConverter/TreeConversion/compilation_context.cs b/TreeConverter/TreeConversion/compilation_context.cs index a8d2b4a41..db25380cc 100644 --- a/TreeConverter/TreeConversion/compilation_context.cs +++ b/TreeConverter/TreeConversion/compilation_context.cs @@ -3001,7 +3001,9 @@ namespace PascalABCCompiler.TreeConverter AddError(new FunctionDuplicateDefinition(compar, fn)); } else + { AddError(new FunctionDuplicateDefinition(compar, fn)); + } } } si = si.Next; @@ -3279,7 +3281,9 @@ namespace PascalABCCompiler.TreeConverter AddError(new FunctionDuplicateDefinition(compar, fn)); } else + { AddError(new FunctionDuplicateDefinition(compar,fn)); + } } si = si.Next; } diff --git a/Yield/YieldConversionSyntax/YieldDesugarSyntaxTreeConverter.cs b/Yield/YieldConversionSyntax/YieldDesugarSyntaxTreeConverter.cs index e365837d2..665abdedb 100644 --- a/Yield/YieldConversionSyntax/YieldDesugarSyntaxTreeConverter.cs +++ b/Yield/YieldConversionSyntax/YieldDesugarSyntaxTreeConverter.cs @@ -25,12 +25,13 @@ namespace YieldDesugarSyntaxTreeConverter public syntax_tree_node Convert(syntax_tree_node root) { root.visit(new MarkMethodHasYieldAndCheckSomeErrorsVisitor()); - root.visit(new ProcessYieldCapturedVarsVisitor()); + ProcessYieldCapturedVarsVisitor.New.ProcessNode(root); + //root.visit(py); - пропускал корень #if DEBUG try { - //root.visit(new SimplePrettyPrinterVisitor(@"d:\\zzz1.txt")); + root.visit(new SimplePrettyPrinterVisitor(@"d:\\zzz1.txt")); } catch { diff --git a/bin/Lib/PABCRtl.dll b/bin/Lib/PABCRtl.dll index 6bc0ea2b4..2c7ac33b5 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 7ddc068f1..178e0eeac 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -1562,6 +1562,8 @@ function ReadSeqReal(const prompt: string; n: integer): sequence of real; /// Выводит приглашение к вводу и возвращает последовательность из n строк, введенных с клавиатуры function ReadSeqString(const prompt: string; n: integer): sequence of string; +/// Возвращает последовательность целых, вводимых с клавиатуры пока выполняется определенное условие +function ReadSeqIntegerWhile(cond: integer -> boolean): sequence of integer; // ----------------------------------------------------- //>> Подпрограммы для генерации динамических массивов # Subroutines for array of T generation @@ -4094,6 +4096,17 @@ begin Result := Range(1,n).Select(i->ReadInteger()); end; +function ReadSeqIntegerWhile(cond: integer -> boolean): sequence of integer; +begin + while True do + begin + var x := ReadInteger(); + if not cond(x) then + break; + yield x; + end; +end; + function ReadSeqInteger(const prompt: string; n: integer): sequence of integer; begin Print(prompt); @@ -8765,6 +8778,8 @@ begin yield c.TakeGroup(); end; +//ToDo Сделать AdjacentGroup с функцией сравнения + /// Возвращает минимальный элемент function Min(Self: array of T): T; extensionmethod; where T: System.IComparable; begin