diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 0a5ea77f6..2ed178f6e 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 = "10"; public const string Build = "0"; - public const string Revision = "3552"; + public const string Revision = "3555"; 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 62ba1afa9..02975e3e2 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%COREVERSION%=0 -%REVISION%=3552 %MINOR%=10 +%REVISION%=3555 +%COREVERSION%=0 %MAJOR%=3 diff --git a/Localization/DefaultLang.resources b/Localization/DefaultLang.resources index a43b04c94..3a7dc55fd 100644 Binary files a/Localization/DefaultLang.resources and b/Localization/DefaultLang.resources differ diff --git a/StringConstants/StringConstants.cs b/StringConstants/StringConstants.cs index 3958ded8b..5c834a805 100644 --- a/StringConstants/StringConstants.cs +++ b/StringConstants/StringConstants.cs @@ -248,8 +248,8 @@ namespace PascalABCCompiler public static string subtract_of_set = "Subtract"; public static string in_set = "InSet"; public static string CreateSetProcedure = "CreateSet"; - public static string IncludeProcedure = "Include"; - public static string ExcludeProcedure = "Exclude"; + //public static string IncludeProcedure = "Include"; + //public static string ExcludeProcedure = "Exclude"; public static string DiapasonType = "Diapason"; public static string CreateDiapason = "CreateDiapason"; public static string CreateObjDiapason = "CreateObjDiapason"; diff --git a/TestSuite/arrayofset2.pas b/TestSuite/arrayofset2.pas index 843c56921..0fc90ff92 100644 --- a/TestSuite/arrayofset2.pas +++ b/TestSuite/arrayofset2.pas @@ -1,4 +1,4 @@ -const c : array of set of char = (['a','b'],[],['k','l']); +const c : array of set of char = (['a','b'],[],['k','l']); var a : array of set of char := (['a','b'],[],['k','l']); b : array of set of 1..4 := ([1,2,7],[2,3],[]); d : array[1..3] of set of 1..4; diff --git a/TestSuite/nested2.pas b/TestSuite/nested2.pas index 9b4bf36fb..dc42f5cd9 100644 --- a/TestSuite/nested2.pas +++ b/TestSuite/nested2.pas @@ -1,4 +1,4 @@ -type TClass = class +type TClass = class procedure Meth; end; diff --git a/TreeConverter/SystemLib/SystemLibInitializer.cs b/TreeConverter/SystemLib/SystemLibInitializer.cs index b0d2a44e3..8e04ae611 100644 --- a/TreeConverter/SystemLib/SystemLibInitializer.cs +++ b/TreeConverter/SystemLib/SystemLibInitializer.cs @@ -263,8 +263,8 @@ namespace PascalABCCompiler.SystemLibrary public static UnitDefinitionItem SetSubtractProcedure; public static UnitDefinitionItem InSetProcedure; public static UnitDefinitionItem CreateSetProcedure; - public static UnitDefinitionItem IncludeProcedure; - public static UnitDefinitionItem ExcludeProcedure; + //public static UnitDefinitionItem IncludeProcedure; + //public static UnitDefinitionItem ExcludeProcedure; public static UnitDefinitionItem DiapasonType; public static UnitDefinitionItem CreateDiapason; public static UnitDefinitionItem CreateObjDiapason; diff --git a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs index 4ff5d9398..575f0b361 100644 --- a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs +++ b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs @@ -1893,7 +1893,9 @@ namespace PascalABCCompiler.TreeConverter { if (ptc.first.from is null_type_node || ptc.second.to == null || ptc.second.from is null_type_node || ptc.second.from.is_generic_parameter) continue; // SSM 9/12/20 fix 2363 - AddError(new PossibleTwoTypeConversionsInFunctionCall(loc,ptc.first,ptc.second)); + if (ptc.first.from == ptc.second.from && ptc.first.to == ptc.second.to) // SSM fix 03/08/24 - непонятно, как до этого могло дойти + continue; + AddError(new PossibleTwoTypeConversionsInFunctionCall(loc,ptc.first,ptc.second)); } } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index ab4dec249..479a1d84e 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -313,8 +313,8 @@ namespace PascalABCCompiler.TreeConverter SystemLibrary.SystemLibInitializer.InSetProcedure = null; SystemLibrary.SystemLibInitializer.CreateSetProcedure = null; SystemLibrary.SystemLibInitializer.TypedSetInitProcedure = null; - SystemLibrary.SystemLibInitializer.IncludeProcedure = null; - SystemLibrary.SystemLibInitializer.ExcludeProcedure = null; + //SystemLibrary.SystemLibInitializer.IncludeProcedure = null; + //SystemLibrary.SystemLibInitializer.ExcludeProcedure = null; SystemLibrary.SystemLibInitializer.DiapasonType = null; SystemLibrary.SystemLibInitializer.CreateDiapason = null; SystemLibrary.SystemLibInitializer.CreateObjDiapason = null; @@ -402,8 +402,8 @@ namespace PascalABCCompiler.TreeConverter SystemLibrary.SystemLibInitializer.SetSubtractProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.subtract_of_set); SystemLibrary.SystemLibInitializer.InSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.in_set); SystemLibrary.SystemLibInitializer.CreateSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateSetProcedure); - SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.IncludeProcedure); - SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.ExcludeProcedure); + //SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.IncludeProcedure); + //SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.ExcludeProcedure); SystemLibrary.SystemLibInitializer.DiapasonType = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.DiapasonType); SystemLibrary.SystemLibInitializer.CreateDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateDiapason); SystemLibrary.SystemLibInitializer.CreateObjDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateObjDiapason); @@ -496,8 +496,8 @@ namespace PascalABCCompiler.TreeConverter SystemLibrary.SystemLibInitializer.SetSubtractProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.subtract_of_set); SystemLibrary.SystemLibInitializer.InSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.in_set); SystemLibrary.SystemLibInitializer.CreateSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateSetProcedure); - SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.IncludeProcedure); - SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.ExcludeProcedure); + //SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.IncludeProcedure); + //SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.ExcludeProcedure); SystemLibrary.SystemLibInitializer.DiapasonType = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.DiapasonType); SystemLibrary.SystemLibInitializer.CreateDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateDiapason); SystemLibrary.SystemLibInitializer.CreateObjDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateObjDiapason); @@ -3738,8 +3738,32 @@ namespace PascalABCCompiler.TreeConverter public override void visit(SyntaxTree.set_type_definition _set_type_definition) { - // throw new NotSupportedError(get_location(_set_type_definition)); - if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) + // PABCSystem.NewSet + // + var ntr = new named_type_reference(new List { new ident("PABCSystem"), new ident("NewSet") }); + type_node el_type = convert_strong(_set_type_definition.of_type); + + if (el_type.type_special_kind == SemanticTree.type_special_kind.diap_type) + { + if (el_type is common_type_node ctn) + el_type = ctn.base_type; + } + + /* Не буду это делать! + * if (el_type == SystemLibrary.SystemLibrary.byte_type + || el_type == SystemLibrary.SystemLibrary.sbyte_type + || el_type == SystemLibrary.SystemLibrary.short_type + || el_type == SystemLibrary.SystemLibrary.ushort_type + ) + el_type = SystemLibrary.SystemLibrary.integer_type; + */ + + var el_sem_type = new SyntaxTree.semantic_type_node(el_type, _set_type_definition.of_type.source_context); + var tpr = new template_param_list(el_sem_type); + var ttr = new SyntaxTree.template_type_reference(ntr, tpr); + ProcessNode(ttr); + + /*if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) AddError(new NotSupportedError(get_location(_set_type_definition))); type_node el_type = convert_strong(_set_type_definition.of_type); if (el_type.IsPointer) @@ -3748,7 +3772,7 @@ namespace PascalABCCompiler.TreeConverter // AddError(new VoidNotValid(get_location(_set_type_definition.of_type))); check_for_type_allowed(el_type, get_location(_set_type_definition.of_type)); check_using_static_class(el_type, get_location(_set_type_definition.of_type)); - return_value(context.create_set_type(el_type, get_location(_set_type_definition))); + return_value(context.create_set_type(el_type, get_location(_set_type_definition)));*/ } public override void visit(SyntaxTree.known_type_definition _known_type_definition) @@ -5110,6 +5134,39 @@ namespace PascalABCCompiler.TreeConverter set_intls[cnfc] = exprs; } + private System.Tuple convert_diap_for_new_set(SyntaxTree.diapason_expr _diapason_expr, out type_node elem_type) + { + expression_node left = convert_strong(_diapason_expr.left); + if (left is typed_expression) left = convert_typed_expression_to_function_call(left as typed_expression); + expression_node right = convert_strong(_diapason_expr.right); + if (right is typed_expression) right = convert_typed_expression_to_function_call(right as typed_expression); + internal_interface ii = left.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (ii == null) + { + AddError(new OrdinalTypeExpected(left.location)); + } + internal_interface iir = right.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (iir == null) + { + AddError(new OrdinalTypeExpected(right.location)); + } + type_node_list tnl = new type_node_list(); + tnl.AddElement(left.type); + tnl.AddElement(right.type); + elem_type = convertion_data_and_alghoritms.select_base_type(tnl, true); + if (elem_type == SystemLibrary.SystemLibrary.object_type) + AddError(new SimpleSemanticError(get_location(_diapason_expr), "BAD_DIAPASON_IN_SET_TYPE")); + // До этого момента совпадает с convert_diap_for_set + + // если элементы - какого то целого типа, то привести к типу integer + if (elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type && elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type && !elem_type.IsEnum) + { + left = convertion_data_and_alghoritms.explicit_convert_type(left, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); + right = convertion_data_and_alghoritms.explicit_convert_type(right, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); + } + return Tuple.Create(left, right); + } + private expression_node convert_diap_for_set(SyntaxTree.diapason_expr _diapason_expr, out type_node elem_type) { expression_node left = convert_strong(_diapason_expr.left); @@ -5175,24 +5232,25 @@ namespace PascalABCCompiler.TreeConverter public override void visit(SyntaxTree.pascal_set_constant _pascal_set_constant) { - //throw new NotSupportedError(get_location(_pascal_set_constant)); - if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) - AddError(new NotSupportedError(get_location(_pascal_set_constant))); + // надо разбить на 2 списка констант expressions_list consts = new expressions_list(); - type_node el_type = null; - type_node_list types = new type_node_list(); + expressions_list consts_diap = new expressions_list(); + + type_node el_type = null; // вывод самого общего типа элемента + type_node_list types = new type_node_list(); // этот список - единый. Он нужен только для вывода самого общего типа if (_pascal_set_constant.values != null && _pascal_set_constant.values.expressions != null) foreach (SyntaxTree.expression e in _pascal_set_constant.values.expressions) { - if (e is SyntaxTree.nil_const) - ErrorsList.Add(new SimpleSemanticError(get_location(e), "NIL_IN_SET_CONSTRUCTOR_NOT_ALLOWED")); - else - if (e is SyntaxTree.diapason_expr) + if (e is SyntaxTree.nil_const) + AddError(new SimpleSemanticError(get_location(e), "NIL_IN_SET_CONSTRUCTOR_NOT_ALLOWED")); + else + if (e is SyntaxTree.diapason_expr) { - expression_node en = convert_diap_for_set((e as SyntaxTree.diapason_expr), out el_type); - consts.AddElement(en); + var pair = convert_diap_for_new_set((e as SyntaxTree.diapason_expr), out el_type); + consts_diap.AddElement(pair.Item1); + consts_diap.AddElement(pair.Item2); if (el_type.IsPointer) - ErrorsList.Add(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED")); + AddError(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED")); types.AddElement(el_type); } else @@ -5200,57 +5258,116 @@ namespace PascalABCCompiler.TreeConverter expression_node en = convert_strong(e); if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string) - en.type = SystemLibrary.SystemLibrary.string_type; + en.type = SystemLibrary.SystemLibrary.string_type; consts.AddElement(en); + if (en.type.IsPointer) + AddError(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED")); types.AddElement(en.type); } } - type_node ctn = null; - if (consts.Count > 0) + // Константы и типы заполнены + // Выводим самый общий тип + + //type_node ctn = null; + if (types.Count > 0) { - el_type = convertion_data_and_alghoritms.select_base_type(types, true); + el_type = convertion_data_and_alghoritms.select_base_type(types, true); // !! if (el_type == null) AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); - - ctn = context.create_set_type(el_type, get_location(_pascal_set_constant)); - + // Делаю невозможным базовый тип object - не нравится это, и в массивах нет + if (el_type == SystemLibrary.SystemLibrary.object_type) + AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); + // если есть диапазоны, то базовый тип не может быть int64 и проч - только integer!!! + if (consts_diap.Count > 0) + if (el_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type + && el_type != PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type + && el_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type + && !el_type.IsEnum) + AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); } - else ctn = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; - /*if (el_type == SystemLibrary.SystemLibrary.string_type) + // Теперь базовый тип известен (он может быть null), и надо сгенерировать + // EmptySet + // NSet(consts) или + // NSet(Arr(consts), Arr(consts_diap)) + // и обойти его + // Для el_type, consts и consts_diap надо делать обёртку semantic_type_node + // и semantic_addr_value (тут не знаю - это константы вроде, хотя там к expression_node приводится так что всё хорошо) + // new semantic_addr_value() + + var p = _pascal_set_constant; + var psc = p.source_context; + if (el_type == null) { - for (int i = 0; i < consts.Count; i++) - if (consts[i].type == SystemLibrary.SystemLibrary.char_type) - { - consts[i] = convertion_data_and_alghoritms.convert_type(consts[i], el_type); - } - } */ // Не работает ! SSM 19.03.19 - - expressions_list consts_copy = new expressions_list(); - consts_copy.AddRange(consts); - - function_node fn = convertion_data_and_alghoritms.select_function(consts, SystemLibrary.SystemLibInitializer.CreateSetProcedure.SymbolInfo, (SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info is common_namespace_function_node)?(SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node).loc:null); - - - if (fn is common_namespace_function_node) + var dn = new dot_node(new ident("PABCSystem", psc), new ident("EmptySet", psc)); + ProcessNode(dn); + } + else if (consts_diap.Count == 0) { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, get_location(_pascal_set_constant)); - add_set_initializer(cnfc, consts_copy); - cnfc.ret_type = ctn; - for (int i = 0; i < consts.Count; i++) - cnfc.parameters.AddElement(consts[i]); - return_value(cnfc); + // Это прямо очень хорошо! Просто вызываем NSet(consts) + var nset_type = new semantic_type_node(el_type, psc); + var dn = new ident("__NewSetCreatorInternal", psc); + var td = new semantic_type_node(el_type, psc); + var tpl = new template_param_list(new List { td }, psc); + var method_name = new ident_with_templateparams(dn, tpl, psc); + var m_el = new expression_list(); + foreach (var el in consts) + m_el.Add(new semantic_addr_value(el, el.location)); + // Добавим все обёрнутые константы + var mc = new method_call(method_name, m_el, psc); + ProcessNode(mc); } else { - compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, get_location(_pascal_set_constant)); - add_set_initializer(cnfc, consts_copy); - cnfc.ret_type = ctn; - for (int i = 0; i < consts.Count; i++) - cnfc.parameters.AddElement(consts[i]); - return_value(cnfc); + _pascal_set_constant = _pascal_set_constant; + // Ну теперь самый общий NSet(Arr(consts), Arr(consts_diap)) + var nset_type = new semantic_type_node(el_type, psc); + var dnNSetInt = new dot_node(new ident("PABCSystem", psc), new ident("__NSetInteger", psc)); + var dnNSetChar = new dot_node(new ident("PABCSystem", psc), new ident("__NSetChar", psc)); + var dnNSetEnum = new dot_node(new ident("PABCSystem", psc), new ident("__NSetEnum", psc)); + var dnNSetBool = new dot_node(new ident("PABCSystem", psc), new ident("__NSetBoolean", psc)); + + // PABCSystem.Arr нельзя использовать - кидает странную ошибку + var dnArr = new dot_node(new ident("PABCSystem", psc), new ident("Arr", psc)); + var td = new semantic_type_node(el_type, psc); + var tpl = new template_param_list(new List { td }, psc); + var method_name_Arr = new ident_with_templateparams(dnArr, tpl, psc); + + var m_el_Arr1 = new expression_list(); + foreach (var el in consts) + m_el_Arr1.Add(new semantic_addr_value(el, el.location)); + + var m_el_Arr2 = new expression_list(); + foreach (var el in consts_diap) + m_el_Arr2.Add(new semantic_addr_value(el, el.location)); + + + var cnt1 = new expression_list(new int32_const(m_el_Arr1.Count), p.values.source_context); + var cnt2 = new expression_list(new int32_const(m_el_Arr2.Count), p.values.source_context); + var arr1_init = new SyntaxTree.array_const(m_el_Arr1, p.values.source_context); + var arr2_init = new SyntaxTree.array_const(m_el_Arr2, p.values.source_context); + var new_arr1 = new new_expr(td, cnt1, true, arr1_init, p.values.source_context); + var new_arr2 = new new_expr(td, cnt2, true, arr2_init, p.values.source_context); + + //var mc1 = new method_call(method_name_Arr, m_el_Arr1, psc); + //var mc2 = new method_call(method_name_Arr, m_el_Arr2, psc); + + var m_el_NSet = new expression_list(); + m_el_NSet.Add(new_arr1); + m_el_NSet.Add(new_arr2); + method_call mc_NSet = null; + + if (el_type == PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type) + mc_NSet = new method_call(dnNSetInt, m_el_NSet, psc); + else if (el_type == PascalABCCompiler.SystemLibrary.SystemLibrary.char_type) + mc_NSet = new method_call(dnNSetChar, m_el_NSet, psc); + else if (el_type.IsEnum) + mc_NSet = new method_call(dnNSetEnum, m_el_NSet, psc); + else if (el_type == PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type) + mc_NSet = new method_call(dnNSetBool, m_el_NSet, psc); + else AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); + ProcessNode(mc_NSet); } - //return_value(new common_namespace_function_call_as_constant(cnfc,cnfc.location)); } public override void visit(SyntaxTree.array_const_new acn) @@ -7031,7 +7148,7 @@ namespace PascalABCCompiler.TreeConverter } } } - else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) + /*else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(sil)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 2) @@ -7083,9 +7200,9 @@ namespace PascalABCCompiler.TreeConverter AddError(en_cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } - } */ + } } - } + }*/ else if (SystemLibrary.SystemLibInitializer.IncProcedure.Equal(sil)) { expression_node bfcint = make_inc_call(sil?.FirstOrDefault(), _method_call.parameters, subloc2); @@ -8029,7 +8146,7 @@ namespace PascalABCCompiler.TreeConverter else ConvertPointersForWriteFromDll(exprs); } - else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) + /*else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(sil)) { if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(FunctionName, loc, true)); @@ -8042,7 +8159,7 @@ namespace PascalABCCompiler.TreeConverter convertion_data_and_alghoritms.check_convert_type(exprs[1], element_type, exprs[1].location); else convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[0].location); if (!exprs[0].is_addressed) AddError(new ThisExpressionCanNotBePassedAsVarParameter(exprs[0])); - } + }*/ else if (SystemLibrary.SystemLibInitializer.InSetProcedure.Equal(sil)) { if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(FunctionName, loc, true)); @@ -15238,7 +15355,9 @@ namespace PascalABCCompiler.TreeConverter if (csmc.type != null && csmc.type != SystemLibrary.SystemLibrary.void_type && (csmc.function_node.IsSpecialName && csmc.function_node.is_readonly || NetHelper.NetHelper.PABCSystemType != null && csmc.function_node.cont_type.compiled_type.Assembly == NetHelper.NetHelper.PABCSystemType.Assembly || !is_const_section)) constant = new compiled_static_method_call_as_constant(csmc, expr.location); } - else if (expr is common_namespace_function_call && SystemLibrary.SystemLibInitializer.CreateSetProcedure != null && (expr as common_namespace_function_call).function_node == SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node) + else if (expr is common_namespace_function_call + && SystemLibrary.SystemLibInitializer.CreateSetProcedure != null + && (expr as common_namespace_function_call).function_node == SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node) { common_namespace_function_call cnfc = expr as common_namespace_function_call; expressions_list exprs = get_set_initializer(cnfc); @@ -15255,6 +15374,23 @@ namespace PascalABCCompiler.TreeConverter } constant = new common_namespace_function_call_as_constant(cnfc, loc); } + else if (expr is common_namespace_function_call cnfc1 + && cnfc1.function_node.attributes.Count > 0 + && cnfc1.function_node.attributes[0].attribute_type.name.ToLower() == "SetCreatorFunctionAttribute".ToLower() + ) + { + // Надо компоненты проверять на константность + constant = new common_namespace_function_call_as_constant(cnfc1, loc); + return constant; + } + else if (expr is common_namespace_function_call cnfc2 + && cnfc2.function_node.name.StartsWith("__NewSetCreatorInternal") + ) + { + // Надо компоненты проверять на константность + constant = new common_namespace_function_call_as_constant(cnfc2, loc); + return constant; + } else if (is_const_section_and_userfuncall && (expr is basic_function_call || expr is common_namespace_function_call)) // только в разделе const { AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); diff --git a/TreeConverter/TreeRealization/type_table.cs b/TreeConverter/TreeRealization/type_table.cs index a30cbde46..c24a0fe13 100644 --- a/TreeConverter/TreeRealization/type_table.cs +++ b/TreeConverter/TreeRealization/type_table.cs @@ -859,7 +859,8 @@ namespace PascalABCCompiler.TreeRealization } else { - ptc.second = new type_conversion(fn); + if (ptc.first.convertion_method != fn) // SSM 04/08/24 !!! - это когда есть op_implicit(Typ): Typ + ptc.second = new type_conversion(fn); } ptc.from = from; ptc.to = to; diff --git a/bin/Lib/PABCExtensions.pas b/bin/Lib/PABCExtensions.pas index ad6c12794..595c9e67d 100644 --- a/bin/Lib/PABCExtensions.pas +++ b/bin/Lib/PABCExtensions.pas @@ -409,9 +409,9 @@ begin Result += x; end;} -///-- -function operator implicit(a: array of integer): set of integer; extensionmethod := TypedSet.InitBy(a); {///-- +function operator implicit(a: array of integer): set of integer; extensionmethod := TypedSet.InitBy(a); +///-- function operator implicit(a: array of real): set of real; extensionmethod := TypedSet.InitBy(a); ///-- function operator implicit(a: array of string): set of string; extensionmethod := TypedSet.InitBy(a); @@ -433,9 +433,9 @@ function operator implicit(a: array of BigInteger): set of BigInteger; extension function operator implicit(a: array of decimal): set of decimal; extensionmethod := TypedSet.InitBy(a); ///-- function operator implicit(a: array of single): set of single; extensionmethod := TypedSet.InitBy(a); -} ///-- function operator implicit(a: array of T): set of T; extensionmethod := TypedSet.InitBy(a); +} //------------------------------------------------------------------------------ // Операции для procedure @@ -452,6 +452,206 @@ begin Result := () -> for var i:=1 to n do p end; +// Важнейший для новых множеств !!! +procedure operator:=(var Self: NewSet; st: NewSet); extensionmethod; +begin + Self._hs := new HashSet(st.hs); +end; + +// Extension-vtnjls для новых множеств +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function NSToInts(ns: NewSet) := ns._hs.Select(x -> integer(x)); +function NSToInts(ns: NewSet) := ns._hs.Select(x -> integer(x)); +function NSToInts64(ns: NewSet) := ns._hs.Select(x -> int64(x)); +function NSToInts64(ns: NewSet) := ns._hs.Select(x -> int64(x)); +function NSToBytes(ns: NewSet) := ns._hs.Select(x -> byte(x)); +function NSToBytes(ns: NewSet) := ns._hs.Select(x -> byte(x)); + +// и для массивов столько же +function operator=(a: NewSet; b: NewSet); extensionmethod := a._hs.SetEquals(NSToInts(b)); +function operator=(a: NewSet; b: NewSet): boolean; extensionmethod := b._hs.SetEquals(NSToInts(a)); +function operator=(a: NewSet; b: NewSet); extensionmethod := a._hs.SetEquals(NSToInts64(b)); +function operator=(a: NewSet; b: NewSet): boolean; extensionmethod := b._hs.SetEquals(NSToInts64(a)); + +function operator=(a: NewSet; b: array of byte); extensionmethod := a._hs.SetEquals(b.Select(x -> integer(x))); +function operator=(a: array of byte; b: NewSet): boolean; extensionmethod := b = a; +function operator=(a: array of int64; b: NewSet); extensionmethod := a.ToHashSet.SetEquals(NSToInts64(b)); +function operator=(a: NewSet; b: array of int64): boolean; extensionmethod := b = a; + +//function operator=(a: NewSet; b: NewSet); extensionmethod := a._hs.SetEquals(NSToInts64(b)); +//function operator=(a: NewSet; b: NewSet): boolean; extensionmethod := a = b; + +// Следующие функции предназначены для сравнения массива целых со множеством. +// Массив должен интерпретироваться как множество +// Не пойму - что использовать - эту строку или предыдущие. Все типы массивов сравнивать с NewSet +// или наоборот все типы множеств - с array of integer +function operator=(a: NewSet; b: array of integer): boolean; extensionmethod := NSToInts(a).ToHashSet.SetEquals(b); + +function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +//function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +//function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); + +function operator<(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSubsetOf(NSToInts(b)); +function operator<(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSubsetOf(NSToInts64(b)); +//function operator<(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSubsetOf(NSToInts64(b)); + +function operator>(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSupersetOf(NSToInts(b)); +function operator>(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSupersetOf(NSToInts64(b)); +//function operator>(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSupersetOf(NSToInts64(b)); + +function operator<(a: NewSet; b: NewSet); extensionmethod := b > a; +function operator<(a: NewSet; b: NewSet); extensionmethod := b > a; +//function operator<(a: NewSet; b: NewSet); extensionmethod := b > a; + +function operator>(a: NewSet; b: NewSet); extensionmethod := b < a; +function operator>(a: NewSet; b: NewSet); extensionmethod := b < a; +//function operator>(a: NewSet; b: NewSet); extensionmethod := b < a; + +function operator<=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSubsetOf(NSToInts(b)); +function operator<=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSubsetOf(NSToInts64(b)); +//function operator<=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSubsetOf(NSToInts64(b)); + +function operator>=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSupersetOf(NSToInts(b)); +function operator>=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSupersetOf(NSToInts64(b)); +//function operator>=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSupersetOf(NSToInts64(b)); + +function operator<=(a: NewSet; b: NewSet); extensionmethod := b >= a; +function operator<=(a: NewSet; b: NewSet); extensionmethod := b >= a; +//function operator<(a: NewSet; b: NewSet); extensionmethod := b >= a; + +function operator>=(a: NewSet; b: NewSet); extensionmethod := b <= a; +function operator>=(a: NewSet; b: NewSet); extensionmethod := b <= a; +//function operator>(a: NewSet; b: NewSet); extensionmethod := b <= a; + +procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToBytes(b)); +procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToInts(b)); +procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToInts64(b)); +procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToInts(b)); + +//procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToBytes(b)); +//procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToInts64(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToBytes(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToInts(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToInts64(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToInts(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToBytes(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToInts64(b)); + +procedure operator-=(var a: NewSet; b: NewSet); extensionmethod := a._hs.ExceptWith(NSToBytes(b)); +procedure operator-=(var a: NewSet; b: NewSet); extensionmethod := a._hs.ExceptWith(NSToInts(b)); +procedure operator-=(var a: NewSet; b: NewSet); extensionmethod := a._hs.ExceptWith(NSToInts64(b)); +procedure operator-=(var a: NewSet; b: NewSet); extensionmethod := a._hs.ExceptWith(NSToInts(b)); + + +// Нет операции между set of byte и set of int64. Один из операндов должен быть set of integer +function operator*(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result *= b +end; + +function operator*(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result *= b +end; + +function operator*(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result *= b +end; + +function operator*(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result *= b +end; +//----- + +function operator+(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result += b +end; + +function operator+(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result += b +end; + +function operator+(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result += b +end; + +function operator+(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result += b +end; + +//----- +function operator-(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result -= b +end; + +function operator-(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result -= b +end; + +function operator-(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result -= b +end; + +function operator-(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result -= b +end; + + + var __initialized: boolean; {procedure __InitModule; diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index a7f234979..f01d360a2 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -481,6 +481,125 @@ type public function Equals(x: System.Object; y: System.Object): boolean; public function GetHashCode(obj: System.Object): integer; end;} + +type + /// Тип нового встроенного множества + NewSet = record(IEnumerable) + private + public + ///-- + _hs := new HashSet; + ///-- + function hs: HashSet; + begin + if _hs = nil then + _hs := new HashSet; + Result := _hs; + end; + constructor (params a: array of T); + begin + hs.UnionWith(a); + end; + function GetEnumerator: IEnumerator := hs.GetEnumerator; + function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := GetEnumerator; + static function operator implicit(a: array of T): NewSet; + begin + Result._hs := new HashSet(a); + end; + function ToString: string; override; + function Count: integer := hs.Count; + function Clone: NewSet; begin Result.hs.UnionWith(hs) end; + function Add(elem: T): boolean := hs.Add(elem); + procedure AddRange(elems: sequence of T) := hs.UnionWith(elems); + function Remove(elem: T): boolean := hs.Remove(elem); + static procedure operator +=(Self: NewSet; elem: T) := Self.hs.Add(elem); + static procedure operator -=(Self: NewSet; elem: T) := Self.hs.Remove(elem); + function Contains(elem: T): boolean := hs.Contains(elem); + static function operator in(elem: T; Self: NewSet): boolean; + begin + Result := Self.hs.Contains(elem); + end; + static procedure operator+=(Self, another: NewSet) := Self.hs.UnionWith(another.hs); + static procedure operator-=(Self, another: NewSet) := Self.hs.ExceptWith(another.hs); + static procedure operator*=(Self, another: NewSet) := Self.hs.IntersectWith(another.hs); + static function operator+(first, second: NewSet): NewSet; + begin + Result += first; Result += second; + end; + static function operator*(first, second: NewSet): NewSet; + begin + Result += first; Result *= second; + end; + static function operator-(first, second: NewSet): NewSet; + begin + Result += first; Result -= second; + end; + static function operator=(first, second: NewSet) := first.hs.SetEquals(second.hs); + static function operator<>(first, second: NewSet) := not (first = second); + static function operator<(first, second: NewSet) := first.hs.IsProperSubsetOf(second.hs); + static function operator<=(first, second: NewSet) := first.hs.IsSubsetOf(second.hs); + static function operator>(first, second: NewSet) := first.hs.IsProperSupersetOf(second.hs); + static function operator>=(first, second: NewSet) := first.hs.IsSupersetOf(second.hs); + + static function operator implicit(ns: NewSet): HashSet := ns.ToHashSet; + static function operator implicit(ns: HashSet): NewSet; + begin + Result.hs.UnionWith(ns); + end; + end; + + NewSetEmpty = record + static function operator implicit(ns: NewSetEmpty): NewSet; begin end; + + static function operator=(s1: NewSet; s2: NewSetEmpty): boolean := s1.Count = 0; + static function operator=(s2: NewSetEmpty; s1: NewSet): boolean := s1.Count = 0; + static function operator<>(s1: NewSet; s2: NewSetEmpty): boolean := not (s1 = s2); + static function operator<>(s2: NewSetEmpty; s1: NewSet): boolean := not (s1 = s2); + static function operator>(s1: NewSet; s2: NewSetEmpty): boolean := s1.Count > 0; + static function operator>(s2: NewSetEmpty; s1: NewSet): boolean := False; + static function operator<(s1: NewSet; s2: NewSetEmpty): boolean := False; + static function operator<(s2: NewSetEmpty; s1: NewSet): boolean := s1.Count > 0; + static function operator>=(s1: NewSet; s2: NewSetEmpty): boolean := s1.Count >= 0; + static function operator>=(s2: NewSetEmpty; s1: NewSet): boolean := False; + static function operator<=(s1: NewSet; s2: NewSetEmpty): boolean := False; + static function operator<=(s2: NewSetEmpty; s1: NewSet): boolean := s1.Count >= 0; + // ToDo: определить то же для массивов на будущее + + static function operator+(first, second: NewSetEmpty): NewSetEmpty; begin end; + static function operator-(first, second: NewSetEmpty): NewSetEmpty; begin end; + static function operator*(first, second: NewSetEmpty): NewSetEmpty; begin end; + static function operator+(first: NewSetEmpty; second: array of T): NewSet; + begin + Result._hs.UnionWith(second); + end; + static function operator+(first: array of T; second: NewSetEmpty): NewSet; + begin + Result._hs.UnionWith(first); + end; + static function operator+(first: NewSet; second: NewSetEmpty): NewSet := first; + static function operator+(first: NewSetEmpty; second: NewSet): NewSet := second; + static function operator*(first: NewSet; second: NewSetEmpty): NewSet; begin end; + static function operator*(first: NewSetEmpty; second: NewSet): NewSet; begin end; + static function operator-(first: NewSet; second: NewSetEmpty): NewSet := first; + static function operator-(first: NewSetEmpty; second: NewSet): NewSet; begin end; + + static function operator*(first: NewSetEmpty; second: array of T): NewSet; begin end; + static function operator*(first: array of T; second: NewSetEmpty): NewSet; begin end; + static function operator-(first: NewSetEmpty; second: array of T): NewSet; begin end; + static function operator-(first: array of T; second: NewSetEmpty): NewSet; + begin + Result._hs.UnionWith(first); + end; + function ToString: string; override := '{}'; + static function operator implicit(Self: NewSetEmpty): array of T; + begin + Result := new T[0]; + end; + static function operator implicit(Self: NewSetEmpty): HashSet; + begin + Result := new HashSet; + end; + end; type // Вспомогательный тип для множества @@ -528,6 +647,20 @@ type procedure Println(delim: string := ' '); end; +/// Значение пустого множества +function EmptySet: NewSetEmpty; + +/// Генератор множества +function __NewSetCreatorInternal(params a: array of T): NewSet; +/// Генератор множества +function __NSetInteger(a: array of integer; dd: array of integer): NewSet; +/// Генератор множества +function __NSetChar(a: array of char; dd: array of char): NewSet; +/// Генератор множества +function __NSetEnum(a: array of T; dd: array of T): NewSet; +/// Генератор множества +function __NSetBoolean(a: array of boolean; dd: array of boolean): NewSet; + type // Base class for typed and binary files ///-- @@ -1872,6 +2005,30 @@ procedure Include(var s: TypedSet; el: object); ///- procedure Exclude(var s: set of T; element: T); ///Удаляет элемент element из множества s procedure Exclude(var s: TypedSet; el: object); +///- procedure Include(var s: set of T; element: T); +///Добавляет элемент element во множество s +procedure Include(var s: NewSet; el: T); +///- procedure Exclude(var s: set of T; element: T); +///Удаляет элемент element из множества s +procedure Exclude(var s: NewSet; el: T); + +procedure Include(var s: NewSet; el: byte); +procedure Exclude(var s: NewSet; el: byte); +procedure Include(var s: NewSet; el: word); +procedure Exclude(var s: NewSet; el: word); +procedure Include(var s: NewSet; el: integer); +procedure Exclude(var s: NewSet; el: integer); +procedure Include(var s: NewSet; el: longword); +procedure Exclude(var s: NewSet; el: longword); +procedure Include(var s: NewSet; el: shortint); +procedure Exclude(var s: NewSet; el: shortint); +procedure Include(var s: NewSet; el: smallint); +procedure Exclude(var s: NewSet; el: smallint); +procedure Include(var s: NewSet; el: int64); +procedure Exclude(var s: NewSet; el: int64); +procedure Include(var s: NewSet; el: uint64); +procedure Exclude(var s: NewSet; el: uint64); + // ----------------------------------------------------- //>> Подпрограммы для работы с символами # Subroutines for char @@ -2970,6 +3127,8 @@ function DQNToNullable(v: T): Nullable; where T: record; implementation +function NewSet.ToString: string := $'{ObjectToString(hs)}'; + var rnd: System.Random; nfi: NumberFormatInfo; @@ -3821,6 +3980,25 @@ begin s.ExcludeElement(el); end; +procedure Include(var s: NewSet; el: T) := s.Add(el); +procedure Exclude(var s: NewSet; el: T) := s.Remove(el); +procedure Include(var s: NewSet; el: byte) := s.Add(el); +procedure Exclude(var s: NewSet; el: byte) := s.Remove(el); +procedure Include(var s: NewSet; el: word) := s.Add(el); +procedure Exclude(var s: NewSet; el: word) := s.Remove(el); +procedure Include(var s: NewSet; el: integer) := s.Add(el); +procedure Exclude(var s: NewSet; el: integer) := s.Remove(el); +procedure Include(var s: NewSet; el: longword) := s.Add(el); +procedure Exclude(var s: NewSet; el: longword) := s.Remove(el); +procedure Include(var s: NewSet; el: shortint) := s.Add(el); +procedure Exclude(var s: NewSet; el: shortint) := s.Remove(el); +procedure Include(var s: NewSet; el: smallint) := s.Add(el); +procedure Exclude(var s: NewSet; el: smallint) := s.Remove(el); +procedure Include(var s: NewSet; el: int64) := s.Add(el); +procedure Exclude(var s: NewSet; el: int64) := s.Remove(el); +procedure Include(var s: NewSet; el: uint64) := s.Add(el); +procedure Exclude(var s: NewSet; el: uint64) := s.Remove(el); + [System.Diagnostics.DebuggerStepThrough] function Union(s1, s2: TypedSet): TypedSet; begin @@ -15206,6 +15384,136 @@ begin result := System.Runtime.InteropServices.Marshal.SizeOf(val); end; +// Функции для новых множеств + +{procedure operator:=(var Self: NewSet; st: NewSet); extensionmethod; +begin + Self.hs := new HashSet(st.hs); +end;} + +// Присваивание реализовано в PABCExtensions. Здесь не работает + +var _emptyset: NewSetEmpty; + +type + SetCreatorFunctionAttribute = class(Attribute) + end; + +function EmptySet := _emptyset; + +[SetCreatorFunction] +function __NewSetCreatorInternal(params a: array of T): NewSet; +begin + Result._hs := new HashSet; + Result._hs.UnionWith(a); +end; + +[SetCreatorFunction] +function __NSetInteger(a: array of integer; dd: array of integer): NewSet; +begin + Result._hs.UnionWith(a); + var n := dd.Length; + for var i:=0 to n-1 step 2 do + begin + for var j := dd[i] to dd[i+1] do + Result.Add(j); + end +end; + +[SetCreatorFunction] +function __NSetChar(a: array of char; dd: array of char): NewSet; +begin + Result._hs.UnionWith(a); + var n := dd.Length; + for var i:=0 to n-1 step 2 do + begin + for var j := dd[i] to dd[i+1] do + Result.Add(j); + end +end; + +[SetCreatorFunction] +function __NSetBoolean(a: array of boolean; dd: array of boolean): NewSet; +begin + Result._hs.UnionWith(a); + var n := dd.Length; + for var i:=0 to n-1 step 2 do + begin + for var j := dd[i] to dd[i+1] do + Result.Add(j); + end +end; + +[SetCreatorFunction] +function __NSetEnum(a: array of T; dd: array of T): NewSet; +begin + Result._hs.UnionWith(a); + var vals := System.Enum.GetValues(typeof(T)).Cast&.ToArray; + var n := dd.Length; + for var i:=0 to n-1 step 2 do + begin + var ind1 := vals.IndexOf(dd[i]); + var ind2 := vals.IndexOf(dd[i+1]); + for var j := ind1 to ind2 do + Result.Add(T(vals[j])); + end +end; + +function operator implicit(a: set of integer): set of BigInteger; extensionmethod; +begin + foreach var x in a do + Result.Add(x); +end; + +//------------------ +function operator implicit(n: array of integer): set of byte; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(n: array of integer): set of shortint; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(n: array of integer): set of smallint; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(n: array of integer): set of word; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(n: array of integer): set of longword; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(a: array of integer): set of int64; extensionmethod; +begin + foreach var x in a do + Result._hs.Add(x); +end; + +function operator implicit(a: array of integer): set of uint64; extensionmethod; +begin + foreach var x in a do + Result._hs.Add(x); +end; + +function operator implicit(a: array of integer): set of BigInteger; extensionmethod; +begin + foreach var x in a do + Result._hs.Add(x); +end; + // ----------------------------------------------------------------------------- // Внутренние вспомогательные функции // ----------------------------------------------------------------------------- diff --git a/bin/PascalABCNET.chw b/bin/PascalABCNET.chw index 119999ab9..f45317f93 100644 Binary files a/bin/PascalABCNET.chw and b/bin/PascalABCNET.chw differ diff --git a/bin/TestRunner.exe b/bin/TestRunner.exe index ff3b098b3..1002ce121 100644 Binary files a/bin/TestRunner.exe and b/bin/TestRunner.exe differ