diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 65b724922..c7ece9551 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 = "1282"; + public const string Revision = "1284"; 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 f4a262eea..78b304ba2 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=1 -%REVISION%=1282 +%REVISION%=1284 %COREVERSION%=0 %MAJOR%=3 diff --git a/PascalABCNET.axml b/PascalABCNET.axml index 9befe45f8..0953801e0 100644 --- a/PascalABCNET.axml +++ b/PascalABCNET.axml @@ -540,6 +540,21 @@ + + + + \TreeConverter\TreeConversion\syntax_tree_visitor.cs + private base_function_call create_not_static_method_call(function_node fn, expression_node en, location loc, bool procedure_allowed) + + private base_function_call create_not_static_method_call ( function_node fn , expression_node en , location loc , bool procedure_allowed ) + public class syntax_tree_visitor : SyntaxTree . AbstractVisitor + namespace PascalABCCompiler . TreeConverter + + + + + + @@ -1138,6 +1153,30 @@ + + \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 + internal void visit_method_call(SyntaxTree.method_call _method_call) + + internal void visit_method_call ( SyntaxTree . method_call _method_call ) + 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 56c64a217..516d10103 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.1.0.1282' +!define VERSION '3.1.0.1284' diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index 917bc28d0..0a56557be 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -8080,17 +8080,14 @@ end; /// Возвращает последние count элементов последовательности function TakeLast(Self: sequence of T; count: integer): sequence of T; extensionmethod; begin - var q := new Queue; - foreach var x in Self do - begin - if q.Count = count then - q.Dequeue(); - q.Enqueue(x); - end; - Result := q; + Result := Self.Reverse.Take(count).Reverse; end; -// ToDo: SkipLast +/// Возвращает последовательность без последних count элементов +function SkipLast(self: sequence of T; count: integer): sequence of T; extensionmethod; +begin + Result := Self.Reverse.Skip(count).Reverse; +end; /// Декартово произведение последовательностей function Cartesian(Self: sequence of T; b: sequence of T1): sequence of (T,T1); extensionmethod; diff --git a/TreeConverter/TreeConversion/LambdaHelper.cs b/TreeConverter/TreeConversion/LambdaHelper.cs index 4a8cd640a..3b6645917 100644 --- a/TreeConverter/TreeConversion/LambdaHelper.cs +++ b/TreeConverter/TreeConversion/LambdaHelper.cs @@ -205,6 +205,34 @@ namespace PascalABCCompiler.TreeConverter retType.real_type = new LambdaResultTypeInferrer(funcHeader, procBody, visitor).InferResultType(); } + /// + /// Заменяет x -> begin result := x.Print end; на x -> begin x.Print end в случае если это один оператор и вызов метода + /// + /// + public static bool TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(function_lambda_definition lambdaDef) + { + var stl = lambdaDef.proc_body as SyntaxTree.statement_list; + if (stl.expr_lambda_body) + { + // Очищаем от Result := + + var ass = stl.list[0] as assign; + if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower() == "result") + { + var f = ass.from; + if (f is method_call) + { + var ff = f as method_call; + stl.list[0] = new procedure_call(ff, ff.source_context); // заменить result := Print(x) на Print(x) + lambdaDef.return_type = null; + return true; + } + } + } + + return false; + } + /// /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной /// @@ -263,27 +291,10 @@ namespace PascalABCCompiler.TreeConverter (lambdaDef.return_type as lambda_inferred_type).real_type = dii_left.return_value_type; else // SSM 23/07/16 - попытка бороться с var p: Shape->() := a->a.Print() { - var stl = lambdaDef.proc_body as SyntaxTree.statement_list; - if (stl.expr_lambda_body) - { - // Очищаем от Result := - - var ass = stl.list[0] as assign; - if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower() == "result") - { - var f = ass.from; - if (f is method_call) - { - var ff = f as method_call; - stl.list[0] = new procedure_call(ff, ff.source_context); // заменить result := Print(x) на Print(x) - lambdaDef.return_type = null; - return; - } - } - } - throw new SimpleSemanticError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE"); + var b = TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef); + if (!b) + throw new SimpleSemanticError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE"); } - //throw new SimpleSemanticError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE"); } } else diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 9c90885fd..827e34a4f 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -8864,7 +8864,7 @@ namespace PascalABCCompiler.TreeConverter try_convert_typed_expression_to_function_call(ref en); if ((!procedure_allowed) && (fn.return_value_type == null)) { - AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn); + AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name); } if (fn.semantic_node_type == semantic_node_type.common_method_node) { @@ -15726,7 +15726,7 @@ namespace PascalABCCompiler.TreeConverter var fld1 = _assign.from as SyntaxTree.function_lambda_definition; if (fld1 != null) { - MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(fld1); + //MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(fld1); LambdaHelper.InferTypesFromVarStmt(to.type, fld1, this); //lroman// } @@ -18223,6 +18223,7 @@ namespace PascalABCCompiler.TreeConverter public void MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(function_lambda_definition _function_lambda_definition) { + // SSM 23/07/16 - вроде сделал лучше в LambdaHelper.InferTypesFromVarStmt, но пока везде удалять вызов этой функции не решаюсь - лень тестировать // SSM 18/04/16 попытка разрешить x->Print(x) var stl = _function_lambda_definition.proc_body as SyntaxTree.statement_list; if (_function_lambda_definition.return_type is lambda_inferred_type && stl != null && stl.list.Count == 1 && _function_lambda_definition.usedkeyword == 0) diff --git a/bin/Lib/PABCRtl.dll b/bin/Lib/PABCRtl.dll index ed57c44d2..ecabb664e 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 917bc28d0..0a56557be 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -8080,17 +8080,14 @@ end; /// Возвращает последние count элементов последовательности function TakeLast(Self: sequence of T; count: integer): sequence of T; extensionmethod; begin - var q := new Queue; - foreach var x in Self do - begin - if q.Count = count then - q.Dequeue(); - q.Enqueue(x); - end; - Result := q; + Result := Self.Reverse.Take(count).Reverse; end; -// ToDo: SkipLast +/// Возвращает последовательность без последних count элементов +function SkipLast(self: sequence of T; count: integer): sequence of T; extensionmethod; +begin + Result := Self.Reverse.Skip(count).Reverse; +end; /// Декартово произведение последовательностей function Cartesian(Self: sequence of T; b: sequence of T1): sequence of (T,T1); extensionmethod; diff --git a/bin/PascalABCNET.chm b/bin/PascalABCNET.chm index 0080c3cfb..d190fed2d 100644 Binary files a/bin/PascalABCNET.chm and b/bin/PascalABCNET.chm differ