From 6c9aed039abc7e6969ad5d46b37df90244b27738 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: Thu, 14 Apr 2016 20:16:31 +0200 Subject: [PATCH] bug fix #122, #134, #137 --- .../ParserTools/DefaultLanguageInformation.cs | 3 +- TestSuite/CompilationSamples/PABCSystem.pas | 4 +- TestSuite/set9.pas | 2 + TreeConverter/NetWrappers/NetHelper.cs | 2 +- TreeConverter/SymbolTable/DSST/SymbolTable.cs | 2 +- .../TreeConversion/compilation_context.cs | 7 ++- .../convertion_data_and_alghoritms.cs | 20 ++++++- .../TreeConversion/syntax_tree_visitor.cs | 59 +++++++++++++++++-- bin/Lib/PABCSystem.pas | 4 +- 9 files changed, 88 insertions(+), 15 deletions(-) diff --git a/ParserTools/ParserTools/DefaultLanguageInformation.cs b/ParserTools/ParserTools/DefaultLanguageInformation.cs index 11991cdfe..08be34ac7 100644 --- a/ParserTools/ParserTools/DefaultLanguageInformation.cs +++ b/ParserTools/ParserTools/DefaultLanguageInformation.cs @@ -1638,7 +1638,8 @@ namespace PascalABCCompiler.Parsers Type[] class_generic_args = pis[i].ParameterType.GetGenericArguments(); for (int j = 0; j < class_generic_args.Length; j++) { - class_generic_table.Add(class_generic_args[i].Name, j); + if (!class_generic_table.ContainsKey(class_generic_args[i].Name)) + class_generic_table.Add(class_generic_args[i].Name, j); } break; } diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index a8fb71b3b..4490a483e 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -8975,7 +8975,7 @@ end; // ------------------------------------------- // Дополнения февраль 2016 -{// Добавляет поле к кортежу +// Добавляет поле к кортежу function Add (Self: (T1,T2); v: T3): (T1,T2,T3); extensionmethod; begin Result := (Self[0],Self[1],v); @@ -9003,7 +9003,7 @@ end; function Add (Self: (T1,T2,T3,T4,T5,T6); v: T7): (T1,T2,T3,T4,T5,T6,T7); extensionmethod; begin Result := (Self[0],Self[1],Self[2],Self[3],Self[4],Self[5],v); -end;} +end; {// Определяет, есть ли указанный элемент в массиве function Contains(self: array of T; x: T): boolean; extensionmethod; diff --git a/TestSuite/set9.pas b/TestSuite/set9.pas index c0fa4bacd..234e5fccb 100644 --- a/TestSuite/set9.pas +++ b/TestSuite/set9.pas @@ -6,4 +6,6 @@ begin hs.Println; var set1: set of integer := hs; assert(2 in set1); + var h: HashSet := [1,3,5]; + assert(3 in h); end. \ No newline at end of file diff --git a/TreeConverter/NetWrappers/NetHelper.cs b/TreeConverter/NetWrappers/NetHelper.cs index 2bdb4d82d..ad5bb8d1f 100644 --- a/TreeConverter/NetWrappers/NetHelper.cs +++ b/TreeConverter/NetWrappers/NetHelper.cs @@ -1519,7 +1519,7 @@ namespace PascalABCCompiler.NetHelper { SymbolInfo temp = new SymbolInfo(compiled_type_node.get_type_node(nested_t)); temp.Next = si; - si = temp; + si = temp; } return si; } diff --git a/TreeConverter/SymbolTable/DSST/SymbolTable.cs b/TreeConverter/SymbolTable/DSST/SymbolTable.cs index d4f35cd36..a8510ec2b 100644 --- a/TreeConverter/SymbolTable/DSST/SymbolTable.cs +++ b/TreeConverter/SymbolTable/DSST/SymbolTable.cs @@ -943,7 +943,7 @@ namespace SymbolTable return si; } else - if (AreaNodes != null) + if (AreaNodes != null && sc != null) { p = AreaNodes.IndexOf(sc.ScopeNum); if (p >= 0) diff --git a/TreeConverter/TreeConversion/compilation_context.cs b/TreeConverter/TreeConversion/compilation_context.cs index 2850686c4..a3005c0df 100644 --- a/TreeConverter/TreeConversion/compilation_context.cs +++ b/TreeConverter/TreeConversion/compilation_context.cs @@ -41,7 +41,6 @@ namespace PascalABCCompiler.TreeConverter public Stack type_stack; // Для вложенных типов public statement_list_stack stlist_stack; public semantic_node ret_value; // Возвращаемое значение класса returner - //LambdaHelper.Reset(); // Пока не знаю, что с этим делать } @@ -286,6 +285,7 @@ namespace PascalABCCompiler.TreeConverter ShortStringTypes.Clear(); TypedSets.Clear(); _compiled_tn = null; + _explicit_interface_type = null; _ctt = null; allow_inherited_ctor_call = false; _types_predefined.Clear(); @@ -297,6 +297,11 @@ namespace PascalABCCompiler.TreeConverter SavedContext = null; SavedContextStack.Clear(); compiled_tc_cache.Clear(); + extension_method = false; + _last_created_function = null; + in_parameters_block = false; + is_order_independed_method_description = false; + } public bool inStaticArea() diff --git a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs index a7edf1361..84cdf2a10 100644 --- a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs +++ b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs @@ -44,6 +44,12 @@ namespace PascalABCCompiler.TreeConverter return default(T); } + private T AddError(location loc, string ErrString, params string[] values) + { + syntax_tree_visitor.AddError(loc, ErrString, values); + return default(T); + } + private void AddError(location loc, string ErrString, params string[] values) { syntax_tree_visitor.AddError(loc, ErrString, values); @@ -586,6 +592,18 @@ namespace PascalABCCompiler.TreeConverter if (pct.first == null) throw new CanNotConvertTypes(en, en.type, to, loc); } + + public bool can_convert_type(expression_node en, type_node to) + { + if (en.type == to) + return true; + possible_type_convertions pct = type_table.get_convertions(en.type, to); + if (pct.second != null) + return false; + if (pct.first == null) + return false; + return true; + } public void check_convert_type_with_inheritance(type_node from, type_node to, location loc) { @@ -1890,7 +1908,7 @@ namespace PascalABCCompiler.TreeConverter if (set_of_possible_functions.Count == 0 && indefinits.Count == 0) { - AddError(loc, "CAN_NOT_CALL_ANY_GENERIC_FUNCTION_{0}_WITH_THESE_PARAMETERS", first_function.name); + return AddError(loc, "CAN_NOT_CALL_ANY_GENERIC_FUNCTION_{0}_WITH_THESE_PARAMETERS", first_function.name); } possible_type_convertions_list_list tcll = new possible_type_convertions_list_list(); diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 12b7df2fc..19a0a21fa 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -569,6 +569,8 @@ namespace PascalABCCompiler.TreeConverter WaitedRefTypes.Clear(); set_intls.Clear(); NetHelper.NetHelper.reset(); + if (ErrorsList != null) + ErrorsList.Clear(); from_pabc_dll = false; in_interface_part = false; compiled_type_node[] ctns = new compiled_type_node[compiled_type_node.compiled_types.Values.Count]; @@ -1244,20 +1246,30 @@ namespace PascalABCCompiler.TreeConverter } } } - if (si == null) + //if (si == null) { - if (si2 == null && left_type.semantic_node_type == semantic_node_type.delegated_method && right_type.semantic_node_type == semantic_node_type.delegated_method) + if (/*si2 == null && */left_type.semantic_node_type == semantic_node_type.delegated_method && right_type.semantic_node_type == semantic_node_type.delegated_method) { + SymbolInfo saved_si = si; + SymbolInfo saved_si2 = si2; base_function_call bfc = ((left as typed_expression).type as delegated_methods).proper_methods[0]; left = convertion_data_and_alghoritms.explicit_convert_type(left, CreateDelegate(bfc.simple_function_node)); si = left.type.find_in_type(name); bfc = ((right as typed_expression).type as delegated_methods).proper_methods[0]; right = convertion_data_and_alghoritms.explicit_convert_type(right, CreateDelegate(bfc.simple_function_node)); si2 = right.type.find_in_type(name); - if (si == null) + if (saved_si != null) + si.Next = saved_si; + else + saved_si = si; + if (saved_si2 != null) + si2.Next = saved_si2; + else + saved_si2 = si2; + if (saved_si == null) AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); } - else + else if (si == null) AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); } @@ -4903,6 +4915,14 @@ namespace PascalABCCompiler.TreeConverter if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfn.ConnectedToType == null) has_obj_methods = true; } + else if (si.sym_info is common_method_node) + { + common_method_node cfn = si.sym_info as common_method_node; + if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + si_list.Add(si); + if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + has_obj_methods = true; + } si = si.Next; } for (int i = 0; i < si_list.Count; i++) @@ -4962,7 +4982,34 @@ namespace PascalABCCompiler.TreeConverter function_node_list spf = null; try { + ThrowCompilationError = false; function_node ffn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); + if (ffn == null) + { + if (skip_first_parameter) + { + expressions_list ex_list = new expressions_list(); + ex_list.AddRange(exprs); + ex_list.remove_at(0); + ffn = convertion_data_and_alghoritms.select_function(ex_list, si, subloc, syntax_nodes_parameters); + if (ffn == null) + { + ThrowCompilationError = true; + throw LastError(); + } + RemoveLastError(); + skip_first_parameter = false; + exprs = ex_list; + ThrowCompilationError = true; + } + else + { + ThrowCompilationError = true; + throw LastError(); + } + + } + ThrowCompilationError = true; int exprCounter = 0; if (skip_first_parameter) { @@ -12626,7 +12673,7 @@ namespace PascalABCCompiler.TreeConverter } else if (exp is compiled_static_method_call && (exp.type.type_special_kind == SemanticTree.type_special_kind.set_type || exp.type.type_special_kind == SemanticTree.type_special_kind.base_set_type)) { - if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type)) + if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type) && !(convertion_data_and_alghoritms.can_convert_type(exp, tn))) { AddError(new CanNotConvertTypes(exp, exp.type, tn, exp.location)); } @@ -12655,7 +12702,7 @@ namespace PascalABCCompiler.TreeConverter } else if (exp is common_namespace_function_call && (exp.type.type_special_kind == SemanticTree.type_special_kind.set_type || exp.type.type_special_kind == SemanticTree.type_special_kind.base_set_type)) { - if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type)) + if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type) && !(convertion_data_and_alghoritms.can_convert_type(exp, tn))) { AddError(new CanNotConvertTypes(exp, exp.type, tn, exp.location)); } diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index a8fb71b3b..4490a483e 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -8975,7 +8975,7 @@ end; // ------------------------------------------- // Дополнения февраль 2016 -{// Добавляет поле к кортежу +// Добавляет поле к кортежу function Add (Self: (T1,T2); v: T3): (T1,T2,T3); extensionmethod; begin Result := (Self[0],Self[1],v); @@ -9003,7 +9003,7 @@ end; function Add (Self: (T1,T2,T3,T4,T5,T6); v: T7): (T1,T2,T3,T4,T5,T6,T7); extensionmethod; begin Result := (Self[0],Self[1],Self[2],Self[3],Self[4],Self[5],v); -end;} +end; {// Определяет, есть ли указанный элемент в массиве function Contains(self: array of T; x: T): boolean; extensionmethod;