public delegate_internal_interface(type_node return_value_type, function_node invoke_method, function_node constructor) { _return_value_type = return_value_type; _invoke_method = invoke_method; _constructor = constructor; }
/// <summary> /// Проверяет, подходит ли фаункция для вызова с указанными параметрами /// </summary> /// <param name="candidate"></param> /// <param name="givenParameterTypes">Типы параметров, указанные пользователем</param> /// <returns></returns> private bool IsSuitableFunction( function_node candidate, type_node[] givenParameterTypes, expression_node patternInstance, location deconstructionLocation, out type_node[] parameterTypes) { parameterTypes = new type_node[givenParameterTypes.Length]; var selfParameter = candidate.is_extension_method ? candidate.parameters.First(IsSelfParameter) : null; Debug.Assert(!candidate.is_extension_method || selfParameter != null, "Couldn't find self parameter in extension method"); var candidateParameterTypes = candidate.is_extension_method ? candidate.parameters.Where(x => !IsSelfParameter(x)).ToArray() : candidate.parameters.ToArray(); if (candidateParameterTypes.Length != givenParameterTypes.Length) { return(false); } // Разрешаем только deconstruct текущего класса, родительские в расчет не берем if (candidate is common_method_node commonMethod && !AreTheSameType(patternInstance.type, commonMethod.cont_type)) { return(false); } var genericDeduceNeeded = candidate.is_extension_method && candidate.is_generic_function; type_node[] deducedGenerics = new type_node[candidate.generic_parameters_count]; if (genericDeduceNeeded) { // Выводим дженерики по self var nils = new List <int>(); var deduceSucceded = generic_convertions.DeduceInstanceTypes(selfParameter.type, patternInstance.type, deducedGenerics, nils); if (!deduceSucceded || deducedGenerics.Contains(null)) { return(false); } } for (int i = 0; i < givenParameterTypes.Length; i++) { var givenParameter = givenParameterTypes[i]; var candidateParameter = candidateParameterTypes[i].type; if (genericDeduceNeeded && (candidateParameter.is_generic_parameter || candidateParameter.is_generic_type_instance)) { candidateParameter = InstantiateParameter(candidateParameter, deducedGenerics); } if (givenParameter != null && !AreTheSameType(candidateParameter, givenParameter)) { return(false); } parameterTypes[i] = candidateParameter; } return(true); }
public SymbolInfo(function_node value) { //reference = new SymbolInfo(value); _sym_info = value; _access_level = access_level.al_public; _symbol_kind = symbol_kind.sk_none; }
/// <summary> /// Проверяет, подходит ли фаункция для вызова с указанными параметрами /// </summary> /// <param name="candidate"></param> /// <param name="givenParameterTypes">Типы параметров, указанные пользователем</param> /// <returns></returns> private bool IsSuitableFunction( function_node candidate, type_node[] givenParameterTypes, expression_node patternInstance, location deconstructionLocation, out type_node[] parameterTypes) { parameterTypes = new type_node[givenParameterTypes.Length]; var selfParameter = candidate.is_extension_method ? candidate.parameters.First(IsSelfParameter) : null; Debug.Assert(!candidate.is_extension_method || selfParameter != null, "Couldn't find self parameter in extension method"); var candidateParameterTypes = candidate.is_extension_method ? candidate.parameters.Where(x => !IsSelfParameter(x)).ToArray() : candidate.parameters.ToArray(); if (candidateParameterTypes.Length != givenParameterTypes.Length) { return(false); } var genericDeduceNeeded = candidate.is_extension_method && candidate.is_generic_function; type_node[] deducedGenerics = new type_node[candidate.generic_parameters_count]; if (genericDeduceNeeded) { // Выводим дженерики по self var nils = new List <int>(); var deduceSucceded = generic_convertions.DeduceInstanceTypes(selfParameter.type, patternInstance.type, deducedGenerics, nils); if (!deduceSucceded || deducedGenerics.Contains(null)) { // Проверка на то, что в Deconstruct все дженерики выводятся по self делается в другом месте // TODO Patterns: сделать проверку из коммента выше // TODO Patterns: запретить дженерик методы в классах. Можно использовать только дженерик-типы самого класса в качестве параметров //AddError(deconstructionLocation, "COULDNT_DEDUCE_DECONSTRUCT_GENERIC_TYPE"); return(false); } } for (int i = 0; i < givenParameterTypes.Length; i++) { var givenParameter = givenParameterTypes[i]; var candidateParameter = candidateParameterTypes[i].type; if (genericDeduceNeeded && (candidateParameter.is_generic_parameter || candidateParameter.is_generic_type_instance)) { candidateParameter = InstantiateParameter(candidateParameter, deducedGenerics); } if (givenParameter != null && !AreTheSameType(candidateParameter, givenParameter)) { return(false); } parameterTypes[i] = candidateParameter; } return(true); }
public void Add(function_node function) { if (_functions == null) { _functions = new List <function_node>(); } _functions.Add(function); UpdateReturnType(); }
private bool IsDefaultDeconstruct(function_node function) { // TODO Patterns: check if it declared in PABCSystem return (function.generic_parameters_count == 1 && function.parameters.Count == 2 && function.parameters[0].type.is_generic_parameter && function.parameters[1].type.is_generic_parameter && AreTheSameType(function.parameters[0].type, function.parameters[1].type)); }
private type_node GetDeconstructorOwner(function_node deconstructor) { switch (deconstructor) { case common_method_node commonMethod: return(commonMethod.cont_type); case common_namespace_function_node commonNamespaseFunction: return(GetSelfParameter(commonNamespaseFunction).type); default: return(null); } }
public common_property_node(string name, common_type_node comprehensive_type, type_node property_type, function_node get_function, function_node set_function, location loc, SemanticTree.field_access_level field_access_level, SemanticTree.polymorphic_state polymorphic_state) { _name = name; _comprehensive_type = comprehensive_type; _property_type = property_type; _get_function = get_function; _set_function = set_function; _loc = loc; _field_access_level = field_access_level; _polymorphic_state = polymorphic_state; }
private symbol_kind get_function_kind(function_node fn) { common_function_node cfn = fn as common_function_node; if (cfn != null) { return(get_function_kind(cfn, cfn.is_overload)); } basic_function_node bfn = fn as basic_function_node; if (bfn != null) { return(get_function_kind(bfn, bfn.is_overload)); } return(symbol_kind.sk_none); }
private static void add_conversion(possible_type_convertions ptc, function_node fn, type_node from, type_node to) { if (fn == null) { return; } if (ptc.first == null) { ptc.first = new type_conversion(fn); } else { ptc.second = new type_conversion(fn); } ptc.from = from; ptc.to = to; }
/// <summary> /// Конструктор класса. /// </summary> /// <param name="inc_method">Метод получения следующего значения порядкового типа.</param> /// <param name="dec_method">Метод получения предыдущего значения порядкового типа.</param> /// <param name="lower_eq_method">Метод сравнения двух значений данного типа. Принимает два значения перечислимого типа и возвращаит true если левое меньше или равро правого. Иначе false.</param> /// <param name="greater_eq_method">Метод сравнения двух значений данного типа. Принимает два значения перечислимого типа и возвращаит true если левое больше или равро правого. Иначе false.</param> /// <param name="lower_value">Наименьшее значени перечислимого типа.</param> /// <param name="upper_value">Наибольшее значение перечеслимого типа.</param> /// <param name="value_to_int">Метод преобразования значения перечислимого типа в целое число.</param> /// <param name="ordinal_type_to_int_method">Делегат, который позволяет преобразовывать значение перечислимого типа в целое во время компиляции.</param> public ordinal_type_interface(function_node inc_method, function_node dec_method, function_node inc_value_method, function_node dec_value_method, function_node lower_eq_method, function_node greater_eq_method, function_node lower_method, function_node greater_method, constant_node lower_value, constant_node upper_value, function_node value_to_int, ordinal_type_to_int ordinal_type_to_int_method) { _inc_method = inc_method; _dec_method = dec_method; _inc_value_method = inc_value_method; _dec_value_method = dec_value_method; _lower_eq_method = lower_eq_method; _greater_eq_method = greater_eq_method; _lower_method = lower_method; _greater_method = greater_method; _lower_value = lower_value; _upper_value = upper_value; _value_to_int = value_to_int; _ordinal_type_to_int = ordinal_type_to_int_method; }
public static void add_type_conversion_from_defined(type_node from, type_node to, function_node convertion_method, type_compare comp, bool is_implicit, bool is_generated) { type_intersection_node tin = from.get_type_intersection(to); if (tin == null) { tin = new type_intersection_node(comp); from.add_intersection_node(to, tin, is_generated); } #if (DEBUG) else { if (tin.this_to_another != null) { throw new PascalABCCompiler.TreeConverter.CompilerInternalError("Duplicate type conversion added"); } } #endif tin.this_to_another = new type_conversion(convertion_method, !is_implicit); }
private symbol_kind get_function_kind(function_node fn, bool is_overload) { symbol_kind sk; if (is_overload) { if (fn.return_value_type == null) { sk = symbol_kind.sk_overload_procedure; } else { sk = symbol_kind.sk_overload_function; } } else { sk = symbol_kind.sk_none; } return(sk); }
public SymbolInfo(function_node value) { _sym_info = value; _access_level = access_level.al_public; _symbol_kind = symbol_kind.sk_none; }
//TODO: Возможно стоит если пересечение типов найдено в откомпилированных типах, добавлять к нашим структурам и не искать повторно. public static possible_type_convertions get_convertions(type_node from, type_node to, bool is_implicit) { possible_type_convertions ret = new possible_type_convertions(); ret.first = null; ret.second = null; if ((from == null) || (to == null)) { return(ret); } type_intersection_node tin_from = from.get_type_intersection(to); type_intersection_node tin_to = to.get_type_intersection(from); if (tin_from != null) { if (tin_from.this_to_another != null) { if ((!is_implicit) || (!(tin_from.this_to_another.is_explicit))) { add_conversion(ret, tin_from.this_to_another.convertion_method, from, to); } } } if (tin_to != null) { if (tin_to.another_to_this != null) { if ((!is_implicit) || (!(tin_to.another_to_this.is_explicit))) { add_conversion(ret, tin_to.another_to_this.convertion_method, from, to); } } } if (ret.second != null) { return(ret); } if (is_derived(to, from) || (from.IsInterface && to == SystemLibrary.SystemLibrary.object_type) || from.is_generic_type_instance && to == SystemLibrary.SystemLibrary.object_type) { add_conversion(ret, TreeConverter.convertion_data_and_alghoritms.get_empty_conversion(from, to, true), from, to); //add_conversion(ret, SystemLibrary.SystemLibrary.empty_method, from, to); } if (ret.second != null) { return(ret); } wrapped_type ctn_to = to as wrapped_type; wrapped_type ctn_from = from as wrapped_type; if (ctn_to != null) { function_node fnode1 = null; fnode1 = ctn_to.get_implicit_conversion_from(from); add_conversion(ret, fnode1, from, to); if (ret.second != null) { return(ret); } fnode1 = null; if (!is_implicit) { fnode1 = ctn_to.get_explicit_conversion_from(from); } add_conversion(ret, fnode1, from, to); if (ret.second != null) { return(ret); } } if (ctn_from != null) { function_node fnode2 = null; fnode2 = ctn_from.get_implicit_conversion_to(to); add_conversion(ret, fnode2, from, to); if (ret.second != null) { return(ret); } fnode2 = null; if (!is_implicit) { fnode2 = ctn_from.get_explicit_conversion_to(to); } add_conversion(ret, fnode2, from, to); if (ret.second != null) { return(ret); } } //TODO: Вот это должно быть в каком нибудь другом месте. internal_interface ii = from.get_internal_interface(internal_interface_kind.delegate_interface); if (ii != null) { delegate_internal_interface dii = (delegate_internal_interface)ii; internal_interface to_ii = to.get_internal_interface(internal_interface_kind.delegate_interface); if (to_ii != null) { delegate_internal_interface to_dii = (delegate_internal_interface)to_ii; if (dii.parameters.Count == to_dii.parameters.Count) { //ms100 error fixed (DS) bool eq = TreeConverter.convertion_data_and_alghoritms.function_eq_params_and_result(dii.invoke_method, to_dii.invoke_method); if (eq) { delegate_to_delegate_type_converter dtdtc = new delegate_to_delegate_type_converter(to); add_conversion(ret, new convert_types_function_node(dtdtc.convert_delegates_to_delegates, false), from, to); } } } if (dii.parameters.Count == 0) { if (dii.return_value_type == to) { add_conversion(ret, new convert_types_function_node(convert_delegate_to_return_value_type, true), from, to); } else { possible_type_convertions ptcc = get_convertions(dii.return_value_type, to); if ((ptcc.first != null) && (ptcc.first.convertion_method != null)) { delegate_type_converter dtc = new delegate_type_converter(ptcc.first.convertion_method); add_conversion(ret, new convert_types_function_node(dtc.convert_delegate_to_return_value_type_with_convertion, false), from, to); } if ((ptcc.second != null) && (ptcc.second.convertion_method != null)) { delegate_type_converter dtc = new delegate_type_converter(ptcc.second.convertion_method); add_conversion(ret, new convert_types_function_node(dtc.convert_delegate_to_return_value_type_with_convertion, false), from, to); } } } } return(ret); }
public attribute_node(function_node _attr_constr, type_node _attr_type, location _loc) { this._attr_constr = _attr_constr; this._attr_type = _attr_type; this._loc = _loc; }
/// <summary> /// Обрабатывает случай, когда левая часть присваивания свойство. /// </summary> /// <returns>True - обработка прошла, иначе False.</returns> private bool ProcessAssignToPropertyIfPossible(assign _assign, addressed_expression to, location loc, expression_node from) { //проверка на обращение к полю записи возвращенной из функции с целью присваивания //нужно чтобы пользователь не мог менять временный обьект if (to.semantic_node_type == semantic_node_type.static_property_reference || to.semantic_node_type == semantic_node_type.non_static_property_reference) { property_node pn; if (to.semantic_node_type == semantic_node_type.static_property_reference) { pn = (to as static_property_reference).property; } else { pn = (to as non_static_property_reference).property; } var ot = MapCompositeAssignmentOperatorToSameBinaryOperator(_assign); var oper_ass_in_prop = ot != Operators.Undefined; if (_assign.operator_type == Operators.Assignment || oper_ass_in_prop) { if (oper_ass_in_prop) { if (pn.get_function == null) { AddError(loc, "THIS_PROPERTY_{0}_CAN_NOT_BE_READED", pn.name); } base_function_call prop_expr; if (to.semantic_node_type == semantic_node_type.non_static_property_reference) { prop_expr = create_not_static_method_call(pn.get_function, (to as non_static_property_reference).expression, loc, false); prop_expr.parameters.AddRange((to as non_static_property_reference).fact_parametres); } else { prop_expr = create_static_method_call(pn.get_function, loc, pn.comprehensive_type, false); prop_expr.parameters.AddRange((to as static_property_reference).fact_parametres); } from = find_operator(ot, prop_expr, from, loc); } if (to.semantic_node_type == semantic_node_type.static_property_reference) { static_property_reference spr = (static_property_reference)to; if (spr.property.set_function == null) { AddError(loc, "THIS_PROPERTY_{0}_CAN_NOT_BE_WRITED", spr.property.name); } check_property_params(spr, loc); function_node set_func = spr.property.set_function; from = convertion_data_and_alghoritms.convert_type(from, spr.property.property_type); spr.fact_parametres.AddElement(from); base_function_call bfc = create_static_method_call(set_func, loc, spr.property.comprehensive_type, true); bfc.parameters.AddRange(spr.fact_parametres); return_value((statement_node)bfc); } else if (to.semantic_node_type == semantic_node_type.non_static_property_reference) { non_static_property_reference nspr = (non_static_property_reference)to; check_property_params(nspr, loc); from = convertion_data_and_alghoritms.convert_type(from, nspr.property.property_type); nspr.fact_parametres.AddElement(from); //Обработка s[i]:='c' if (SystemUnitAssigned) { if (nspr.property.comprehensive_type == SystemLibrary.SystemLibrary.string_type) { if (nspr.property == SystemLibrary.SystemLibrary.string_type.default_property_node) { if (SystemLibInitializer.StringDefaultPropertySetProcedure != null) { expressions_list exl = new expressions_list(); exl.AddElement(nspr.expression); exl.AddElement(nspr.fact_parametres[0]); exl.AddElement(from); function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibInitializer.StringDefaultPropertySetProcedure .SymbolInfo, loc); expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); return_value((statement_node)ret); return(true); } } } } if (nspr.property.set_function == null) { AddError(loc, "THIS_PROPERTY_{0}_CAN_NOT_BE_WRITED", nspr.property.name); } function_node set_func = nspr.property.set_function; base_function_call bfc = create_not_static_method_call(set_func, nspr.expression, loc, true); bfc.parameters.AddRange(nspr.fact_parametres); return_value((statement_node)bfc); } return(true); } } return(false); }
public type_conversion(function_node conversion) { _conversion_method = conversion; }
private parameter GetSelfParameter(function_node node) => node.parameters.FirstOrDefault(x => IsSelfParameter(x));
public type_conversion(function_node conversion, bool is_explicit) { _conversion_method = conversion; _is_explicit = is_explicit; }
public indefinite_function_call(function_node fn, location loc) : base(fn.return_value_type, loc) { _function_node = fn; }
public static void add_generated_type_conversion_from_defined(type_node from, type_node to, function_node convertion_method, type_compare comp, bool is_implicit) { add_type_conversion_from_defined(from, to, convertion_method, comp, is_implicit, true); }
/// <summary> /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной /// </summary> public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor, Operators op = Operators.Undefined) { if (lambdaDef == null) { return; } if (leftType != null) { delegate_internal_interface dii_left = (delegate_internal_interface)leftType.get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left == null) { if (leftType != SystemLibrary.SystemLibrary.system_delegate_type) { if (op != Operators.Undefined) { var sil = leftType.find_in_type(name_reflector.get_name(op)); if (sil != null && sil.Count > 0) { foreach (SymbolInfo si in sil) { if (si.sym_info is function_node) { function_node fn = si.sym_info as function_node; if (fn.parameters.Count == 2) { dii_left = (delegate_internal_interface)fn.parameters[1].type.get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left != null) { break; } if (fn.parameters[1].type.is_generic_parameter) { compiled_type_node ctn = leftType as compiled_type_node; common_type_node ctn2 = leftType as common_type_node; if (ctn != null && ctn.is_generic_type_instance && fn.parameters[0].type.is_generic_type_instance && ctn.original_generic == fn.parameters[0].type.original_generic) { dii_left = (delegate_internal_interface)ctn.generic_params[0].get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left != null) { break; } } if (ctn2 != null && ctn2.is_generic_type_instance && ctn2.instance_params.Count > 0 && fn.parameters[0].type.is_generic_type_instance && ctn2.original_generic == fn.parameters[0].type.original_generic) { dii_left = (delegate_internal_interface)ctn2.instance_params[0].get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left != null) { break; } } } } } } } } if (dii_left == null) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE"); } } else { return; } } int leftTypeParamsNumber = dii_left.parameters.Count; int lambdaDefParamsCount = 0; if (lambdaDef.formal_parameters != null && lambdaDef.formal_parameters.params_list.Count != 0) { for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) { lambdaDefParamsCount += lambdaDef.formal_parameters.params_list[i].idents.idents.Count; } if (lambdaDefParamsCount != leftTypeParamsNumber) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_PARAMETERS_NUMBER"); } bool flag = true; SyntaxTree.formal_parameters lambdaDefParamsTypes = new formal_parameters(); for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) { for (int j = 0; j < lambdaDef.formal_parameters.params_list[i].idents.idents.Count; j++) { var param = new SyntaxTree.typed_parameters(); param.idents = new ident_list(); param.idents.Add(lambdaDef.formal_parameters.params_list[i].idents.idents[j]); param.vars_type = lambdaDef.formal_parameters.params_list[i].vars_type; param.source_context = lambdaDef.formal_parameters.source_context; lambdaDefParamsTypes.Add(param); } } for (int i = 0; i < leftTypeParamsNumber && flag; i++) { if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type) { if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node) { var curLeftParType = dii_left.parameters[i].type; lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type(); (lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type = curLeftParType; continue; } } var lambdaPar = visitor.convert_strong(lambdaDefParamsTypes.params_list[i].vars_type); if (!convertion_data_and_alghoritms.eq_type_nodes(dii_left.parameters[i].type, lambdaPar)) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE"); } } lambdaDef.formal_parameters = lambdaDefParamsTypes; } if (lambdaDef.return_type != null && lambdaDef.return_type is lambda_inferred_type) { if (dii_left.return_value_type != null) { (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() { // lambdaDef.usedkeyword == 1 // function var b = lambdaDef.usedkeyword == 0 && TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef); // пытаться конвертировать только если мы явно не указали, что это функция if (!b) { visitor.AddError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE"); } } } } else { if (lambdaDef.formal_parameters != null) { for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) { if (lambdaDef.formal_parameters.params_list[i].vars_type is lambda_inferred_type) { visitor.AddError(visitor.get_location(lambdaDef), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); } } } } }
public delegate_type_converter(function_node convert_function) { this.convert_function = convert_function; }