private void IncreaseNumAssField(class_field_reference fld) { FldInfo vi = helper.GetField(fld.field); if (vi == null) return; vi.num_use++; vi.cur_ass++; if (vi.cur_use > 0) vi.cur_use--; }
private void VisitClassFieldReference(class_field_reference en) { VisitExpression(en.obj); IncreaseNumUseField(en); }
private void VisitClassFieldReference(class_field_reference expr) { VisitExpression(expr.obj); WriteFieldReference(expr.field); }
private void IncreaseNumUseField(class_field_reference fld) { FldInfo vi = helper.GetField(fld.field); if (vi == null) return; vi.num_use++; vi.cur_use++; //if (vi.cur_ass == 0) warns.Add(new UseWithoutAssign(lvr.var.name, lvr.location)); }
private expression_node make_dec_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) { if (parameters == null) throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node); if (parameters.expressions.Count == 1 || parameters.expressions.Count == 2) { expression_node param0 = convert_strong(parameters.expressions[0]); if (!param0.is_addressed) { bool is_pascal_array_ref = false; if (param0.semantic_node_type == semantic_node_type.common_method_call) { common_method_call cmc = (common_method_call)param0; internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); if (ii != null) { if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) { bounded_array_interface bai = (bounded_array_interface)ii; class_field cf = bai.int_array; expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); expression_node right = cmc.parameters[0]; //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); is_pascal_array_ref = true; } } if (!is_pascal_array_ref) { throw new ThisExpressionCanNotBePassedAsVarParameter(param0); } } else if (param0 is compiled_function_call) { compiled_function_call cfc = param0 as compiled_function_call; if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function)) { expressions_list exl = new expressions_list(); exl.AddElement(cfc.obj); exl.AddElement(cfc.parameters[0]); basic_function_call bfc2 = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); bfc2.parameters.AddElement(param0); expression_node _param1 = null; if (parameters.expressions.Count == 2) { _param1 = convert_strong(parameters.expressions[1]); } if (_param1 != null) bfc2.parameters.AddElement(convertion_data_and_alghoritms.convert_type(_param1,SystemLibrary.SystemLibrary.integer_type)); else bfc2.parameters.AddElement(new int_const_node(1,null)); expressions_list el = new expressions_list(); el.AddElement(convertion_data_and_alghoritms.convert_type(bfc2,SystemLibrary.SystemLibrary.ushort_type)); function_node chr_func = convertion_data_and_alghoritms.select_function(el, SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc); exl.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray())); function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.SymbolInfo, loc); expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); return ret; } else { throw new ThisExpressionCanNotBePassedAsVarParameter(param0); } } else throw new ThisExpressionCanNotBePassedAsVarParameter(param0); } else check_on_loop_variable(param0); expression_node param1 = null; int type_flag = 0; bool is_uint=false; bool is_enum=false; if (parameters.expressions.Count == 2) { param1 = convert_strong(parameters.expressions[1]); param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); } basic_function_call ass = null; basic_function_call bfc = null; if (param0.type == SystemLibrary.SystemLibrary.integer_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.char_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.char_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.byte_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.byte_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.sbyte_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.sbyte_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.short_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.short_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.ushort_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.ushort_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.uint_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.uint_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.uint_sub as basic_function_node,loc); type_flag = 2; is_uint = true; } else if (param0.type == SystemLibrary.SystemLibrary.int64_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.long_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.long_sub as basic_function_node,loc); type_flag = 1; } else if (param0.type == SystemLibrary.SystemLibrary.uint64_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.ulong_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.ulong_sub as basic_function_node,loc); type_flag = 2; } else if (param0.type == SystemLibrary.SystemLibrary.bool_type) { if (param1 == null) { ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); type_flag = 4; } else { basic_function_call mod_expr = new basic_function_call(SystemLibrary.SystemLibrary.int_mod as basic_function_node,loc); mod_expr.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type)); mod_expr.parameters.AddElement(new int_const_node(2,loc)); basic_function_call condition = new basic_function_call(SystemLibrary.SystemLibrary.int_eq as basic_function_node,loc); condition.parameters.AddElement(mod_expr); condition.parameters.AddElement(new int_const_node(0,loc)); basic_function_call not_expr = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); not_expr.parameters.AddElement(param0); question_colon_expression qce = new question_colon_expression(condition, param0, not_expr, loc); ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); ass.parameters.AddElement(param0); ass.parameters.AddElement(qce); type_flag = 5; } } else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) { ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) { type_node bt = param0.type.base_type; if (bt == SystemLibrary.SystemLibrary.int64_type) type_flag = 1; else if (bt == SystemLibrary.SystemLibrary.uint64_type) type_flag = 2; else if (bt == SystemLibrary.SystemLibrary.uint_type) { type_flag =2; is_uint = true; } else if (bt.IsEnum) is_enum = true; } else if (param0.type.IsEnum) is_enum = true; } else throw new NoFunctionWithSameArguments(loc,false); if (type_flag != 5) { if (param1 != null) switch (type_flag) { case 0: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); break; case 3: case 1: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.int64_type); break; case 2: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.uint64_type); break; } //bfc.parameters.AddElement(param0); if (param0.type != SystemLibrary.SystemLibrary.char_type && !is_enum && param0.type != SystemLibrary.SystemLibrary.bool_type) switch (type_flag) { case 0: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.integer_type)); break; case 3: case 1: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.int64_type)); break; case 2: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.uint64_type)); break; } else bfc.parameters.AddElement(param0); if (param1 == null) { if (type_flag == 0 || type_flag == 3) bfc.parameters.AddElement(new int_const_node(1, null)); else if (type_flag == 1) bfc.parameters.AddElement(new long_const_node(1, null)); else if (type_flag == 2) bfc.parameters.AddElement(new ulong_const_node(1, null)); } else bfc.parameters.AddElement(param1); ass.parameters.AddElement(param0); if (is_uint) ass.parameters.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.uint_type)); else ass.parameters.AddElement(bfc); } return ass; } throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node); }
private addressed_expression create_class_field_reference(expression_node en, definition_node dn, SyntaxTree.ident id_right) { try_convert_typed_expression_to_function_call(ref en); if (dn.semantic_node_type == semantic_node_type.class_field) { class_field cf = (class_field)dn; if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotReferanceToStaticFieldWithExpression(cf, get_location(id_right), en)); } class_field_reference cfr = new class_field_reference(cf, en, get_location(id_right)); //return_value(cfr); return cfr; } if (dn.semantic_node_type == semantic_node_type.compiled_variable_definition) { compiled_variable_definition cfd = (compiled_variable_definition)dn; if (cfd.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotReferanceToStaticFieldWithExpression(cfd, get_location(id_right), en)); } compiled_variable_reference cfr2 = new compiled_variable_reference(cfd, en, get_location(id_right)); //return_value(cfr2); return cfr2; } #if (DEBUG) throw new CompilerInternalError("Invalid variable kind"); #endif return null; }
internal void visit_method_call(SyntaxTree.method_call _method_call) { // frninja 01/03/16 - for iterator capturing (yield) if (_method_call.dereferencing_value is yield_unknown_ident) { var nodeToVisit = new method_call(ProcessUnknownIdent(_method_call.dereferencing_value as yield_unknown_ident), _method_call.parameters); visit(nodeToVisit); return; } // end frninja //lroman if (_method_call.dereferencing_value is closure_substituting_node) { var nodeToVisit = new method_call(((closure_substituting_node) _method_call.dereferencing_value).substitution, _method_call.parameters); visit(nodeToVisit); return; } bool proc_wait = procedure_wait; bool lambdas_are_in_parameters = false; //lroman// var syntax_nodes_parameters = _method_call.parameters == null ? new List<expression>() : _method_call.parameters.expressions; if (procedure_wait) { procedure_wait = false; } //throw new ArgumentNullException("test"); motivation mot = motivation_keeper.motivation; expression_node expr_node = null; expressions_list exprs = new expressions_list(); SyntaxTree.ident id = null; SymbolInfo si = null; type_node to_type = null; SyntaxTree.addressed_value deref_value = _method_call.dereferencing_value; int templ_args_count = 0; //bool needs_generic_type_search = false; SyntaxTree.ident_with_templateparams iwt = deref_value as SyntaxTree.ident_with_templateparams; if (iwt != null) { deref_value = iwt.name; templ_args_count = iwt.template_params.params_list.Count; //needs_generic_type_search = _method_call.parameters.expressions.Count == 1; } SyntaxTree.inherited_ident inh_id = deref_value as SyntaxTree.inherited_ident; if (inh_id != null) { inherited_ident_processing = true; si = find_in_base(inh_id); if (si != null) if (si.sym_info is common_method_node) { if ((si.sym_info as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD"); } else if (si.sym_info is compiled_function_node) { if ((si.sym_info as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD"); } id = inh_id; } else { id = deref_value as SyntaxTree.ident; if (id != null) { if (templ_args_count != 0) { //Ищем generics si = context.find(id.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); if (si != null) { si = new SymbolInfo(get_generic_instance(si, iwt.template_params.params_list)); iwt = null; } } if (si == null) { SyntaxTree.operator_name_ident oni = id as SyntaxTree.operator_name_ident; if (oni != null) { si = context.find(name_reflector.get_name(oni.operator_type)); } else { si = context.find(id.name); if (templ_args_count != 0) { SymbolInfo conv = ConvertTypeToInstance(si, iwt.template_params.params_list, get_location(id)); if (conv != null) { si = conv; iwt = null; } } } } } else { SyntaxTree.dot_node _dot_node = deref_value as SyntaxTree.dot_node; if (_dot_node != null) { bool skip_first_parameter = false; //lroman// bool has_extension_overload = false; semantic_node sn = convert_semantic_strong(_dot_node.left); //SyntaxTree.ident id_right = ConvertOperatorNameToIdent(_dot_node.right as SyntaxTree.ident); SyntaxTree.ident id_right = _dot_node.right as SyntaxTree.ident; switch (sn.general_node_type) { case general_node_type.expression: { expression_node exp = (expression_node)sn; if (exp is typed_expression) try_convert_typed_expression_to_function_call(ref exp); SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; if (oni_right != null) { si = exp.type.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope); } else { si = exp.type.find_in_type(id_right.name, context.CurrentScope); if (si != null && si.sym_info != null && si.sym_info.semantic_node_type == semantic_node_type.wrap_def) BasePCUReader.RestoreSymbols(si, id_right.name); } //definition_node ddn=check_name_node_type(id_right.name,si,get_location(id_right), // general_node_type.function_node,general_node_type.variable_node); location subloc = get_location(id_right); if (si == null) { AddError(new UndefinedNameReference(id_right.name, subloc)); } if (si.sym_info.general_node_type != general_node_type.function_node) { if (si.sym_info.general_node_type == general_node_type.type_node) { to_type = ((type_node)(si.sym_info)); } else { dot_node_as_expression_dot_ident(exp, id_right, motivation.expression_evaluation, _dot_node.left); exp = ret.get_expression(); internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface); if (ii == null) { AddError(subloc, "EXPECTED_DELEGATE"); } delegate_internal_interface dii = ii as delegate_internal_interface; si = new SymbolInfo(dii.invoke_method); } } if (to_type != null) { if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) { AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED" ); } } SymbolInfo tmp_si = si; while (si != null) { if (si.sym_info is common_namespace_function_node) { common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node; if (cnfn.ConnectedToType != null && !cnfn.IsOperator) { exprs.AddElementFirst(exp); skip_first_parameter = true; break; } } if (si.sym_info is compiled_function_node) { compiled_function_node cfn = si.sym_info as compiled_function_node; if (cfn.ConnectedToType != null) { exprs.AddElementFirst(exp); skip_first_parameter = true; if (cfn.is_generic_function) { //generic_convertions.DeduceFunction(cfn, exprs); //si.sym_info = cfn.get_instance(new List<type_node>(new type_node[] { exp.type }), true, get_location(_method_call)); } break; } } si = si.Next; } si = tmp_si; if (skip_first_parameter) { SymbolInfo new_si = null; bool has_obj_methods = false; List<SymbolInfo> si_list = new List<SymbolInfo>(); while (si != null) { if (si.sym_info is common_namespace_function_node) { common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node; if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cnfn.ConnectedToType != null) si_list.Add(si); if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cnfn.ConnectedToType == null) has_obj_methods = true; } else if (si.sym_info is compiled_function_node) { compiled_function_node cfn = si.sym_info as compiled_function_node; if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cfn.ConnectedToType != null) si_list.Add(si); 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++) { if (new_si == null) { new_si = si_list[i]; si = new_si; } else { si.Next = si_list[i]; si = si.Next; } } if (si != null) si.Next = null; si = new_si; } if (_method_call.parameters != null) { foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов //lroman// if (en is SyntaxTree.function_lambda_definition) { lambdas_are_in_parameters = true; ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; } //lroman// #endregion var cen = convert_strong(en); exprs.AddElement(cen); } } expression_node subexpr1 = null; if (to_type != null) { subexpr1 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type); } else { if (iwt != null) { si = get_generic_functions(si, true, subloc); si = get_function_instances(si, iwt.template_params.params_list, id_right.name, subloc, si.Next == null); } #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим //lroman// if (lambdas_are_in_parameters) { LambdaHelper.processingLambdaParametersForTypeInference++; // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями 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) { exprCounter++; } foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var enLambda = (SyntaxTree.function_lambda_definition)en; LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; exprs[exprCounter] = convert_strong(en); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; exprCounter++; } } } catch (SeveralFunctionsCanBeCalled sf) { spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна } Exception lastmultex = null; if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try { // exprs - глобальная, поэтому надо копировать int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! int GoodVersionsCount = 0; int GoodVersionsCountWithSameResType = 0; for (int i = 0; i < spf.Count; i++) // цикл по версиям { function_node fnn = spf[i]; try { int exprCounter = 0; if (skip_first_parameter) { exprCounter++; } expressions_list exprs1 = new expressions_list(); exprs1.AddRange(exprs); // сделали копию foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var fld = en as SyntaxTree.function_lambda_definition; var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо var fl = fld.lambda_visit_mode; // запомнили типы параметров лямбды - SSM object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK == null) realparamstype[k] = null; else realparamstype[k] = laminftypeK.real_type; } // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим var restype = fld.return_type as SyntaxTree.lambda_inferred_type; object realrestype = null; if (restype != null) realrestype = restype.real_type; LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! //contextChanger.SaveContextAndUpToNearestDefSect(); try { exprs1[exprCounter] = convert_strong(en); type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; type_node resformaltype = fld.RealSemTypeOfResult as type_node; var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } /*compiled_type_node tt; tt = fnn.parameters[exprCounter].type as compiled_type_node; if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) { resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } }*/ } catch { throw; } finally { LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); // восстанавливаем сохраненный тип возвращаемого значения if (restype != null) restype.real_type = realrestype; // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK != null) laminftypeK.real_type = realparamstype[k]; } fld.lambda_name = lambdaName; //lroman Восстанавливаем имена fld.lambda_visit_mode = fl; } //contextChanger.RestoreCurrentContext(); exprCounter++; } } /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так { spfnum = -2; break; }*/ if (GoodVersionsCountWithSameResType == 0) spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения GoodVersionsCount += 1; for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо exprs[j] = exprs1[j]; } catch (Exception e) { // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать //contextChanger.RestoreCurrentContext(); lastmultex = e; } } // конец цикла по версиям if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения throw new SeveralFunctionsCanBeCalled(subloc, spf); if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд { throw lastmultex; //throw new NoFunctionWithSameArguments(subloc2, false); } int kk = 0; if (skip_first_parameter) kk++; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды { if (!(en is SyntaxTree.function_lambda_definition)) { kk++; continue; } else { LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); exprs[kk] = convert_strong(en); kk++; } } } // SSM 21.05.14 end LambdaHelper.processingLambdaParametersForTypeInference--; } //lroman// #endregion function_node fn = null; if (!skip_first_parameter || si.Next == null) fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); else { try { ThrowCompilationError = false; fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); if (fn == null && skip_first_parameter) { if (si.Next == null) { ThrowCompilationError = true; throw LastError(); } RemoveLastError(); skip_first_parameter = false; si = tmp_si; exprs.remove_at(0); fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); if (fn == null) { ThrowCompilationError = true; throw LastError(); } // else // RemoveLastError(); // ошибка уже убрана чуть выше } } catch (Exception ex) { ThrowCompilationError = true; if (skip_first_parameter) { si = tmp_si; exprs.remove_at(0); fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); } else throw ex; } ThrowCompilationError = true; } SemanticTree.IGenericInstance igi = fn as SemanticTree.IGenericInstance; if (igi != null) { //проверяем на соответствие ограничителям int num_err; //CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list( } base_function_call bfc = create_not_static_method_call(fn, exp, get_location(id_right), proc_wait); bfc.parameters.AddRange(exprs); subexpr1 = bfc; } switch (mot) { case motivation.expression_evaluation: { return_value(subexpr1); return; } case motivation.semantic_node_reciving: { return_semantic_value(subexpr1); return; } default: { AddError(subexpr1.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } case general_node_type.namespace_node: { namespace_node nsn = (namespace_node)sn; if (templ_args_count != 0) { //Ищем generics si = context.find(id_right.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); if (si != null) { si = new SymbolInfo(get_generic_instance(si, iwt.template_params.params_list)); iwt = null; } } if (si == null) { SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; if (oni_right != null) { si = nsn.find(name_reflector.get_name(oni_right.operator_type)); } else { si = nsn.find(id_right.name); if (templ_args_count != 0) { SymbolInfo conv = ConvertTypeToInstance(si, iwt.template_params.params_list, get_location(id_right)); if (conv != null) { si = conv; iwt = null; } } } } id = id_right; break; } case general_node_type.unit_node: { unit_node un = (unit_node)sn; SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; if (oni_right != null) { si = un.find_only_in_namespace(name_reflector.get_name(oni_right.operator_type)); } else { si = un.find_only_in_namespace(id_right.name); } id = id_right; break; } case general_node_type.type_node: { type_node tn = (type_node)sn; /*if (tn == SystemLibrary.SystemLibrary.void_type) { throw new VoidNotValid(get_location(id_right)); }*/ check_for_type_allowed(tn,get_location(id_right)); SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; if (oni_right != null) { si = tn.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope); } else { si = tn.find_in_type(id_right.name, context.CurrentScope);//CurrentScope delete_inherited_constructors(ref si, tn); delete_extension_methods(ref si, tn); // SSM 2.2.2016 Пока временно закомментировал - в старом коде этого не было. Из-за этого не работает System.Linq.Enumerable.Select } //definition_node ddn2=check_name_node_type(id_right.name,si,get_location(id_right), // general_node_type.function_node); expression_node exp = null; location subloc = get_location(id_right); if (si == null) { AddError( new UndefinedNameReference(id_right.name, subloc)); } if (si.sym_info.general_node_type != general_node_type.function_node) { if (si.sym_info.general_node_type == general_node_type.type_node) { to_type = ((type_node)(si.sym_info)); } else { dot_node_as_type_ident(tn, id_right, motivation.expression_evaluation); exp = ret.get_expression(); internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface); if (ii == null) { AddError(subloc, "EXPECTED_DELEGATE"); } delegate_internal_interface dii = ii as delegate_internal_interface; si = new SymbolInfo(dii.invoke_method); } } if (to_type != null) { if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) { AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED" ); } } if (_method_call.parameters != null) { foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов //lroman// if (en is SyntaxTree.function_lambda_definition) { lambdas_are_in_parameters = true; ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; } //lroman// #endregion exprs.AddElement(convert_strong(en)); } } expression_node subexpr2 = null; if (to_type != null) { subexpr2 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type); } else { if (iwt != null) { si = get_generic_functions(si, true, subloc); si = get_function_instances(si, iwt.template_params.params_list, id_right.name, subloc, si.Next == null); } #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим //lroman// if (lambdas_are_in_parameters) { LambdaHelper.processingLambdaParametersForTypeInference++; // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями function_node_list spf = null; try { function_node ffn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); int exprCounter = 0; if (skip_first_parameter) { exprCounter++; } foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var enLambda = (SyntaxTree.function_lambda_definition)en; LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; exprs[exprCounter] = convert_strong(en); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; exprCounter++; } } } catch (SeveralFunctionsCanBeCalled sf) { spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна } Exception lastmultex = null; if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try { // exprs - глобальная, поэтому надо копировать int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! int GoodVersionsCount = 0; int GoodVersionsCountWithSameResType = 0; for (int i = 0; i < spf.Count; i++) // цикл по версиям { function_node fnn = spf[i]; try { int exprCounter = 0; if (skip_first_parameter) { exprCounter++; } expressions_list exprs1 = new expressions_list(); exprs1.AddRange(exprs); // сделали копию foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var fld = en as SyntaxTree.function_lambda_definition; var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо var fl = fld.lambda_visit_mode; // запомнили типы параметров лямбды - SSM object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK == null) realparamstype[k] = null; else realparamstype[k] = laminftypeK.real_type; } // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим var restype = fld.return_type as SyntaxTree.lambda_inferred_type; object realrestype = null; if (restype != null) realrestype = restype.real_type; LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! //contextChanger.SaveContextAndUpToNearestDefSect(); try { exprs1[exprCounter] = convert_strong(en); type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; type_node resformaltype = fld.RealSemTypeOfResult as type_node; var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } /*compiled_type_node tt; tt = fnn.parameters[exprCounter].type as compiled_type_node; if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) { resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } }*/ } catch { throw; } finally { LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); // восстанавливаем сохраненный тип возвращаемого значения if (restype != null) restype.real_type = realrestype; // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK != null) laminftypeK.real_type = realparamstype[k]; } fld.lambda_name = lambdaName; //lroman Восстанавливаем имена fld.lambda_visit_mode = fl; } //contextChanger.RestoreCurrentContext(); exprCounter++; } } /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так { spfnum = -2; break; }*/ if (GoodVersionsCountWithSameResType == 0) spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения GoodVersionsCount += 1; for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо exprs[j] = exprs1[j]; } catch (Exception e) { // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать //contextChanger.RestoreCurrentContext(); lastmultex = e; } } // конец цикла по версиям if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения throw new SeveralFunctionsCanBeCalled(subloc, spf); if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд { throw lastmultex; //throw new NoFunctionWithSameArguments(subloc2, false); } int kk = 0; if (skip_first_parameter) kk++; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды { if (!(en is SyntaxTree.function_lambda_definition)) { kk++; continue; } else { LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); exprs[kk] = convert_strong(en); kk++; } } } // SSM 21.05.14 end LambdaHelper.processingLambdaParametersForTypeInference--; } //lroman// #endregion function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); if (!debug && fn == SystemLibrary.SystemLibrary.assert_method) { // return_value(new empty_statement(null)); // return; } /*if ((proc_wait==false)&&(fn.return_value_type==null)) { throw new FunctionExpectedProcedureMeet(fn,get_location(id_right)); }*/ base_function_call bfc2 = null; if (exp == null) { bfc2 = create_static_method_call(fn, subloc, tn, proc_wait); } else { bfc2 = create_not_static_method_call(fn, exp, subloc, proc_wait); } bfc2.parameters.AddRange(exprs); subexpr2 = bfc2; } switch (mot) { case motivation.expression_evaluation: { return_value(subexpr2); return; } case motivation.semantic_node_reciving: { return_semantic_value(subexpr2); return; } default: { AddError(subexpr2.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else { SyntaxTree.expression expr = deref_value as SyntaxTree.expression; if (expr != null) { //throw new CompilerInternalError("Not supported"); expression_node exp_int = convert_strong(expr); location sloc = get_location(expr); internal_interface ii = exp_int.type.get_internal_interface(internal_interface_kind.delegate_interface); if (ii == null) { AddError(sloc, "EXPECTED_DELEGATE"); } delegate_internal_interface dii = (delegate_internal_interface)ii; si = new SymbolInfo(dii.invoke_method); if (_method_call.parameters != null) { foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов //lroman// if (en is SyntaxTree.function_lambda_definition) { lambdas_are_in_parameters = true; ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; } //lroman// #endregion exprs.AddElement(convert_strong(en)); } } location subloc = sloc; #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим //lroman// if (lambdas_are_in_parameters) { LambdaHelper.processingLambdaParametersForTypeInference++; // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями function_node_list spf = null; try { function_node ffn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); int exprCounter = 0; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var enLambda = (SyntaxTree.function_lambda_definition)en; LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; exprs[exprCounter] = convert_strong(en); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; exprCounter++; } } } catch (SeveralFunctionsCanBeCalled sf) { spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна } Exception lastmultex = null; if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try { // exprs - глобальная, поэтому надо копировать int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! int GoodVersionsCount = 0; int GoodVersionsCountWithSameResType = 0; for (int i = 0; i < spf.Count; i++) // цикл по версиям { function_node fnn = spf[i]; try { int exprCounter = 0; expressions_list exprs1 = new expressions_list(); exprs1.AddRange(exprs); // сделали копию foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var fld = en as SyntaxTree.function_lambda_definition; var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо var fl = fld.lambda_visit_mode; // запомнили типы параметров лямбды - SSM object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK == null) realparamstype[k] = null; else realparamstype[k] = laminftypeK.real_type; } // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим var restype = fld.return_type as SyntaxTree.lambda_inferred_type; object realrestype = null; if (restype != null) realrestype = restype.real_type; LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! //contextChanger.SaveContextAndUpToNearestDefSect(); try { exprs1[exprCounter] = convert_strong(en); type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; type_node resformaltype = fld.RealSemTypeOfResult as type_node; var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } /*compiled_type_node tt; tt = fnn.parameters[exprCounter].type as compiled_type_node; if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) { resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } }*/ } catch { throw; } finally { LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); // восстанавливаем сохраненный тип возвращаемого значения if (restype != null) restype.real_type = realrestype; // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK != null) laminftypeK.real_type = realparamstype[k]; } fld.lambda_name = lambdaName; //lroman Восстанавливаем имена fld.lambda_visit_mode = fl; } //contextChanger.RestoreCurrentContext(); exprCounter++; } } /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так { spfnum = -2; break; }*/ if (GoodVersionsCountWithSameResType == 0) spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения GoodVersionsCount += 1; for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо exprs[j] = exprs1[j]; } catch (Exception e) { // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать //contextChanger.RestoreCurrentContext(); lastmultex = e; } } // конец цикла по версиям if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения throw new SeveralFunctionsCanBeCalled(subloc, spf); if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд { throw lastmultex; //throw new NoFunctionWithSameArguments(subloc2, false); } int kk = 0; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды { if (!(en is SyntaxTree.function_lambda_definition)) { kk++; continue; } else { LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); exprs[kk] = convert_strong(en); kk++; } } } // SSM 21.05.14 end LambdaHelper.processingLambdaParametersForTypeInference--; } //lroman// #endregion function_node del_func = convertion_data_and_alghoritms.select_function(exprs, si, sloc, syntax_nodes_parameters); base_function_call bbfc = create_not_static_method_call(del_func, exp_int, sloc, proc_wait); bbfc.parameters.AddRange(exprs); switch (mot) { case motivation.expression_evaluation: { return_value(bbfc); return; } case motivation.semantic_node_reciving: { return_semantic_value(bbfc); return; } default: { AddError(bbfc.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } else { throw new CompilerInternalError("Unexpected method name kind"); } } } } //definition_node dn=check_name_node_type(id.name,si,get_location(_method_call),general_node_type.function_node); expression_node exp2 = null; location subloc2 = get_location(id); List<TreeConverter.SymbolInfo> sibak = new List<TreeConverter.SymbolInfo>(); TreeConverter.SymbolInfo ssi=si; while (ssi != null) { ssi = ssi.Next; sibak.Add(ssi); } if (si == null) { AddError(new UndefinedNameReference(id.name, subloc2)); } is_format_allowed = false; if (SystemUnitAssigned) if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si) || SystemLibrary.SystemLibInitializer.readln_procedure.Equal(si)) { expression_node bfcint = make_read_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.write_procedure.Equal(si) || SystemLibrary.SystemLibInitializer.writeln_procedure.Equal(si) || SystemLibrary.SystemLibInitializer.StrProcedure.Equal(si)) { is_format_allowed = true; } else if (SystemLibrary.SystemLibInitializer.ArrayCopyFunction.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind) { location loc = get_location(_method_call); expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ArrayCopyFunction.sym_info as function_node,loc,param0); function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, param0.type, false); en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en); return_value(en); return; } } } else if (SystemLibrary.SystemLibInitializer.SetLengthProcedure.Equal(si) || SystemLibrary.SystemLibrary.resize_func == si.sym_info as function_node) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count >= 2) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); if (!param0.is_addressed) AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); base_function_call cnfn = null; if (SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info is common_namespace_function_node) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); cnfn.parameters.AddElement(new int_const_node((param0.type as short_string_type_node).Length,null)); switch (mot) { case motivation.expression_evaluation: { return_value(cnfn); return; } case motivation.semantic_node_reciving: { return_semantic_value(cnfn); return; } default: { AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } else if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind) { int rank = 1; if (param0.type is compiled_type_node) rank = (param0.type as compiled_type_node).rank; else if (param0.type is common_type_node) rank = (param0.type as common_type_node).rank; if (_method_call.parameters.expressions.Count-1 != rank) AddError(get_location(_method_call), "{0}_PARAMETERS_EXPECTED", rank+1); if (rank > 1) { type_node tn = param0.type.element_type; location loc = get_location(_method_call); typeof_operator to = new typeof_operator(tn, loc); List<expression_node> lst = new List<expression_node>(); //размер for (int i=1; i<_method_call.parameters.expressions.Count; i++) { expression_node expr = convert_strong(_method_call.parameters.expressions[i]);; expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.integer_type); if (expr is int_const_node && (expr as int_const_node).constant_value < 0) AddError(expr.location,"NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", (expr as int_const_node).constant_value); lst.Add(expr); } //это вызов спецфункции expression_node retv = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, loc, to, new int_const_node(lst.Count,loc)); common_namespace_function_call cnfc = retv as common_namespace_function_call; foreach (expression_node e in lst) cnfc.parameters.AddElement(e); expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CopyWithSizeFunction.sym_info as function_node,loc,param0,cnfc); function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, retv.type, false); en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en); basic_function_call bfc = new basic_function_call(tn.find(compiler_string_consts.assign_name).sym_info as basic_function_node,loc,param0,en); return_value(bfc); return; } } } } else if (SystemLibrary.SystemLibInitializer.InsertProcedure.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3) { //expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); //expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); if (param1.type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); param0 = convertion_data_and_alghoritms.convert_type(param0,SystemLibrary.SystemLibrary.string_type); param2 = convertion_data_and_alghoritms.convert_type(param2,SystemLibrary.SystemLibrary.integer_type); base_function_call cnfn = null; if (SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info is common_namespace_function_node) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); cnfn.parameters.AddElement(param2); cnfn.parameters.AddElement(new int_const_node((param1.type as short_string_type_node).Length,null)); switch (mot) { case motivation.expression_evaluation: { return_value(cnfn); return; } case motivation.semantic_node_reciving: { return_semantic_value(cnfn); return; } default: { AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else if (SystemLibrary.SystemLibInitializer.DeleteProcedure.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3) { //expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); //expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); param2 = convertion_data_and_alghoritms.convert_type(param2,SystemLibrary.SystemLibrary.integer_type); base_function_call cnfn = null; if (SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info is common_namespace_function_node) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as compiled_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); cnfn.parameters.AddElement(param2); switch (mot) { case motivation.expression_evaluation: { return_value(cnfn); return; } case motivation.semantic_node_reciving: { return_semantic_value(cnfn); return; } default: { AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si) || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 2) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); expressions_list args = new expressions_list(); args.AddElement(param0); args.AddElement(param1); CheckSpecialFunctionCall(si,args,get_location(_method_call)); expression_node en_cnfn = null; if (SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info is common_namespace_function_node) { common_namespace_function_call cnfn = null; if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si)) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); else cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); en_cnfn = cnfn; } else { compiled_static_method_call cnfn = null; if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si)) cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as compiled_function_node, get_location(_method_call)); else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as compiled_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); en_cnfn = cnfn; } switch (mot) { case motivation.expression_evaluation: { return_value(en_cnfn); return; } case motivation.semantic_node_reciving: { return_semantic_value(en_cnfn); return; } default: { AddError(en_cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } else if (SystemLibrary.SystemLibInitializer.IncProcedure.Equal(si)) { expression_node bfcint = make_inc_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.DecProcedure.Equal(si)) { expression_node bfcint = make_dec_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.SuccFunction.Equal(si)) { expression_node bfcint = make_succ_call(si, _method_call.parameters, subloc2); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.PredFunction.Equal(si)) { expression_node bfcint = make_pred_call(si, _method_call.parameters, subloc2); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.OrdFunction.Equal(si)) { expression_node bfcint = make_ord_call(si, _method_call.parameters, subloc2); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.LowFunction.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) { bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),get_location(_method_call)); switch (mot) { case motivation.expression_evaluation: { return_value(en); return; } case motivation.semantic_node_reciving: { return_semantic_value(en); return; } default: { AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else if (SystemLibrary.SystemLibInitializer.HighFunction.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) { bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.upper_value),get_location(_method_call)); switch (mot) { case motivation.expression_evaluation: { return_value(en); return; } case motivation.semantic_node_reciving: { return_semantic_value(en); return; } default: { AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else if (si == SystemLibrary.SystemLibInitializer.NewProcedure) { expression_node bfcint = make_new_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (si == SystemLibrary.SystemLibInitializer.DisposeProcedure) { //if (convertion_data_and_alghoritms.select_function(convert_expression_list(_method_call.parameters.expressions), si, subloc2) == SystemLibrary.SystemLibInitializer.DisposeProcedure.sym_info) //{ expression_node bfcint = make_dispose_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; // } } else if (!debug && SystemLibrary.SystemLibInitializer.AssertProcedure.Equal(si)) { // return_value(new empty_statement(null)); // return; } /*else if (SystemLibrary.SystemLibInitializer.IncProcedure != null && SystemLibrary.SystemLibInitializer.IncProcedure.Equal(si)) { expression_node bfcint = make_inc_call(si, _method_call.parameters, subloc2); }*/ if (si.sym_info.general_node_type != general_node_type.function_node) { if (si.sym_info.general_node_type == general_node_type.type_node) { to_type = ((type_node)(si.sym_info)); /*if (to_type == SystemLibrary.SystemLibrary.void_type) { throw new VoidNotValid(subloc2); }*/ check_for_type_allowed(to_type,subloc2); } else { exp2 = ident_value_reciving(si, id); internal_interface ii = exp2.type.get_internal_interface(internal_interface_kind.delegate_interface); if (ii == null) { AddError(subloc2, "EXPECTED_DELEGATE"); } if (exp2 is nonstatic_event_reference) { nonstatic_event_reference nser = exp2 as nonstatic_event_reference; common_event ce = nser.en as common_event; if (ce != null) exp2 = new class_field_reference(ce.field,new this_node(ce.cont_type,null),null); else AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name); } else if (exp2 is static_event_reference) { static_event_reference nser = exp2 as static_event_reference; common_event ce = nser.en as common_event; if (ce != null) exp2 = new static_class_field_reference(ce.field, null); else if (nser.en is common_namespace_event && _compiled_unit.namespaces.IndexOf((nser.en as common_namespace_event).namespace_node) != -1) exp2 = new namespace_variable_reference((nser.en as common_namespace_event).field, null); else AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name); } delegate_internal_interface dii = ii as delegate_internal_interface; si = new SymbolInfo(dii.invoke_method); } } if (to_type != null) { if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) { AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED"); } } if (_method_call.parameters != null) { foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { bool tmp = is_format_allowed; #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов //lroman// if (en is SyntaxTree.function_lambda_definition) { lambdas_are_in_parameters = true; ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; } //lroman// #endregion exprs.AddElement(convert_strong(en)); is_format_allowed = tmp; } } is_format_allowed = false; CheckSpecialFunctionCall(si, exprs,get_location(_method_call)); ssi=si; foreach (SymbolInfo sii in sibak) { ssi.Next = sii; ssi = sii; } if (to_type != null) { //(ssyy) К вызову функции здесь явно не приводим, т.к. это излишне. expression_node ee = exprs[0]; bool del = to_type is common_type_node && (to_type as common_type_node).IsDelegate; if (!del) try_convert_typed_expression_to_function_call(ref ee); else ee = convert_strong(_method_call.parameters.expressions[0]); expr_node = convertion_data_and_alghoritms.explicit_convert_type(ee, to_type); //expression_node expr = convert_if_typed_expression_to_function_call(exprs[0]); //expr_node = convertion_data_and_alghoritms.explicit_convert_type(expr, to_type); } else { if (exp2 == null) { location mcloc = get_location(_method_call); if (iwt != null) { si = get_generic_functions(si, true, mcloc); si = get_function_instances(si, iwt.template_params.params_list, id.name, mcloc, si.Next == null); } #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим //lroman// if (lambdas_are_in_parameters) { LambdaHelper.processingLambdaParametersForTypeInference++; // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями function_node_list spf = null; try { function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc2, syntax_nodes_parameters); int exprCounter = 0; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var enLambda = (SyntaxTree.function_lambda_definition) en; LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, enLambda, this); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; exprs[exprCounter] = convert_strong(en); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; exprCounter++; } } } catch (SeveralFunctionsCanBeCalled sf) { spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна } Exception lastmultex = null; if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try { // exprs - глобальная, поэтому надо копировать int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! И еще выше по коду!!! кошмар!!! int GoodVersionsCount = 0; int GoodVersionsCountWithSameResType = 0; for (int i = 0; i < spf.Count; i++) // цикл по версиям { function_node fn = spf[i]; try // внутренний try регенерирует исключение, а этот гасит { int exprCounter = 0; expressions_list exprs1 = new expressions_list(); exprs1.AddRange(exprs); // сделали копию foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var fld = en as SyntaxTree.function_lambda_definition; var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо var fl = fld.lambda_visit_mode; // запомнили типы параметров лямбды - SSM object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK == null) realparamstype[k] = null; else realparamstype[k] = laminftypeK.real_type; } // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим var restype = fld.return_type as SyntaxTree.lambda_inferred_type; object realrestype = null; if (restype != null) realrestype = restype.real_type; LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, fld, this); fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! //contextChanger.SaveContextAndUpToNearestDefSect(); try { exprs1[exprCounter] = convert_strong(en); // SSM 7/08/15 type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; type_node resformaltype = fld.RealSemTypeOfResult as type_node; var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } /*var tt = fn.parameters[exprCounter].type as compiled_type_node; if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) { resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } }*/ } catch { throw; } finally { LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); // восстанавливаем сохраненный тип возвращаемого значения if (restype != null) restype.real_type = realrestype; // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK != null) laminftypeK.real_type = realparamstype[k]; } fld.lambda_name = lambdaName; //lroman Восстанавливаем имена fld.lambda_visit_mode = fl; } //contextChanger.RestoreCurrentContext(); exprCounter++; } } /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так { spfnum = -2; break; }*/ if (GoodVersionsCountWithSameResType==0) spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения GoodVersionsCount += 1; for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо exprs[j] = exprs1[j]; } catch (Exception e) { // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать //contextChanger.RestoreCurrentContext(); lastmultex = e; } } //--------------- конец цикла по версиям if (GoodVersionsCount>1 && GoodVersionsCountWithSameResType!=1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения throw new SeveralFunctionsCanBeCalled(subloc2, spf); if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд { throw lastmultex; //throw new NoFunctionWithSameArguments(subloc2, false); } var kk = 0; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды { if (!(en is SyntaxTree.function_lambda_definition)) { kk++; continue; } else { LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); exprs[kk] = convert_strong(en); kk++; } } } // SSM 21.05.14 end LambdaHelper.processingLambdaParametersForTypeInference--; } //lroman// #endregion expr_node = convertion_data_and_alghoritms.create_full_function_call(exprs, si, mcloc, context.converted_type, context.top_function, proc_wait); } else { function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc2, syntax_nodes_parameters); base_function_call bbffcc = create_not_static_method_call(fn, exp2, subloc2, proc_wait); bbffcc.parameters.AddRange(exprs); expr_node = bbffcc; } } /*if ((proc_wait==false)&&(expr_node.type==null)) { throw new FunctionExpectedProcedureMeet((function_node)dn,get_location(_method_call)); }*/ switch (mot) { case motivation.expression_evaluation: { return_value(expr_node); return; } case motivation.semantic_node_reciving: { return_semantic_value(expr_node); return; } case motivation.address_reciving: { AddError(get_location(_method_call), "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); return; } default: { //throw new CompilerInternalError("Can not recive address from method call");//! AddError(get_location(_method_call), "EXPECTED_VARIABLE"); return; } } //throw new CompilerInternalError("Error in creation method call"); }
private expression_node make_dispose_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) { if (parameters == null) { AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); return null; } if (parameters.expressions.Count == 1) { expression_node param0 = convert_strong(parameters.expressions[0]); if (!param0.type.IsPointer || param0.type == SystemLibrary.SystemLibrary.pointer_type) AddError(new NoFunctionWithSameArguments(loc, true)); if (!param0.is_addressed) { bool is_pascal_array_ref = false; if (param0.semantic_node_type == semantic_node_type.common_method_call) { common_method_call cmc = (common_method_call)param0; internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); if (ii != null) { if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) { bounded_array_interface bai = (bounded_array_interface)ii; class_field cf = bai.int_array; expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); expression_node right = cmc.parameters[0]; //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); is_pascal_array_ref = true; } } if (!is_pascal_array_ref) { AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); return null; } } else { AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); return null; } } function_node fn = si.sym_info as function_node; common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); cnfc.parameters.AddElement(param0); return cnfc; } else { AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); return null; } }
private void check_field_reference_for_assign(class_field_reference expr, location loc) { if (expr.obj is namespace_constant_reference || expr.obj is function_constant_reference) AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); else if (expr.obj is class_field_reference) check_field_reference_for_assign(expr.obj as class_field_reference,loc); else if (expr.obj is simple_array_indexing) check_expression_for_assign((expr.obj as simple_array_indexing).simple_arr_expr,loc); }
internal function_node GenerateGetMethodForField(common_property_node cpn, string AcessorName, class_field cf, location loc) { SymbolInfo exist_si = context.find_only_in_namespace(AcessorName); if (exist_si != null && exist_si.sym_info.general_node_type != general_node_type.function_node) { AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); } while (exist_si != null) { if (((function_node)(exist_si.sym_info)).parameters.Count == 0) { AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); } exist_si = exist_si.Next; } common_method_node cmn = new common_method_node( AcessorName, loc, cf.cont_type, cf.polymorphic_state, context.get_field_access_level(), null); cpn.common_comprehensive_type.methods.AddElement(cmn); cmn.return_value_type = cf.type; cmn.is_overload = true; expression_node var_ref; if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_common) { var_ref = new class_field_reference(cf, new this_node(cf.type, loc), loc); } else { var_ref = new static_class_field_reference(cf, loc); } cmn.function_code = new return_node(var_ref, loc); cf.cont_type.scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); return cmn; }
private void indexer_as_expression_index(expression_node expr, SyntaxTree.expression_list parameters, motivation mot, location loc) { try_convert_typed_expression_to_function_call(ref expr); // SSM 10.01.16 Tuple t[i] var ent = expr.type as compiled_type_node; if (ent== null) { var eeee = expr.type as compiled_generic_instance_type_node; if (eeee!= null) ent = eeee.original_generic as compiled_type_node; } if (ent != null) { var t = ent.compiled_type; if (t.FullName.StartsWith("System.Tuple")) { expression eee = parameters.expressions[0]; if (parameters.expressions.Count > 1) AddError(get_location(eee), "TUPLE_CAN_HAVE_ONLY_ONE_INDEX"); var cn = convert_strong_to_constant_node(eee); var v = cn as int_const_node; if (v != null) { if (v.constant_value<0 || v.constant_value >= t.GetGenericArguments().Count()) AddError(cn.location, "TUPLE_INDEX_OUT_OF_RANGE_{0}", t.GetGenericArguments().Count()-1); var dn = new dot_node(new semantic_addr_value(expr), new ident("Item" + (v.constant_value + 1).ToString(), eee.source_context),new SourceContext(loc.begin_line_num,loc.begin_column_num,loc.end_line_num,loc.end_column_num)); visit(dn); return; } else AddError(cn.location, "TUPLE_INDEX_MUST_BE_INTEGER_CONSTANT"); } } // end SSM 09.01.16 Tuple t[i] if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_kind) { internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.unsized_array_interface); array_internal_interface aii = (array_internal_interface)ii; int rank = aii.rank; //TODO: Многомерные массивы. expression_node ind_expr = convert_strong(parameters.expressions[0]); ind_expr = additional_indexer_convertion(ind_expr, expr.type); simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc); if (rank == 1) for (int i = 1; i < parameters.expressions.Count; i++) { ii = sai.type.get_internal_interface(internal_interface_kind.unsized_array_interface); location lloc = get_location(parameters.expressions[i]); if (ii == null) { AddError(lloc, "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", i, i+1); } aii = (array_internal_interface)ii; ind_expr = convert_strong(parameters.expressions[i]); ind_expr = additional_indexer_convertion(ind_expr, sai.type); sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc); } else { if (rank != parameters.expressions.Count) AddError(get_location(parameters), "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", rank, rank + 1); List<expression_node> lst = new List<expression_node>(); for (int i = 0; i < parameters.expressions.Count; i++) { location lloc = get_location(parameters.expressions[i]); ind_expr = convert_strong(parameters.expressions[i]); ind_expr = additional_indexer_convertion(ind_expr, sai.type); lst.Add(ind_expr); } sai = new simple_array_indexing(expr, lst[0], aii.element_type, get_location(parameters)); sai.expr_indices = lst.ToArray(); } switch (mot) { case motivation.address_reciving: { return_addressed_value(sai); break; } case motivation.expression_evaluation: { return_value(sai); break; } case motivation.semantic_node_reciving: { return_semantic_value(sai); break; } } return; } else if (expr.type.type_special_kind == SemanticTree.type_special_kind.short_string) { if (parameters.expressions.Count != 1) AddError(loc, "INVALID_PARAMETER_COUNT_IN_INDEXER"); expression_node ind_expr = convert_strong(parameters.expressions[0]); ind_expr = additional_indexer_convertion(ind_expr, expr.type); //expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null)); switch (mot) { case motivation.address_reciving: { simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, SystemLibrary.SystemLibrary.char_type, loc); return_addressed_value(sai); //return_addressed_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr) as common_namespace_function_call); break; } case motivation.expression_evaluation: { return_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null))); break; } case motivation.semantic_node_reciving: { return_semantic_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null))); break; } } return; } /*else if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) { internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.bounded_array_interface); array_internal_interface aii = (array_internal_interface)ii; //TODO: Многомерные массивы. expression_node ind_expr = convert_strong(parameters.expressions[0]); ind_expr = additional_indexer_convertion(ind_expr, expr.type); simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc); for (int i = 1; i < parameters.expressions.Count; i++) { ii = sai.type.get_internal_interface(internal_interface_kind.bounded_array_interface); location lloc = get_location(parameters.expressions[i]); if (ii == null) { throw new NDimensionalArrayCanNotHaveNPlusOneIndexer(lloc, expr, i); } aii = (array_internal_interface)ii; ind_expr = convert_strong(parameters.expressions[i]); ind_expr = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, ind_expr, new int_const_node(ii.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location)); ind_expr = additional_indexer_convertion(ind_expr, sai.type); sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc); } switch (mot) { case motivation.address_reciving: { return_addressed_value(sai); break; } case motivation.expression_evaluation: { return_value(sai); break; } case motivation.semantic_node_reciving: { return_semantic_value(sai); break; } } return; if (factparams[i].semantic_node_type == semantic_node_type.common_method_call) { common_method_call cmc = (common_method_call)factparams[i]; internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); if (ii != null) { if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) { bounded_array_interface bai = (bounded_array_interface)ii; class_field cf = bai.int_array; expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); expression_node right = cmc.parameters[0]; //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); right = convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location)); factparams[i] = new simple_array_indexing(left, right, cmc.type, cmc.location); is_pascal_array_ref = true; } } } }*/ if (expr.type.default_property_node == null) { if (expr.type.semantic_node_type != semantic_node_type.delegated_method) { AddError(loc, "NO_DEFAULT_PROPERTY_TO_TYPE_{0}", expr.type.PrintableName); } else { AddError(loc, "NO_DEFAULT_PROPERTY_TO_FUNCTION_TYPE"); } } if (expr.type.default_property_node.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotReferenceToStaticPropertyWithExpression(expr.type.default_property_node, loc, expr.type)); } non_static_property_reference nspr = new non_static_property_reference(expr.type.default_property_node, expr, loc); indexer_as_property_indexes(nspr, parameters, mot, loc); //eto vrode rabotaet normalno. no imet v vidu if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) { expression_node en = ret.get_expression(); if (en is non_static_property_reference) { non_static_property_reference cmc = (non_static_property_reference)en; internal_interface ii = cmc.expression.type.get_internal_interface(internal_interface_kind.bounded_array_interface); if (ii != null) { //if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) { bounded_array_interface bai = (bounded_array_interface)ii; class_field cf = bai.int_array; expression_node left = new class_field_reference(cf, cmc.expression, cmc.location); expression_node right = cmc.fact_parametres[0]; //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); en = new simple_array_indexing(left, right, cmc.type, cmc.location); //is_pascal_array_ref = true; } } } else { common_method_call cmc = (common_method_call)en; internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); if (ii != null) { //if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) { bounded_array_interface bai = (bounded_array_interface)ii; class_field cf = bai.int_array; expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); expression_node right = cmc.parameters[0]; //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); en = new simple_array_indexing(left, right, cmc.type, cmc.location); //is_pascal_array_ref = true; } } } return_value(en); } return; }
/// <summary> /// Возвращает список преобразований типов для вызова метода. /// </summary> /// <param name="factparams">Список фактических параметров.</param> /// <param name="formalparams">Список формальных параметров.</param> /// <param name="is_alone_method_defined">Для единственного метода у которого типы параметров совпадают, но в качестве var параметра мы передаем константное значение мы можем сгенерировать более подробное сообщение об ошибке.</param> /// <returns>Список преобразований типов.</returns> internal possible_type_convertions_list get_conversions(expressions_list factparams, parameter_list formalparams,bool is_alone_method_defined, location locg) { //TODO:Явно указывать capacity при создании. possible_type_convertions_list tc = new possible_type_convertions_list(); possible_type_convertions ptc; if (factparams.Count>formalparams.Count) { if ( (formalparams.Count==0) || (!(formalparams[formalparams.Count-1].is_params)) ) { return null; } } type_node for_par_type = null; array_internal_interface aii=null; if (formalparams.Count > 0) { parameter pr=formalparams[formalparams.Count - 1]; if (pr.is_params && //это для возможности вызова сразу с массивом[], типа просто не обращаем внимаение на params !(factparams.Count == formalparams.Count && factparams[factparams.Count - 1].type == formalparams[formalparams.Count - 1].type)) { //TODO: Добавить проверку на правильность. aii = (array_internal_interface) pr.type.get_internal_interface(internal_interface_kind.unsized_array_interface); for_par_type = aii.element_type; tc.snl = new statement_node_list(); location loc=null; if (factparams.Count > 0) loc = factparams[factparams.Count-1].location; //var_definition_node vdn=syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(),loc); var_definition_node vdn = null; if (syntax_tree_visitor.context.converted_func_stack.size > 0) { common_function_node cfn = syntax_tree_visitor.context.converted_func_stack.first(); if (cfn.is_generic_function) { vdn = syntax_tree_visitor.context.add_var_definition(get_temp_arr_name(), loc); } else vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc); } else if (syntax_tree_visitor.context.converted_type != null) vdn = syntax_tree_visitor.context.add_field(get_temp_arr_name(), loc, pr.type, polymorphic_state.ps_static); else vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc); syntax_tree_visitor.context.close_var_definition_list(pr.type,null); expression_node fst=null; /*switch (syntax_tree_visitor.context.converting_block()) { case block_type.function_block: { fst=new local_variable_reference((local_variable)vdn,0,loc); break; } case block_type.namespace_block: { fst=new namespace_variable_reference((namespace_variable)vdn,loc); break; } }*/ switch (vdn.semantic_node_type) { case semantic_node_type.local_variable: { fst = new local_variable_reference((local_variable)vdn, 0, loc); break; } case semantic_node_type.namespace_variable: { fst = new namespace_variable_reference((namespace_variable)vdn, loc); break; } case semantic_node_type.local_block_variable: { fst = new local_block_variable_reference((local_block_variable)vdn, loc); break; } case semantic_node_type.class_field: { class_field cf = vdn as class_field; cf.polymorphic_state = polymorphic_state.ps_static; fst = new static_class_field_reference(cf, loc); break; } default: throw new CompilerInternalError("Invalid node type"); } tc.var_ref = fst; int del=factparams.Count-formalparams.Count+1; int_const_node icn=new int_const_node(del,loc); expression_node bfc = create_simple_function_call(SystemLibrary.SystemLibrary.resize_func, loc, fst, icn); tc.snl.AddElement(bfc); /*if (factparams.Count == 0) { possible_type_convertions ptci=new possible_type_convertions(); ptci.first=null; ptci.second=null; ptci.from=null; ptci.to = for_par_type; tc.AddElement(ptci); }*/ } } for(int i=0;i<factparams.Count;i++) { type_node formal_param_type = null; if ((for_par_type!=null)&&(i >= formalparams.Count-1)) { formal_param_type = for_par_type; } else { formal_param_type = formalparams[i].type; } if (possible_equal_types(factparams[i].type, formal_param_type)) { if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var)) { bool is_pascal_array_ref = false; bool is_ok = false; if (factparams[i].is_addressed==false) { if (factparams[i].semantic_node_type == semantic_node_type.common_method_call) { common_method_call cmc = (common_method_call)factparams[i]; internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); if (ii != null) { if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) { bounded_array_interface bai = (bounded_array_interface)ii; class_field cf = bai.int_array; expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); expression_node right = cmc.parameters[0]; //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); right = convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location)); factparams[i] = new simple_array_indexing(left, right, cmc.type, cmc.location); is_pascal_array_ref = true; } } } if (!is_pascal_array_ref) { //Если мы попали сюда, то мы пытаемся передать по ссылке значение, //которое не мохет быть передано по ссылке. Например, передать //по ссылки из одной функции в другую константный параметр. if (is_alone_method_defined) { if (syntax_tree_visitor.assign_is_converting) { AddError(factparams[i].location, "CAN_NOT_ASSIGN_TO_LEFT_PART"); } else { if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const /*&& factparams[i] is common_parameter_reference*/) { is_ok = true; } else if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const) ; //throw new ThisExpressionCanNotBePassedAsConstParameter(factparams[i].location); else if (is_string_getter(factparams[i])) { if (factparams[i] is compiled_function_call) factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call); else factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call); is_ok = true; } else AddError(new ThisExpressionCanNotBePassedAsVarParameter(factparams[i])); } } else if (is_string_getter(factparams[i])) { if (factparams[i] is compiled_function_call) factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call); else factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call); is_ok = true; } if (!is_ok) return null; } } } //Разобраться: может лучше добавлять null к списку. possible_type_convertions ptci=new possible_type_convertions(); ptci.first=null; ptci.second=null; ptci.from=factparams[i].type; ptci.to = formal_param_type; tc.AddElement(ptci); if ((for_par_type != null) && (i >= formalparams.Count - 1)) { expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1], new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location); expression_node from = factparams[i]; statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location); tc.snl.AddElement(stat); } continue; } if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var)) { return null; } else { ptc = type_table.get_convertions(factparams[i].type, formal_param_type); if (ptc.first==null) { if (type_table.is_derived(formal_param_type, factparams[i].type)) { possible_type_convertions ptci=new possible_type_convertions(); ptci.first=null; ptci.second=null; ptci.from=factparams[i].type; ptci.to = formal_param_type; tc.AddElement(ptci); if ((for_par_type != null) && (i >= formalparams.Count - 1)) { expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1], new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location); expression_node from = factparams[i]; statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location); tc.snl.AddElement(stat); } } else { if (is_alone_method_defined) { AddError(new CanNotConvertTypes(factparams[i], factparams[i].type, formal_param_type, locg)); } return null; } } else { tc.AddElement(ptc); if ((for_par_type != null) && (i >= formalparams.Count - 1)) { expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1], new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location); expression_node from = create_simple_function_call(ptc.first.convertion_method, factparams[i].location, factparams[i]); statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location); tc.snl.AddElement(stat); } } } } if (tc.snl != null) foreach (statement_node sn in tc.snl) sn.location = null; return tc; }
private void add_equal_operator_if_need() { SymbolInfo si = _ctn.find_in_type(compiler_string_consts.eq_name); if (si.sym_info is common_method_node) return; SymbolTable.ClassMethodScope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,_ctn.scope); common_method_node cmn = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.eq_name),SystemLibrary.SystemLibrary.bool_type,null,_ctn, SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope); cmn.IsOperator = true; common_parameter prm1 = new common_parameter("a",_ctn,SemanticTree.parameter_type.value,cmn,concrete_parameter_type.cpt_none,null,null); common_parameter prm2 = new common_parameter("b",_ctn,SemanticTree.parameter_type.value,cmn,concrete_parameter_type.cpt_none,null,null); cmn.parameters.AddElement(prm1); cmn.parameters.AddElement(prm2); statements_list body = new statements_list(null); foreach (class_field cf in _ctn.fields) { expression_node left = new class_field_reference(cf,new common_parameter_reference(prm1,0,null),null); expression_node right = new class_field_reference(cf,new common_parameter_reference(prm2,0,null),null); expression_node cond = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.eq_name, left,right,null); basic_function_call bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,null); bfc.parameters.AddElement(cond); if_node if_stmt = new if_node(bfc,new return_node(new bool_const_node(false,null),null),null,null); body.statements.AddElement(if_stmt); } body.statements.AddElement(new return_node(new bool_const_node(true,null),null)); cmn.function_code = body; cmn.is_overload = true; _ctn.methods.AddElement(cmn); _ctn.Scope.AddSymbol(compiler_string_consts.eq_name,new SymbolInfo(cmn)); }
public common_event add_event_definition(string name, location loc, type_node tn, SemanticTree.polymorphic_state ps, bool is_abstract) { class_field cf = new class_field(name + "$", tn, converted_type, ps, _fal, loc); common_event ce = new common_event(name, tn, converted_type, null, null, null, _fal, ps, loc); //add common_method_node add_meth = new common_method_node(compiler_string_consts.GetAddHandler(name), null, this.converted_type, ps, SemanticTree.field_access_level.fal_public, null); common_parameter cp = new common_parameter("value", tn, SemanticTree.parameter_type.value, add_meth, concrete_parameter_type.cpt_none, null, null); add_meth.parameters.AddElement(cp); expression_node fld_ref = null; if (!cf.IsStatic) fld_ref = new class_field_reference(cf, new this_node(converted_type, null), null); else fld_ref = new static_class_field_reference(cf, null); expression_node en = this.syntax_tree_visitor.convertion_data_and_alghoritms.type_constructor.delegate_add_assign_compile_time_executor (null, new expression_node[2] { fld_ref, new common_parameter_reference(cp, 0, null) }); if (!is_abstract) { add_meth.function_code = new statements_list(null); (add_meth.function_code as statements_list).statements.AddElement(en); } converted_type.scope.AddSymbol(add_meth.name, new SymbolInfo(add_meth)); //remove common_method_node remove_meth = new common_method_node(compiler_string_consts.GetRemoveHandler(name), null, this.converted_type, ps, SemanticTree.field_access_level.fal_public, null); cp = new common_parameter("value", tn, SemanticTree.parameter_type.value, add_meth, concrete_parameter_type.cpt_none, null, null); remove_meth.parameters.AddElement(cp); en = this.syntax_tree_visitor.convertion_data_and_alghoritms.type_constructor.delegate_sub_assign_compile_time_executor (null, new expression_node[2] { fld_ref, new common_parameter_reference(cp, 0, null) }); if (!is_abstract) { remove_meth.function_code = new statements_list(null); (remove_meth.function_code as statements_list).statements.AddElement(en); } converted_type.scope.AddSymbol(remove_meth.name, new SymbolInfo(remove_meth)); this.converted_type.methods.AddElement(add_meth); this.converted_type.methods.AddElement(remove_meth); ce.set_add_method(add_meth); ce.set_remove_method(remove_meth); ce.field = cf; this.converted_type.events.AddElement(ce); if (!is_abstract) this.converted_type.fields.AddElement(cf); converted_type.scope.AddSymbol(name, new SymbolInfo(ce)); return ce; }
private type_node create_array_type(ordinal_type_interface oti_indexer, type_node element_type,common_namespace_node _cmn, location loc) { int arr_length = oti_indexer.ordinal_type_to_int(oti_indexer.upper_value) - oti_indexer.ordinal_type_to_int(oti_indexer.lower_value) + 1; if (arr_length <= 0) { throw new SimpleSemanticError(loc, "NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", arr_length); } simple_array sa = new simple_array(element_type, arr_length); //sa.length = arr_length; //sa.element_type = element_type; SymbolTable.Scope top_scope = null; if (_cmn != null) { top_scope = _cmn.scope; } string name = get_pascal_array_name(); //if (_cmn.namespace_name != null) // name = _cmn.namespace_name + name; common_type_node ctn = new common_type_node(null, name, SemanticTree.type_access_level.tal_public, _cmn, convertion_data_and_alghoritms.symbol_table.CreateClassScope(top_scope, null), loc); ctn.SetBaseType(SystemLibrary.SystemLibrary.object_type); //DarkStar Add //loc не нужно мне это! и некому не нужно! //loc = null; //ctn.internal_is_value = true; class_constant_definition cdn1 = new class_constant_definition(compiler_string_consts.lower_array_const_name, oti_indexer.lower_value, loc, ctn, SemanticTree.field_access_level.fal_public); ctn.scope.AddSymbol(cdn1.name, new SymbolInfo(cdn1)); class_constant_definition cdn2 = new class_constant_definition(compiler_string_consts.upper_array_const_name, oti_indexer.upper_value, loc, ctn, SemanticTree.field_access_level.fal_public); ctn.scope.AddSymbol(cdn2.name, new SymbolInfo(cdn2)); class_field int_arr = new class_field(compiler_string_consts.internal_array_name, sa, ctn, SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_public,loc); ctn.scope.AddSymbol(int_arr.name, new SymbolInfo(int_arr)); ctn.fields.AddElement(int_arr); SystemLibrary.SystemLibrary.init_reference_type(ctn); ctn.const_defs.AddElement(cdn1); ctn.const_defs.AddElement(cdn2); common_method_node get_func = new common_method_node(compiler_string_consts.get_val_pascal_array_name, element_type, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), ctn, SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_private, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); common_parameter get_param = new common_parameter(compiler_string_consts.unary_param_name, oti_indexer.lower_value.type, SemanticTree.parameter_type.value, get_func, concrete_parameter_type.cpt_none, null, loc); get_func.parameters.AddElement(get_param); common_parameter_reference cpr = new common_parameter_reference(get_param, 0, loc); expression_node en1 = convertion_data_and_alghoritms.create_simple_function_call(oti_indexer.value_to_int, loc, cpr); expression_node en2 = new int_const_node(oti_indexer.ordinal_type_to_int(oti_indexer.lower_value), loc); expression_node sub_expr = convertion_data_and_alghoritms.create_simple_function_call( SystemLibrary.SystemLibrary.int_sub, loc, en1, en2); this_node thisnode = new this_node(ctn, loc); class_field_reference cfr1 = new class_field_reference(int_arr, thisnode, loc); expression_node index_expr = new simple_array_indexing(cfr1, sub_expr, element_type, loc); statement_node sn = new return_node(index_expr, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc)); get_func.function_code = sn; common_method_node set_func = new common_method_node(compiler_string_consts.set_val_pascal_array_name, null, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), ctn, SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_private, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); common_parameter set_ind = new common_parameter(compiler_string_consts.left_param_name, oti_indexer.lower_value.type, SemanticTree.parameter_type.value, set_func, concrete_parameter_type.cpt_none, null, loc); set_func.parameters.AddElement(set_ind); common_parameter set_val = new common_parameter(compiler_string_consts.right_param_name, element_type, SemanticTree.parameter_type.value, set_func, concrete_parameter_type.cpt_none, null, loc); set_func.parameters.AddElement(set_val); common_parameter_reference cpr2 = new common_parameter_reference(set_ind, 0, loc); expression_node en3 = convertion_data_and_alghoritms.create_simple_function_call(oti_indexer.value_to_int, loc, cpr2); expression_node en4 = new int_const_node(oti_indexer.ordinal_type_to_int(oti_indexer.lower_value), loc); expression_node sub_expr2 = convertion_data_and_alghoritms.create_simple_function_call( SystemLibrary.SystemLibrary.int_sub, loc, en3, en4); class_field_reference cfr2 = new class_field_reference(int_arr, thisnode, loc); expression_node index_expr2 = new simple_array_indexing(cfr2, sub_expr2, element_type,loc); SymbolInfo si = element_type.find_in_type(compiler_string_consts.assign_name); if (si == null) { throw new NotSupportedError(loc); throw new CompilerInternalError("Varable of this type can not be assigned"); } if (si.sym_info.general_node_type != general_node_type.function_node) { throw new CompilerInternalError("Invalid assign operator"); } expression_node val_ref = new common_parameter_reference(set_val, 0, loc); function_node assign = (function_node)si.sym_info; statement_node assign_call = convertion_data_and_alghoritms.create_simple_function_call(assign, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), index_expr2, val_ref); set_func.function_code = assign_call; ctn.methods.AddElement(get_func); ctn.methods.AddElement(set_func); common_property_node cpn = new common_property_node(compiler_string_consts.index_property_pascal_array_name, ctn, element_type, get_func, set_func, loc, SemanticTree.field_access_level.fal_public, SemanticTree.polymorphic_state.ps_common); common_parameter prop_cp = new common_parameter(compiler_string_consts.unary_param_name, oti_indexer.lower_value.type, SemanticTree.parameter_type.value, null, concrete_parameter_type.cpt_none, null, loc); cpn.parameters.AddElement(prop_cp); ctn.properties.AddElement(cpn); ctn.default_property = cpn; if (_cmn != null) { _cmn.types.AddElement(ctn); } bounded_array_interface bai = new bounded_array_interface(oti_indexer, element_type, cpn, oti_indexer.lower_value.type, int_arr); ctn.add_internal_interface(bai); ctn.type_special_kind = SemanticTree.type_special_kind.array_wrapper; if (element_type.type_special_kind != SemanticTree.type_special_kind.array_wrapper) { ctn.ImplementingInterfaces.Add(compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName))); common_method_node en_cmn = new common_method_node(compiler_string_consts.GetEnumeratorMethodName, compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumeratorInterfaceName)), null, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, null); compiled_function_node en_fnc = NetHelper.NetHelper.FindName(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName), compiler_string_consts.GetEnumeratorMethodName).sym_info as compiled_function_node; statements_list sl = new statements_list(null); sl.statements.AddElement(new return_node( new compiled_function_call(en_fnc, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null)); en_cmn.function_code = sl; en_cmn.newslot_awaited = true; ctn.methods.AddElement(en_cmn); if (!element_type.IsPointer) { List<type_node> generic_args = new List<type_node>(); generic_args.Add(element_type); type_node en_tn = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumerableInterfaceName)).get_instance(generic_args); ctn.ImplementingInterfaces.Add(en_tn); en_cmn = new common_method_node(compiler_string_consts.GetEnumeratorMethodName, compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumeratorInterfaceName)).get_instance(generic_args), null, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, null); //en_fnc = en_tn.find_in_type("GetEnumerator").sym_info as function_node;//NetHelper.NetHelper.FindName(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumerableInterfaceName), compiler_string_consts.GetEnumeratorMethodName).sym_info as compiled_function_node; SymbolInfo en_si = en_tn.find_in_type("GetEnumerator"); if (en_si.Next != null && (en_si.Next.sym_info as function_node).return_value_type.is_generic_type_instance) en_si = en_si.Next; function_node en_fnc_inst = en_si.sym_info as function_node; ;//.get_instance(generic_args, true, loc); sl = new statements_list(null); if (en_fnc_inst is compiled_function_node) sl.statements.AddElement(new return_node( new compiled_function_call(en_fnc_inst as compiled_function_node, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null)); else sl.statements.AddElement(new return_node( new common_method_call(en_fnc_inst as common_method_node, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null)); en_cmn.function_code = sl; en_cmn.newslot_awaited = true; ctn.methods.AddElement(en_cmn); } } //= operation SymbolTable.ClassMethodScope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope); common_method_node cmn_eq = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.eq_name),SystemLibrary.SystemLibrary.bool_type,null,ctn, SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope); cmn_eq.IsOperator = true; common_parameter prm1 = new common_parameter("a",ctn,SemanticTree.parameter_type.value,cmn_eq,concrete_parameter_type.cpt_none,null,null); common_parameter prm2 = new common_parameter("b",ctn,SemanticTree.parameter_type.value,cmn_eq,concrete_parameter_type.cpt_none,null,null); cmn_eq.parameters.AddElement(prm1); cmn_eq.parameters.AddElement(prm2); statements_list body = new statements_list(null); local_variable vdn = new local_variable("$i",SystemLibrary.SystemLibrary.integer_type,cmn_eq,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null); cmn_eq.var_definition_nodes_list.AddElement(vdn); expression_node var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null); basic_function_call cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node,null); cond.parameters.AddElement(var_ref); cond.parameters.AddElement(new int_const_node(arr_length,null)); while_node while_stmt = new while_node(cond,null); statements_list while_body = new statements_list(null); while_stmt.body = while_body; simple_array_indexing left_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm1,0,null), null),var_ref,element_type,null); simple_array_indexing right_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm2,0,null), null),var_ref,element_type,null); expression_node cond2 = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.noteq_name, left_sar,right_sar,null); if_node if_stmt = new if_node(cond2,new return_node(new bool_const_node(false,null),null),null,null); while_body.statements.AddElement(if_stmt); while_body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,null ,var_ref,new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,null,var_ref,new int_const_node(1,null)))); body.statements.AddElement(while_stmt); body.statements.AddElement(new return_node(new bool_const_node(true,null),null)); cmn_eq.function_code = body; cmn_eq.is_overload = true; ctn.methods.AddElement(cmn_eq); ctn.Scope.AddSymbol(compiler_string_consts.eq_name,new SymbolInfo(cmn_eq)); //<> operation scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope); common_method_node cmn_noteq = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.noteq_name),SystemLibrary.SystemLibrary.bool_type,null,ctn, SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope); cmn_noteq.IsOperator = true; prm1 = new common_parameter("a",ctn,SemanticTree.parameter_type.value,cmn_noteq,concrete_parameter_type.cpt_none,null,null); prm2 = new common_parameter("b",ctn,SemanticTree.parameter_type.value,cmn_noteq,concrete_parameter_type.cpt_none,null,null); cmn_noteq.parameters.AddElement(prm1); cmn_noteq.parameters.AddElement(prm2); body = new statements_list(null); vdn = new local_variable("$i",SystemLibrary.SystemLibrary.integer_type,cmn_noteq,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null); cmn_noteq.var_definition_nodes_list.AddElement(vdn); var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null); cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node,null); cond.parameters.AddElement(var_ref); cond.parameters.AddElement(new int_const_node(arr_length,null)); while_stmt = new while_node(cond,null); while_body = new statements_list(null); while_stmt.body = while_body; left_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm1,0,null), null),var_ref,element_type,null); right_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm2,0,null), null),var_ref,element_type,null); cond2 = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.noteq_name, left_sar,right_sar,null); if_stmt = new if_node(cond2,new return_node(new bool_const_node(true,null),null),null,null); while_body.statements.AddElement(if_stmt); while_body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,null ,var_ref,new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,null,var_ref,new int_const_node(1,null)))); body.statements.AddElement(while_stmt); body.statements.AddElement(new return_node(new bool_const_node(false,null),null)); cmn_noteq.function_code = body; cmn_noteq.is_overload = true; ctn.methods.AddElement(cmn_noteq); ctn.Scope.AddSymbol(compiler_string_consts.noteq_name,new SymbolInfo(cmn_noteq)); //Equals /*scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope); common_method_node cmn_equals = new common_method_node("Equals",SystemLibrary.SystemLibrary.bool_type,null,ctn, SemanticTree.polymorphic_state.ps_virtual,SemanticTree.field_access_level.fal_public,scope); prm1 = new common_parameter("a",SystemLibrary.SystemLibrary.object_type,SemanticTree.parameter_type.value,cmn_equals,concrete_parameter_type.cpt_none,null,null); cmn_equals.parameters.AddElement(prm1); body = new statements_list(null); vdn = new local_variable("$i",ctn,cmn_equals,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null); cmn_equals.var_definition_nodes_list.AddElement(vdn); var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null); as_node _as = new as_node(new common_parameter_reference(prm1,0,null),ctn,null); base_function_call ass_bfc = new basic_function_call(SystemLibrary.SystemLibrary.object_type.find(compiler_string_consts.assign_name).sym_info as basic_function_node,null); ass_bfc.parameters.AddElement(var_ref); ass_bfc.parameters.AddElement(_as); body.statements.AddElement(ass_bfc); common_static_method_call csmc = new common_static_method_call(ctn.find_in_type(compiler_string_consts.eq_name).sym_info as common_method_node,null); csmc.parameters.AddElement(new this_node(ctn,null)); csmc.parameters.AddElement(var_ref); body.statements.AddElement(new return_node(csmc,null)); ctn.methods.AddElement(cmn_equals); ctn.Scope.AddSymbol("Equals",new SymbolInfo(cmn_equals));*/ return ctn; }