From 1d31faee2b20be5ec8a3f308cf9e8f9b52983be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=BD=D0=B4=D0=B0=D1=80=D0=B5=D0=B2=20=D0=98?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD?= Date: Tue, 10 Jan 2017 13:31:39 +0100 Subject: [PATCH 1/2] bug fix #327 --- TestSuite/extensionmethods19.pas | 5 ++++ .../TreeConversion/syntax_tree_visitor.cs | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 TestSuite/extensionmethods19.pas diff --git a/TestSuite/extensionmethods19.pas b/TestSuite/extensionmethods19.pas new file mode 100644 index 000000000..dbef8b67e --- /dev/null +++ b/TestSuite/extensionmethods19.pas @@ -0,0 +1,5 @@ +begin + var a := Arr(1,3,5,4,3); + var b := a.Println.ToArray; + assert(b[2] = 5); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index b073cb7c4..195aca181 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -8969,6 +8969,30 @@ namespace PascalABCCompiler.TreeConverter { return new indefinite_reference(dn as indefinite_definition_node, get_location(id_right)); } + if (expected_delegate && en != null) + { + SymbolInfo tmp_si = si; + function_node tmp_fn = null; + bool has_empty_methods = false; + bool only_extension_methods = true; + while (tmp_si != null) + { + tmp_fn = tmp_si.sym_info as function_node; + if (tmp_fn != null) + { + if (!tmp_fn.is_extension_method) + only_extension_methods = false; + else + { + if (tmp_fn.parameters.Count == 1 || tmp_fn.parameters.Count == 2 && (tmp_fn.parameters[1].is_params || tmp_fn.parameters[1].default_value != null)) + has_empty_methods = true; + } + } + tmp_si = tmp_si.Next; + } + if (has_empty_methods && only_extension_methods) + expected_delegate = false; + } if (expected_delegate) return make_delegate_wrapper(en, si, get_location(id_right), false); else From 36638334678b30f67a599dda5586b1468c7c5d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=BD=D0=B4=D0=B0=D1=80=D0=B5=D0=B2=20=D0=98?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD?= Date: Tue, 10 Jan 2017 15:36:05 +0100 Subject: [PATCH 2/2] #330 --- NETGenerator/NETGenerator.cs | 25 ++- TestSuite/CompilationSamples/PABCSystem.pas | 170 +++++++++++++++++--- 2 files changed, 166 insertions(+), 29 deletions(-) diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 9e7d75032..bcc565c13 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -127,6 +127,7 @@ namespace PascalABCCompiler.NETGenerator protected CompilerOptions comp_opt = new CompilerOptions();//опции компилятора protected Dictionary sym_docs = new Dictionary();//таблица отладочных документов protected bool is_constructor = false;//флаг, переводим ли мы конструктор + protected bool init_call_awaited = false; protected bool save_debug_info = false; protected bool add_special_debug_variables = false; protected bool make_next_spoint = true; @@ -5782,15 +5783,17 @@ namespace PascalABCCompiler.NETGenerator ConvertCommonFunctionConstantDefinitions(value.constants); ConvertLocalVariables(value.var_definition_nodes); //вызываем метод $Init$ для инициализации массивов и проч. - if (value.polymorphic_state != polymorphic_state.ps_static && value.common_comprehensive_type.base_type is ICompiledTypeNode && (value.common_comprehensive_type.base_type as ICompiledTypeNode).compiled_type == TypeFactory.ObjectType) + /*if (value.polymorphic_state != polymorphic_state.ps_static && value.common_comprehensive_type.base_type is ICompiledTypeNode && (value.common_comprehensive_type.base_type as ICompiledTypeNode).compiled_type == TypeFactory.ObjectType) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, TypeFactory.ObjectType.GetConstructor(Type.EmptyTypes)); - } + }*/ if (value.polymorphic_state != polymorphic_state.ps_static) { - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Call, cur_ti.init_meth); + init_call_awaited = true; + + //il.Emit(OpCodes.Ldarg_0); + //il.Emit(OpCodes.Call, cur_ti.init_meth); } //переводим тело is_constructor = true; @@ -9182,6 +9185,12 @@ namespace PascalABCCompiler.NETGenerator { is_dot_expr = false; } + if (init_call_awaited && !value.new_obj_awaited()) + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Call, cur_ti.init_meth); + init_call_awaited = false; + } } //вызов откомпилированного конструктора @@ -9263,7 +9272,13 @@ namespace PascalABCCompiler.NETGenerator { is_dot_expr = false; } - //\ssyy + //\ssyy + if (init_call_awaited && !value.new_obj_awaited()) + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Call, cur_ti.init_meth); + init_call_awaited = false; + } } private bool TypeNeedToFix(ITypeNode type) diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index b5fac1d8b..3325eed7c 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -216,10 +216,10 @@ type Predicate = System.Predicate; /// Представляет функцию с двумя параметрами, возвращающую boolean - Predicate2 = System.Predicate; + Predicate2 = function(x1: T1; x2: T2): boolean; /// Представляет функцию с тремя параметрами, возвращающую boolean - Predicate3 = System.Predicate; + Predicate3 = function(x1: T1; x2: T2; x3: T3): boolean; /// Представляет регулярное выражение Regex = System.Text.RegularExpressions.Regex; @@ -8603,8 +8603,64 @@ begin Result := Self; end; +procedure CorrectFromTo(situation: integer; Len: integer; var from,&to: integer; step: integer); +begin + if step>0 then + begin + case situation of + 1: from := 0; + 2: &to := Len; + 3: begin + from := 0; + &to := Len; + end; + end; + end + else + begin + case situation of + 1: from := Len - 1; + 2: &to := -1; + 3: begin + from := Len - 1; + &to := -1; + end; + end; + end; +end; + ///-- -function CalcCountForSystemSlice(situation: integer; Len: integer; var from,&to: integer; step: integer): integer; +function CorrectFromToAndCalcCountForSystemSliceQuestion(situation: integer; Len: integer; var from,&to: integer; step: integer): integer; +begin + if step = 0 then + raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0)); + + CorrectFromTo(situation,Len,from,&to,step); + + if step>0 then + begin + if from<0 then + from += (step - from - 1) div step * step; + // from может оказаться > Len - 1 + var m := min(Len,&to); + if from >= m then + Result := 0 + else Result := (m - from - 1) div step + 1 + end + else + begin + if from > Len - 1 then + from -= (from - Len - step) div step * step; + // from может оказаться < 0 + var m := max(&to,-1); + if from <= m then + Result := 0 + else Result := (from - m - 1) div (-step) + 1 + end; +end; + +///-- +function CheckAndCorrectFromToAndCalcCountForSystemSlice(situation: integer; Len: integer; var from,&to: integer; step: integer): integer; begin // situation = 0 - все параметры присутствуют // situation = 1 - from отсутствует @@ -8621,19 +8677,12 @@ begin if (&to < -1) or (&to > Len) then raise new ArgumentException(GetTranslation(PARAMETER_TO_OUT_OF_RANGE)); + CorrectFromTo(situation,Len,from,&to,step); + var count: integer; if step>0 then begin - case situation of - 1: from := 0; - 2: &to := Len; - 3: begin - from := 0; - &to := Len; - end; - end; - var cnt := &to - from; if cnt<=0 then count := 0 @@ -8641,27 +8690,40 @@ begin end else begin - case situation of - 1: from := Len - 1; - 2: &to := -1; - 3: begin - from := Len - 1; - &to := -1; - end; - end; - var cnt := from - &to; if cnt<=0 then count := 0 else count := (cnt-1) div (-step) + 1; end; + Result := count; end; +///-- +procedure CheckStepAndCorrectFromTo(situation: integer; Len: integer; var from,&to: integer; step: integer); +begin +// situation = 0 - все параметры присутствуют +// situation = 1 - from отсутствует +// situation = 2 - to отсутствует +// situation = 3 - from и to отсутствуют + if step = 0 then + raise new ArgumentException(GetTranslation(PARAMETER_STEP_MUST_BE_NOT_EQUAL_0)); + + {if (situation=0) or (situation=2) then + if (from < 0) or (from > Len - 1) then + raise new ArgumentException(GetTranslation(PARAMETER_FROM_OUT_OF_RANGE)); + + if (situation=0) or (situation=1) then + if (&to < -1) or (&to > Len) then + raise new ArgumentException(GetTranslation(PARAMETER_TO_OUT_OF_RANGE));} + + CorrectFromTo(situation,Len,from,&to,step); +end; + ///-- function SystemSliceListImpl(Self: List; situation: integer; from,&to: integer; step: integer := 1): List; begin - var count := CalcCountForSystemSlice(situation,Self.Count,from,&to,step); + var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation,Self.Count,from,&to,step); Result := CreateSliceFromListInternal(Self,from,step,count); end; @@ -8678,6 +8740,25 @@ begin Result := SystemSliceListImpl(Self,situation,from,&to,step); end; +///-- +function SystemSliceListImplQuestion(Self: List; situation: integer; from,&to: integer; step: integer := 1): List; +begin + var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation,Self.Count,from,&to,step); + + Result := CreateSliceFromListInternal(Self,from,step,count); +end; + +///-- +function SystemSliceQuestion(Self: List; situation: integer; from,&to: integer): List; extensionmethod; +begin + Result := SystemSliceListImplQuestion(Self,situation,from,&to,1); +end; + +///-- +function SystemSliceQuestion(Self: List; situation: integer; from,&to,step: integer): List; extensionmethod; +begin + Result := SystemSliceListImplQuestion(Self,situation,from,&to,step); +end; // ----------------------------------------------------- //>> Методы расширения типа array [,] of T # Extension methods for array [,] of T // ----------------------------------------------------- @@ -9220,7 +9301,7 @@ end; ///-- function SystemSliceArrayImpl(Self: array of T; situation: integer; from,&to: integer; step: integer := 1): array of T; begin - var count := CalcCountForSystemSlice(situation,Self.Length,from,&to,step); + var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation,Self.Length,from,&to,step); Result := CreateSliceFromArrayInternal(Self,from,step,count) end; @@ -9237,6 +9318,26 @@ begin Result := SystemSliceArrayImpl(Self,situation,from,&to,step); end; +///-- +function SystemSliceArrayImplQuestion(Self: array of T; situation: integer; from,&to: integer; step: integer := 1): array of T; +begin + var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation,Self.Length,from,&to,step); + + Result := CreateSliceFromArrayInternal(Self,from,step,count); +end; + +///-- +function SystemSliceQuestion(Self: array of T; situation: integer; from,&to: integer): array of T; extensionmethod; +begin + Result := SystemSliceArrayImplQuestion(Self,situation,from,&to,1); +end; + +///-- +function SystemSliceQuestion(Self: array of T; situation: integer; from,&to,step: integer): array of T; extensionmethod; +begin + Result := SystemSliceArrayImplQuestion(Self,situation,from,&to,step); +end; + // ----------------------------------------------------- //>> Методы расширения типа integer # Extension methods for integer // ----------------------------------------------------- @@ -9588,7 +9689,7 @@ function SystemSliceStringImpl(Self: string; situation: integer; from,&to: integ begin var fromv := from-1; var tov := &to-1; - var count := CalcCountForSystemSlice(situation,Self.Length,fromv,tov,step); + var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation,Self.Length,fromv,tov,step); Result := CreateSliceFromStringInternal(Self,fromv+1,step,count) end; @@ -9605,7 +9706,28 @@ begin Result := SystemSliceStringImpl(Self,situation,from,&to,step); end; +///-- +function SystemSliceStringImplQuestion(Self: string; situation: integer; from,&to: integer; step: integer := 1): string; +begin + var fromv := from-1; + var tov := &to-1; + + var count := CorrectFromToAndCalcCountForSystemSliceQuestion(situation,Self.Length,fromv,tov,step); + + Result := CreateSliceFromStringInternal(Self,fromv+1,step,count); +end; +///-- +function SystemSliceQuestion(Self: string; situation: integer; from,&to: integer): string; extensionmethod; +begin + Result := SystemSliceStringImplQuestion(Self,situation,from,&to,1); +end; + +///-- +function SystemSliceQuestion(Self: string; situation: integer; from,&to,step: integer): string; extensionmethod; +begin + Result := SystemSliceStringImplQuestion(Self,situation,from,&to,step); +end; //-------------------------------------------- //>> Методы расширения типа Func # Extension methods for Func //--------------------------------------------